{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export class WordSensor {\n  private forbiddenWords: Map<string, string | null>;\n  private maskChar: string;\n  private caseInsensitive: boolean;\n  private logDetections: boolean;\n  private detectionLogs: string[];\n\n  constructor(\n    words: string[] = [],\n    maskChar = \"*\",\n    caseInsensitive = true,\n    logDetections = false\n  ) {\n    this.forbiddenWords = new Map();\n    this.maskChar = maskChar;\n    this.caseInsensitive = caseInsensitive;\n    this.logDetections = logDetections;\n    this.detectionLogs = [];\n\n    words.forEach((word) => this.addWord(word));\n  }\n\n  addWord(word: string, mask?: string) {\n    const key = this.caseInsensitive ? word.toLowerCase() : word;\n    this.forbiddenWords.set(key, mask ?? null);\n  }\n\n  addWords(words: string[]) {\n    words.forEach((word) => this.addWord(word));\n  }\n\n  removeWord(word: string) {\n    const key = this.caseInsensitive ? word.toLowerCase() : word;\n    this.forbiddenWords.delete(key);\n  }\n\n  removeWords(words: string[]) {\n    words.forEach((word) => this.removeWord(word));\n  }\n\n  private applyMask(word: string, maskType: \"full\" | \"partial\"): string {\n    if (maskType === \"partial\" && word.length > 2) {\n      return (\n        word[0] + this.maskChar.repeat(word.length - 2) + word[word.length - 1]\n      );\n    }\n    return this.maskChar.repeat(word.length);\n  }\n\n  filter(\n    text: string,\n    mode: \"replace\" | \"remove\" = \"replace\",\n    maskType: \"full\" | \"partial\" = \"full\"\n  ): string {\n    if (this.forbiddenWords.size === 0) return text;\n\n    const regex = new RegExp(\n      `\\\\b(${[...this.forbiddenWords.keys()]\n        .map((w) => w.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, \"\\\\$&\"))\n        .join(\"|\")})\\\\b`,\n      this.caseInsensitive ? \"gi\" : \"g\"\n    );\n\n    return text.replace(regex, (match) => {\n      const key = this.caseInsensitive ? match.toLowerCase() : match;\n\n      if (this.logDetections) {\n        this.detectionLogs.push(match);\n      }\n\n      if (mode === \"remove\") return \"\";\n\n      // Jika ada custom mask, gunakan itu, jika tidak, gunakan `applyMask()`\n      return this.forbiddenWords.get(key) ?? this.applyMask(match, maskType);\n    });\n  }\n\n  detect(text: string): string[] {\n    if (this.forbiddenWords.size === 0) return [];\n\n    const regex = new RegExp(\n      `\\\\b(${[...this.forbiddenWords.keys()]\n        .map((w) => w.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, \"\\\\$&\"))\n        .join(\"|\")})\\\\b`,\n      this.caseInsensitive ? \"gi\" : \"g\"\n    );\n\n    const matches: string[] = [];\n    let match;\n    while ((match = regex.exec(text)) !== null) {\n      matches.push(match[0]);\n    }\n\n    return matches;\n  }\n\n  getDetectionLogs(): string[] {\n    return this.detectionLogs;\n  }\n}\n\nexport function getNestedValue(obj: any, path: string): any {\n  return path\n    .split(\".\")\n    .reduce((acc, key) => (acc && acc[key] !== undefined ? acc[key] : undefined), obj);\n}\n\nexport async function loadForbiddenWordsFromAPI(\n  url: string,\n  path: string | null,\n  sensor: WordSensor\n) {\n  try {\n    const response = await fetch(url);\n    if (!response.ok) {\n      throw new Error(`Failed to fetch: ${response.statusText}`);\n    }\n\n    const data = await response.json();\n\n    let words: string[] = [];\n\n    if (Array.isArray(data)) {\n      words = data; // Jika API langsung berupa array\n    } else if (path) {\n      words = getNestedValue(data, path) ?? [];\n    }\n\n    if (!Array.isArray(words)) {\n      throw new Error(\"Invalid words format from API\");\n    }\n\n    sensor.addWords(words);\n    console.log(\"Forbidden words added from API:\", words);\n  } catch (error) {\n    console.error(\"Error loading forbidden words:\", error);\n  }\n}"],"mappings":"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","names":[]}