import structuredClone from "../../../../@ungap_structured-clone@1.3.0/node_modules/@ungap/structured-clone/esm/index.js";
import { handlers } from "./handlers/index.js";
import { visit } from "../../../../unist-util-visit@5.0.0/node_modules/unist-util-visit/lib/index.js";
import { position } from "../../../../unist-util-position@5.0.0/node_modules/unist-util-position/lib/index.js";
const own = {}.hasOwnProperty;
const emptyOptions = {};
function createState(tree, options) {
  const settings = options || emptyOptions;
  const definitionById = /* @__PURE__ */ new Map();
  const footnoteById = /* @__PURE__ */ new Map();
  const footnoteCounts = /* @__PURE__ */ new Map();
  const handlers$1 = { ...handlers, ...settings.handlers };
  const state = {
    all,
    applyData,
    definitionById,
    footnoteById,
    footnoteCounts,
    footnoteOrder: [],
    handlers: handlers$1,
    one,
    options: settings,
    patch,
    wrap
  };
  visit(tree, function(node) {
    if (node.type === "definition" || node.type === "footnoteDefinition") {
      const map = node.type === "definition" ? definitionById : footnoteById;
      const id = String(node.identifier).toUpperCase();
      if (!map.has(id)) {
        map.set(id, node);
      }
    }
  });
  return state;
  function one(node, parent) {
    const type = node.type;
    const handle = state.handlers[type];
    if (own.call(state.handlers, type) && handle) {
      return handle(state, node, parent);
    }
    if (state.options.passThrough && state.options.passThrough.includes(type)) {
      if ("children" in node) {
        const { children, ...shallow } = node;
        const result = structuredClone(shallow);
        result.children = state.all(node);
        return result;
      }
      return structuredClone(node);
    }
    const unknown = state.options.unknownHandler || defaultUnknownHandler;
    return unknown(state, node, parent);
  }
  function all(parent) {
    const values = [];
    if ("children" in parent) {
      const nodes = parent.children;
      let index = -1;
      while (++index < nodes.length) {
        const result = state.one(nodes[index], parent);
        if (result) {
          if (index && nodes[index - 1].type === "break") {
            if (!Array.isArray(result) && result.type === "text") {
              result.value = trimMarkdownSpaceStart(result.value);
            }
            if (!Array.isArray(result) && result.type === "element") {
              const head = result.children[0];
              if (head && head.type === "text") {
                head.value = trimMarkdownSpaceStart(head.value);
              }
            }
          }
          if (Array.isArray(result)) {
            values.push(...result);
          } else {
            values.push(result);
          }
        }
      }
    }
    return values;
  }
}
function patch(from, to) {
  if (from.position) to.position = position(from);
}
function applyData(from, to) {
  let result = to;
  if (from && from.data) {
    const hName = from.data.hName;
    const hChildren = from.data.hChildren;
    const hProperties = from.data.hProperties;
    if (typeof hName === "string") {
      if (result.type === "element") {
        result.tagName = hName;
      } else {
        const children = "children" in result ? result.children : [result];
        result = { type: "element", tagName: hName, properties: {}, children };
      }
    }
    if (result.type === "element" && hProperties) {
      Object.assign(result.properties, structuredClone(hProperties));
    }
    if ("children" in result && result.children && hChildren !== null && hChildren !== void 0) {
      result.children = hChildren;
    }
  }
  return result;
}
function defaultUnknownHandler(state, node) {
  const data = node.data || {};
  const result = "value" in node && !(own.call(data, "hProperties") || own.call(data, "hChildren")) ? { type: "text", value: node.value } : {
    type: "element",
    tagName: "div",
    properties: {},
    children: state.all(node)
  };
  state.patch(node, result);
  return state.applyData(node, result);
}
function wrap(nodes, loose) {
  const result = [];
  let index = -1;
  if (loose) {
    result.push({ type: "text", value: "\n" });
  }
  while (++index < nodes.length) {
    if (index) result.push({ type: "text", value: "\n" });
    result.push(nodes[index]);
  }
  if (loose && nodes.length > 0) {
    result.push({ type: "text", value: "\n" });
  }
  return result;
}
function trimMarkdownSpaceStart(value) {
  let index = 0;
  let code = value.charCodeAt(index);
  while (code === 9 || code === 32) {
    index++;
    code = value.charCodeAt(index);
  }
  return value.slice(index);
}
export {
  createState,
  wrap
};
//# sourceMappingURL=state.js.map
