{"version":3,"file":"utils.cjs","names":["UNESCAPE_R","CR_NEWLINE_R","FORMFEED_R","TAB_R","HTML_CUSTOM_ATTR_R","CAPTURE_LETTER_AFTER_HYPHEN","ATTRIBUTES_TO_SANITIZE","INTERPOLATION_R","TABLE_RIGHT_ALIGN","TABLE_CENTER_ALIGN","TABLE_LEFT_ALIGN","TABLE_TRIM_PIPES"],"sources":["../../../src/markdown/utils.ts"],"sourcesContent":["import {\n  ATTRIBUTES_TO_SANITIZE,\n  CAPTURE_LETTER_AFTER_HYPHEN,\n  CR_NEWLINE_R,\n  DURATION_DELAY_TRIGGER,\n  FORMFEED_R,\n  HTML_CUSTOM_ATTR_R,\n  INTERPOLATION_R,\n  TAB_R,\n  TABLE_CENTER_ALIGN,\n  TABLE_LEFT_ALIGN,\n  TABLE_RIGHT_ALIGN,\n  TABLE_TRIM_PIPES,\n  UNESCAPE_R,\n} from './constants';\nimport type { NestedParser, ParserResult, ParseState, Rule } from './types';\n\n// ============================================================================\n// STRING UTILITIES\n// ============================================================================\n\n/**\n * Trim trailing whitespace from a string.\n */\nexport const trimEnd = (str: string): string => {\n  let end = str.length;\n\n  while (end > 0 && str[end - 1] <= ' ') end--;\n\n  return str.slice(0, end);\n};\n\n/**\n * Check if string starts with prefix.\n */\nexport const startsWith = (str: string, prefix: string): boolean => {\n  return str.startsWith(prefix);\n};\n\n/**\n * Remove symmetrical leading and trailing quotes.\n */\nexport const unquote = (str: string): string => {\n  const first = str[0];\n\n  if (\n    (first === '\"' || first === \"'\") &&\n    str.length >= 2 &&\n    str[str.length - 1] === first\n  ) {\n    return str.slice(1, -1);\n  }\n\n  return str;\n};\n\n/**\n * Unescape backslash-escaped characters.\n */\nexport const unescapeString = (rawString: string): string =>\n  rawString ? rawString.replace(UNESCAPE_R, '$1') : rawString;\n\n/**\n * Join class names, filtering out falsy values.\n */\nexport const cx = (...args: any[]): string => args.filter(Boolean).join(' ');\n\n/**\n * Get a nested property from an object using dot notation.\n */\nexport const get = (src: any, path: string, fb?: any): any => {\n  let ptr = src;\n  const frags = path.split('.');\n\n  while (frags.length) {\n    ptr = ptr[frags[0]];\n\n    if (ptr === undefined) break;\n    else frags.shift();\n  }\n\n  return ptr ?? fb;\n};\n\n// ============================================================================\n// SLUGIFY\n// ============================================================================\n\n/**\n * Convert a string to a URL-safe slug.\n * Based on https://stackoverflow.com/a/18123682/1141611\n */\nexport const slugify = (str: string): string =>\n  str\n    .replace(/[ÀÁÂÃÄÅàáâãäåæÆ]/g, 'a')\n    .replace(/[çÇ]/g, 'c')\n    .replace(/[ðÐ]/g, 'd')\n    .replace(/[ÈÉÊËéèêë]/g, 'e')\n    .replace(/[ÏïÎîÍíÌì]/g, 'i')\n    .replace(/[Ññ]/g, 'n')\n    .replace(/[øØœŒÕõÔôÓóÒò]/g, 'o')\n    .replace(/[ÜüÛûÚúÙù]/g, 'u')\n    .replace(/[ŸÿÝý]/g, 'y')\n    .replace(/[^a-z0-9- ]/gi, '')\n    .replace(/ /gi, '-')\n    .toLowerCase();\n\n// ============================================================================\n// SANITIZER\n// ============================================================================\n\nconst SANITIZE_R = /(javascript|vbscript|data(?!:image)):/i;\n\n/**\n * Sanitize URLs to prevent XSS attacks.\n * Returns null if the URL is unsafe.\n */\nexport const sanitizer = (input: string): string | null => {\n  try {\n    const decoded = decodeURIComponent(input).replace(/[^A-Za-z0-9/:]/g, '');\n\n    if (SANITIZE_R.test(decoded)) {\n      console.warn(\n        'Input contains an unsafe JavaScript/VBScript/data expression, it will not be rendered.',\n        decoded\n      );\n\n      return null;\n    }\n  } catch (_e) {\n    console.warn(\n      'Input could not be decoded due to malformed syntax or characters, it will not be rendered.',\n      input\n    );\n\n    // decodeURIComponent sometimes throws a URIError\n    return null;\n  }\n\n  return input;\n};\n\n// ============================================================================\n// WHITESPACE NORMALIZATION\n// ============================================================================\n\n/**\n * Normalize whitespace in source string.\n */\nexport const normalizeWhitespace = (source: string): string => {\n  const start = performance.now();\n  const result = source\n    .replace(CR_NEWLINE_R, '\\n')\n    .replace(FORMFEED_R, '')\n    .replace(TAB_R, '    ');\n\n  const duration = performance.now() - start;\n\n  if (duration > DURATION_DELAY_TRIGGER) {\n    console.log(\n      `normalizeWhitespace: ${duration.toFixed(3)}ms, source length: ${source.length}`\n    );\n  }\n\n  return result;\n};\n\n/**\n * Safely remove a uniform leading indentation from lines, but do NOT touch\n * the content inside fenced code blocks (``` or ~~~).\n */\nexport const trimLeadingWhitespaceOutsideFences = (\n  text: string,\n  whitespace: string\n): string => {\n  const start = performance.now();\n  if (!whitespace) return text;\n\n  const lines = text.split('\\n');\n\n  // Strip the base structural indentation from every line uniformly.\n  // Lines that don't start with the whitespace prefix are left as-is,\n  // which correctly preserves relative indentation inside code fences.\n  const result = lines\n    .map((line) =>\n      line.startsWith(whitespace) ? line.slice(whitespace.length) : line\n    )\n    .join('\\n');\n\n  const duration = performance.now() - start;\n  if (duration > DURATION_DELAY_TRIGGER) {\n    console.log(\n      `trimLeadingWhitespaceOutsideFences: ${duration.toFixed(3)}ms, text length: ${text.length}, lines count: ${lines.length}`\n    );\n  }\n\n  return result;\n};\n\n/**\n * Normalize HTML attribute key to JSX prop name.\n */\nexport const normalizeAttributeKey = (key: string): string => {\n  const hyphenIndex = key.indexOf('-');\n\n  if (hyphenIndex !== -1 && key.match(HTML_CUSTOM_ATTR_R) === null) {\n    key = key.replace(CAPTURE_LETTER_AFTER_HYPHEN, (_, letter) => {\n      return letter.toUpperCase();\n    });\n  }\n\n  return key;\n};\n\ntype StyleTuple = [key: string, value: string];\n\n/**\n * Parse a CSS style string into an array of [key, value] tuples.\n */\nexport const parseStyleAttribute = (styleString: string): StyleTuple[] => {\n  const start = performance.now();\n  const styles: StyleTuple[] = [];\n  let buffer = '';\n  let inUrl = false;\n  let inQuotes = false;\n  let quoteChar: '\"' | \"'\" | '' = '';\n\n  if (!styleString) return styles;\n\n  for (let i = 0; i < styleString.length; i++) {\n    const char = styleString[i];\n\n    if ((char === '\"' || char === \"'\") && !inUrl) {\n      if (!inQuotes) {\n        inQuotes = true;\n        quoteChar = char;\n      } else if (char === quoteChar) {\n        inQuotes = false;\n        quoteChar = '';\n      }\n    }\n\n    if (char === '(' && buffer.endsWith('url')) {\n      inUrl = true;\n    } else if (char === ')' && inUrl) {\n      inUrl = false;\n    }\n\n    if (char === ';' && !inQuotes && !inUrl) {\n      const declaration = buffer.trim();\n\n      if (declaration) {\n        const colonIndex = declaration.indexOf(':');\n\n        if (colonIndex > 0) {\n          const key = declaration.slice(0, colonIndex).trim();\n          const value = declaration.slice(colonIndex + 1).trim();\n          styles.push([key, value]);\n        }\n      }\n      buffer = '';\n    } else {\n      buffer += char;\n    }\n  }\n\n  const declaration = buffer.trim();\n\n  if (declaration) {\n    const colonIndex = declaration.indexOf(':');\n    if (colonIndex > 0) {\n      const key = declaration.slice(0, colonIndex).trim();\n      const value = declaration.slice(colonIndex + 1).trim();\n      styles.push([key, value]);\n    }\n  }\n\n  const duration = performance.now() - start;\n\n  if (duration > DURATION_DELAY_TRIGGER) {\n    console.log(\n      `parseStyleAttribute: ${duration.toFixed(3)}ms, styleString length: ${styleString.length}, styles count: ${styles.length}`\n    );\n  }\n\n  return styles;\n};\n\n/**\n * Convert an attribute value to a Node prop value.\n */\nexport const attributeValueToNodePropValue = (\n  tag: string,\n  key: string,\n  value: string,\n  sanitizeUrlFn: (\n    value: string,\n    tag: string,\n    attribute: string\n  ) => string | null\n): any => {\n  if (key === 'style') {\n    return parseStyleAttribute(value).reduce(\n      (styles, [styleKey, styleValue]) => {\n        const camelCasedKey = styleKey.replace(/(-[a-z])/g, (substr) =>\n          substr[1].toUpperCase()\n        );\n\n        (styles as Record<string, any>)[camelCasedKey] = sanitizeUrlFn(\n          styleValue,\n          tag,\n          styleKey\n        );\n\n        return styles;\n      },\n      {} as Record<string, any>\n    );\n  } else if (ATTRIBUTES_TO_SANITIZE.indexOf(key) !== -1) {\n    return sanitizeUrlFn(unescapeString(value), tag, key);\n  } else if (value.match(INTERPOLATION_R)) {\n    value = unescapeString(value.slice(1, value.length - 1));\n  }\n\n  if (value === 'true') {\n    return true;\n  } else if (value === 'false') {\n    return false;\n  }\n\n  return value;\n};\n\n// ============================================================================\n// TABLE PARSING\n// ============================================================================\n\n/**\n * Parse table alignment from a separator row.\n */\nexport const parseTableAlignCapture = (\n  alignCapture: string\n): 'left' | 'right' | 'center' => {\n  if (TABLE_RIGHT_ALIGN.test(alignCapture)) {\n    return 'right';\n  } else if (TABLE_CENTER_ALIGN.test(alignCapture)) {\n    return 'center';\n  } else if (TABLE_LEFT_ALIGN.test(alignCapture)) {\n    return 'left';\n  }\n\n  return 'left';\n};\n\n/**\n * Parse table alignment row.\n */\nexport const parseTableAlign = (\n  source: string\n): ('left' | 'right' | 'center')[] => {\n  const alignText = source.replace(TABLE_TRIM_PIPES, '').split('|');\n  return alignText.map(parseTableAlignCapture);\n};\n\n/**\n * Parse a single table row.\n */\nexport const parseTableRow = (\n  source: string,\n  parse: NestedParser,\n  state: ParseState,\n  tableOutput: boolean\n): ParserResult[][] => {\n  const start = performance.now();\n  const prevInTable = state.inTable;\n\n  state.inTable = true;\n\n  const cells: ParserResult[][] = [[]];\n  let acc = '';\n\n  const flush = (): void => {\n    if (!acc) return;\n\n    const cell = cells[cells.length - 1];\n    cell.push.apply(cell, parse(acc, state));\n    acc = '';\n  };\n\n  source\n    .trim()\n    .split(/(`[^`]*`|\\\\\\||\\|)/)\n    .filter(Boolean)\n    .forEach((fragment, i, arr) => {\n      if (fragment.trim() === '|') {\n        flush();\n\n        if (tableOutput) {\n          if (i !== 0 && i !== arr.length - 1) {\n            cells.push([]);\n          }\n\n          return;\n        }\n      }\n\n      acc += fragment;\n    });\n\n  flush();\n\n  state.inTable = prevInTable;\n\n  const duration = performance.now() - start;\n  if (duration > DURATION_DELAY_TRIGGER) {\n    console.log(\n      `parseTableRow: ${duration.toFixed(3)}ms, source length: ${source.length}, cells count: ${cells.length}`\n    );\n  }\n\n  return cells;\n};\n\n/**\n * Parse table cells (multiple rows).\n */\nexport const parseTableCells = (\n  source: string,\n  parse: NestedParser,\n  state: ParseState\n): ParserResult[][][] => {\n  const start = performance.now();\n  const rowsText = source.trim().split('\\n');\n\n  const result = rowsText.map((rowText) =>\n    parseTableRow(rowText, parse, state, true)\n  );\n\n  const duration = performance.now() - start;\n  if (duration > DURATION_DELAY_TRIGGER) {\n    console.log(\n      `parseTableCells: ${duration.toFixed(3)}ms, source length: ${source.length}, rows count: ${rowsText.length}`\n    );\n  }\n\n  return result;\n};\n\n// ============================================================================\n// PARSING HELPERS\n// ============================================================================\n\n/**\n * Check if a rule qualifies for the current source and state.\n */\nexport const qualifies = (\n  source: string,\n  state: ParseState,\n  qualify: NonNullable<Rule<any>['_qualify']>\n): boolean => {\n  if (Array.isArray(qualify)) {\n    for (let i = 0; i < qualify.length; i++) {\n      if (startsWith(source, qualify[i])) return true;\n    }\n\n    return false;\n  }\n\n  return (qualify as (source: string, state: ParseState) => boolean)(\n    source,\n    state\n  );\n};\n\n/**\n * Marks a matcher function as eligible for being run inside an inline context.\n */\nexport const allowInline = <T extends (...args: any[]) => any>(\n  fn: T\n): T & { inline: 1 } => {\n  (fn as any).inline = 1;\n  return fn as T & { inline: 1 };\n};\n\n/**\n * Creates a match function for an inline scoped element from a regex.\n */\nexport const inlineRegex = (regex: RegExp) =>\n  allowInline((source: string, state: ParseState): RegExpMatchArray | null => {\n    if (state.inline) {\n      return regex.exec(source);\n    } else {\n      return null;\n    }\n  });\n\n/**\n * Creates a match function for inline elements except links.\n */\nexport const simpleInlineRegex = (regex: RegExp) =>\n  allowInline((source: string, state: ParseState): RegExpMatchArray | null => {\n    if (state.inline || state.simple) {\n      return regex.exec(source);\n    } else {\n      return null;\n    }\n  });\n\n/**\n * Creates a match function for a block scoped element from a regex.\n */\nexport const blockRegex =\n  (regex: RegExp) =>\n  (source: string, state: ParseState): RegExpMatchArray | null => {\n    if (state.inline || state.simple) {\n      return null;\n    } else {\n      return regex.exec(source);\n    }\n  };\n\n/**\n * Creates a match function from a regex, ignoring block/inline scope.\n */\nexport const anyScopeRegex = (\n  fn: RegExp | ((source: string, state: ParseState) => RegExpMatchArray | null)\n) =>\n  allowInline((source: string, state: ParseState): RegExpMatchArray | null => {\n    if (typeof fn === 'function') {\n      return fn(source, state);\n    }\n    return fn.exec(source);\n  });\n\n/**\n * Parse inline content (including links).\n */\nexport const parseInline = (\n  parse: NestedParser,\n  children: string,\n  state: ParseState\n): ParserResult[] => {\n  const start = performance.now();\n  const isCurrentlyInline = state.inline ?? false;\n  const isCurrentlySimple = state.simple ?? false;\n  state.inline = true;\n  state.simple = true;\n  const result = parse(children, state);\n  state.inline = isCurrentlyInline;\n  state.simple = isCurrentlySimple;\n\n  const duration = performance.now() - start;\n  if (duration > DURATION_DELAY_TRIGGER) {\n    console.log(\n      `parseInline: ${duration.toFixed(3)}ms, children length: ${children.length}, result count: ${result.length}`\n    );\n  }\n\n  return result;\n};\n\n/**\n * Parse simple inline content (no links).\n */\nexport const parseSimpleInline = (\n  parse: NestedParser,\n  children: string,\n  state: ParseState\n): ParserResult[] => {\n  const start = performance.now();\n  const isCurrentlyInline = state.inline ?? false;\n  const isCurrentlySimple = state.simple ?? false;\n\n  state.inline = false;\n  state.simple = true;\n  const result = parse(children, state);\n  state.inline = isCurrentlyInline;\n  state.simple = isCurrentlySimple;\n\n  const duration = performance.now() - start;\n  if (duration > DURATION_DELAY_TRIGGER) {\n    console.log(\n      `parseSimpleInline: ${duration.toFixed(3)}ms, children length: ${children.length}, result count: ${result.length}`\n    );\n  }\n\n  return result;\n};\n\n/**\n * Parse block content.\n */\nexport const parseBlock = (\n  parse: NestedParser,\n  children: string,\n  state: ParseState = {}\n): ParserResult[] => {\n  const start = performance.now();\n  const isCurrentlyInline = state.inline || false;\n  state.inline = false;\n  const normalizedChildren = trimEnd(children);\n  const needsTerminator = /\\n\\n$/.test(normalizedChildren) === false;\n  const blockInput = needsTerminator\n    ? normalizedChildren.endsWith('\\n')\n      ? `${normalizedChildren}\\n`\n      : `${normalizedChildren}\\n\\n`\n    : normalizedChildren;\n\n  const result = parse(blockInput, state);\n  state.inline = isCurrentlyInline;\n\n  const duration = performance.now() - start;\n  if (duration > DURATION_DELAY_TRIGGER) {\n    console.log(\n      `parseBlock: ${duration.toFixed(3)}ms, children length: ${children.length}, result count: ${result.length}`\n    );\n  }\n\n  return result;\n};\n\n/**\n * Helper to parse capture group 2 as inline content.\n */\nexport const parseCaptureInline = (\n  capture: RegExpMatchArray,\n  parse: NestedParser,\n  state: ParseState\n): { children: ParserResult[] } => {\n  return {\n    children: parseInline(parse, capture[2], state),\n  };\n};\n\n/**\n * Helper that captures nothing (empty object).\n */\nexport const captureNothing = (): Record<string, never> => ({});\n\n/**\n * Helper that renders nothing (null).\n */\nexport const renderNothing = (): null => null;\n\n/**\n * Check if any regex in a list matches the input.\n */\nexport const some = (regexes: RegExp[], input: string): boolean => {\n  for (let i = 0; i < regexes.length; i++) {\n    if (regexes[i].test(input)) {\n      return true;\n    }\n  }\n  return false;\n};\n"],"mappings":"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"}