"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/components/MultipleChoice/MultipleChoice.tsx
var MultipleChoice_exports = {};
__export(MultipleChoice_exports, {
  MultipleChoiceList: () => MultipleChoiceList
});
module.exports = __toCommonJS(MultipleChoice_exports);
var import_react5 = require("react");

// src/components/CheckBox/CheckboxList.tsx
var import_react2 = require("react");
var import_zustand = require("zustand");

// src/components/CheckBox/CheckBox.tsx
var import_react = require("react");

// src/utils/utils.ts
var import_clsx = require("clsx");
var import_tailwind_merge = require("tailwind-merge");
function cn(...inputs) {
  return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
}

// src/components/Text/Text.tsx
var import_jsx_runtime = require("react/jsx-runtime");
var Text = ({
  children,
  size = "md",
  weight = "normal",
  color = "text-text-950",
  as,
  className = "",
  ...props
}) => {
  let sizeClasses;
  let weightClasses;
  const sizeClassMap = {
    "2xs": "text-2xs",
    xs: "text-xs",
    sm: "text-sm",
    md: "text-md",
    lg: "text-lg",
    xl: "text-xl",
    "2xl": "text-2xl",
    "3xl": "text-3xl",
    "4xl": "text-4xl",
    "5xl": "text-5xl",
    "6xl": "text-6xl"
  };
  sizeClasses = sizeClassMap[size] ?? sizeClassMap.md;
  const weightClassMap = {
    hairline: "font-hairline",
    light: "font-light",
    normal: "font-normal",
    medium: "font-medium",
    semibold: "font-semibold",
    bold: "font-bold",
    extrabold: "font-extrabold",
    black: "font-black"
  };
  weightClasses = weightClassMap[weight] ?? weightClassMap.normal;
  const baseClasses = "font-primary";
  const Component = as ?? "p";
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    Component,
    {
      className: cn(baseClasses, sizeClasses, weightClasses, color, className),
      ...props,
      children
    }
  );
};
var Text_default = Text;

// src/components/CheckBox/CheckBox.tsx
var import_phosphor_react = require("phosphor-react");
var import_jsx_runtime2 = require("react/jsx-runtime");
var SIZE_CLASSES = {
  small: {
    checkbox: "w-4 h-4",
    // 16px x 16px
    textSize: "sm",
    spacing: "gap-1.5",
    // 6px
    borderWidth: "border-2",
    iconSize: 14,
    // pixels for Phosphor icons
    labelHeight: "h-[21px]"
  },
  medium: {
    checkbox: "w-5 h-5",
    // 20px x 20px
    textSize: "md",
    spacing: "gap-2",
    // 8px
    borderWidth: "border-2",
    iconSize: 16,
    // pixels for Phosphor icons
    labelHeight: "h-6"
  },
  large: {
    checkbox: "w-6 h-6",
    // 24px x 24px
    textSize: "lg",
    spacing: "gap-2",
    // 8px
    borderWidth: "border-[3px]",
    // 3px border
    iconSize: 20,
    // pixels for Phosphor icons
    labelHeight: "h-[27px]"
  }
};
var BASE_CHECKBOX_CLASSES = "rounded border cursor-pointer transition-all duration-200 flex items-center justify-center focus:outline-none";
var STATE_CLASSES = {
  default: {
    unchecked: "border-border-400 bg-background hover:border-border-500",
    checked: "border-primary-950 bg-primary-950 text-text hover:border-primary-800 hover:bg-primary-800"
  },
  hovered: {
    unchecked: "border-border-500 bg-background",
    checked: "border-primary-800 bg-primary-800 text-text"
  },
  focused: {
    unchecked: "border-indicator-info bg-background ring-2 ring-indicator-info/20",
    checked: "border-indicator-info bg-primary-950 text-text ring-2 ring-indicator-info/20"
  },
  invalid: {
    unchecked: "border-error-700 bg-background hover:border-error-600",
    checked: "border-error-700 bg-primary-950 text-text"
  },
  disabled: {
    unchecked: "border-border-400 bg-background cursor-not-allowed opacity-40",
    checked: "border-primary-600 bg-primary-600 text-text cursor-not-allowed opacity-40"
  }
};
var CheckBox = (0, import_react.forwardRef)(
  ({
    label,
    size = "medium",
    state = "default",
    indeterminate = false,
    errorMessage,
    helperText,
    className = "",
    labelClassName = "",
    checked: checkedProp,
    disabled,
    id,
    onChange,
    ...props
  }, ref) => {
    const generatedId = (0, import_react.useId)();
    const inputId = id ?? `checkbox-${generatedId}`;
    const [internalChecked, setInternalChecked] = (0, import_react.useState)(false);
    const isControlled = checkedProp !== void 0;
    const checked = isControlled ? checkedProp : internalChecked;
    const handleChange = (event) => {
      if (!isControlled) {
        setInternalChecked(event.target.checked);
      }
      onChange?.(event);
    };
    const currentState = disabled ? "disabled" : state;
    const sizeClasses = SIZE_CLASSES[size];
    const checkVariant = checked || indeterminate ? "checked" : "unchecked";
    const stylingClasses = STATE_CLASSES[currentState][checkVariant];
    const borderWidthClass = state === "focused" || state === "hovered" && size === "large" ? "border-[3px]" : sizeClasses.borderWidth;
    const checkboxClasses = cn(
      BASE_CHECKBOX_CLASSES,
      sizeClasses.checkbox,
      borderWidthClass,
      stylingClasses,
      className
    );
    const renderIcon = () => {
      if (indeterminate) {
        return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
          import_phosphor_react.Minus,
          {
            size: sizeClasses.iconSize,
            weight: "bold",
            color: "currentColor"
          }
        );
      }
      if (checked) {
        return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
          import_phosphor_react.Check,
          {
            size: sizeClasses.iconSize,
            weight: "bold",
            color: "currentColor"
          }
        );
      }
      return null;
    };
    return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col", children: [
      /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
        "div",
        {
          className: cn(
            "flex flex-row items-center",
            sizeClasses.spacing,
            disabled ? "opacity-40" : ""
          ),
          children: [
            /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
              "input",
              {
                ref,
                type: "checkbox",
                id: inputId,
                checked,
                disabled,
                onChange: handleChange,
                className: "sr-only",
                ...props
              }
            ),
            /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { htmlFor: inputId, className: checkboxClasses, children: renderIcon() }),
            label && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
              "div",
              {
                className: cn(
                  "flex flex-row items-center",
                  sizeClasses.labelHeight
                ),
                children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
                  Text_default,
                  {
                    as: "label",
                    htmlFor: inputId,
                    size: sizeClasses.textSize,
                    weight: "normal",
                    className: cn(
                      "cursor-pointer select-none leading-[150%] flex items-center font-roboto",
                      labelClassName
                    ),
                    children: label
                  }
                )
              }
            )
          ]
        }
      ),
      errorMessage && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
        Text_default,
        {
          size: "sm",
          weight: "normal",
          className: "mt-1.5",
          color: "text-error-600",
          children: errorMessage
        }
      ),
      helperText && !errorMessage && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
        Text_default,
        {
          size: "sm",
          weight: "normal",
          className: "mt-1.5",
          color: "text-text-500",
          children: helperText
        }
      )
    ] });
  }
);
CheckBox.displayName = "CheckBox";
var CheckBox_default = CheckBox;

// src/components/CheckBox/CheckboxList.tsx
var import_jsx_runtime3 = require("react/jsx-runtime");
var createCheckboxListStore = (name, defaultValues, disabled, onValuesChange) => (0, import_zustand.create)((set, get) => ({
  values: defaultValues,
  setValues: (values) => {
    if (!get().disabled) {
      set({ values });
      get().onValuesChange?.(values);
    }
  },
  toggleValue: (value) => {
    if (!get().disabled) {
      const currentValues = get().values;
      const newValues = currentValues.includes(value) ? currentValues.filter((v) => v !== value) : [...currentValues, value];
      set({ values: newValues });
      get().onValuesChange?.(newValues);
    }
  },
  onValuesChange,
  disabled,
  name
}));
var useCheckboxListStore = (externalStore) => {
  if (!externalStore) {
    throw new Error("CheckboxListItem must be used within a CheckboxList");
  }
  return externalStore;
};
var injectStore = (children, store) => import_react2.Children.map(children, (child) => {
  if (!(0, import_react2.isValidElement)(child)) return child;
  const typedChild = child;
  const shouldInject = typedChild.type === CheckboxListItem;
  return (0, import_react2.cloneElement)(typedChild, {
    ...shouldInject ? { store } : {},
    ...typedChild.props.children ? { children: injectStore(typedChild.props.children, store) } : {}
  });
});
var CheckboxList = (0, import_react2.forwardRef)(
  ({
    values: propValues,
    defaultValues = [],
    onValuesChange,
    name: propName,
    disabled = false,
    className = "",
    children,
    ...props
  }, ref) => {
    const generatedId = (0, import_react2.useId)();
    const name = propName || `checkbox-list-${generatedId}`;
    const storeRef = (0, import_react2.useRef)(null);
    storeRef.current ??= createCheckboxListStore(
      name,
      defaultValues,
      disabled,
      onValuesChange
    );
    const store = storeRef.current;
    const { setValues } = (0, import_zustand.useStore)(store, (s) => s);
    (0, import_react2.useEffect)(() => {
      const currentValues = store.getState().values;
      if (currentValues.length > 0 && onValuesChange) {
        onValuesChange(currentValues);
      }
    }, []);
    (0, import_react2.useEffect)(() => {
      if (propValues !== void 0) {
        setValues(propValues);
      }
    }, [propValues, setValues]);
    (0, import_react2.useEffect)(() => {
      store.setState({ disabled });
    }, [disabled, store]);
    return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
      "div",
      {
        ref,
        className: cn("flex flex-col gap-2 w-full", className),
        "aria-label": name,
        ...props,
        children: injectStore(children, store)
      }
    );
  }
);
CheckboxList.displayName = "CheckboxList";
var CheckboxListItem = (0, import_react2.forwardRef)(
  ({
    value,
    store: externalStore,
    disabled: itemDisabled,
    size = "medium",
    state = "default",
    className = "",
    id,
    ...props
  }, ref) => {
    const store = useCheckboxListStore(externalStore);
    const {
      values: groupValues,
      toggleValue,
      disabled: groupDisabled,
      name
    } = (0, import_zustand.useStore)(store);
    const generatedId = (0, import_react2.useId)();
    const inputId = id ?? `checkbox-item-${generatedId}`;
    const isChecked = groupValues.includes(value);
    const isDisabled = groupDisabled || itemDisabled;
    const currentState = isDisabled ? "disabled" : state;
    return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
      CheckBox_default,
      {
        ref,
        id: inputId,
        name,
        value,
        checked: isChecked,
        disabled: isDisabled,
        size,
        state: currentState,
        className,
        onChange: () => {
          if (!isDisabled) {
            toggleValue(value);
          }
        },
        ...props
      }
    );
  }
);
CheckboxListItem.displayName = "CheckboxListItem";
var CheckboxList_default = CheckboxList;

// src/components/MultipleChoice/MultipleChoice.tsx
var import_phosphor_react3 = require("phosphor-react");

// src/components/Badge/Badge.tsx
var import_phosphor_react2 = require("phosphor-react");
var import_jsx_runtime4 = require("react/jsx-runtime");
var VARIANT_ACTION_CLASSES = {
  solid: {
    error: "bg-error-background text-error-700 focus-visible:outline-none",
    warning: "bg-warning text-warning-800 focus-visible:outline-none",
    success: "bg-success text-success-800 focus-visible:outline-none",
    info: "bg-info text-info-800 focus-visible:outline-none",
    muted: "bg-background-muted text-background-800 focus-visible:outline-none"
  },
  outlined: {
    error: "bg-error text-error-700 border border-error-300 focus-visible:outline-none",
    warning: "bg-warning text-warning-800 border border-warning-300 focus-visible:outline-none",
    success: "bg-success text-success-800 border border-success-300 focus-visible:outline-none",
    info: "bg-info text-info-800 border border-info-300 focus-visible:outline-none",
    muted: "bg-background-muted text-background-800 border border-border-300 focus-visible:outline-none"
  },
  exams: {
    exam1: "bg-exam-1 text-info-700 focus-visible:outline-none",
    exam2: "bg-exam-2 text-typography-1 focus-visible:outline-none",
    exam3: "bg-exam-3 text-typography-2 focus-visible:outline-none",
    exam4: "bg-exam-4 text-success-700 focus-visible:outline-none"
  },
  examsOutlined: {
    exam1: "bg-exam-1 text-info-700 border border-info-700 focus-visible:outline-none",
    exam2: "bg-exam-2 text-typography-1 border border-typography-1 focus-visible:outline-none",
    exam3: "bg-exam-3 text-typography-2 border border-typography-2 focus-visible:outline-none",
    exam4: "bg-exam-4 text-success-700 border border-success-700 focus-visible:outline-none"
  },
  resultStatus: {
    negative: "bg-error text-error-800 focus-visible:outline-none",
    positive: "bg-success text-success-800 focus-visible:outline-none"
  },
  notification: "text-primary"
};
var SIZE_CLASSES2 = {
  small: "text-2xs px-2 py-1",
  medium: "text-xs px-2 py-1",
  large: "text-sm px-2 py-1"
};
var SIZE_CLASSES_ICON = {
  small: "size-3",
  medium: "size-3.5",
  large: "size-4"
};
var Badge = ({
  children,
  iconLeft,
  iconRight,
  size = "medium",
  variant = "solid",
  action = "error",
  className = "",
  notificationActive = false,
  ...props
}) => {
  const sizeClasses = SIZE_CLASSES2[size];
  const sizeClassesIcon = SIZE_CLASSES_ICON[size];
  const variantActionMap = VARIANT_ACTION_CLASSES[variant] || {};
  const variantClasses = typeof variantActionMap === "string" ? variantActionMap : variantActionMap[action] ?? variantActionMap.muted ?? "";
  const baseClasses = "inline-flex items-center justify-center rounded-xs font-normal gap-1 relative";
  const baseClassesIcon = "flex items-center";
  if (variant === "notification") {
    return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
      "div",
      {
        className: cn(baseClasses, variantClasses, sizeClasses, className),
        ...props,
        children: [
          /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_phosphor_react2.Bell, { size: 24, className: "text-current", "aria-hidden": "true" }),
          notificationActive && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
            "span",
            {
              "data-testid": "notification-dot",
              className: "absolute top-[5px] right-[10px] block h-2 w-2 rounded-full bg-indicator-error ring-2 ring-white"
            }
          )
        ]
      }
    );
  }
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
    "div",
    {
      className: cn(baseClasses, variantClasses, sizeClasses, className),
      ...props,
      children: [
        iconLeft && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: cn(baseClassesIcon, sizeClassesIcon), children: iconLeft }),
        children,
        iconRight && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: cn(baseClassesIcon, sizeClassesIcon), children: iconRight })
      ]
    }
  );
};
var Badge_default = Badge;

// src/components/HtmlMathRenderer/HtmlMathRenderer.tsx
var import_react4 = require("react");
var import_katex_min2 = require("katex/dist/katex.min.css");

// src/components/HtmlMathRenderer/KatexMath.tsx
var import_katex = __toESM(require("katex"));
var import_jsx_runtime5 = require("react/jsx-runtime");
var KatexMath = ({
  math,
  displayMode = false,
  renderError
}) => {
  let html;
  try {
    html = import_katex.default.renderToString(math, {
      displayMode,
      throwOnError: true
    });
  } catch (error_) {
    return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: renderError ? renderError(error_) : null });
  }
  const Tag = displayMode ? "div" : "span";
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
    Tag,
    {
      "data-testid": "react-katex",
      dangerouslySetInnerHTML: { __html: html }
    }
  );
};

// src/components/MarkdownMathRenderer/MarkdownMathRenderer.tsx
var import_react3 = require("react");
var import_katex_min = require("katex/dist/katex.min.css");
var import_react_markdown = __toESM(require("react-markdown"));
var import_remark_gfm = __toESM(require("remark-gfm"));
var import_remark_math = __toESM(require("remark-math"));
var import_rehype_katex = __toESM(require("rehype-katex"));

// src/components/HtmlMathRenderer/utils.ts
var generateSecureRandomId = () => {
  return crypto.randomUUID();
};
var cleanLatex = (str) => {
  return str.replaceAll(/[\u200B-\u200D\uFEFF]/g, "").replaceAll(/&amp;lt;|&lt;/gi, String.raw`\lt `).replaceAll(/&amp;gt;|&gt;/gi, String.raw`\gt `).replaceAll(/&amp;amp;|&amp;/gi, "&").trim();
};
var looksLikeLatex = (str) => {
  if (/[\\^_{}]/.test(str)) return true;
  const words = str.match(/[a-zA-Z]{3,}/g);
  if (words && words.length >= 2) return false;
  return true;
};
var HTML_TAG_NAMES = /* @__PURE__ */ new Set([
  "p",
  "div",
  "span",
  "br",
  "b",
  "strong",
  "i",
  "em",
  "u",
  "s",
  "ul",
  "ol",
  "li",
  "h1",
  "h2",
  "h3",
  "h4",
  "h5",
  "h6",
  "a",
  "img",
  "table",
  "thead",
  "tbody",
  "tfoot",
  "tr",
  "td",
  "th",
  "blockquote",
  "pre",
  "code",
  "sub",
  "sup",
  "font",
  "latex"
]);
var containsHtmlTag = (content) => {
  for (const match of content.matchAll(/<\/?([a-z][a-z0-9]*)/gi)) {
    if (HTML_TAG_NAMES.has(match[1].toLowerCase())) return true;
  }
  return false;
};
var isLikelyMarkdown = (content) => {
  if (!content) return false;
  if (containsHtmlTag(content)) return false;
  const MARKDOWN_SIGNALS = [
    /^#{1,6}[ \t]+\S/m,
    // ATX heading (#, ##, ... ######)
    /\*\*[^*\n]+\*\*/,
    // bold
    /__[^_\n]+__/,
    // bold (underscore)
    /^[ \t]*[-*+][ \t]+\S/m,
    // bullet list
    /^[ \t]*\d+\.[ \t]+\S/m,
    // ordered list
    /\|[ \t]*:?-+:?[ \t]*\|/,
    // GFM table delimiter row (|---|---|)
    /\n\n/
    // paragraph break (only reached when no HTML tag is present)
  ];
  return MARKDOWN_SIGNALS.some((pattern) => pattern.test(content));
};
var recoverFromKatexErrorSpans = (htmlContent) => {
  if (typeof document === "undefined" || !/class="[^"]*katex-error/i.test(htmlContent)) {
    return htmlContent;
  }
  const tempContainer = document.createElement("div");
  tempContainer.innerHTML = htmlContent;
  const sanitizeRecoveredLatex = (raw) => raw.replaceAll(/[\u0300-\u036F]/g, "").replaceAll(/<\/?[a-zA-Z][a-zA-Z0-9]*\s*>?$/g, "").replaceAll(/&amp;lt;|&lt;|</gi, String.raw`\lt `).replaceAll(/&amp;gt;|&gt;|>/gi, String.raw`\gt `).replaceAll(/&amp;amp;|&amp;/gi, "&").trim();
  Array.from(tempContainer.querySelectorAll(".katex-error")).forEach(
    (errorNode) => {
      if (!tempContainer.contains(errorNode)) return;
      const title = errorNode.getAttribute("title") || "";
      const positionMatch = /at position\s+\d+:(.+)$/.exec(title);
      let recovered = positionMatch ? positionMatch[1] : "";
      if (!recovered) {
        const parts = [];
        const walk = (n) => {
          if (n.nodeType === Node.TEXT_NODE) {
            parts.push(n.textContent || "");
            return;
          }
          if (n.nodeType !== Node.ELEMENT_NODE) return;
          const el = n;
          if (el.tagName.toLowerCase() === "annotation") {
            parts.push(el.textContent || "");
            return;
          }
          if (el.classList.contains("katex-html")) return;
          Array.from(el.childNodes).forEach(walk);
        };
        Array.from(errorNode.childNodes).forEach(walk);
        recovered = parts.join(" ");
      }
      recovered = sanitizeRecoveredLatex(recovered);
      if (recovered) {
        errorNode.replaceWith(document.createTextNode(`$${recovered}$`));
      } else {
        errorNode.remove();
      }
    }
  );
  return tempContainer.innerHTML;
};
var decodeDollarEscapes = (text) => text.replaceAll(String.raw`\$`, "$");
var DANGEROUS_ATTRIBUTES = /* @__PURE__ */ new Set([
  "contenteditable",
  "srcdoc",
  "formaction",
  "xlink:href"
]);
var DANGEROUS_URI_PATTERN = /^\s*(javascript|vbscript|data):/i;
var sanitizeHtmlForDisplay = (htmlContent) => {
  if (!htmlContent) return htmlContent;
  if (typeof document === "undefined") {
    let sanitized = htmlContent;
    sanitized = sanitized.replaceAll(
      /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
      ""
    );
    sanitized = sanitized.replaceAll(
      /<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi,
      ""
    );
    sanitized = sanitized.replaceAll(/ on[a-z]+="[^"]*"/gi, "");
    sanitized = sanitized.replaceAll(/ on[a-z]+='[^']*'/gi, "");
    sanitized = sanitized.replaceAll(/ on[a-z]+=[^\s>"']+/gi, "");
    sanitized = sanitized.replaceAll(
      / href="(?:javascript|vbscript|data):[^"]*"/gi,
      ""
    );
    sanitized = sanitized.replaceAll(
      / href='(?:javascript|vbscript|data):[^']*'/gi,
      ""
    );
    sanitized = sanitized.replaceAll(
      / src="(?:javascript|vbscript|data):[^"]*"/gi,
      ""
    );
    sanitized = sanitized.replaceAll(
      / src='(?:javascript|vbscript|data):[^']*'/gi,
      ""
    );
    sanitized = sanitized.replaceAll(
      / action="(?:javascript|vbscript|data):[^"]*"/gi,
      ""
    );
    sanitized = sanitized.replaceAll(
      / action='(?:javascript|vbscript|data):[^']*'/gi,
      ""
    );
    return sanitized;
  }
  const tempDiv = document.createElement("div");
  tempDiv.innerHTML = htmlContent;
  const dangerousTags = tempDiv.querySelectorAll(
    "script, style, iframe, object, embed"
  );
  dangerousTags.forEach((element) => element.remove());
  const allElements = tempDiv.querySelectorAll("*");
  allElements.forEach((element) => {
    const attributeNames = element.getAttributeNames();
    attributeNames.forEach((attrName) => {
      const lowerAttrName = attrName.toLowerCase();
      if (lowerAttrName.startsWith("on")) {
        element.removeAttribute(attrName);
        return;
      }
      if (DANGEROUS_ATTRIBUTES.has(lowerAttrName)) {
        element.removeAttribute(attrName);
        return;
      }
      if (lowerAttrName === "href" || lowerAttrName === "src" || lowerAttrName === "action") {
        const value = element.getAttribute(attrName);
        if (value && DANGEROUS_URI_PATTERN.test(value)) {
          element.removeAttribute(attrName);
        }
      }
    });
  });
  return tempDiv.innerHTML;
};
var processHtmlWithMath = (htmlContent) => {
  if (!htmlContent) return [];
  let processedContent = recoverFromKatexErrorSpans(htmlContent);
  const parts = [];
  const sentinel = `__MATH_${generateSecureRandomId()}_`;
  const mathFormulaPattern = /<span[^>]*class="math-formula"[^>]*data-latex="([^"]*)"[^>]*>[\s\S]*?<\/span>/g;
  processedContent = processedContent.replaceAll(
    mathFormulaPattern,
    (match2, latex) => {
      const isDisplayMode = match2.includes('data-display-mode="true"');
      const placeholder = `${sentinel}${parts.length}__`;
      parts.push({
        type: isDisplayMode ? "block-math" : "math",
        content: match2,
        latex: cleanLatex(latex)
      });
      return placeholder;
    }
  );
  const wrappedMathPattern = /<span[^>]*class="math-expression"[^>]*data-math="([^"]*)"[^>]*>.*?<\/span>/g;
  processedContent = processedContent.replaceAll(
    wrappedMathPattern,
    (match2, latex) => {
      const placeholder = `${sentinel}${parts.length}__`;
      parts.push({
        type: "math",
        content: match2,
        latex: cleanLatex(latex)
      });
      return placeholder;
    }
  );
  const doubleDollarPattern = /(?<!\\)\$\$([\s\S]+?)\$\$/g;
  processedContent = processedContent.replaceAll(
    doubleDollarPattern,
    (match2, latex) => {
      const placeholder = `${sentinel}${parts.length}__`;
      parts.push({
        type: "block-math",
        content: match2,
        latex: cleanLatex(latex)
      });
      return placeholder;
    }
  );
  const singleDollarPattern = /(?<!\\)\$([\s\S]+?)\$/g;
  processedContent = processedContent.replaceAll(
    singleDollarPattern,
    (match2, latex) => {
      if (!looksLikeLatex(latex)) return match2;
      const placeholder = `${sentinel}${parts.length}__`;
      parts.push({
        type: "math",
        content: match2,
        latex: cleanLatex(latex)
      });
      return placeholder;
    }
  );
  const latexTagPattern = /(?:<latex>|&lt;latex&gt;)([\s\S]*?)(?:<\/latex>|&lt;\/latex&gt;)/g;
  processedContent = processedContent.replaceAll(
    latexTagPattern,
    (match2, latex) => {
      const placeholder = `${sentinel}${parts.length}__`;
      parts.push({
        type: "math",
        content: match2,
        latex: cleanLatex(latex)
      });
      return placeholder;
    }
  );
  const latexEnvPattern = /\\begin\{([^}]+)\}([\s\S]*?)\\end\{\1\}/g;
  processedContent = processedContent.replaceAll(latexEnvPattern, (match2) => {
    const placeholder = `${sentinel}${parts.length}__`;
    parts.push({
      type: "block-math",
      content: match2,
      latex: cleanLatex(match2)
    });
    return placeholder;
  });
  const finalParts = [];
  let currentIndex = 0;
  const escapedSentinel = sentinel.replaceAll(
    /[.*+?^${}()|[\]\\]/g,
    String.raw`\$&`
  );
  const placeholderPattern = new RegExp(
    String.raw`${escapedSentinel}(\d+)__`,
    "g"
  );
  let match;
  while ((match = placeholderPattern.exec(processedContent)) !== null) {
    if (match.index > currentIndex) {
      finalParts.push({
        type: "text",
        content: decodeDollarEscapes(
          processedContent.slice(currentIndex, match.index)
        )
      });
    }
    const mathIndex = Number.parseInt(match[1], 10);
    if (parts[mathIndex]) {
      finalParts.push(parts[mathIndex]);
    }
    currentIndex = match.index + match[0].length;
  }
  if (currentIndex < processedContent.length) {
    finalParts.push({
      type: "text",
      content: decodeDollarEscapes(processedContent.slice(currentIndex))
    });
  }
  return finalParts;
};

// src/components/MarkdownMathRenderer/MarkdownMathRenderer.tsx
var import_jsx_runtime6 = require("react/jsx-runtime");
var stripInvisibleChars = (str) => str.replaceAll(/[\u200B-\u200D\uFEFF]/g, "");
var protectCurrencyInlineMath = (markdown) => markdown.replaceAll(
  /(?<!\\)\$(?!\$)([^\n$]+?)(?<!\\)\$(?!\$)/g,
  (match, inner) => looksLikeLatex(inner) ? match : match.replaceAll("$", String.raw`\$`)
);
var reflowDisplayMath = (markdown) => markdown.replaceAll(
  /(?<!\$)\$\$(?!\$)([^\n]+?)\$\$(?!\$)/g,
  (_match, inner) => `

$$
${inner.trim()}
$$

`
);
var withProtectedCode = (markdown, transform) => {
  const stash = [];
  const tokenized = markdown.replaceAll(
    /```[\s\S]*?```|`[^`\n]*`/g,
    (segment) => {
      const token = `__CODE_SEG_${stash.length}__`;
      stash.push(segment);
      return token;
    }
  );
  return transform(tokenized).replaceAll(
    /__CODE_SEG_(\d+)__/g,
    (_match, index) => stash[Number(index)]
  );
};
var preprocessMarkdown = (content) => withProtectedCode(
  stripInvisibleChars(content),
  (safe) => reflowDisplayMath(protectCurrencyInlineMath(safe))
);
var MarkdownMathRenderer = (0, import_react3.forwardRef)(({ content, className, style, testId }, ref) => {
  const sharedClassName = cn(
    "leading-relaxed",
    // Paragraph spacing
    "[&_p]:my-2 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0",
    // Headings
    "[&_h1]:text-xl [&_h1]:font-bold [&_h1]:mt-3 [&_h1]:mb-2",
    "[&_h2]:text-lg [&_h2]:font-bold [&_h2]:mt-3 [&_h2]:mb-2",
    "[&_h3]:text-base [&_h3]:font-semibold [&_h3]:mt-2.5 [&_h3]:mb-1.5",
    "[&_h4]:text-base [&_h4]:font-semibold [&_h4]:mt-2.5 [&_h4]:mb-1.5",
    "[&_h5]:font-semibold [&_h6]:font-semibold",
    // Lists
    "[&_ul]:list-disc [&_ul]:pl-5 [&_ul]:my-2",
    "[&_ol]:list-decimal [&_ol]:pl-5 [&_ol]:my-2",
    "[&_li]:my-1 [&_li>ul]:my-1 [&_li>ol]:my-1",
    // Text formatting
    "[&_b]:font-bold [&_strong]:font-bold",
    "[&_i]:italic [&_em]:italic",
    "[&_u]:underline",
    "[&_blockquote]:border-l-4 [&_blockquote]:border-border-200 [&_blockquote]:pl-3 [&_blockquote]:text-text-700",
    "[&_code]:rounded [&_code]:bg-background-100 [&_code]:px-1 [&_code]:py-0.5 [&_code]:text-sm",
    // Hide the KaTeX MathML accessibility layer visually (still readable to
    // screen readers). Tailwind preflight overrides KaTeX's default clip
    // rule, so without this the MathML layer duplicates every formula as
    // raw text next to the visual render.
    "[&_.katex-mathml]:sr-only",
    // Display math spacing
    "[&_.katex-display]:my-2.5",
    // Tables (GFM)
    "[&_table]:border-collapse [&_table]:w-full [&_table]:my-2.5 [&_table]:table-auto",
    "[&_table_td]:border [&_table_td]:border-border-200 [&_table_td]:p-2 [&_table_td]:min-w-[50px] [&_table_td]:align-top",
    "[&_table_th]:border [&_table_th]:border-border-200 [&_table_th]:p-2 [&_table_th]:min-w-[50px] [&_table_th]:align-top [&_table_th]:bg-background-50 [&_table_th]:font-semibold",
    // Images and links
    "[&_img]:max-w-full [&_img]:h-auto [&_img]:rounded-md [&_img]:my-2",
    "[&_a]:text-primary-500 [&_a]:underline [&_a:hover]:text-primary-600",
    className
  );
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
    "div",
    {
      ref,
      className: sharedClassName,
      style,
      "data-testid": testId,
      children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
        import_react_markdown.default,
        {
          remarkPlugins: [import_remark_gfm.default, import_remark_math.default],
          rehypePlugins: [import_rehype_katex.default],
          children: preprocessMarkdown(content)
        }
      )
    }
  );
});
MarkdownMathRenderer.displayName = "MarkdownMathRenderer";
var MarkdownMathRenderer_default = (0, import_react3.memo)(MarkdownMathRenderer);

// src/components/HtmlMathRenderer/HtmlMathRenderer.tsx
var import_jsx_runtime7 = require("react/jsx-runtime");
var HtmlMathRenderer = (0, import_react4.forwardRef)(
  ({
    content,
    className,
    style,
    sanitize = true,
    renderMathError,
    testId,
    inline = false
  }, ref) => {
    if (!inline && content && isLikelyMarkdown(content)) {
      return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
        MarkdownMathRenderer_default,
        {
          ref,
          content,
          className,
          style,
          testId
        }
      );
    }
    const defaultErrorRenderer = (latex) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "text-error-600 text-sm", children: [
      "Math Error: ",
      latex
    ] });
    const errorRenderer = renderMathError || defaultErrorRenderer;
    const renderContent = () => {
      if (!content) return null;
      const processedContent = sanitize ? sanitizeHtmlForDisplay(content) : content;
      const parts = processHtmlWithMath(processedContent);
      if (parts.every((part) => part.type === "text")) {
        const joinedHtml = parts.map((part) => part.content).join("");
        const Element = inline ? "span" : "div";
        return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
          Element,
          {
            dangerouslySetInnerHTML: {
              __html: joinedHtml || processedContent
            }
          }
        );
      }
      const getPartKey = (part, idx) => {
        const contentHash = (part.latex || part.content).slice(0, 20);
        return `${part.type}-${idx}-${contentHash}`;
      };
      return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: parts.map((part, index) => {
        const key = getPartKey(part, index);
        if (part.type === "math" && part.latex) {
          return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
            KatexMath,
            {
              math: part.latex,
              renderError: () => errorRenderer(part.latex)
            },
            key
          );
        } else if (part.type === "block-math" && part.latex) {
          if (inline) {
            return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
              KatexMath,
              {
                math: part.latex,
                renderError: () => errorRenderer(part.latex)
              },
              key
            );
          }
          return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "my-2.5 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
            KatexMath,
            {
              math: part.latex,
              displayMode: true,
              renderError: () => errorRenderer(part.latex)
            }
          ) }, key);
        } else {
          return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
            "span",
            {
              dangerouslySetInnerHTML: { __html: part.content }
            },
            key
          );
        }
      }) });
    };
    const sharedClassName = cn(
      // Base styles
      "leading-relaxed",
      // Paragraph styles
      "[&_p]:mb-0",
      // Hide the KaTeX MathML accessibility layer visually (still readable
      // to screen readers). Tailwind preflight overrides the KaTeX default
      // `position: absolute; clip:...` rule, so the MathML layer ends up
      // duplicating every formula as raw text next to the visual render.
      "[&_.katex-mathml]:sr-only",
      // Table styles (only relevant for block mode, but harmless for inline)
      "[&_table]:border-collapse [&_table]:w-full [&_table]:my-2.5 [&_table]:table-auto",
      "[&_table_td]:border [&_table_td]:border-border-200 [&_table_td]:p-2 [&_table_td]:min-w-[50px] [&_table_td]:align-top",
      "[&_table_th]:border [&_table_th]:border-border-200 [&_table_th]:p-2 [&_table_th]:min-w-[50px] [&_table_th]:align-top [&_table_th]:bg-background-50 [&_table_th]:font-semibold",
      "[&_table_tr:nth-child(even)]:bg-background-50/50",
      "[&_table_tr:hover]:bg-background-100/50",
      // Image styles
      "[&_img]:max-w-full [&_img]:h-auto [&_img]:rounded-md [&_img]:my-2",
      // Link styles
      "[&_a]:text-primary-500 [&_a]:underline [&_a:hover]:text-primary-600",
      // Text formatting styles
      "[&_b]:font-bold [&_strong]:font-bold",
      "[&_i]:italic [&_em]:italic",
      "[&_u]:underline",
      className
    );
    if (inline) {
      return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
        "span",
        {
          ref,
          className: sharedClassName,
          style,
          "data-testid": testId,
          children: renderContent()
        }
      );
    }
    return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
      "div",
      {
        ref,
        className: sharedClassName,
        style,
        "data-testid": testId,
        children: renderContent()
      }
    );
  }
);
HtmlMathRenderer.displayName = "HtmlMathRenderer";
var HtmlMathRenderer_default = (0, import_react4.memo)(HtmlMathRenderer);

// src/components/MultipleChoice/MultipleChoice.tsx
var import_jsx_runtime8 = require("react/jsx-runtime");
var MultipleChoiceList = ({
  disabled = false,
  className = "",
  choices,
  name,
  selectedValues,
  onHandleSelectedValues,
  mode = "interactive" /* INTERACTIVE */
}) => {
  const [actualValue, setActualValue] = (0, import_react5.useState)(selectedValues);
  (0, import_react5.useEffect)(() => {
    setActualValue(selectedValues);
  }, [selectedValues]);
  const getStatusBadge = (status) => {
    switch (status) {
      case "correct" /* CORRECT */:
        return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Badge_default, { variant: "solid", action: "success", iconLeft: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_phosphor_react3.CheckCircle, {}), children: "Resposta correta" });
      case "incorrect" /* INCORRECT */:
        return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Badge_default, { variant: "solid", action: "error", iconLeft: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_phosphor_react3.XCircle, {}), children: "Resposta incorreta" });
      default:
        return null;
    }
  };
  const getStatusStyles = (status) => {
    switch (status) {
      case "correct" /* CORRECT */:
        return "bg-success-background border-success-300";
      case "incorrect" /* INCORRECT */:
        return "bg-error-background border-error-300";
      default:
        return `bg-background border-border-100`;
    }
  };
  const renderVisualCheckbox = (isSelected, isDisabled) => {
    const checkboxClasses = cn(
      "w-5 h-5 rounded border-2 cursor-default transition-all duration-200 flex items-center justify-center",
      isSelected ? "border-primary-950 bg-primary-950 text-text" : "border-border-400 bg-background",
      isDisabled && "opacity-40 cursor-not-allowed"
    );
    return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: checkboxClasses, children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_phosphor_react3.Check, { size: 16, weight: "bold" }) });
  };
  if (mode === "readonly") {
    return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: cn("flex flex-col gap-2", className), children: choices.map((choice, i) => {
      const isSelected = actualValue?.includes(choice.value) || false;
      const statusStyles = getStatusStyles(choice.status);
      const statusBadge = getStatusBadge(choice.status);
      return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
        "div",
        {
          className: cn(
            "flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all",
            statusStyles,
            choice.disabled ? "opacity-50 cursor-not-allowed" : ""
          ),
          children: [
            /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-2 flex-1", children: [
              renderVisualCheckbox(isSelected, choice.disabled || disabled),
              /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
                HtmlMathRenderer_default,
                {
                  content: choice.label,
                  className: cn(
                    "flex-1",
                    isSelected || choice.status && choice.status != "neutral" /* NEUTRAL */ ? "text-text-950" : "text-text-600",
                    choice.disabled || disabled ? "cursor-not-allowed" : "cursor-default"
                  )
                }
              )
            ] }),
            statusBadge && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex-shrink-0", children: statusBadge })
          ]
        },
        `readonly-${choice.value}-${i}`
      );
    }) });
  }
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
    "div",
    {
      className: cn(
        "flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all",
        disabled ? "opacity-50 cursor-not-allowed" : "",
        className
      ),
      children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
        CheckboxList_default,
        {
          name,
          values: actualValue,
          onValuesChange: (v) => {
            setActualValue(v);
            onHandleSelectedValues?.(v);
          },
          disabled,
          children: choices.map((choice, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
            "div",
            {
              className: "flex flex-row gap-2 items-center",
              children: [
                /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
                  CheckboxListItem,
                  {
                    value: choice.value,
                    id: `interactive-${choice.value}-${i}`,
                    disabled: choice.disabled || disabled
                  }
                ),
                /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
                  "label",
                  {
                    htmlFor: `interactive-${choice.value}-${i}`,
                    className: cn(
                      "flex-1",
                      actualValue?.includes(choice.value) ? "text-text-950" : "text-text-600",
                      choice.disabled || disabled ? "cursor-not-allowed" : "cursor-pointer"
                    ),
                    children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(HtmlMathRenderer_default, { content: choice.label })
                  }
                )
              ]
            },
            `interactive-${choice.value}-${i}`
          ))
        }
      )
    }
  );
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  MultipleChoiceList
});
//# sourceMappingURL=index.js.map