"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 __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
var __typeError = (msg) => {
  throw TypeError(msg);
};
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all2) => {
  for (var name in all2)
    __defProp(target, name, { get: all2[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);
var __decoratorStart = (base) => [, , , __create(base?.[__knownSymbol("metadata")] ?? null)];
var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn;
var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) });
var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
var __runInitializers = (array, flags, self, value) => {
  for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);
  return value;
};
var __decorateElement = (array, flags, name, decorators, target, extra) => {
  var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);
  var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings[k + 5];
  var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
  var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc(k < 4 ? target : { get [name]() {
    return __privateGet(this, extra);
  }, set [name](x) {
    return __privateSet(this, extra, x);
  } }, name));
  k ? p && k < 4 && __name(extra, (k > 2 ? "set " : k > 1 ? "get " : "") + name) : __name(target, name);
  for (var i = decorators.length - 1; i >= 0; i--) {
    ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
    if (k) {
      ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn(target, x) : (x) => name in x };
      if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet : __privateMethod)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name];
      if (k > 2) access.set = p ? (x, y) => __privateSet(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y;
    }
    it = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key] : k > 4 ? void 0 : { get: desc.get, set: desc.set } : target, ctx), done._ = 1;
    if (k ^ 4 || it === void 0) __expectFn(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it);
    else if (typeof it !== "object" || it === null) __typeError("Object expected");
    else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn);
  }
  return k || __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
};
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use the "in" operator on this value') : member.has(obj);
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);

// src/core/markdown/index.ts
var index_exports = {};
__export(index_exports, {
  INCLUDE_REGEX: () => INCLUDE_REGEX,
  MarkdownService: () => MarkdownService,
  findLink: () => findLink,
  getHooks: () => getHooks
});
module.exports = __toCommonJS(index_exports);

// src/core/markdown/hooks.ts
var import_tapable = require("tapable");
var import_utils = require("@diplodoc/cli/lib/utils");
function hooks(name) {
  return {
    Collects: new import_tapable.AsyncSeriesWaterfallHook(["collects"], `${name}.Collects`),
    Plugins: new import_tapable.AsyncSeriesWaterfallHook(["plugins"], `${name}.Plugins`),
    Loaded: new import_tapable.AsyncSeriesHook(
      ["markdown", "meta", "path"],
      `${name}.Loaded`
    ),
    Resolved: new import_tapable.AsyncSeriesHook(
      ["markdown", "path"],
      `${name}.Resolved`
    ),
    Dump: new import_tapable.AsyncSeriesHook(["vfile"], `${name}.Dump`)
  };
}
var [getHooks, withHooks] = (0, import_utils.generateHooksAccess)("Markdown", hooks);

// src/core/markdown/MarkdownService.ts
var import_node_path3 = require("node:path");
var import_liquid3 = require("@diplodoc/liquid");
var import_utils11 = require("@diplodoc/cli/lib/utils");

// src/core/markdown/loader.ts
var import_lodash = require("lodash");
var import_utils10 = require("@diplodoc/cli/lib/utils");

// src/core/markdown/loader/mangle-frontmatter.ts
var import_liquid = require("@diplodoc/liquid");
function safeExtractFrontmatter(content) {
  try {
    return (0, import_liquid.extractFrontMatter)(content);
  } catch (error) {
    const err = error;
    if (err.reason === "duplicated mapping key") {
      const line = typeof err.mark?.line === "number" ? err.mark.line + 1 : void 0;
      const key = line === void 0 ? "" : content.split("\n")[line]?.trim().split(":")[0];
      if (key && key !== "vcsPath") {
        const context = `[Reason: "${err.reason}"; Line: ${line}; Key: "${key}"]`;
        const errorMessage = `${this.path}: ${line}: YFM017 / invalid front matter format ${context}`;
        this.logger.error(errorMessage);
      }
    }
    return (0, import_liquid.extractFrontMatter)(content, { json: true });
  }
}
function mangleFrontMatter(rawContent) {
  const { vars, options } = this;
  const { disableLiquid } = options;
  const [frontmatter, content, rawFrontmatter] = safeExtractFrontmatter.call(this, rawContent);
  if (!rawFrontmatter) {
    this.api.meta.set({});
    return rawContent;
  }
  if (disableLiquid) {
    this.api.meta.set(frontmatter);
  } else {
    this.api.meta.set(import_liquid.liquidJson.call(this, frontmatter, vars));
  }
  this.sourcemap.delete(1, rawFrontmatter);
  return content;
}

// src/core/markdown/loader/template-content.ts
var import_liquid2 = require("@diplodoc/liquid");
function templateContent(rawContent) {
  const { vars, options } = this;
  const { disableLiquid } = options;
  if (disableLiquid) {
    return rawContent;
  }
  let content;
  if (this.mode === "translate") {
    content = import_liquid2.liquidDocument.call(this, rawContent, vars);
  } else {
    content = import_liquid2.liquidSnippet.call(this, rawContent, vars, this.sourcemap);
  }
  return content;
}

// src/core/markdown/loader/resolve-comments.ts
function resolveComments(content) {
  const COMMENTS_CONTENTS = /<!-{2,}[\s\S]*?-{2,}>/g;
  const comments = [];
  let match;
  while (match = COMMENTS_CONTENTS.exec(content)) {
    comments.push([match.index, COMMENTS_CONTENTS.lastIndex]);
  }
  this.api.comments.set(comments);
  return content;
}

// src/core/markdown/loader/resolve-deps.ts
var import_node_path = require("node:path");
var import_utils3 = require("@diplodoc/cli/lib/utils");

// src/core/markdown/utils.ts
var import_js_yaml = require("js-yaml");
var import_utils2 = require("@diplodoc/cli/lib/utils");
var modifiers = { "!": "image", "@": "video", "": "link" };
function findLink(content) {
  const rx = /]\(\s*/g;
  const match = rx.exec(content);
  if (!match) {
    return void 0;
  }
  const link = parseLinkDestination(content, rx.lastIndex);
  if (link === null || link.match(/[${}]/)) {
    return void 0;
  }
  rx.lastIndex += link.length + 1;
  return link;
}
function extractImages(block) {
  const images = [];
  if (!block) {
    return images;
  }
  if (typeof block === "string") {
    const trimmedBlock = block.trim();
    if (import_utils2.MEDIA_FORMATS.test(trimmedBlock) && trimmedBlock.split(/\s+/).length === 1) {
      images.push(trimmedBlock);
    }
    return images;
  }
  (0, import_utils2.walkLinks)(block, (value) => {
    if (import_utils2.MEDIA_FORMATS.test(value) && value.split(/\s+/).length === 1) {
      images.push(value);
    }
  });
  return images;
}
function parsePcBlocks(blocks = [], images = []) {
  for (const block of blocks) {
    images.push(...extractImages(block));
  }
  return images;
}
function getPcIconTitle(iconPath) {
  const file = iconPath.split("/").pop() || iconPath;
  return file.replace(/\.[^.]+$/, "");
}
var PC_REGEX = /^([ \t]*):::\s*page-constructor[ \t]*\r?\n?/m;
var INCLUDE_REGEX = /{%\s*include\s*.+?%}/g;
function findPcImages(content) {
  const pcImages = [];
  const openRegex = new RegExp(PC_REGEX.source, PC_REGEX.flags);
  let searchStart = 0;
  while (searchStart < content.length) {
    const remaining = content.slice(searchStart);
    const match = openRegex.exec(remaining);
    if (!match) {
      break;
    }
    const indent = match[1] || "";
    const matchIndex = searchStart + match.index;
    const startIdx = matchIndex + match[0].length;
    const closeRegex = new RegExp(`^${indent}:::[ \\t]*$`, "m");
    const afterMatch = content.slice(startIdx);
    const closeMatch = closeRegex.exec(afterMatch);
    if (!closeMatch) {
      searchStart = startIdx;
      continue;
    }
    const rawBlock = afterMatch.slice(0, closeMatch.index);
    let data;
    try {
      data = (0, import_js_yaml.load)(rawBlock);
    } catch {
      searchStart = startIdx;
      continue;
    }
    const images = parsePcBlocks(data?.blocks, []);
    for (const img of images) {
      const parsed = (0, import_utils2.parseLocalUrl)(img);
      if (!parsed) {
        continue;
      }
      const blockEnd = startIdx + closeMatch.index + closeMatch[0].length;
      pcImages.push({
        ...parsed,
        type: "image",
        subtype: "image",
        title: getPcIconTitle(img),
        autotitle: false,
        hash: null,
        search: null,
        location: [matchIndex, blockEnd],
        // no inline svg inside page-constructor because we hasn't a location for asset
        options: { width: void 0, height: void 0, inline: false, title: void 0 }
      });
    }
    searchStart = startIdx + closeMatch.index + closeMatch[0].length;
  }
  return pcImages;
}
function findHtmlDownloadLinks(content) {
  const assets = [];
  const tagRx = /<a\s[^>]*?\bdownload\b[^>]*>/gi;
  const hrefRx = /\bhref="([^"]+)"/i;
  let match;
  while ((match = tagRx.exec(content)) !== null) {
    const hrefMatch = hrefRx.exec(match[0]);
    if (!hrefMatch) {
      continue;
    }
    const parsed = (0, import_utils2.parseLocalUrl)(hrefMatch[1]);
    if (!parsed) {
      continue;
    }
    assets.push({
      ...parsed,
      type: "link",
      subtype: null,
      title: "",
      autotitle: false,
      location: [match.index, match.index + match[0].length]
    });
  }
  return assets;
}
function findFileBlocks(content) {
  const fileAssets = [];
  const rx = /{%\s*file\s.*?src="([^"]+)".*?%}/g;
  let match;
  while ((match = rx.exec(content)) !== null) {
    const src = match[1];
    const parsed = (0, import_utils2.parseLocalUrl)(src);
    if (!parsed) {
      continue;
    }
    fileAssets.push({
      ...parsed,
      type: "link",
      subtype: null,
      title: "",
      autotitle: false,
      location: [match.index, match.index + match[0].length]
    });
  }
  return fileAssets;
}
function findLinksInfo(content) {
  const links = find(/]\(\s*/g, content, (match, rx) => {
    const link = parseLinkDestination(content, rx.lastIndex);
    const title = parseLinkTitle(content, rx.lastIndex - match[0].length);
    const options = parseLinkOptions(content, rx.lastIndex + (link?.length || 0) + 1);
    if (link === null || title === null || link.match(/[${}]/)) {
      return void 0;
    }
    const parsed = (0, import_utils2.parseLocalUrl)(link);
    if (!parsed) {
      return void 0;
    }
    const modifier = content[rx.lastIndex - match[0].length - title.length - 2];
    const type = modifiers[modifier] || "link";
    rx.lastIndex += link.length + 1;
    return {
      ...parsed,
      type,
      subtype: type === "image" ? "image" : null,
      title,
      autotitle: type === "link" && (!title || title === "{#T}"),
      options
    };
  });
  const referenceLinks = find(/]\[\s*/g, content, (match, rx) => {
    let link = parseLinkDestination(content, rx.lastIndex, ["[", "]"]);
    let title = parseLinkTitle(content, rx.lastIndex - match[0].length);
    const options = parseLinkOptions(content, rx.lastIndex + (link?.length || 0) + 1);
    if (link === null && title === null || link?.match(/[${}]/)) {
      return void 0;
    }
    title = title || "";
    link = link || title;
    const parsed = (0, import_utils2.parseLocalUrl)(link);
    if (!parsed) {
      return void 0;
    }
    const modifier = content[rx.lastIndex - match[0].length - title.length - 2];
    const type = modifiers[modifier] || "link";
    rx.lastIndex += (content[rx.lastIndex] === "]" ? 0 : link.length) + 1;
    return {
      ...parsed,
      type,
      subtype: "reference",
      code: link,
      title,
      autotitle: type === "link" && (!title || title === "{#T}"),
      options
    };
  });
  return [...links, ...referenceLinks];
}
function findDefs(content) {
  return find(/^\s*\[(.*?)]:\s*([^\s]+)/gm, content, (match) => {
    const parsed = (0, import_utils2.parseLocalUrl)(match[2]);
    if (!parsed) {
      return void 0;
    }
    return {
      ...parsed,
      type: "def",
      code: match[1] || void 0,
      title: "",
      autotitle: true
    };
  });
}
function find(matcher, content, map) {
  const links = [];
  let match;
  while (match = matcher.exec(content)) {
    const result = map(match, matcher);
    if (!result) {
      continue;
    }
    if (result) {
      links.push({
        ...result,
        location: [match.index, matcher.lastIndex]
      });
    }
  }
  return links;
}
function parseLinkDestination(str, start, symbols = ["(", ")"]) {
  const max = str.length;
  const [symbolStart, symbolEnd] = symbols.map((symbol) => symbol.charCodeAt(0));
  let code, level = 0, pos = start;
  if (str.charCodeAt(pos) === 60) {
    return parseSimpleLink(str, start + 1);
  }
  while (pos < max) {
    code = str.charCodeAt(pos);
    if (code === 32) {
      break;
    }
    if (code < 32 || code === 127) {
      break;
    }
    if (code === 92 && pos + 1 < max) {
      if (str.charCodeAt(pos + 1) === 32) {
        break;
      }
      pos += 2;
      continue;
    }
    if (code === symbolStart) {
      level++;
      if (level > 32) {
        return null;
      }
    }
    if (code === symbolEnd) {
      if (level === 0) {
        break;
      }
      level--;
    }
    pos++;
  }
  if (start === pos) {
    return null;
  }
  if (level !== 0) {
    return null;
  }
  return str.slice(start, pos);
}
function parseLinkTitle(str, start) {
  let code, prev, level = 0, pos = start;
  while (pos >= 0) {
    code = str.charCodeAt(pos);
    prev = str.charCodeAt(pos - 1);
    if (code < 32 || code === 127) {
      break;
    }
    if (prev === 92) {
      pos -= 2;
      continue;
    }
    if (code === 93) {
      level++;
      if (level > 32) {
        return null;
      }
    }
    if (code === 91) {
      if (level === 1) {
        break;
      }
      level--;
    }
    pos--;
  }
  return str.slice(pos + 1, start);
}
function parseLinkOptions(str, start) {
  const max = str.length;
  const options = {
    width: void 0,
    height: void 0,
    inline: void 0,
    title: void 0
  };
  let code, level = 0, pos = start, startOption = start;
  if (str[pos - 1] !== ")") {
    level--;
  }
  if (str.charCodeAt(pos) !== 123 && level === 0) {
    return options;
  }
  while (pos < max) {
    code = str.charCodeAt(pos);
    if (code === 41 && level === -1) {
      if (str.charCodeAt(pos + 1) !== 123) {
        return options;
      }
      level++;
    }
    if (code === 123 && level > -1) {
      level++;
      startOption = pos + 1;
      if (level > 32) {
        return options;
      }
    }
    if (code === 125) {
      if (level === 1) {
        level--;
        break;
      }
      level--;
    }
    pos++;
  }
  if (start === pos || level !== 0) {
    return options;
  }
  const attrRegex = /(\w+)=(?:'([^']*)'|"([^"]*)"|(\S+))/g;
  const optionsString = str.slice(startOption, pos);
  let match;
  while ((match = attrRegex.exec(optionsString)) !== null) {
    const key = match[1];
    const value = match[2] || match[3] || match[4];
    if (key === "inline") {
      options[key] = value === "true";
    } else {
      options[key] = value;
    }
  }
  return options;
}
function parseSimpleLink(str, start) {
  const max = str.length;
  let code, pos = start;
  while (pos < max) {
    code = str.charCodeAt(pos);
    if (code === 10) {
      return null;
    }
    if (code === 60) {
      return null;
    }
    if (code === 62) {
      return str.slice(start, pos);
    }
    if (code === 92 && pos + 1 < max) {
      pos += 2;
      continue;
    }
    pos++;
  }
  return null;
}
function findIncludedBlockRanges(content) {
  const INCLUDED_OPEN = /{%\s*included\s*\(.+?\)\s*%}/g;
  const INCLUDED_CLOSE = /{%\s*endincluded\s*%}/g;
  const ranges = [];
  let openMatch;
  while (openMatch = INCLUDED_OPEN.exec(content)) {
    INCLUDED_CLOSE.lastIndex = INCLUDED_OPEN.lastIndex;
    const closeMatch = INCLUDED_CLOSE.exec(content);
    if (closeMatch) {
      ranges.push([openMatch.index, INCLUDED_CLOSE.lastIndex]);
    }
  }
  return ranges;
}
function filterRanges(excludes, infos) {
  const contains = (exclude, point) => {
    return exclude[1] >= point[0] && exclude[1] <= point[1] || exclude[0] >= point[0] && exclude[0] < point[1] || exclude[0] < point[0] && exclude[1] >= point[1];
  };
  return infos.filter((item) => {
    return !excludes.some((exclude) => contains(exclude, item.location));
  });
}
function parseHeading(content) {
  const anchors = [];
  const commonHeading = content.match(/^#+/);
  const alternateHeading = content[content.length - 1];
  const alternaleLevels = ["-", "="];
  const level = commonHeading ? commonHeading[0].length : alternaleLevels.indexOf(alternateHeading) + 1;
  if (commonHeading) {
    content = content.replace(/^#+\s*/, "");
  } else {
    content = content.replace(/\n[-=]+$/, "");
  }
  const ANCHOR = /[^[]{(#[^}]+)}/g;
  let match;
  while (match = ANCHOR.exec(content)) {
    anchors.push(match[1]);
    content = content.replace(match[0], "");
    ANCHOR.lastIndex -= match[0].length;
  }
  const title = content.trim();
  return { anchors, title, level };
}

// src/core/markdown/loader/resolve-deps.ts
function resolveDependencies(content) {
  const includes = [];
  const exclude = [...this.api.comments.get(), ...findIncludedBlockRanges(content)];
  const includeRegex = new RegExp(INCLUDE_REGEX.source, INCLUDE_REGEX.flags);
  let match;
  while (match = includeRegex.exec(content)) {
    if (content[match.index - 1] === "`") {
      continue;
    }
    const matchStart = match.index;
    const matchEnd = includeRegex.lastIndex;
    if (exclude.some(([exStart, exEnd]) => matchStart >= exStart && matchEnd <= exEnd)) {
      continue;
    }
    const link = findLink(match[0]);
    const include = (0, import_utils3.parseLocalUrl)(link);
    if (include && include.path) {
      const currentPath = this.path;
      const normalizedIncludePath = (0, import_utils3.normalizePath)((0, import_node_path.join)((0, import_node_path.dirname)(currentPath), include.path));
      if (normalizedIncludePath === currentPath) {
        this.logger.error("YFM016", `${currentPath}: The file is included in itself`);
        continue;
      }
      include.path = (0, import_utils3.rebasePath)(currentPath, include.path);
      include.link = link;
      include.match = content.slice(match.index, includeRegex.lastIndex);
      include.location = [match.index, includeRegex.lastIndex];
      includes.push(include);
    }
  }
  this.api.deps.set(filterRanges(exclude, includes));
  return content;
}

// src/core/markdown/loader/resolve-assets.ts
var import_node_path2 = require("node:path");
var import_utils5 = require("@diplodoc/cli/lib/utils");
function fixUnreachableLink(path, loaderContext) {
  let newPath = path;
  const pathnameParts = (0, import_utils5.normalizePath)(path).split("/");
  const relativePartsCount = pathnameParts.filter((part) => part === "..").length;
  let includedFilePath;
  for (let i = 0; i <= relativePartsCount; i++) {
    try {
      includedFilePath = (0, import_utils5.normalizePath)(
        (0, import_node_path2.join)(loaderContext.input, pathnameParts.slice(i).join("/"))
      );
      import_utils5.fs.realpathSync(includedFilePath);
      if (i > 0) {
        newPath = (0, import_utils5.normalizePath)(pathnameParts.slice(i).join("/"));
        loaderContext.logger.error(`Path was fixed from ${path} 
                        to ${newPath}`);
      }
      return newPath;
    } catch {
      if (i === relativePartsCount - 1) {
        return newPath;
      } else {
        continue;
      }
    }
  }
  return newPath;
}
function getSize(path, loaderContext, assetSizes) {
  if (path === null) {
    return 0;
  }
  if (assetSizes.has(path)) {
    return assetSizes.get(path);
  }
  try {
    const fixedPath = fixUnreachableLink(path, loaderContext);
    const fullPath2 = loaderContext.fullPath(fixedPath);
    const size = import_utils5.fs.statSync(fullPath2).size;
    assetSizes.set(path, size);
    return size;
  } catch {
    assetSizes.set(path, 0);
    return 0;
  }
}
function resolveAssets(content) {
  const assets = [];
  const assetSizes = /* @__PURE__ */ new Map();
  const exclude = [
    ...this.api.deps.get().map(({ location }) => location),
    ...this.api.comments.get(),
    ...this.api.blockCodes.get(),
    ...findIncludedBlockRanges(content)
  ];
  const defs = filterRanges(exclude, findDefs(content));
  const links = filterRanges(exclude, findLinksInfo(content));
  const pcImages = filterRanges(exclude, findPcImages(content));
  const fileBlocks = filterRanges(exclude, findFileBlocks(content));
  const htmlDownloadLinks = filterRanges(exclude, findHtmlDownloadLinks(content));
  for (const info of [...defs, ...links, ...pcImages, ...fileBlocks, ...htmlDownloadLinks]) {
    try {
      if (info.path !== null && !info.path?.startsWith("*") && !info.path?.includes("%")) {
        info.path = (0, import_utils5.rebasePath)(this.path, decodeURIComponent(info.path));
      }
      let size = 0;
      if (["def", "image"].includes(info.type) && info.subtype === "image") {
        size = getSize(info.path, this, assetSizes);
      }
      assets.push({ ...info, size });
    } catch (error) {
      this.logger.warn(`Error processing asset from ${this.path} to ${info.path}: ${error}`);
    }
  }
  this.api.assets.set([...assets]);
  return content;
}

// src/core/markdown/loader/resolve-headings.ts
function resolveHeadings(content) {
  const headings = [];
  const exclude = [...this.api.comments.get(), ...findIncludedBlockRanges(content)];
  const heading = /(?<=^|\n)([#=-])/g;
  let match;
  while (match = heading.exec(content)) {
    const [result, location] = match[1] === "#" ? findCommonHeading(match.index, content) : findAlternateHeading(match.index, content);
    if (result) {
      headings.push({ content: result, location });
      heading.lastIndex = location[1];
    }
  }
  this.api.headings.set(filterRanges(exclude, headings));
  return content;
}
var SPACE = /[ \t]/;
function findCommonHeading(start, content) {
  let title = "";
  let index = start;
  while (index < content.length) {
    if (index - start > 6) {
      return [];
    }
    if (content[index] === "#") {
      index++;
    } else if (content[index].match(SPACE)) {
      break;
    } else {
      return [];
    }
  }
  while (index < content.length) {
    if (content[index + 1] && content[index] !== "\n") {
      title += content[index];
      index++;
    } else if (title.trim()) {
      return [content.slice(start, index), [start, index]];
    } else {
      return [];
    }
  }
  return [];
}
function findAlternateHeading(start, content) {
  const delim = content[start];
  const newline = [];
  let title = "";
  let end = start;
  while (end < content.length) {
    if (content[end] === delim) {
      end++;
    } else if (content[end] === "\n" || !content[end + 1]) {
      break;
    } else {
      return [];
    }
  }
  let index = start - 1;
  while (index >= 0) {
    const isContentStart = !index;
    const isTitleStart = newline.length === 2 && !content.slice(...newline).trim();
    if (newline.length && !isTitleStart) {
      newline.length = 1;
    }
    if (!isTitleStart) {
      title = content[index] + title;
    }
    if (isContentStart || isTitleStart) {
      const clean = title.trimStart();
      if (clean) {
        return [content.slice(start - clean.length, end), [start - clean.length, end]];
      } else {
        return [];
      }
    }
    if (content[index] === "\n") {
      newline.unshift(index);
    }
    index--;
  }
  return [];
}

// src/core/markdown/loader/resolve-no-translate.ts
function resolveNoTranslate(content) {
  if (this.mode === "translate") {
    return content;
  }
  content = resolveContainerDirectives(content);
  content = resolveLeafBlockDirectives(content);
  content = resolveInlineDirectives(content);
  return content;
}
function resolveContainerDirectives(content) {
  const lines = content.split("\n");
  const result = [];
  const stack = [];
  for (let i = 0; i < lines.length; i++) {
    const line = lines[i];
    if (line.trim().startsWith(":::")) {
      const directiveLine = line.trim();
      if (directiveLine === ":::") {
        if (stack.length > 0) {
          const lastDirective = stack.pop();
          if (lastDirective === "no-translate" && stack.length === 0) {
            continue;
          }
          result.push(line);
        }
      } else {
        const directiveMatch = directiveLine.match(/^:::\s*([^\s]+)/);
        const directiveName = directiveMatch ? directiveMatch[1] : "";
        if (directiveName === "no-translate") {
          stack.push("no-translate");
          continue;
        } else {
          stack.push(directiveName);
          result.push(line);
        }
      }
    } else {
      result.push(line);
    }
  }
  return result.join("\n");
}
function resolveLeafBlockDirectives(content) {
  const blockRegex = /::\s*no-translate\s*\[([\s\S]*?)\]/g;
  return content.replace(blockRegex, (_, innerContent) => {
    return innerContent;
  });
}
function resolveInlineDirectives(content) {
  const inlineRegex = /(?<![:]):no-translate\s*\[([\s\S]*?)\]/g;
  return content.replace(inlineRegex, (_, innerContent) => {
    return innerContent;
  });
}

// src/core/markdown/loader/resolve-code.ts
var import_markdown_it = __toESM(require("markdown-it"));
var import_markdown_it_deflist = __toESM(require("markdown-it-deflist"));
var import_imsize = __toESM(require("@diplodoc/transform/lib/plugins/imsize"));
var import_table = __toESM(require("@diplodoc/transform/lib/plugins/table"));
function computeLineStarts(lines) {
  const lineStarts = [0];
  for (let i = 1; i < lines.length; i++) {
    const lineEndingLength = 1;
    lineStarts[i] = lineStarts[i - 1] + lines[i - 1].length + lineEndingLength;
  }
  return lineStarts;
}
var lineToCharPosition = (line, lineStarts, content) => line >= lineStarts.length ? content.length : lineStarts[line];
function calculateAdjustedEnd(endLine, lineStarts, lines, content) {
  let end = content.length;
  if (endLine <= lineStarts.length) {
    end = endLine === 0 ? 0 : lineStarts[endLine - 1] + lines[endLine - 1].length;
  }
  return endLine <= lines.length && endLine > 0 ? end + 1 : end;
}
function processBlockCode(token, lineStarts, lines, content, codes) {
  if (!token.map || token.map.length !== 2) {
    return;
  }
  const [startLine, endLine] = token.map;
  const start = lineToCharPosition(startLine, lineStarts, content);
  let adjustedEnd;
  if (token.type === "fence" && endLine <= lines.length) {
    const endLineContent = lines[endLine - 1] || "";
    const fenceEndIndex = endLineContent.indexOf(token.markup);
    if (fenceEndIndex > -1) {
      const lineStart = lineStarts[endLine - 1] || 0;
      const fenceEndPos = lineStart + fenceEndIndex + token.markup.length;
      adjustedEnd = fenceEndPos;
    } else {
      adjustedEnd = calculateAdjustedEnd(endLine, lineStarts, lines, content);
    }
  } else {
    adjustedEnd = calculateAdjustedEnd(endLine, lineStarts, lines, content);
  }
  codes.push([start, adjustedEnd]);
}
function checkAttribute(imagePart, matchStart, codeText, start, end, regex, getAttrStart) {
  const match = imagePart.match(regex);
  if (match) {
    if (codeText !== null) {
      if (match[1].includes(codeText)) {
        return true;
      }
    } else if (start !== void 0 && end !== void 0) {
      const attrStart = getAttrStart(matchStart, imagePart);
      const attrEnd = attrStart + match[0].length;
      if (start >= attrStart && end <= attrEnd) {
        return true;
      }
    }
  }
  return false;
}
function checkImageAttributes(imagePart, matchStart, codeText, start, end) {
  const braceMatch = checkAttribute(
    imagePart,
    matchStart,
    codeText,
    start,
    end,
    /\s*{([^}]*)}/,
    (matchStart2, imagePart2) => matchStart2 + imagePart2.indexOf("{")
  );
  const quoteMatch = checkAttribute(
    imagePart,
    matchStart,
    codeText,
    start,
    end,
    /\s*"([^"]*)"/,
    (matchStart2, imagePart2) => matchStart2 + imagePart2.indexOf('"')
  );
  return { braceMatch, quoteMatch };
}
function addCodeAndUpdatePosition(startIndex, endIndex, content, codes, parentStartPos, lines) {
  const insideAttrs = isInsideImageAttributes(content, startIndex, endIndex, lines);
  if (!insideAttrs) {
    codes.push([startIndex, endIndex]);
  }
  return insideAttrs ? parentStartPos : Math.max(parentStartPos, endIndex);
}
function processInlineCode(token, content, parentStartPos, codes, lineStarts, lines) {
  if (!token.markup || !token.content) {
    return parentStartPos;
  }
  if (token.map && token.map.length === 2) {
    const [startLine, _endLine] = token.map;
    const start = lineToCharPosition(startLine, lineStarts, content);
    const lineContent = lines[startLine] || "";
    const searchPattern = token.markup + token.content + token.markup;
    const patternIndex = lineContent.indexOf(searchPattern);
    if (patternIndex !== -1) {
      const startIndex = start + patternIndex;
      const endIndex = startIndex + searchPattern.length;
      return addCodeAndUpdatePosition(
        startIndex,
        endIndex,
        content,
        codes,
        parentStartPos,
        lines
      );
    }
  } else {
    const searchPattern = token.markup + token.content + token.markup;
    const startIndex = content.indexOf(searchPattern, parentStartPos);
    if (startIndex !== -1) {
      const endIndex = startIndex + searchPattern.length;
      return addCodeAndUpdatePosition(
        startIndex,
        endIndex,
        content,
        codes,
        parentStartPos,
        lines
      );
    }
  }
  return parentStartPos;
}
function isInsideImageAttributes(content, start, end, lines) {
  const windowSize = 200;
  const checkStart = Math.max(0, start - windowSize);
  const checkEnd = Math.min(content.length, end + windowSize);
  const contentWindow = content.substring(checkStart, checkEnd);
  const imageRegex = /!\[[^\]]*\]\([^)]*\)(?:\s*"[^"]*")?(?:\s*{[^}]*})?/g;
  let match;
  while ((match = imageRegex.exec(contentWindow)) !== null) {
    const matchStart = match.index + checkStart;
    const matchEnd = matchStart + match[0].length;
    if (start >= matchStart && end <= matchEnd) {
      const imagePart = match[0];
      const relativeStart = start - matchStart;
      const relativeEnd = end - matchStart;
      const { braceMatch, quoteMatch } = checkImageAttributes(
        imagePart,
        matchStart,
        null,
        relativeStart,
        relativeEnd
      );
      if (braceMatch || quoteMatch) {
        return true;
      }
    }
  }
  const codeContent = content.substring(start, end);
  const codeText = codeContent.replace(/`/g, "");
  const allImagesRegex = /!\[[^\]]*\]\([^)]*\)(?:\s*"[^"]*")?(?:\s*{[^}]*})?/gs;
  let imageMatch;
  while ((imageMatch = allImagesRegex.exec(contentWindow)) !== null) {
    const imagePart = imageMatch[0];
    const { braceMatch, quoteMatch } = checkImageAttributes(
      imagePart,
      imageMatch.index,
      codeText
    );
    if (braceMatch || quoteMatch) {
      return true;
    }
  }
  let lineIndex = 0;
  let charCount = 0;
  for (let i = 0; i < lines.length; i++) {
    if (charCount <= start && start < charCount + lines[i].length + 1) {
      lineIndex = i;
      break;
    }
    charCount += lines[i].length + 1;
  }
  if (lineIndex > 0 && lineIndex < lines.length - 1) {
    const prevLine = lines[lineIndex - 1];
    const currentLine = lines[lineIndex];
    const nextLine = lines[lineIndex + 1];
    if (prevLine.trim().startsWith("#|") && nextLine.trim().startsWith("|#") && currentLine.includes("![") && currentLine.includes("](")) {
      return true;
    }
  }
  return false;
}
function processInlineToken(token, lineStarts, content, parentStartPos) {
  if (!token.children || token.children.length === 0) {
    return parentStartPos;
  }
  let inlineStartPos = parentStartPos;
  if (token.map && token.map.length === 2) {
    const [startLine] = token.map;
    inlineStartPos = lineToCharPosition(startLine, lineStarts, content);
  }
  return inlineStartPos;
}
function resolveBlockCodes(content) {
  if (!this.options.mergeContentParts || !content.includes("![")) {
    this.api.blockCodes.set([]);
    return content;
  }
  const md = new import_markdown_it.default({ html: true });
  const diplodocOptions = {
    notesAutotitle: false,
    path: ""
  };
  md.use(import_markdown_it_deflist.default, diplodocOptions);
  md.use(import_imsize.default, diplodocOptions);
  md.use(import_table.default, diplodocOptions);
  const tokens = md.parse(content, {});
  const codes = [];
  const lines = content.split("\n");
  const lineStarts = computeLineStarts(lines);
  function extractCodeBlocks(tokens2, parentStartPos = 0, parentType = null) {
    for (const token of tokens2) {
      let currentParentStartPos = parentStartPos;
      if (token.type === "fence" || token.type === "code_block") {
        processBlockCode(token, lineStarts, lines, content, codes);
      } else if (token.type === "inline") {
        currentParentStartPos = processInlineToken(
          token,
          lineStarts,
          content,
          currentParentStartPos
        );
      } else if (token.type === "code_inline") {
        if (parentType !== "image") {
          currentParentStartPos = processInlineCode(
            token,
            content,
            currentParentStartPos,
            codes,
            lineStarts,
            lines
          );
        }
      }
      if (token.children && token.children.length > 0) {
        extractCodeBlocks(token.children, currentParentStartPos, token.type);
      }
    }
  }
  extractCodeBlocks(tokens);
  this.api.blockCodes.set(codes);
  return content;
}

// src/core/markdown/loader/resolve-conditions.ts
var import_js_yaml2 = require("js-yaml");
var import_utils8 = require("@diplodoc/cli/lib/utils");
function processPageConstructorBlocks(content, options) {
  const { vars, skipMissingVars, logger, path } = options;
  const blocks = [];
  const openRegex = new RegExp(PC_REGEX.source, PC_REGEX.flags);
  let searchStart = 0;
  while (searchStart < content.length) {
    const remaining = content.slice(searchStart);
    const match = openRegex.exec(remaining);
    if (!match) {
      break;
    }
    const indent = match[1] || "";
    const matchIndex = searchStart + match.index;
    const contentStart = matchIndex + match[0].length;
    const closePattern = new RegExp(`^${indent}:::[ \\t]*$`, "m");
    const afterMatch = content.slice(contentStart);
    const closeMatch = closePattern.exec(afterMatch);
    if (!closeMatch) {
      searchStart = contentStart;
      continue;
    }
    const yamlContent = afterMatch.slice(0, closeMatch.index);
    let data;
    try {
      data = (0, import_js_yaml2.load)(yamlContent);
    } catch (error) {
      logger.warn(`Failed to parse page-constructor YAML in ${path}: ${error}`);
      searchStart = contentStart;
      continue;
    }
    if (!(0, import_utils8.hasWhenConditions)(data)) {
      searchStart = contentStart + closeMatch.index + closeMatch[0].length;
      continue;
    }
    const filtered = (0, import_utils8.filterBlocksByConditions)(data, vars, skipMissingVars);
    const hasBlocks = Array.isArray(filtered.blocks) && filtered.blocks.length > 0;
    const blockStart = matchIndex;
    const blockEnd = contentStart + closeMatch.index + closeMatch[0].length;
    if (hasBlocks) {
      const yaml = (0, import_js_yaml2.dump)(filtered, {
        lineWidth: -1,
        noRefs: true,
        quotingType: "'",
        forceQuotes: false
      });
      const indentedYaml = yaml.split("\n").filter((line) => line.trim()).map((line) => `${indent}${line}`).join("\n");
      blocks.push({
        start: blockStart,
        end: blockEnd,
        replacement: `${indent}::: page-constructor
${indentedYaml}
${indent}:::
`
      });
    } else {
      blocks.push({
        start: blockStart,
        end: blockEnd,
        replacement: ""
      });
    }
    searchStart = blockEnd;
  }
  for (let i = blocks.length - 1; i >= 0; i--) {
    const { start, end, replacement } = blocks[i];
    content = content.slice(0, start) + replacement + content.slice(end);
  }
  return content;
}
function resolveConditions(content) {
  const { skipMissingVars = false } = this.options;
  const vars = this.vars || {};
  content = processPageConstructorBlocks(content, {
    vars,
    skipMissingVars,
    logger: this.logger,
    path: this.path
  });
  return content;
}

// src/core/markdown/loader.ts
var LoaderAPI = class {
  constructor(proxy = {}) {
    this.blockCodes = proxy.blockCodes || (0, import_utils10.bucket)();
    this.deps = proxy.deps || (0, import_utils10.bucket)();
    this.assets = proxy.assets || (0, import_utils10.bucket)();
    this.meta = proxy.meta || (0, import_utils10.bucket)();
    this.comments = proxy.comments || (0, import_utils10.bucket)();
    this.headings = proxy.headings || (0, import_utils10.bucket)();
    this.sourcemap = proxy.sourcemap || (0, import_utils10.bucket)();
  }
};
async function loader(content) {
  content = mangleFrontMatter.call(this, content);
  content = resolveNoTranslate.call(this, content);
  content = templateContent.call(this, content);
  content = resolveConditions.call(this, content);
  content = await applyCollectPlugins.call(this, content);
  content = resolveBlockCodes.call(this, content);
  content = resolveComments.call(this, content);
  content = resolveDependencies.call(this, content);
  content = resolveAssets.call(this, content);
  content = resolveHeadings.call(this, content);
  this.api.sourcemap.set(this.sourcemap.dump());
  return content;
}
async function applyCollectPlugins(content) {
  let meta = {};
  for (const collect of this.collects) {
    let result = await collect.call(this, content, {});
    if (Array.isArray(result)) {
      meta = (0, import_lodash.merge)(meta, result[1] || {});
      result = result[0];
    }
    if (result !== void 0) {
      content = result;
    }
  }
  return content;
}

// src/core/markdown/MarkdownService.ts
function hash(path, from) {
  return `${path}${from ? "+" + from : ""}`;
}
var byLocation = (a, b) => a.location[0] - b.location[0];
var _inspect_dec, _dump_dec, _load_dec, _init_dec, _MarkdownService_decorators, _init;
_MarkdownService_decorators = [withHooks], _init_dec = [import_utils11.bounded], _load_dec = [import_utils11.bounded], _dump_dec = [import_utils11.bounded], _inspect_dec = [import_utils11.bounded];
var MarkdownService = class {
  constructor(run, options = { mode: "build", skipMissingVars: false }) {
    __runInitializers(_init, 5, this);
    this.name = "Markdown";
    this.run = void 0;
    this._collects = [];
    this._plugins = [];
    this.pathToMeta = new import_utils11.Buckets();
    this.pathToComments = new import_utils11.Buckets();
    this.pathToDeps = new import_utils11.Buckets();
    this.pathToAssets = new import_utils11.Buckets();
    this.pathToHeadings = new import_utils11.Buckets();
    this.pathToSourcemap = new import_utils11.Buckets();
    this.cache = {};
    this.options = void 0;
    this.run = run;
    this.options = options;
  }
  get logger() {
    return this.run.logger;
  }
  get plugins() {
    return this._plugins.slice();
  }
  get collects() {
    return this._collects.slice();
  }
  get config() {
    return this.run.config;
  }
  async init() {
    this._collects = await getHooks(this).Collects.promise(this._collects);
    this._plugins = await getHooks(this).Plugins.promise(this._plugins);
  }
  async load(path, from) {
    const file = (0, import_utils11.normalizePath)(path);
    const key = hash(file, from);
    if (key in this.cache) {
      const { content, varsMetadata, varsSystem, meta } = await this.cache[key];
      this.run.meta.addMetadata(file, varsMetadata);
      this.run.meta.addSystemVars(file, varsSystem);
      this.run.meta.add(file, meta, true);
      return content;
    }
    const defer = new import_utils11.Defer();
    this.cache[key] = defer.promise;
    try {
      const source = (0, import_utils11.normalizePath)((0, import_node_path3.join)(this.run.input, file));
      const raw = await this.run.read(source);
      const vars = this.run.vars.for(file, from);
      const context = this.loaderContext(file, raw, vars, this.proxy(key));
      const content = await loader.call(context, raw);
      const meta = context.api.meta.get();
      await getHooks(this).Loaded.promise(raw, meta, file);
      this.run.meta.addMetadata(file, vars.__metadata);
      this.run.meta.addSystemVars(file, vars.__system);
      this.run.meta.add(file, meta, true);
      const result = {
        content,
        varsMetadata: vars.__metadata,
        varsSystem: vars.__system,
        meta
      };
      this.cache[key] = result;
      defer.resolve(result);
      await getHooks(this).Resolved.promise(content, file);
    } catch (error) {
      const isFileNotFound = error instanceof Error && "code" in error && error.code === "ENOENT";
      const isMergedInput = this.config.outputFormat !== "md" && this.config.preprocess?.mergeIncludes;
      if (isFileNotFound && from && isMergedInput) {
        const empty = {
          content: "",
          varsMetadata: {},
          varsSystem: {},
          meta: {}
        };
        this.cache[key] = empty;
        this.pathToDeps.set(key, []);
        defer.resolve(empty);
      } else {
        defer.reject(error);
      }
    }
    return (await defer.promise).content;
  }
  async dump(file, markdown) {
    const vfile = new import_utils11.VFile(file, markdown || await this.load(file));
    vfile.info = { title: "", headings: [] };
    await getHooks(this).Dump.promise(vfile);
    return vfile;
  }
  async meta(path) {
    return this._meta((0, import_utils11.normalizePath)(path));
  }
  async deps(path) {
    return this._deps((0, import_utils11.normalizePath)(path));
  }
  async graph(path) {
    return this._graph((0, import_utils11.normalizePath)(path));
  }
  async relations(path) {
    return this._relations((0, import_utils11.normalizePath)(path));
  }
  async assets(path) {
    return this._assets((0, import_utils11.normalizePath)(path));
  }
  async headings(path) {
    return this._headings((0, import_utils11.normalizePath)(path));
  }
  async titles(path) {
    const file = (0, import_utils11.normalizePath)(path);
    const titles = {};
    try {
      const headings = await this.headings(file);
      const contents = headings.map(({ content }) => content);
      for (const content of contents) {
        const { level, title, anchors } = parseHeading(content);
        if (level === 1 && !titles["#"]) {
          titles["#"] = title;
        }
        for (const anchor of anchors) {
          titles[anchor] = title;
        }
      }
    } catch {
    }
    return titles;
  }
  async inspect(path, raw, vars) {
    const file = (0, import_utils11.normalizePath)(path);
    const api = new LoaderAPI();
    const context = this.loaderContext(file, raw, vars, api);
    const content = await loader.call(context, raw);
    const deps = api.deps.get();
    const assets = [...api.assets.get()];
    return { content, deps, assets };
  }
  remap(path, line) {
    const file = (0, import_utils11.normalizePath)(path);
    const sourcemap = this.pathToSourcemap.get(file);
    if (!sourcemap) {
      return line;
    }
    return Number(sourcemap[line]) || line;
  }
  release(path, from) {
    const key = hash(path, from);
    delete this.cache[key];
    this.pathToDeps.delete(key);
    this.pathToMeta.delete(key);
    this.pathToAssets.delete(key);
    this.pathToHeadings.delete(key);
    this.pathToComments.delete(key);
    this.pathToSourcemap.delete(key);
  }
  async _meta(file, from) {
    const key = hash(file, from);
    await this.load(file, from);
    return this.pathToMeta.get(key);
  }
  async _deps(file, from) {
    const key = hash(file, from);
    await this.load(file, from);
    const deps = this.pathToDeps.get(key) || [];
    const internals = await (0, import_utils11.all)(
      (this.pathToDeps.get(key) || []).map(async ({ path }) => {
        try {
          return await this._deps(path, from || file);
        } catch (error) {
          const isMergedInput = this.config.outputFormat !== "md" && this.config.preprocess?.mergeIncludes;
          const isFileNotFound = error instanceof Error && "code" in error && error.code === "ENOENT";
          if (isMergedInput && isFileNotFound) {
            return [];
          }
          throw error;
        }
      })
    );
    return deps.concat(...internals);
  }
  async _graph(path, from) {
    const key = hash(path, from);
    const content = await this.load(path, from);
    const assets = this.pathToAssets.get(key) || [];
    const deps = await (0, import_utils11.all)(
      (this.pathToDeps.get(key) || []).map(async (dep) => {
        return {
          ...dep,
          ...await this._graph(dep.path, from || path)
        };
      })
    );
    return { path, content, deps, assets };
  }
  async _relations(path, from) {
    const key = hash(path, from);
    const graph = new import_utils11.Graph();
    graph.addNode(path, { type: "entry" });
    await this.load(path, from);
    await (0, import_utils11.all)(
      (this.pathToDeps.get(key) || []).map(async (dep) => {
        graph.consume(await this._relations(dep.path, from || path));
        graph.setNodeData(dep.path, { type: "source" });
        graph.addDependency(path, dep.path);
      })
    );
    (this.pathToAssets.get(key) || []).map(async (asset) => {
      if (["image", "video"].includes(asset.type)) {
        graph.addNode(asset.path);
        graph.setNodeData(asset.path, { type: "resource" });
        graph.addDependency(path, asset.path);
      }
      if (["link"].includes(asset.type) && asset.autotitle) {
        graph.addNode(asset.path);
        graph.setNodeData(asset.path, { type: "source" });
        graph.addDependency(path, asset.path);
      }
    });
    const meta = this.run.meta.get(path);
    const resources = [].concat(meta.script || [], meta.style || []);
    for (const resource of resources) {
      const file = (0, import_utils11.normalizePath)((0, import_node_path3.join)((0, import_node_path3.dirname)(path), resource));
      graph.addNode(file);
      graph.setNodeData(file, { type: "resource" });
      graph.addDependency(path, file);
    }
    return graph;
  }
  async _assets(file, from) {
    const key = hash(file, from);
    await this.load(file, from);
    const assets = this.pathToAssets.get(key) || [];
    const internals = await (0, import_utils11.all)(
      (this.pathToDeps.get(key) || []).map(async ({ path }) => {
        return this._assets(path, from || file);
      })
    );
    return assets.concat(...internals);
  }
  async _headings(file, from) {
    const key = hash(file, from);
    await this.load(file, from);
    const headings = this.pathToHeadings.get(key) || [];
    const internals = await (0, import_utils11.all)(
      (this.pathToDeps.get(key) || []).map(async ({ path, location }) => {
        const headings2 = await this._headings(path, from || file);
        return headings2.map((heading) => ({ ...heading, location }));
      })
    );
    return headings.concat(...internals).sort(byLocation);
  }
  proxy(key) {
    return {
      deps: this.pathToDeps.bind(key),
      assets: this.pathToAssets.bind(key),
      meta: this.pathToMeta.bind(key),
      comments: this.pathToComments.bind(key),
      headings: this.pathToHeadings.bind(key),
      sourcemap: this.pathToSourcemap.bind(key)
    };
  }
  loaderContext(path, raw, vars, api) {
    return {
      path,
      vars,
      logger: this.logger,
      readFile: (path2) => {
        return this.run.read((0, import_node_path3.join)(this.run.input, path2));
      },
      emitFile: async (file, content) => {
        const rootPath = (0, import_utils11.fullPath)(file, path);
        await this.run.write((0, import_node_path3.join)(this.run.input, rootPath), content, true);
      },
      fullPath: (path2) => (0, import_node_path3.join)(this.run.input, path2),
      input: this.run.input,
      api: new LoaderAPI(api),
      collects: this.collects,
      sourcemap: new import_liquid3.SourceMap(raw),
      settings: {
        substitutions: this.config.template.features.substitutions,
        conditions: typeof this.config.template.features.conditions === "string" ? this.config.template.features.conditions : Boolean(this.config.template.features.conditions),
        conditionsInCode: this.config.template.scopes.code,
        keepNotVar: this.config.template.keepNotVar,
        legacyConditions: this.config.template.legacyConditions,
        keepConditionSyntaxOnTrue: this.options.mode === "translate"
      },
      options: {
        disableLiquid: !this.config.template.enabled,
        mergeContentParts: this.config.preprocess?.mergeSvg ?? false,
        skipMissingVars: this.options.skipMissingVars
      },
      mode: this.options.mode
    };
  }
};
_init = __decoratorStart(null);
__decorateElement(_init, 1, "init", _init_dec, MarkdownService);
__decorateElement(_init, 1, "load", _load_dec, MarkdownService);
__decorateElement(_init, 1, "dump", _dump_dec, MarkdownService);
__decorateElement(_init, 1, "inspect", _inspect_dec, MarkdownService);
MarkdownService = __decorateElement(_init, 0, "MarkdownService", _MarkdownService_decorators, MarkdownService);
__runInitializers(_init, 1, MarkdownService);
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  INCLUDE_REGEX,
  MarkdownService,
  findLink,
  getHooks
});
//# sourceMappingURL=index.js.map
