const VOID_ELEMENTS = /* @__PURE__ */ new Set([
  "area",
  "base",
  "br",
  "col",
  "embed",
  "hr",
  "img",
  "input",
  "link",
  "meta",
  "source",
  "track",
  "wbr"
]);
const ATTRIBUTE_RENAMES = {
  class: "className",
  for: "htmlFor",
  tabindex: "tabIndex",
  readonly: "readOnly",
  maxlength: "maxLength",
  minlength: "minLength",
  colspan: "colSpan",
  rowspan: "rowSpan",
  autofocus: "autoFocus",
  autocomplete: "autoComplete",
  cellpadding: "cellPadding",
  cellspacing: "cellSpacing",
  enctype: "encType",
  usemap: "useMap",
  accesskey: "accessKey",
  contenteditable: "contentEditable",
  spellcheck: "spellCheck",
  crossorigin: "crossOrigin",
  srcset: "srcSet",
  srcdoc: "srcDoc"
};
function htmlToJsx(html) {
  if (!html) return "";
  const tokens = tokenize(html);
  return tokens.map(transformToken).join("");
}
function tokenize(input) {
  const tokens = [];
  let i = 0;
  const n = input.length;
  while (i < n) {
    const ch = input[i];
    if (ch === "<") {
      const tagStart = i;
      i++;
      let quote = null;
      while (i < n) {
        const c = input[i];
        if (quote) {
          if (c === quote) quote = null;
          i++;
          continue;
        }
        if (c === '"' || c === "'") {
          quote = c;
          i++;
          continue;
        }
        if (c === ">") {
          i++;
          break;
        }
        i++;
      }
      const raw = input.slice(tagStart, i);
      const isClosing = raw.startsWith("</");
      const isSelfClosed = raw.endsWith("/>");
      const tagName = parseTagName(raw);
      tokens.push({ kind: "tag", raw, tagName, isClosing, isSelfClosed });
    } else {
      const textStart = i;
      while (i < n && input[i] !== "<") i++;
      tokens.push({ kind: "text", value: input.slice(textStart, i) });
    }
  }
  return tokens;
}
function parseTagName(tagRaw) {
  const m = tagRaw.match(/^<\/?([a-zA-Z][a-zA-Z0-9-]*)/);
  return m ? m[1].toLowerCase() : "";
}
function transformToken(token) {
  if (token.kind === "text") {
    return token.value;
  }
  return transformTag(token.raw, token.tagName, token.isClosing, token.isSelfClosed);
}
function transformTag(raw, tagName, isClosing, isSelfClosed) {
  if (isClosing) {
    return raw;
  }
  const inner = isSelfClosed ? raw.slice(1, -2).trimEnd() : raw.slice(1, -1);
  const nameMatch = inner.match(/^([a-zA-Z][a-zA-Z0-9-]*)(.*)$/s);
  if (!nameMatch) return raw;
  const elementName = nameMatch[1];
  const attrsSection = nameMatch[2];
  const attrs = parseAttributes(attrsSection);
  const renamedAttrs = attrs.map(renameAttribute);
  const rebuiltAttrs = serializeAttributes(renamedAttrs);
  const shouldSelfClose = VOID_ELEMENTS.has(tagName) && !isSelfClosed;
  if (shouldSelfClose || isSelfClosed) {
    return `<${elementName}${rebuiltAttrs} />`;
  }
  return `<${elementName}${rebuiltAttrs}>`;
}
function parseAttributes(section) {
  const attrs = [];
  let i = 0;
  const n = section.length;
  while (i < n) {
    while (i < n && /\s/.test(section[i])) i++;
    if (i >= n) break;
    const nameStart = i;
    while (i < n && /[a-zA-Z0-9:_-]/.test(section[i])) i++;
    if (i === nameStart) {
      i++;
      continue;
    }
    const name = section.slice(nameStart, i);
    let j = i;
    while (j < n && /\s/.test(section[j])) j++;
    if (j >= n || section[j] !== "=") {
      attrs.push({ name });
      continue;
    }
    i = j + 1;
    while (i < n && /\s/.test(section[i])) i++;
    if (i >= n) {
      attrs.push({ name });
      break;
    }
    const vc = section[i];
    if (vc === '"' || vc === "'") {
      const quote = vc;
      i++;
      const valStart = i;
      while (i < n && section[i] !== quote) i++;
      const value = section.slice(valStart, i);
      if (i < n) i++;
      attrs.push({ name, value, quote });
    } else {
      const valStart = i;
      while (i < n && !/[\s/>]/.test(section[i])) i++;
      const value = section.slice(valStart, i);
      attrs.push({ name, value });
    }
  }
  return attrs;
}
function renameAttribute(attr) {
  const lower = attr.name.toLowerCase();
  const newName = ATTRIBUTE_RENAMES[lower] ?? attr.name;
  if (lower === "style" && attr.value !== void 0) {
    return { name: newName, value: cssStringToJsxObject(attr.value), quote: void 0 };
  }
  return { ...attr, name: newName };
}
function serializeAttributes(attrs) {
  if (attrs.length === 0) return "";
  const parts = attrs.map((attr) => {
    if (attr.value === void 0) return ` ${attr.name}`;
    if (attr.value.startsWith("{{") && attr.value.endsWith("}}")) {
      return ` ${attr.name}=${attr.value}`;
    }
    const q = attr.quote ?? '"';
    return ` ${attr.name}=${q}${attr.value}${q}`;
  });
  return parts.join("");
}
function cssStringToJsxObject(css) {
  const declarations = css.split(";").map((d) => d.trim()).filter((d) => d.length > 0);
  if (declarations.length === 0) return "{{}}";
  const entries = declarations.map((decl) => {
    const colonIdx = decl.indexOf(":");
    if (colonIdx === -1) return null;
    const prop = decl.slice(0, colonIdx).trim();
    const value = decl.slice(colonIdx + 1).trim();
    const camelProp = prop.replace(/-([a-z])/g, (_m, c) => c.toUpperCase());
    const escapedValue = value.replace(/'/g, "\\'");
    return `${camelProp}: '${escapedValue}'`;
  }).filter((e) => e !== null);
  return `{{ ${entries.join(", ")} }}`;
}
export {
  htmlToJsx
};
