const TRACKING_PARAMS = /* @__PURE__ */ new Set([
  "fbclid",
  "gclid",
  "msclkid",
  "mc_cid",
  "mc_eid",
  "ref",
  "ref_src",
  "amp"
  // bare ?amp=1 marker
]);
const MOBILE_SUBDOMAINS = /* @__PURE__ */ new Set(["m", "mobile"]);
function isTrackingParam(name) {
  if (TRACKING_PARAMS.has(name)) return true;
  return name.startsWith("utm_");
}
function stripMobileAndWww(host) {
  let h = host.toLowerCase().replace(/^www\./, "");
  const firstDot = h.indexOf(".");
  if (firstDot > 0) {
    const head = h.slice(0, firstDot);
    if (MOBILE_SUBDOMAINS.has(head)) {
      h = h.slice(firstDot + 1);
    }
  }
  return h;
}
function stripAmpFromPathname(pathname) {
  let p = pathname;
  if (p.startsWith("/amp/")) p = p.slice(4);
  p = p.replace(/\/amp\/?$/i, "");
  p = p.replace(/\.amp$/i, "");
  if (p === "") p = "/";
  return p;
}
function canonicalizeUrl(input) {
  if (!input) return input;
  let parsed;
  try {
    parsed = new URL(input);
  } catch {
    return input;
  }
  parsed.protocol = "https:";
  parsed.hostname = stripMobileAndWww(parsed.hostname);
  parsed.hash = "";
  if (parsed.port === "80" && parsed.protocol === "http:" || parsed.port === "443" && parsed.protocol === "https:" || parsed.port === "80" || parsed.port === "443") {
    parsed.port = "";
  }
  parsed.pathname = stripAmpFromPathname(parsed.pathname);
  const kept = [];
  for (const [k, v] of parsed.searchParams.entries()) {
    if (isTrackingParam(k)) continue;
    kept.push([k, v]);
  }
  kept.sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0);
  parsed.search = "";
  for (const [k, v] of kept) parsed.searchParams.append(k, v);
  let out = parsed.toString();
  if (parsed.pathname !== "/" && parsed.search === "" && out.endsWith("/")) {
    out = out.slice(0, -1);
  } else if (parsed.pathname === "/" && parsed.search === "" && parsed.hash === "") {
    out = out.replace(/\/$/, "");
  }
  return out;
}
export {
  canonicalizeUrl
};
//# sourceMappingURL=canonical-url.js.map