var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __objRest = (source, exclude) => {
  var target = {};
  for (var prop in source)
    if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
      target[prop] = source[prop];
  if (source != null && __getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(source)) {
      if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
        target[prop] = source[prop];
    }
  return target;
};
import shorthash from "shorthash";
import { extractDirectives, generateHydrateScript } from "./hydration.js";
import { serializeListValue } from "./util.js";
import { createMetadata } from "./metadata.js";
const voidElementNames = /^(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/i;
async function _render(child) {
  child = await child;
  if (Array.isArray(child)) {
    return (await Promise.all(child.map((value) => _render(value)))).join("");
  } else if (typeof child === "function") {
    return _render(child());
  } else if (typeof child === "string") {
    return child;
  } else if (!child && child !== 0) {
  } else if (child instanceof AstroComponent || Object.prototype.toString.call(child) === "[object AstroComponent]") {
    return await renderAstroComponent(child);
  } else {
    return child;
  }
}
class AstroComponent {
  constructor(htmlParts, expressions) {
    this.htmlParts = htmlParts;
    this.expressions = expressions;
  }
  get [Symbol.toStringTag]() {
    return "AstroComponent";
  }
  *[Symbol.iterator]() {
    const { htmlParts, expressions } = this;
    for (let i = 0; i < htmlParts.length; i++) {
      const html = htmlParts[i];
      const expression = expressions[i];
      yield _render(html);
      yield _render(expression);
    }
  }
}
async function render(htmlParts, ...expressions) {
  return new AstroComponent(htmlParts, expressions);
}
function createComponent(cb) {
  cb.isAstroComponentFactory = true;
  return cb;
}
async function renderSlot(_result, slotted, fallback) {
  if (slotted) {
    return _render(slotted);
  }
  return fallback;
}
const Fragment = Symbol("Astro.Fragment");
function guessRenderers(componentUrl) {
  const extname = componentUrl == null ? void 0 : componentUrl.split(".").pop();
  switch (extname) {
    case "svelte":
      return ["@astrojs/renderer-svelte"];
    case "vue":
      return ["@astrojs/renderer-vue"];
    case "jsx":
    case "tsx":
      return ["@astrojs/renderer-react", "@astrojs/renderer-preact"];
    default:
      return ["@astrojs/renderer-react", "@astrojs/renderer-preact", "@astrojs/renderer-vue", "@astrojs/renderer-svelte"];
  }
}
function formatList(values) {
  if (values.length === 1) {
    return values[0];
  }
  return `${values.slice(0, -1).join(", ")} or ${values[values.length - 1]}`;
}
async function renderComponent(result, displayName, Component, _props, slots = {}) {
  var _a, _b;
  Component = await Component;
  const children = await renderSlot(result, slots == null ? void 0 : slots.default);
  if (Component === Fragment) {
    return children;
  }
  if (Component && Component.isAstroComponentFactory) {
    const output = await renderToString(result, Component, _props, slots);
    return output;
  }
  if (Component === null && !_props["client:only"]) {
    throw new Error(`Unable to render ${displayName} because it is ${Component}!
Did you forget to import the component or is it possible there is a typo?`);
  }
  const { renderers } = result._metadata;
  const metadata = { displayName };
  const { hydration, props } = extractDirectives(_props);
  let html = "";
  if (hydration) {
    metadata.hydrate = hydration.directive;
    metadata.hydrateArgs = hydration.value;
    metadata.componentExport = hydration.componentExport;
    metadata.componentUrl = hydration.componentUrl;
  }
  const probableRendererNames = guessRenderers(metadata.componentUrl);
  if (Array.isArray(renderers) && renderers.length === 0 && typeof Component !== "string") {
    const message = `Unable to render ${metadata.displayName}!

There are no \`renderers\` set in your \`astro.config.mjs\` file.
Did you mean to enable ${formatList(probableRendererNames.map((r) => "`" + r + "`"))}?`;
    throw new Error(message);
  }
  let renderer;
  if (metadata.hydrate !== "only") {
    for (const r of renderers) {
      if (await r.ssr.check(Component, props, children)) {
        renderer = r;
        break;
      }
    }
  } else {
    if (metadata.hydrateArgs) {
      const rendererName = metadata.hydrateArgs;
      renderer = renderers.filter(({ name }) => name === `@astrojs/renderer-${rendererName}` || name === rendererName)[0];
    }
    if (!renderer && renderers.length === 1) {
      renderer = renderers[0];
    }
    if (!renderer) {
      const extname = (_a = metadata.componentUrl) == null ? void 0 : _a.split(".").pop();
      renderer = renderers.filter(({ name }) => name === `@astrojs/renderer-${extname}` || name === extname)[0];
    }
  }
  if (!renderer) {
    if (metadata.hydrate === "only") {
      throw new Error(`Unable to render ${metadata.displayName}!

Using the \`client:only\` hydration strategy, Astro needs a hint to use the correct renderer.
Did you mean to pass <${metadata.displayName} client:only="${probableRendererNames.map((r) => r.replace("@astrojs/renderer-", "")).join("|")}" />
`);
    } else if (typeof Component !== "string") {
      const matchingRenderers = renderers.filter((r) => probableRendererNames.includes(r.name));
      const plural = renderers.length > 1;
      if (matchingRenderers.length === 0) {
        throw new Error(`Unable to render ${metadata.displayName}!

There ${plural ? "are" : "is"} ${renderers.length} renderer${plural ? "s" : ""} configured in your \`astro.config.mjs\` file,
but ${plural ? "none were" : "it was not"} able to server-side render ${metadata.displayName}.

Did you mean to enable ${formatList(probableRendererNames.map((r) => "`" + r + "`"))}?`);
      } else {
        throw new Error(`Unable to render ${metadata.displayName}!

This component likely uses ${formatList(probableRendererNames)},
but Astro encountered an error during server-side rendering.

Please ensure that ${metadata.displayName}:
1. Does not unconditionally access browser-specific globals like \`window\` or \`document\`.
   If this is unavoidable, use the \`client:only\` hydration directive.
2. Does not conditionally return \`null\` or \`undefined\` when rendered on the server.

If you're still stuck, please open an issue on GitHub or join us at https://astro.build/chat.`);
      }
    }
  } else {
    if (metadata.hydrate === "only") {
      html = await renderSlot(result, slots == null ? void 0 : slots.fallback);
    } else {
      ({ html } = await renderer.ssr.renderToStaticMarkup(Component, props, children));
    }
  }
  if (!html && typeof Component === "string") {
    html = await renderAstroComponent(await render`<${Component}${spreadAttributes(props)}${(children == null || children == "") && voidElementNames.test(Component) ? `/>` : `>${children}</${Component}>`}`);
  }
  if ((_b = renderer == null ? void 0 : renderer.polyfills) == null ? void 0 : _b.length) {
    for (const src of renderer.polyfills) {
      result.scripts.add({
        props: { type: "module" },
        children: `import "${await result.resolve(src)}";`
      });
    }
  }
  if (!hydration) {
    return html.replace(/\<\/?astro-fragment\>/g, "");
  }
  const astroId = shorthash.unique(`<!--${metadata.componentExport.value}:${metadata.componentUrl}-->
${html}`);
  result.scripts.add(await generateHydrateScript({ renderer, result, astroId, props }, metadata));
  return `<astro-root uid="${astroId}">${html != null ? html : ""}</astro-root>`;
}
function createFetchContentFn(url) {
  const fetchContent = (importMetaGlobResult) => {
    let allEntries = [...Object.entries(importMetaGlobResult)];
    if (allEntries.length === 0) {
      throw new Error(`[${url.pathname}] Astro.fetchContent() no matches found.`);
    }
    return allEntries.map(([spec, mod]) => {
      if (!mod.frontmatter) {
        return;
      }
      const urlSpec = new URL(spec, url).pathname;
      return __spreadProps(__spreadValues({}, mod.frontmatter), {
        Content: mod.default,
        content: mod.metadata,
        file: new URL(spec, url),
        url: urlSpec.includes("/pages/") ? urlSpec.replace(/^.*\/pages\//, "/").replace(/(\/index)?\.md$/, "") : void 0
      });
    }).filter(Boolean);
  };
  return fetchContent;
}
function createAstro(filePathname, site, projectRootStr) {
  const url = new URL(filePathname, site);
  const projectRoot = new URL(projectRootStr);
  const fetchContent = createFetchContentFn(url);
  return {
    site: new URL(site),
    fetchContent,
    resolve(...segments) {
      let resolved = segments.reduce((u, segment) => new URL(segment, u), url).pathname;
      if (resolved.startsWith(projectRoot.pathname)) {
        resolved = "/" + resolved.substr(projectRoot.pathname.length);
      }
      return resolved;
    }
  };
}
const toAttributeString = (value) => String(value).replace(/&/g, "&#38;").replace(/"/g, "&#34;");
function addAttribute(value, key) {
  if (value == null || value === false) {
    return "";
  }
  if (key === "class:list") {
    return ` ${key.slice(0, -5)}="${toAttributeString(serializeListValue(value))}"`;
  }
  if (value === true && key.startsWith("data-")) {
    return ` ${key}`;
  } else {
    return ` ${key}="${toAttributeString(value)}"`;
  }
}
function spreadAttributes(values) {
  let output = "";
  for (const [key, value] of Object.entries(values)) {
    output += addAttribute(value, key);
  }
  return output;
}
function defineStyleVars(selector, vars) {
  let output = "\n";
  for (const [key, value] of Object.entries(vars)) {
    output += `  --${key}: ${value};
`;
  }
  return `${selector} {${output}}`;
}
function defineScriptVars(vars) {
  let output = "";
  for (const [key, value] of Object.entries(vars)) {
    output += `let ${key} = ${JSON.stringify(value)};
`;
  }
  return output;
}
async function renderToString(result, componentFactory, props, children) {
  const Component = await componentFactory(result, props, children);
  let template = await renderAstroComponent(Component);
  return template;
}
const uniqueElements = (item, index, all) => {
  const props = JSON.stringify(item.props);
  const children = item.children;
  return index === all.findIndex((i) => JSON.stringify(i.props) === props && i.children == children);
};
async function renderPage(result, Component, props, children) {
  const template = await renderToString(result, Component, props, children);
  const styles = result._metadata.experimentalStaticBuild ? [] : Array.from(result.styles).filter(uniqueElements).map((style) => renderElement("style", __spreadProps(__spreadValues({}, style), {
    props: __spreadProps(__spreadValues({}, style.props), { "astro-style": true })
  })));
  let needsHydrationStyles = false;
  const scripts = Array.from(result.scripts).filter(uniqueElements).map((script, i) => {
    if ("data-astro-component-hydration" in script.props) {
      needsHydrationStyles = true;
    }
    return renderElement("script", __spreadProps(__spreadValues({}, script), {
      props: __spreadProps(__spreadValues({}, script.props), { "astro-script": result._metadata.pathname + "/script-" + i })
    }));
  });
  if (needsHydrationStyles) {
    styles.push(renderElement("style", { props: { "astro-style": true }, children: "astro-root, astro-fragment { display: contents; }" }));
  }
  const links = Array.from(result.links).filter(uniqueElements).map((link) => renderElement("link", link));
  let headPos = template.indexOf("</head>");
  if (headPos === -1) {
    return links.join("\n") + styles.join("\n") + scripts.join("\n") + template;
  }
  return template.substring(0, headPos) + links.join("\n") + styles.join("\n") + scripts.join("\n") + template.substring(headPos);
}
async function renderAstroComponent(component) {
  let template = "";
  for await (const value of component) {
    if (value || value === 0) {
      template += value;
    }
  }
  return template;
}
function renderElement(name, { props: _props, children = "" }) {
  const _a = _props, { lang: _, "data-astro-id": astroId, "define:vars": defineVars } = _a, props = __objRest(_a, ["lang", "data-astro-id", "define:vars"]);
  if (defineVars) {
    if (name === "style") {
      if (props.global) {
        children = defineStyleVars(`:root`, defineVars) + "\n" + children;
      } else {
        children = defineStyleVars(`.astro-${astroId}`, defineVars) + "\n" + children;
      }
      delete props.global;
    }
    if (name === "script") {
      delete props.hoist;
      children = defineScriptVars(defineVars) + "\n" + children;
    }
  }
  return `<${name}${spreadAttributes(props)}>${children}</${name}>`;
}
export {
  AstroComponent,
  Fragment,
  addAttribute,
  createAstro,
  createComponent,
  createMetadata,
  defineScriptVars,
  defineStyleVars,
  render,
  renderAstroComponent,
  renderComponent,
  renderPage,
  renderSlot,
  renderToString,
  spreadAttributes
};
//# sourceMappingURL=data:application/json;base64, 
