/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/

var __create = Object.create;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
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 __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __export = (target, all) => {
  __markAsModule(target);
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __reExport = (target, module2, desc) => {
  if (module2 && typeof module2 === "object" || typeof module2 === "function") {
    for (let key of __getOwnPropNames(module2))
      if (!__hasOwnProp.call(target, key) && key !== "default")
        __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
  }
  return target;
};
var __toModule = (module2) => {
  return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __async = (__this, __arguments, generator) => {
  return new Promise((resolve2, reject) => {
    var fulfilled = (value) => {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    };
    var rejected = (value) => {
      try {
        step(generator.throw(value));
      } catch (e) {
        reject(e);
      }
    };
    var step = (x) => x.done ? resolve2(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
    step((generator = generator.apply(__this, __arguments)).next());
  });
};

// src/main.ts
__export(exports, {
  default: () => TemplaterPlugin
});
var import_obsidian19 = __toModule(require("obsidian"));

// src/settings/Settings.ts
var import_obsidian6 = __toModule(require("obsidian"));

// src/utils/Log.ts
var import_obsidian = __toModule(require("obsidian"));
function log_error(e) {
  const notice = new import_obsidian.Notice("", 8e3);
  if (e instanceof TemplaterError && e.console_msg) {
    notice.noticeEl.innerHTML = `<b>Templater Error</b>:<br/>${e.message}<br/>Check console for more informations`;
    console.error(`Templater Error:`, e.message, "\n", e.console_msg);
  } else {
    notice.noticeEl.innerHTML = `<b>Templater Error</b>:<br/>${e.message}`;
  }
}

// src/utils/Error.ts
var TemplaterError = class extends Error {
  constructor(msg, console_msg) {
    super(msg);
    this.console_msg = console_msg;
    this.name = this.constructor.name;
    Error.captureStackTrace(this, this.constructor);
  }
};
function errorWrapper(fn2, msg) {
  return __async(this, null, function* () {
    try {
      return yield fn2();
    } catch (e) {
      if (!(e instanceof TemplaterError)) {
        log_error(new TemplaterError(msg, e.message));
      } else {
        log_error(e);
      }
      return null;
    }
  });
}
function errorWrapperSync(fn2, msg) {
  try {
    return fn2();
  } catch (e) {
    log_error(new TemplaterError(msg, e.message));
    return null;
  }
}

// src/settings/suggesters/FolderSuggester.ts
var import_obsidian3 = __toModule(require("obsidian"));

// src/settings/suggesters/suggest.ts
var import_obsidian2 = __toModule(require("obsidian"));

// node_modules/@popperjs/core/lib/enums.js
var top = "top";
var bottom = "bottom";
var right = "right";
var left = "left";
var auto = "auto";
var basePlacements = [top, bottom, right, left];
var start = "start";
var end = "end";
var clippingParents = "clippingParents";
var viewport = "viewport";
var popper = "popper";
var reference = "reference";
var variationPlacements = /* @__PURE__ */ basePlacements.reduce(function(acc, placement) {
  return acc.concat([placement + "-" + start, placement + "-" + end]);
}, []);
var placements = /* @__PURE__ */ [].concat(basePlacements, [auto]).reduce(function(acc, placement) {
  return acc.concat([placement, placement + "-" + start, placement + "-" + end]);
}, []);
var beforeRead = "beforeRead";
var read = "read";
var afterRead = "afterRead";
var beforeMain = "beforeMain";
var main = "main";
var afterMain = "afterMain";
var beforeWrite = "beforeWrite";
var write = "write";
var afterWrite = "afterWrite";
var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];

// node_modules/@popperjs/core/lib/dom-utils/getNodeName.js
function getNodeName(element) {
  return element ? (element.nodeName || "").toLowerCase() : null;
}

// node_modules/@popperjs/core/lib/dom-utils/getWindow.js
function getWindow(node) {
  if (node == null) {
    return window;
  }
  if (node.toString() !== "[object Window]") {
    var ownerDocument = node.ownerDocument;
    return ownerDocument ? ownerDocument.defaultView || window : window;
  }
  return node;
}

// node_modules/@popperjs/core/lib/dom-utils/instanceOf.js
function isElement(node) {
  var OwnElement = getWindow(node).Element;
  return node instanceof OwnElement || node instanceof Element;
}
function isHTMLElement(node) {
  var OwnElement = getWindow(node).HTMLElement;
  return node instanceof OwnElement || node instanceof HTMLElement;
}
function isShadowRoot(node) {
  if (typeof ShadowRoot === "undefined") {
    return false;
  }
  var OwnElement = getWindow(node).ShadowRoot;
  return node instanceof OwnElement || node instanceof ShadowRoot;
}

// node_modules/@popperjs/core/lib/modifiers/applyStyles.js
function applyStyles(_ref) {
  var state = _ref.state;
  Object.keys(state.elements).forEach(function(name) {
    var style = state.styles[name] || {};
    var attributes = state.attributes[name] || {};
    var element = state.elements[name];
    if (!isHTMLElement(element) || !getNodeName(element)) {
      return;
    }
    Object.assign(element.style, style);
    Object.keys(attributes).forEach(function(name2) {
      var value = attributes[name2];
      if (value === false) {
        element.removeAttribute(name2);
      } else {
        element.setAttribute(name2, value === true ? "" : value);
      }
    });
  });
}
function effect(_ref2) {
  var state = _ref2.state;
  var initialStyles = {
    popper: {
      position: state.options.strategy,
      left: "0",
      top: "0",
      margin: "0"
    },
    arrow: {
      position: "absolute"
    },
    reference: {}
  };
  Object.assign(state.elements.popper.style, initialStyles.popper);
  state.styles = initialStyles;
  if (state.elements.arrow) {
    Object.assign(state.elements.arrow.style, initialStyles.arrow);
  }
  return function() {
    Object.keys(state.elements).forEach(function(name) {
      var element = state.elements[name];
      var attributes = state.attributes[name] || {};
      var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]);
      var style = styleProperties.reduce(function(style2, property) {
        style2[property] = "";
        return style2;
      }, {});
      if (!isHTMLElement(element) || !getNodeName(element)) {
        return;
      }
      Object.assign(element.style, style);
      Object.keys(attributes).forEach(function(attribute) {
        element.removeAttribute(attribute);
      });
    });
  };
}
var applyStyles_default = {
  name: "applyStyles",
  enabled: true,
  phase: "write",
  fn: applyStyles,
  effect,
  requires: ["computeStyles"]
};

// node_modules/@popperjs/core/lib/utils/getBasePlacement.js
function getBasePlacement(placement) {
  return placement.split("-")[0];
}

// node_modules/@popperjs/core/lib/utils/math.js
var max = Math.max;
var min = Math.min;
var round = Math.round;

// node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js
function getBoundingClientRect(element, includeScale) {
  if (includeScale === void 0) {
    includeScale = false;
  }
  var rect = element.getBoundingClientRect();
  var scaleX = 1;
  var scaleY = 1;
  if (isHTMLElement(element) && includeScale) {
    var offsetHeight = element.offsetHeight;
    var offsetWidth = element.offsetWidth;
    if (offsetWidth > 0) {
      scaleX = round(rect.width) / offsetWidth || 1;
    }
    if (offsetHeight > 0) {
      scaleY = round(rect.height) / offsetHeight || 1;
    }
  }
  return {
    width: rect.width / scaleX,
    height: rect.height / scaleY,
    top: rect.top / scaleY,
    right: rect.right / scaleX,
    bottom: rect.bottom / scaleY,
    left: rect.left / scaleX,
    x: rect.left / scaleX,
    y: rect.top / scaleY
  };
}

// node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js
function getLayoutRect(element) {
  var clientRect = getBoundingClientRect(element);
  var width = element.offsetWidth;
  var height = element.offsetHeight;
  if (Math.abs(clientRect.width - width) <= 1) {
    width = clientRect.width;
  }
  if (Math.abs(clientRect.height - height) <= 1) {
    height = clientRect.height;
  }
  return {
    x: element.offsetLeft,
    y: element.offsetTop,
    width,
    height
  };
}

// node_modules/@popperjs/core/lib/dom-utils/contains.js
function contains(parent, child) {
  var rootNode = child.getRootNode && child.getRootNode();
  if (parent.contains(child)) {
    return true;
  } else if (rootNode && isShadowRoot(rootNode)) {
    var next = child;
    do {
      if (next && parent.isSameNode(next)) {
        return true;
      }
      next = next.parentNode || next.host;
    } while (next);
  }
  return false;
}

// node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js
function getComputedStyle(element) {
  return getWindow(element).getComputedStyle(element);
}

// node_modules/@popperjs/core/lib/dom-utils/isTableElement.js
function isTableElement(element) {
  return ["table", "td", "th"].indexOf(getNodeName(element)) >= 0;
}

// node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js
function getDocumentElement(element) {
  return ((isElement(element) ? element.ownerDocument : element.document) || window.document).documentElement;
}

// node_modules/@popperjs/core/lib/dom-utils/getParentNode.js
function getParentNode(element) {
  if (getNodeName(element) === "html") {
    return element;
  }
  return element.assignedSlot || element.parentNode || (isShadowRoot(element) ? element.host : null) || getDocumentElement(element);
}

// node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js
function getTrueOffsetParent(element) {
  if (!isHTMLElement(element) || getComputedStyle(element).position === "fixed") {
    return null;
  }
  return element.offsetParent;
}
function getContainingBlock(element) {
  var isFirefox = navigator.userAgent.toLowerCase().indexOf("firefox") !== -1;
  var isIE = navigator.userAgent.indexOf("Trident") !== -1;
  if (isIE && isHTMLElement(element)) {
    var elementCss = getComputedStyle(element);
    if (elementCss.position === "fixed") {
      return null;
    }
  }
  var currentNode = getParentNode(element);
  while (isHTMLElement(currentNode) && ["html", "body"].indexOf(getNodeName(currentNode)) < 0) {
    var css = getComputedStyle(currentNode);
    if (css.transform !== "none" || css.perspective !== "none" || css.contain === "paint" || ["transform", "perspective"].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === "filter" || isFirefox && css.filter && css.filter !== "none") {
      return currentNode;
    } else {
      currentNode = currentNode.parentNode;
    }
  }
  return null;
}
function getOffsetParent(element) {
  var window2 = getWindow(element);
  var offsetParent = getTrueOffsetParent(element);
  while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === "static") {
    offsetParent = getTrueOffsetParent(offsetParent);
  }
  if (offsetParent && (getNodeName(offsetParent) === "html" || getNodeName(offsetParent) === "body" && getComputedStyle(offsetParent).position === "static")) {
    return window2;
  }
  return offsetParent || getContainingBlock(element) || window2;
}

// node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js
function getMainAxisFromPlacement(placement) {
  return ["top", "bottom"].indexOf(placement) >= 0 ? "x" : "y";
}

// node_modules/@popperjs/core/lib/utils/within.js
function within(min2, value, max2) {
  return max(min2, min(value, max2));
}
function withinMaxClamp(min2, value, max2) {
  var v = within(min2, value, max2);
  return v > max2 ? max2 : v;
}

// node_modules/@popperjs/core/lib/utils/getFreshSideObject.js
function getFreshSideObject() {
  return {
    top: 0,
    right: 0,
    bottom: 0,
    left: 0
  };
}

// node_modules/@popperjs/core/lib/utils/mergePaddingObject.js
function mergePaddingObject(paddingObject) {
  return Object.assign({}, getFreshSideObject(), paddingObject);
}

// node_modules/@popperjs/core/lib/utils/expandToHashMap.js
function expandToHashMap(value, keys) {
  return keys.reduce(function(hashMap, key) {
    hashMap[key] = value;
    return hashMap;
  }, {});
}

// node_modules/@popperjs/core/lib/modifiers/arrow.js
var toPaddingObject = function toPaddingObject2(padding, state) {
  padding = typeof padding === "function" ? padding(Object.assign({}, state.rects, {
    placement: state.placement
  })) : padding;
  return mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements));
};
function arrow(_ref) {
  var _state$modifiersData$;
  var state = _ref.state, name = _ref.name, options = _ref.options;
  var arrowElement = state.elements.arrow;
  var popperOffsets2 = state.modifiersData.popperOffsets;
  var basePlacement = getBasePlacement(state.placement);
  var axis = getMainAxisFromPlacement(basePlacement);
  var isVertical = [left, right].indexOf(basePlacement) >= 0;
  var len = isVertical ? "height" : "width";
  if (!arrowElement || !popperOffsets2) {
    return;
  }
  var paddingObject = toPaddingObject(options.padding, state);
  var arrowRect = getLayoutRect(arrowElement);
  var minProp = axis === "y" ? top : left;
  var maxProp = axis === "y" ? bottom : right;
  var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets2[axis] - state.rects.popper[len];
  var startDiff = popperOffsets2[axis] - state.rects.reference[axis];
  var arrowOffsetParent = getOffsetParent(arrowElement);
  var clientSize = arrowOffsetParent ? axis === "y" ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;
  var centerToReference = endDiff / 2 - startDiff / 2;
  var min2 = paddingObject[minProp];
  var max2 = clientSize - arrowRect[len] - paddingObject[maxProp];
  var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;
  var offset2 = within(min2, center, max2);
  var axisProp = axis;
  state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset2, _state$modifiersData$.centerOffset = offset2 - center, _state$modifiersData$);
}
function effect2(_ref2) {
  var state = _ref2.state, options = _ref2.options;
  var _options$element = options.element, arrowElement = _options$element === void 0 ? "[data-popper-arrow]" : _options$element;
  if (arrowElement == null) {
    return;
  }
  if (typeof arrowElement === "string") {
    arrowElement = state.elements.popper.querySelector(arrowElement);
    if (!arrowElement) {
      return;
    }
  }
  if (true) {
    if (!isHTMLElement(arrowElement)) {
      console.error(['Popper: "arrow" element must be an HTMLElement (not an SVGElement).', "To use an SVG arrow, wrap it in an HTMLElement that will be used as", "the arrow."].join(" "));
    }
  }
  if (!contains(state.elements.popper, arrowElement)) {
    if (true) {
      console.error(['Popper: "arrow" modifier\'s `element` must be a child of the popper', "element."].join(" "));
    }
    return;
  }
  state.elements.arrow = arrowElement;
}
var arrow_default = {
  name: "arrow",
  enabled: true,
  phase: "main",
  fn: arrow,
  effect: effect2,
  requires: ["popperOffsets"],
  requiresIfExists: ["preventOverflow"]
};

// node_modules/@popperjs/core/lib/utils/getVariation.js
function getVariation(placement) {
  return placement.split("-")[1];
}

// node_modules/@popperjs/core/lib/modifiers/computeStyles.js
var unsetSides = {
  top: "auto",
  right: "auto",
  bottom: "auto",
  left: "auto"
};
function roundOffsetsByDPR(_ref) {
  var x = _ref.x, y = _ref.y;
  var win = window;
  var dpr = win.devicePixelRatio || 1;
  return {
    x: round(x * dpr) / dpr || 0,
    y: round(y * dpr) / dpr || 0
  };
}
function mapToStyles(_ref2) {
  var _Object$assign2;
  var popper2 = _ref2.popper, popperRect = _ref2.popperRect, placement = _ref2.placement, variation = _ref2.variation, offsets = _ref2.offsets, position = _ref2.position, gpuAcceleration = _ref2.gpuAcceleration, adaptive = _ref2.adaptive, roundOffsets = _ref2.roundOffsets, isFixed = _ref2.isFixed;
  var _offsets$x = offsets.x, x = _offsets$x === void 0 ? 0 : _offsets$x, _offsets$y = offsets.y, y = _offsets$y === void 0 ? 0 : _offsets$y;
  var _ref3 = typeof roundOffsets === "function" ? roundOffsets({
    x,
    y
  }) : {
    x,
    y
  };
  x = _ref3.x;
  y = _ref3.y;
  var hasX = offsets.hasOwnProperty("x");
  var hasY = offsets.hasOwnProperty("y");
  var sideX = left;
  var sideY = top;
  var win = window;
  if (adaptive) {
    var offsetParent = getOffsetParent(popper2);
    var heightProp = "clientHeight";
    var widthProp = "clientWidth";
    if (offsetParent === getWindow(popper2)) {
      offsetParent = getDocumentElement(popper2);
      if (getComputedStyle(offsetParent).position !== "static" && position === "absolute") {
        heightProp = "scrollHeight";
        widthProp = "scrollWidth";
      }
    }
    offsetParent = offsetParent;
    if (placement === top || (placement === left || placement === right) && variation === end) {
      sideY = bottom;
      var offsetY = isFixed && win.visualViewport ? win.visualViewport.height : offsetParent[heightProp];
      y -= offsetY - popperRect.height;
      y *= gpuAcceleration ? 1 : -1;
    }
    if (placement === left || (placement === top || placement === bottom) && variation === end) {
      sideX = right;
      var offsetX = isFixed && win.visualViewport ? win.visualViewport.width : offsetParent[widthProp];
      x -= offsetX - popperRect.width;
      x *= gpuAcceleration ? 1 : -1;
    }
  }
  var commonStyles = Object.assign({
    position
  }, adaptive && unsetSides);
  var _ref4 = roundOffsets === true ? roundOffsetsByDPR({
    x,
    y
  }) : {
    x,
    y
  };
  x = _ref4.x;
  y = _ref4.y;
  if (gpuAcceleration) {
    var _Object$assign;
    return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? "0" : "", _Object$assign[sideX] = hasX ? "0" : "", _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign));
  }
  return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : "", _Object$assign2[sideX] = hasX ? x + "px" : "", _Object$assign2.transform = "", _Object$assign2));
}
function computeStyles(_ref5) {
  var state = _ref5.state, options = _ref5.options;
  var _options$gpuAccelerat = options.gpuAcceleration, gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, _options$adaptive = options.adaptive, adaptive = _options$adaptive === void 0 ? true : _options$adaptive, _options$roundOffsets = options.roundOffsets, roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;
  if (true) {
    var transitionProperty = getComputedStyle(state.elements.popper).transitionProperty || "";
    if (adaptive && ["transform", "top", "right", "bottom", "left"].some(function(property) {
      return transitionProperty.indexOf(property) >= 0;
    })) {
      console.warn(["Popper: Detected CSS transitions on at least one of the following", 'CSS properties: "transform", "top", "right", "bottom", "left".', "\n\n", 'Disable the "computeStyles" modifier\'s `adaptive` option to allow', "for smooth transitions, or remove these properties from the CSS", "transition declaration on the popper element if only transitioning", "opacity or background-color for example.", "\n\n", "We recommend using the popper element as a wrapper around an inner", "element that can have any CSS property transitioned for animations."].join(" "));
    }
  }
  var commonStyles = {
    placement: getBasePlacement(state.placement),
    variation: getVariation(state.placement),
    popper: state.elements.popper,
    popperRect: state.rects.popper,
    gpuAcceleration,
    isFixed: state.options.strategy === "fixed"
  };
  if (state.modifiersData.popperOffsets != null) {
    state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {
      offsets: state.modifiersData.popperOffsets,
      position: state.options.strategy,
      adaptive,
      roundOffsets
    })));
  }
  if (state.modifiersData.arrow != null) {
    state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {
      offsets: state.modifiersData.arrow,
      position: "absolute",
      adaptive: false,
      roundOffsets
    })));
  }
  state.attributes.popper = Object.assign({}, state.attributes.popper, {
    "data-popper-placement": state.placement
  });
}
var computeStyles_default = {
  name: "computeStyles",
  enabled: true,
  phase: "beforeWrite",
  fn: computeStyles,
  data: {}
};

// node_modules/@popperjs/core/lib/modifiers/eventListeners.js
var passive = {
  passive: true
};
function effect3(_ref) {
  var state = _ref.state, instance = _ref.instance, options = _ref.options;
  var _options$scroll = options.scroll, scroll = _options$scroll === void 0 ? true : _options$scroll, _options$resize = options.resize, resize = _options$resize === void 0 ? true : _options$resize;
  var window2 = getWindow(state.elements.popper);
  var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);
  if (scroll) {
    scrollParents.forEach(function(scrollParent) {
      scrollParent.addEventListener("scroll", instance.update, passive);
    });
  }
  if (resize) {
    window2.addEventListener("resize", instance.update, passive);
  }
  return function() {
    if (scroll) {
      scrollParents.forEach(function(scrollParent) {
        scrollParent.removeEventListener("scroll", instance.update, passive);
      });
    }
    if (resize) {
      window2.removeEventListener("resize", instance.update, passive);
    }
  };
}
var eventListeners_default = {
  name: "eventListeners",
  enabled: true,
  phase: "write",
  fn: function fn() {
  },
  effect: effect3,
  data: {}
};

// node_modules/@popperjs/core/lib/utils/getOppositePlacement.js
var hash = {
  left: "right",
  right: "left",
  bottom: "top",
  top: "bottom"
};
function getOppositePlacement(placement) {
  return placement.replace(/left|right|bottom|top/g, function(matched) {
    return hash[matched];
  });
}

// node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js
var hash2 = {
  start: "end",
  end: "start"
};
function getOppositeVariationPlacement(placement) {
  return placement.replace(/start|end/g, function(matched) {
    return hash2[matched];
  });
}

// node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js
function getWindowScroll(node) {
  var win = getWindow(node);
  var scrollLeft = win.pageXOffset;
  var scrollTop = win.pageYOffset;
  return {
    scrollLeft,
    scrollTop
  };
}

// node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js
function getWindowScrollBarX(element) {
  return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;
}

// node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js
function getViewportRect(element) {
  var win = getWindow(element);
  var html = getDocumentElement(element);
  var visualViewport = win.visualViewport;
  var width = html.clientWidth;
  var height = html.clientHeight;
  var x = 0;
  var y = 0;
  if (visualViewport) {
    width = visualViewport.width;
    height = visualViewport.height;
    if (!/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {
      x = visualViewport.offsetLeft;
      y = visualViewport.offsetTop;
    }
  }
  return {
    width,
    height,
    x: x + getWindowScrollBarX(element),
    y
  };
}

// node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js
function getDocumentRect(element) {
  var _element$ownerDocumen;
  var html = getDocumentElement(element);
  var winScroll = getWindowScroll(element);
  var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;
  var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);
  var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);
  var x = -winScroll.scrollLeft + getWindowScrollBarX(element);
  var y = -winScroll.scrollTop;
  if (getComputedStyle(body || html).direction === "rtl") {
    x += max(html.clientWidth, body ? body.clientWidth : 0) - width;
  }
  return {
    width,
    height,
    x,
    y
  };
}

// node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js
function isScrollParent(element) {
  var _getComputedStyle = getComputedStyle(element), overflow = _getComputedStyle.overflow, overflowX = _getComputedStyle.overflowX, overflowY = _getComputedStyle.overflowY;
  return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
}

// node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js
function getScrollParent(node) {
  if (["html", "body", "#document"].indexOf(getNodeName(node)) >= 0) {
    return node.ownerDocument.body;
  }
  if (isHTMLElement(node) && isScrollParent(node)) {
    return node;
  }
  return getScrollParent(getParentNode(node));
}

// node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js
function listScrollParents(element, list) {
  var _element$ownerDocumen;
  if (list === void 0) {
    list = [];
  }
  var scrollParent = getScrollParent(element);
  var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);
  var win = getWindow(scrollParent);
  var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;
  var updatedList = list.concat(target);
  return isBody ? updatedList : updatedList.concat(listScrollParents(getParentNode(target)));
}

// node_modules/@popperjs/core/lib/utils/rectToClientRect.js
function rectToClientRect(rect) {
  return Object.assign({}, rect, {
    left: rect.x,
    top: rect.y,
    right: rect.x + rect.width,
    bottom: rect.y + rect.height
  });
}

// node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js
function getInnerBoundingClientRect(element) {
  var rect = getBoundingClientRect(element);
  rect.top = rect.top + element.clientTop;
  rect.left = rect.left + element.clientLeft;
  rect.bottom = rect.top + element.clientHeight;
  rect.right = rect.left + element.clientWidth;
  rect.width = element.clientWidth;
  rect.height = element.clientHeight;
  rect.x = rect.left;
  rect.y = rect.top;
  return rect;
}
function getClientRectFromMixedType(element, clippingParent) {
  return clippingParent === viewport ? rectToClientRect(getViewportRect(element)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent) : rectToClientRect(getDocumentRect(getDocumentElement(element)));
}
function getClippingParents(element) {
  var clippingParents2 = listScrollParents(getParentNode(element));
  var canEscapeClipping = ["absolute", "fixed"].indexOf(getComputedStyle(element).position) >= 0;
  var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;
  if (!isElement(clipperElement)) {
    return [];
  }
  return clippingParents2.filter(function(clippingParent) {
    return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== "body";
  });
}
function getClippingRect(element, boundary, rootBoundary) {
  var mainClippingParents = boundary === "clippingParents" ? getClippingParents(element) : [].concat(boundary);
  var clippingParents2 = [].concat(mainClippingParents, [rootBoundary]);
  var firstClippingParent = clippingParents2[0];
  var clippingRect = clippingParents2.reduce(function(accRect, clippingParent) {
    var rect = getClientRectFromMixedType(element, clippingParent);
    accRect.top = max(rect.top, accRect.top);
    accRect.right = min(rect.right, accRect.right);
    accRect.bottom = min(rect.bottom, accRect.bottom);
    accRect.left = max(rect.left, accRect.left);
    return accRect;
  }, getClientRectFromMixedType(element, firstClippingParent));
  clippingRect.width = clippingRect.right - clippingRect.left;
  clippingRect.height = clippingRect.bottom - clippingRect.top;
  clippingRect.x = clippingRect.left;
  clippingRect.y = clippingRect.top;
  return clippingRect;
}

// node_modules/@popperjs/core/lib/utils/computeOffsets.js
function computeOffsets(_ref) {
  var reference2 = _ref.reference, element = _ref.element, placement = _ref.placement;
  var basePlacement = placement ? getBasePlacement(placement) : null;
  var variation = placement ? getVariation(placement) : null;
  var commonX = reference2.x + reference2.width / 2 - element.width / 2;
  var commonY = reference2.y + reference2.height / 2 - element.height / 2;
  var offsets;
  switch (basePlacement) {
    case top:
      offsets = {
        x: commonX,
        y: reference2.y - element.height
      };
      break;
    case bottom:
      offsets = {
        x: commonX,
        y: reference2.y + reference2.height
      };
      break;
    case right:
      offsets = {
        x: reference2.x + reference2.width,
        y: commonY
      };
      break;
    case left:
      offsets = {
        x: reference2.x - element.width,
        y: commonY
      };
      break;
    default:
      offsets = {
        x: reference2.x,
        y: reference2.y
      };
  }
  var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;
  if (mainAxis != null) {
    var len = mainAxis === "y" ? "height" : "width";
    switch (variation) {
      case start:
        offsets[mainAxis] = offsets[mainAxis] - (reference2[len] / 2 - element[len] / 2);
        break;
      case end:
        offsets[mainAxis] = offsets[mainAxis] + (reference2[len] / 2 - element[len] / 2);
        break;
      default:
    }
  }
  return offsets;
}

// node_modules/@popperjs/core/lib/utils/detectOverflow.js
function detectOverflow(state, options) {
  if (options === void 0) {
    options = {};
  }
  var _options = options, _options$placement = _options.placement, placement = _options$placement === void 0 ? state.placement : _options$placement, _options$boundary = _options.boundary, boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, _options$rootBoundary = _options.rootBoundary, rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, _options$elementConte = _options.elementContext, elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, _options$altBoundary = _options.altBoundary, altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, _options$padding = _options.padding, padding = _options$padding === void 0 ? 0 : _options$padding;
  var paddingObject = mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements));
  var altContext = elementContext === popper ? reference : popper;
  var popperRect = state.rects.popper;
  var element = state.elements[altBoundary ? altContext : elementContext];
  var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary);
  var referenceClientRect = getBoundingClientRect(state.elements.reference);
  var popperOffsets2 = computeOffsets({
    reference: referenceClientRect,
    element: popperRect,
    strategy: "absolute",
    placement
  });
  var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets2));
  var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect;
  var overflowOffsets = {
    top: clippingClientRect.top - elementClientRect.top + paddingObject.top,
    bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,
    left: clippingClientRect.left - elementClientRect.left + paddingObject.left,
    right: elementClientRect.right - clippingClientRect.right + paddingObject.right
  };
  var offsetData = state.modifiersData.offset;
  if (elementContext === popper && offsetData) {
    var offset2 = offsetData[placement];
    Object.keys(overflowOffsets).forEach(function(key) {
      var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;
      var axis = [top, bottom].indexOf(key) >= 0 ? "y" : "x";
      overflowOffsets[key] += offset2[axis] * multiply;
    });
  }
  return overflowOffsets;
}

// node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js
function computeAutoPlacement(state, options) {
  if (options === void 0) {
    options = {};
  }
  var _options = options, placement = _options.placement, boundary = _options.boundary, rootBoundary = _options.rootBoundary, padding = _options.padding, flipVariations = _options.flipVariations, _options$allowedAutoP = _options.allowedAutoPlacements, allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP;
  var variation = getVariation(placement);
  var placements2 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function(placement2) {
    return getVariation(placement2) === variation;
  }) : basePlacements;
  var allowedPlacements = placements2.filter(function(placement2) {
    return allowedAutoPlacements.indexOf(placement2) >= 0;
  });
  if (allowedPlacements.length === 0) {
    allowedPlacements = placements2;
    if (true) {
      console.error(["Popper: The `allowedAutoPlacements` option did not allow any", "placements. Ensure the `placement` option matches the variation", "of the allowed placements.", 'For example, "auto" cannot be used to allow "bottom-start".', 'Use "auto-start" instead.'].join(" "));
    }
  }
  var overflows = allowedPlacements.reduce(function(acc, placement2) {
    acc[placement2] = detectOverflow(state, {
      placement: placement2,
      boundary,
      rootBoundary,
      padding
    })[getBasePlacement(placement2)];
    return acc;
  }, {});
  return Object.keys(overflows).sort(function(a, b) {
    return overflows[a] - overflows[b];
  });
}

// node_modules/@popperjs/core/lib/modifiers/flip.js
function getExpandedFallbackPlacements(placement) {
  if (getBasePlacement(placement) === auto) {
    return [];
  }
  var oppositePlacement = getOppositePlacement(placement);
  return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];
}
function flip(_ref) {
  var state = _ref.state, options = _ref.options, name = _ref.name;
  if (state.modifiersData[name]._skip) {
    return;
  }
  var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, specifiedFallbackPlacements = options.fallbackPlacements, padding = options.padding, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, _options$flipVariatio = options.flipVariations, flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, allowedAutoPlacements = options.allowedAutoPlacements;
  var preferredPlacement = state.options.placement;
  var basePlacement = getBasePlacement(preferredPlacement);
  var isBasePlacement = basePlacement === preferredPlacement;
  var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));
  var placements2 = [preferredPlacement].concat(fallbackPlacements).reduce(function(acc, placement2) {
    return acc.concat(getBasePlacement(placement2) === auto ? computeAutoPlacement(state, {
      placement: placement2,
      boundary,
      rootBoundary,
      padding,
      flipVariations,
      allowedAutoPlacements
    }) : placement2);
  }, []);
  var referenceRect = state.rects.reference;
  var popperRect = state.rects.popper;
  var checksMap = new Map();
  var makeFallbackChecks = true;
  var firstFittingPlacement = placements2[0];
  for (var i = 0; i < placements2.length; i++) {
    var placement = placements2[i];
    var _basePlacement = getBasePlacement(placement);
    var isStartVariation = getVariation(placement) === start;
    var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;
    var len = isVertical ? "width" : "height";
    var overflow = detectOverflow(state, {
      placement,
      boundary,
      rootBoundary,
      altBoundary,
      padding
    });
    var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;
    if (referenceRect[len] > popperRect[len]) {
      mainVariationSide = getOppositePlacement(mainVariationSide);
    }
    var altVariationSide = getOppositePlacement(mainVariationSide);
    var checks = [];
    if (checkMainAxis) {
      checks.push(overflow[_basePlacement] <= 0);
    }
    if (checkAltAxis) {
      checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);
    }
    if (checks.every(function(check) {
      return check;
    })) {
      firstFittingPlacement = placement;
      makeFallbackChecks = false;
      break;
    }
    checksMap.set(placement, checks);
  }
  if (makeFallbackChecks) {
    var numberOfChecks = flipVariations ? 3 : 1;
    var _loop = function _loop2(_i2) {
      var fittingPlacement = placements2.find(function(placement2) {
        var checks2 = checksMap.get(placement2);
        if (checks2) {
          return checks2.slice(0, _i2).every(function(check) {
            return check;
          });
        }
      });
      if (fittingPlacement) {
        firstFittingPlacement = fittingPlacement;
        return "break";
      }
    };
    for (var _i = numberOfChecks; _i > 0; _i--) {
      var _ret = _loop(_i);
      if (_ret === "break")
        break;
    }
  }
  if (state.placement !== firstFittingPlacement) {
    state.modifiersData[name]._skip = true;
    state.placement = firstFittingPlacement;
    state.reset = true;
  }
}
var flip_default = {
  name: "flip",
  enabled: true,
  phase: "main",
  fn: flip,
  requiresIfExists: ["offset"],
  data: {
    _skip: false
  }
};

// node_modules/@popperjs/core/lib/modifiers/hide.js
function getSideOffsets(overflow, rect, preventedOffsets) {
  if (preventedOffsets === void 0) {
    preventedOffsets = {
      x: 0,
      y: 0
    };
  }
  return {
    top: overflow.top - rect.height - preventedOffsets.y,
    right: overflow.right - rect.width + preventedOffsets.x,
    bottom: overflow.bottom - rect.height + preventedOffsets.y,
    left: overflow.left - rect.width - preventedOffsets.x
  };
}
function isAnySideFullyClipped(overflow) {
  return [top, right, bottom, left].some(function(side) {
    return overflow[side] >= 0;
  });
}
function hide(_ref) {
  var state = _ref.state, name = _ref.name;
  var referenceRect = state.rects.reference;
  var popperRect = state.rects.popper;
  var preventedOffsets = state.modifiersData.preventOverflow;
  var referenceOverflow = detectOverflow(state, {
    elementContext: "reference"
  });
  var popperAltOverflow = detectOverflow(state, {
    altBoundary: true
  });
  var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);
  var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);
  var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);
  var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);
  state.modifiersData[name] = {
    referenceClippingOffsets,
    popperEscapeOffsets,
    isReferenceHidden,
    hasPopperEscaped
  };
  state.attributes.popper = Object.assign({}, state.attributes.popper, {
    "data-popper-reference-hidden": isReferenceHidden,
    "data-popper-escaped": hasPopperEscaped
  });
}
var hide_default = {
  name: "hide",
  enabled: true,
  phase: "main",
  requiresIfExists: ["preventOverflow"],
  fn: hide
};

// node_modules/@popperjs/core/lib/modifiers/offset.js
function distanceAndSkiddingToXY(placement, rects, offset2) {
  var basePlacement = getBasePlacement(placement);
  var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;
  var _ref = typeof offset2 === "function" ? offset2(Object.assign({}, rects, {
    placement
  })) : offset2, skidding = _ref[0], distance = _ref[1];
  skidding = skidding || 0;
  distance = (distance || 0) * invertDistance;
  return [left, right].indexOf(basePlacement) >= 0 ? {
    x: distance,
    y: skidding
  } : {
    x: skidding,
    y: distance
  };
}
function offset(_ref2) {
  var state = _ref2.state, options = _ref2.options, name = _ref2.name;
  var _options$offset = options.offset, offset2 = _options$offset === void 0 ? [0, 0] : _options$offset;
  var data = placements.reduce(function(acc, placement) {
    acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset2);
    return acc;
  }, {});
  var _data$state$placement = data[state.placement], x = _data$state$placement.x, y = _data$state$placement.y;
  if (state.modifiersData.popperOffsets != null) {
    state.modifiersData.popperOffsets.x += x;
    state.modifiersData.popperOffsets.y += y;
  }
  state.modifiersData[name] = data;
}
var offset_default = {
  name: "offset",
  enabled: true,
  phase: "main",
  requires: ["popperOffsets"],
  fn: offset
};

// node_modules/@popperjs/core/lib/modifiers/popperOffsets.js
function popperOffsets(_ref) {
  var state = _ref.state, name = _ref.name;
  state.modifiersData[name] = computeOffsets({
    reference: state.rects.reference,
    element: state.rects.popper,
    strategy: "absolute",
    placement: state.placement
  });
}
var popperOffsets_default = {
  name: "popperOffsets",
  enabled: true,
  phase: "read",
  fn: popperOffsets,
  data: {}
};

// node_modules/@popperjs/core/lib/utils/getAltAxis.js
function getAltAxis(axis) {
  return axis === "x" ? "y" : "x";
}

// node_modules/@popperjs/core/lib/modifiers/preventOverflow.js
function preventOverflow(_ref) {
  var state = _ref.state, options = _ref.options, name = _ref.name;
  var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, padding = options.padding, _options$tether = options.tether, tether = _options$tether === void 0 ? true : _options$tether, _options$tetherOffset = options.tetherOffset, tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;
  var overflow = detectOverflow(state, {
    boundary,
    rootBoundary,
    padding,
    altBoundary
  });
  var basePlacement = getBasePlacement(state.placement);
  var variation = getVariation(state.placement);
  var isBasePlacement = !variation;
  var mainAxis = getMainAxisFromPlacement(basePlacement);
  var altAxis = getAltAxis(mainAxis);
  var popperOffsets2 = state.modifiersData.popperOffsets;
  var referenceRect = state.rects.reference;
  var popperRect = state.rects.popper;
  var tetherOffsetValue = typeof tetherOffset === "function" ? tetherOffset(Object.assign({}, state.rects, {
    placement: state.placement
  })) : tetherOffset;
  var normalizedTetherOffsetValue = typeof tetherOffsetValue === "number" ? {
    mainAxis: tetherOffsetValue,
    altAxis: tetherOffsetValue
  } : Object.assign({
    mainAxis: 0,
    altAxis: 0
  }, tetherOffsetValue);
  var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;
  var data = {
    x: 0,
    y: 0
  };
  if (!popperOffsets2) {
    return;
  }
  if (checkMainAxis) {
    var _offsetModifierState$;
    var mainSide = mainAxis === "y" ? top : left;
    var altSide = mainAxis === "y" ? bottom : right;
    var len = mainAxis === "y" ? "height" : "width";
    var offset2 = popperOffsets2[mainAxis];
    var min2 = offset2 + overflow[mainSide];
    var max2 = offset2 - overflow[altSide];
    var additive = tether ? -popperRect[len] / 2 : 0;
    var minLen = variation === start ? referenceRect[len] : popperRect[len];
    var maxLen = variation === start ? -popperRect[len] : -referenceRect[len];
    var arrowElement = state.elements.arrow;
    var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {
      width: 0,
      height: 0
    };
    var arrowPaddingObject = state.modifiersData["arrow#persistent"] ? state.modifiersData["arrow#persistent"].padding : getFreshSideObject();
    var arrowPaddingMin = arrowPaddingObject[mainSide];
    var arrowPaddingMax = arrowPaddingObject[altSide];
    var arrowLen = within(0, referenceRect[len], arrowRect[len]);
    var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;
    var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;
    var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);
    var clientOffset = arrowOffsetParent ? mainAxis === "y" ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;
    var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;
    var tetherMin = offset2 + minOffset - offsetModifierValue - clientOffset;
    var tetherMax = offset2 + maxOffset - offsetModifierValue;
    var preventedOffset = within(tether ? min(min2, tetherMin) : min2, offset2, tether ? max(max2, tetherMax) : max2);
    popperOffsets2[mainAxis] = preventedOffset;
    data[mainAxis] = preventedOffset - offset2;
  }
  if (checkAltAxis) {
    var _offsetModifierState$2;
    var _mainSide = mainAxis === "x" ? top : left;
    var _altSide = mainAxis === "x" ? bottom : right;
    var _offset = popperOffsets2[altAxis];
    var _len = altAxis === "y" ? "height" : "width";
    var _min = _offset + overflow[_mainSide];
    var _max = _offset - overflow[_altSide];
    var isOriginSide = [top, left].indexOf(basePlacement) !== -1;
    var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;
    var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;
    var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;
    var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);
    popperOffsets2[altAxis] = _preventedOffset;
    data[altAxis] = _preventedOffset - _offset;
  }
  state.modifiersData[name] = data;
}
var preventOverflow_default = {
  name: "preventOverflow",
  enabled: true,
  phase: "main",
  fn: preventOverflow,
  requiresIfExists: ["offset"]
};

// node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js
function getHTMLElementScroll(element) {
  return {
    scrollLeft: element.scrollLeft,
    scrollTop: element.scrollTop
  };
}

// node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js
function getNodeScroll(node) {
  if (node === getWindow(node) || !isHTMLElement(node)) {
    return getWindowScroll(node);
  } else {
    return getHTMLElementScroll(node);
  }
}

// node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js
function isElementScaled(element) {
  var rect = element.getBoundingClientRect();
  var scaleX = round(rect.width) / element.offsetWidth || 1;
  var scaleY = round(rect.height) / element.offsetHeight || 1;
  return scaleX !== 1 || scaleY !== 1;
}
function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {
  if (isFixed === void 0) {
    isFixed = false;
  }
  var isOffsetParentAnElement = isHTMLElement(offsetParent);
  var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);
  var documentElement = getDocumentElement(offsetParent);
  var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled);
  var scroll = {
    scrollLeft: 0,
    scrollTop: 0
  };
  var offsets = {
    x: 0,
    y: 0
  };
  if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
    if (getNodeName(offsetParent) !== "body" || isScrollParent(documentElement)) {
      scroll = getNodeScroll(offsetParent);
    }
    if (isHTMLElement(offsetParent)) {
      offsets = getBoundingClientRect(offsetParent, true);
      offsets.x += offsetParent.clientLeft;
      offsets.y += offsetParent.clientTop;
    } else if (documentElement) {
      offsets.x = getWindowScrollBarX(documentElement);
    }
  }
  return {
    x: rect.left + scroll.scrollLeft - offsets.x,
    y: rect.top + scroll.scrollTop - offsets.y,
    width: rect.width,
    height: rect.height
  };
}

// node_modules/@popperjs/core/lib/utils/orderModifiers.js
function order(modifiers) {
  var map = new Map();
  var visited = new Set();
  var result = [];
  modifiers.forEach(function(modifier) {
    map.set(modifier.name, modifier);
  });
  function sort(modifier) {
    visited.add(modifier.name);
    var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);
    requires.forEach(function(dep) {
      if (!visited.has(dep)) {
        var depModifier = map.get(dep);
        if (depModifier) {
          sort(depModifier);
        }
      }
    });
    result.push(modifier);
  }
  modifiers.forEach(function(modifier) {
    if (!visited.has(modifier.name)) {
      sort(modifier);
    }
  });
  return result;
}
function orderModifiers(modifiers) {
  var orderedModifiers = order(modifiers);
  return modifierPhases.reduce(function(acc, phase) {
    return acc.concat(orderedModifiers.filter(function(modifier) {
      return modifier.phase === phase;
    }));
  }, []);
}

// node_modules/@popperjs/core/lib/utils/debounce.js
function debounce(fn2) {
  var pending;
  return function() {
    if (!pending) {
      pending = new Promise(function(resolve2) {
        Promise.resolve().then(function() {
          pending = void 0;
          resolve2(fn2());
        });
      });
    }
    return pending;
  };
}

// node_modules/@popperjs/core/lib/utils/format.js
function format(str) {
  for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    args[_key - 1] = arguments[_key];
  }
  return [].concat(args).reduce(function(p, c) {
    return p.replace(/%s/, c);
  }, str);
}

// node_modules/@popperjs/core/lib/utils/validateModifiers.js
var INVALID_MODIFIER_ERROR = 'Popper: modifier "%s" provided an invalid %s property, expected %s but got %s';
var MISSING_DEPENDENCY_ERROR = 'Popper: modifier "%s" requires "%s", but "%s" modifier is not available';
var VALID_PROPERTIES = ["name", "enabled", "phase", "fn", "effect", "requires", "options"];
function validateModifiers(modifiers) {
  modifiers.forEach(function(modifier) {
    [].concat(Object.keys(modifier), VALID_PROPERTIES).filter(function(value, index, self) {
      return self.indexOf(value) === index;
    }).forEach(function(key) {
      switch (key) {
        case "name":
          if (typeof modifier.name !== "string") {
            console.error(format(INVALID_MODIFIER_ERROR, String(modifier.name), '"name"', '"string"', '"' + String(modifier.name) + '"'));
          }
          break;
        case "enabled":
          if (typeof modifier.enabled !== "boolean") {
            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"enabled"', '"boolean"', '"' + String(modifier.enabled) + '"'));
          }
          break;
        case "phase":
          if (modifierPhases.indexOf(modifier.phase) < 0) {
            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"phase"', "either " + modifierPhases.join(", "), '"' + String(modifier.phase) + '"'));
          }
          break;
        case "fn":
          if (typeof modifier.fn !== "function") {
            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"fn"', '"function"', '"' + String(modifier.fn) + '"'));
          }
          break;
        case "effect":
          if (modifier.effect != null && typeof modifier.effect !== "function") {
            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"effect"', '"function"', '"' + String(modifier.fn) + '"'));
          }
          break;
        case "requires":
          if (modifier.requires != null && !Array.isArray(modifier.requires)) {
            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requires"', '"array"', '"' + String(modifier.requires) + '"'));
          }
          break;
        case "requiresIfExists":
          if (!Array.isArray(modifier.requiresIfExists)) {
            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requiresIfExists"', '"array"', '"' + String(modifier.requiresIfExists) + '"'));
          }
          break;
        case "options":
        case "data":
          break;
        default:
          console.error('PopperJS: an invalid property has been provided to the "' + modifier.name + '" modifier, valid properties are ' + VALID_PROPERTIES.map(function(s) {
            return '"' + s + '"';
          }).join(", ") + '; but "' + key + '" was provided.');
      }
      modifier.requires && modifier.requires.forEach(function(requirement) {
        if (modifiers.find(function(mod) {
          return mod.name === requirement;
        }) == null) {
          console.error(format(MISSING_DEPENDENCY_ERROR, String(modifier.name), requirement, requirement));
        }
      });
    });
  });
}

// node_modules/@popperjs/core/lib/utils/uniqueBy.js
function uniqueBy(arr, fn2) {
  var identifiers = new Set();
  return arr.filter(function(item) {
    var identifier = fn2(item);
    if (!identifiers.has(identifier)) {
      identifiers.add(identifier);
      return true;
    }
  });
}

// node_modules/@popperjs/core/lib/utils/mergeByName.js
function mergeByName(modifiers) {
  var merged = modifiers.reduce(function(merged2, current) {
    var existing = merged2[current.name];
    merged2[current.name] = existing ? Object.assign({}, existing, current, {
      options: Object.assign({}, existing.options, current.options),
      data: Object.assign({}, existing.data, current.data)
    }) : current;
    return merged2;
  }, {});
  return Object.keys(merged).map(function(key) {
    return merged[key];
  });
}

// node_modules/@popperjs/core/lib/createPopper.js
var INVALID_ELEMENT_ERROR = "Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.";
var INFINITE_LOOP_ERROR = "Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash.";
var DEFAULT_OPTIONS = {
  placement: "bottom",
  modifiers: [],
  strategy: "absolute"
};
function areValidElements() {
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
    args[_key] = arguments[_key];
  }
  return !args.some(function(element) {
    return !(element && typeof element.getBoundingClientRect === "function");
  });
}
function popperGenerator(generatorOptions) {
  if (generatorOptions === void 0) {
    generatorOptions = {};
  }
  var _generatorOptions = generatorOptions, _generatorOptions$def = _generatorOptions.defaultModifiers, defaultModifiers2 = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, _generatorOptions$def2 = _generatorOptions.defaultOptions, defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;
  return function createPopper2(reference2, popper2, options) {
    if (options === void 0) {
      options = defaultOptions;
    }
    var state = {
      placement: "bottom",
      orderedModifiers: [],
      options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),
      modifiersData: {},
      elements: {
        reference: reference2,
        popper: popper2
      },
      attributes: {},
      styles: {}
    };
    var effectCleanupFns = [];
    var isDestroyed = false;
    var instance = {
      state,
      setOptions: function setOptions(setOptionsAction) {
        var options2 = typeof setOptionsAction === "function" ? setOptionsAction(state.options) : setOptionsAction;
        cleanupModifierEffects();
        state.options = Object.assign({}, defaultOptions, state.options, options2);
        state.scrollParents = {
          reference: isElement(reference2) ? listScrollParents(reference2) : reference2.contextElement ? listScrollParents(reference2.contextElement) : [],
          popper: listScrollParents(popper2)
        };
        var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers2, state.options.modifiers)));
        state.orderedModifiers = orderedModifiers.filter(function(m) {
          return m.enabled;
        });
        if (true) {
          var modifiers = uniqueBy([].concat(orderedModifiers, state.options.modifiers), function(_ref) {
            var name = _ref.name;
            return name;
          });
          validateModifiers(modifiers);
          if (getBasePlacement(state.options.placement) === auto) {
            var flipModifier = state.orderedModifiers.find(function(_ref2) {
              var name = _ref2.name;
              return name === "flip";
            });
            if (!flipModifier) {
              console.error(['Popper: "auto" placements require the "flip" modifier be', "present and enabled to work."].join(" "));
            }
          }
          var _getComputedStyle = getComputedStyle(popper2), marginTop = _getComputedStyle.marginTop, marginRight = _getComputedStyle.marginRight, marginBottom = _getComputedStyle.marginBottom, marginLeft = _getComputedStyle.marginLeft;
          if ([marginTop, marginRight, marginBottom, marginLeft].some(function(margin) {
            return parseFloat(margin);
          })) {
            console.warn(['Popper: CSS "margin" styles cannot be used to apply padding', "between the popper and its reference element or boundary.", "To replicate margin, use the `offset` modifier, as well as", "the `padding` option in the `preventOverflow` and `flip`", "modifiers."].join(" "));
          }
        }
        runModifierEffects();
        return instance.update();
      },
      forceUpdate: function forceUpdate() {
        if (isDestroyed) {
          return;
        }
        var _state$elements = state.elements, reference3 = _state$elements.reference, popper3 = _state$elements.popper;
        if (!areValidElements(reference3, popper3)) {
          if (true) {
            console.error(INVALID_ELEMENT_ERROR);
          }
          return;
        }
        state.rects = {
          reference: getCompositeRect(reference3, getOffsetParent(popper3), state.options.strategy === "fixed"),
          popper: getLayoutRect(popper3)
        };
        state.reset = false;
        state.placement = state.options.placement;
        state.orderedModifiers.forEach(function(modifier) {
          return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);
        });
        var __debug_loops__ = 0;
        for (var index = 0; index < state.orderedModifiers.length; index++) {
          if (true) {
            __debug_loops__ += 1;
            if (__debug_loops__ > 100) {
              console.error(INFINITE_LOOP_ERROR);
              break;
            }
          }
          if (state.reset === true) {
            state.reset = false;
            index = -1;
            continue;
          }
          var _state$orderedModifie = state.orderedModifiers[index], fn2 = _state$orderedModifie.fn, _state$orderedModifie2 = _state$orderedModifie.options, _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, name = _state$orderedModifie.name;
          if (typeof fn2 === "function") {
            state = fn2({
              state,
              options: _options,
              name,
              instance
            }) || state;
          }
        }
      },
      update: debounce(function() {
        return new Promise(function(resolve2) {
          instance.forceUpdate();
          resolve2(state);
        });
      }),
      destroy: function destroy() {
        cleanupModifierEffects();
        isDestroyed = true;
      }
    };
    if (!areValidElements(reference2, popper2)) {
      if (true) {
        console.error(INVALID_ELEMENT_ERROR);
      }
      return instance;
    }
    instance.setOptions(options).then(function(state2) {
      if (!isDestroyed && options.onFirstUpdate) {
        options.onFirstUpdate(state2);
      }
    });
    function runModifierEffects() {
      state.orderedModifiers.forEach(function(_ref3) {
        var name = _ref3.name, _ref3$options = _ref3.options, options2 = _ref3$options === void 0 ? {} : _ref3$options, effect4 = _ref3.effect;
        if (typeof effect4 === "function") {
          var cleanupFn = effect4({
            state,
            name,
            instance,
            options: options2
          });
          var noopFn = function noopFn2() {
          };
          effectCleanupFns.push(cleanupFn || noopFn);
        }
      });
    }
    function cleanupModifierEffects() {
      effectCleanupFns.forEach(function(fn2) {
        return fn2();
      });
      effectCleanupFns = [];
    }
    return instance;
  };
}

// node_modules/@popperjs/core/lib/popper.js
var defaultModifiers = [eventListeners_default, popperOffsets_default, computeStyles_default, applyStyles_default, offset_default, flip_default, preventOverflow_default, arrow_default, hide_default];
var createPopper = /* @__PURE__ */ popperGenerator({
  defaultModifiers
});

// src/settings/suggesters/suggest.ts
var wrapAround = (value, size) => {
  return (value % size + size) % size;
};
var Suggest = class {
  constructor(owner, containerEl, scope) {
    this.owner = owner;
    this.containerEl = containerEl;
    containerEl.on("click", ".suggestion-item", this.onSuggestionClick.bind(this));
    containerEl.on("mousemove", ".suggestion-item", this.onSuggestionMouseover.bind(this));
    scope.register([], "ArrowUp", (event) => {
      if (!event.isComposing) {
        this.setSelectedItem(this.selectedItem - 1, true);
        return false;
      }
    });
    scope.register([], "ArrowDown", (event) => {
      if (!event.isComposing) {
        this.setSelectedItem(this.selectedItem + 1, true);
        return false;
      }
    });
    scope.register([], "Enter", (event) => {
      if (!event.isComposing) {
        this.useSelectedItem(event);
        return false;
      }
    });
  }
  onSuggestionClick(event, el) {
    event.preventDefault();
    const item = this.suggestions.indexOf(el);
    this.setSelectedItem(item, false);
    this.useSelectedItem(event);
  }
  onSuggestionMouseover(_event, el) {
    const item = this.suggestions.indexOf(el);
    this.setSelectedItem(item, false);
  }
  setSuggestions(values) {
    this.containerEl.empty();
    const suggestionEls = [];
    values.forEach((value) => {
      const suggestionEl = this.containerEl.createDiv("suggestion-item");
      this.owner.renderSuggestion(value, suggestionEl);
      suggestionEls.push(suggestionEl);
    });
    this.values = values;
    this.suggestions = suggestionEls;
    this.setSelectedItem(0, false);
  }
  useSelectedItem(event) {
    const currentValue = this.values[this.selectedItem];
    if (currentValue) {
      this.owner.selectSuggestion(currentValue, event);
    }
  }
  setSelectedItem(selectedIndex, scrollIntoView) {
    const normalizedIndex = wrapAround(selectedIndex, this.suggestions.length);
    const prevSelectedSuggestion = this.suggestions[this.selectedItem];
    const selectedSuggestion = this.suggestions[normalizedIndex];
    prevSelectedSuggestion == null ? void 0 : prevSelectedSuggestion.removeClass("is-selected");
    selectedSuggestion == null ? void 0 : selectedSuggestion.addClass("is-selected");
    this.selectedItem = normalizedIndex;
    if (scrollIntoView) {
      selectedSuggestion.scrollIntoView(false);
    }
  }
};
var TextInputSuggest = class {
  constructor(app, inputEl) {
    this.app = app;
    this.inputEl = inputEl;
    this.scope = new import_obsidian2.Scope();
    this.suggestEl = createDiv("suggestion-container");
    const suggestion = this.suggestEl.createDiv("suggestion");
    this.suggest = new Suggest(this, suggestion, this.scope);
    this.scope.register([], "Escape", this.close.bind(this));
    this.inputEl.addEventListener("input", this.onInputChanged.bind(this));
    this.inputEl.addEventListener("focus", this.onInputChanged.bind(this));
    this.inputEl.addEventListener("blur", this.close.bind(this));
    this.suggestEl.on("mousedown", ".suggestion-container", (event) => {
      event.preventDefault();
    });
  }
  onInputChanged() {
    const inputStr = this.inputEl.value;
    const suggestions = this.getSuggestions(inputStr);
    if (!suggestions) {
      this.close();
      return;
    }
    if (suggestions.length > 0) {
      this.suggest.setSuggestions(suggestions);
      this.open(this.app.dom.appContainerEl, this.inputEl);
    } else {
      this.close();
    }
  }
  open(container, inputEl) {
    this.app.keymap.pushScope(this.scope);
    container.appendChild(this.suggestEl);
    this.popper = createPopper(inputEl, this.suggestEl, {
      placement: "bottom-start",
      modifiers: [
        {
          name: "sameWidth",
          enabled: true,
          fn: ({ state, instance }) => {
            const targetWidth = `${state.rects.reference.width}px`;
            if (state.styles.popper.width === targetWidth) {
              return;
            }
            state.styles.popper.width = targetWidth;
            instance.update();
          },
          phase: "beforeWrite",
          requires: ["computeStyles"]
        }
      ]
    });
  }
  close() {
    this.app.keymap.popScope(this.scope);
    this.suggest.setSuggestions([]);
    if (this.popper)
      this.popper.destroy();
    this.suggestEl.detach();
  }
};

// src/settings/suggesters/FolderSuggester.ts
var FolderSuggest = class extends TextInputSuggest {
  getSuggestions(inputStr) {
    const abstractFiles = this.app.vault.getAllLoadedFiles();
    const folders = [];
    const lowerCaseInputStr = inputStr.toLowerCase();
    abstractFiles.forEach((folder) => {
      if (folder instanceof import_obsidian3.TFolder && folder.path.toLowerCase().contains(lowerCaseInputStr)) {
        folders.push(folder);
      }
    });
    return folders;
  }
  renderSuggestion(file, el) {
    el.setText(file.path);
  }
  selectSuggestion(file) {
    this.inputEl.value = file.path;
    this.inputEl.trigger("input");
    this.close();
  }
};

// src/settings/suggesters/FileSuggester.ts
var import_obsidian5 = __toModule(require("obsidian"));

// src/utils/Utils.ts
var import_obsidian4 = __toModule(require("obsidian"));
function delay(ms) {
  return new Promise((resolve2) => setTimeout(resolve2, ms));
}
function escape_RegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function generate_dynamic_command_regex() {
  return /(<%(?:-|_)?\s*[*~]{0,1})\+((?:.|\s)*?%>)/g;
}
function resolve_tfolder(app, folder_str) {
  folder_str = (0, import_obsidian4.normalizePath)(folder_str);
  const folder = app.vault.getAbstractFileByPath(folder_str);
  if (!folder) {
    throw new TemplaterError(`Folder "${folder_str}" doesn't exist`);
  }
  if (!(folder instanceof import_obsidian4.TFolder)) {
    throw new TemplaterError(`${folder_str} is a file, not a folder`);
  }
  return folder;
}
function resolve_tfile(app, file_str) {
  file_str = (0, import_obsidian4.normalizePath)(file_str);
  const file = app.vault.getAbstractFileByPath(file_str);
  if (!file) {
    throw new TemplaterError(`File "${file_str}" doesn't exist`);
  }
  if (!(file instanceof import_obsidian4.TFile)) {
    throw new TemplaterError(`${file_str} is a folder, not a file`);
  }
  return file;
}
function get_tfiles_from_folder(app, folder_str) {
  const folder = resolve_tfolder(app, folder_str);
  const files = [];
  import_obsidian4.Vault.recurseChildren(folder, (file) => {
    if (file instanceof import_obsidian4.TFile) {
      files.push(file);
    }
  });
  files.sort((a, b) => {
    return a.basename.localeCompare(b.basename);
  });
  return files;
}
function arraymove(arr, fromIndex, toIndex) {
  if (toIndex < 0 || toIndex === arr.length) {
    return;
  }
  const element = arr[fromIndex];
  arr[fromIndex] = arr[toIndex];
  arr[toIndex] = element;
}

// src/settings/suggesters/FileSuggester.ts
var FileSuggestMode;
(function(FileSuggestMode2) {
  FileSuggestMode2[FileSuggestMode2["TemplateFiles"] = 0] = "TemplateFiles";
  FileSuggestMode2[FileSuggestMode2["ScriptFiles"] = 1] = "ScriptFiles";
})(FileSuggestMode || (FileSuggestMode = {}));
var FileSuggest = class extends TextInputSuggest {
  constructor(app, inputEl, plugin, mode) {
    super(app, inputEl);
    this.app = app;
    this.inputEl = inputEl;
    this.plugin = plugin;
    this.mode = mode;
  }
  get_folder(mode) {
    switch (mode) {
      case 0:
        return this.plugin.settings.templates_folder;
      case 1:
        return this.plugin.settings.user_scripts_folder;
    }
  }
  get_error_msg(mode) {
    switch (mode) {
      case 0:
        return `Templates folder doesn't exist`;
      case 1:
        return `User Scripts folder doesn't exist`;
    }
  }
  getSuggestions(input_str) {
    const all_files = errorWrapperSync(() => get_tfiles_from_folder(this.app, this.get_folder(this.mode)), this.get_error_msg(this.mode));
    if (!all_files) {
      return [];
    }
    const files = [];
    const lower_input_str = input_str.toLowerCase();
    all_files.forEach((file) => {
      if (file instanceof import_obsidian5.TFile && file.extension === "md" && file.path.toLowerCase().contains(lower_input_str)) {
        files.push(file);
      }
    });
    return files;
  }
  renderSuggestion(file, el) {
    el.setText(file.path);
  }
  selectSuggestion(file) {
    this.inputEl.value = file.path;
    this.inputEl.trigger("input");
    this.close();
  }
};

// src/settings/Settings.ts
var DEFAULT_SETTINGS = {
  command_timeout: 5,
  templates_folder: "",
  templates_pairs: [["", ""]],
  trigger_on_file_creation: false,
  auto_jump_to_cursor: false,
  enable_system_commands: false,
  shell_path: "",
  user_scripts_folder: "",
  enable_folder_templates: true,
  folder_templates: [{ folder: "", template: "" }],
  syntax_highlighting: true,
  enabled_templates_hotkeys: [""],
  startup_templates: [""]
};
var TemplaterSettingTab = class extends import_obsidian6.PluginSettingTab {
  constructor(app, plugin) {
    super(app, plugin);
    this.app = app;
    this.plugin = plugin;
  }
  display() {
    this.containerEl.empty();
    this.add_general_setting_header();
    this.add_template_folder_setting();
    this.add_internal_functions_setting();
    this.add_syntax_highlighting_setting();
    this.add_auto_jump_to_cursor();
    this.add_trigger_on_new_file_creation_setting();
    this.add_templates_hotkeys_setting();
    if (this.plugin.settings.trigger_on_file_creation) {
      this.add_folder_templates_setting();
    }
    this.add_startup_templates_setting();
    this.add_user_script_functions_setting();
    this.add_user_system_command_functions_setting();
  }
  add_general_setting_header() {
    this.containerEl.createEl("h2", { text: "General Settings" });
  }
  add_template_folder_setting() {
    new import_obsidian6.Setting(this.containerEl).setName("Template folder location").setDesc("Files in this folder will be available as templates.").addSearch((cb) => {
      new FolderSuggest(this.app, cb.inputEl);
      cb.setPlaceholder("Example: folder1/folder2").setValue(this.plugin.settings.templates_folder).onChange((new_folder) => {
        this.plugin.settings.templates_folder = new_folder;
        this.plugin.save_settings();
      });
      cb.containerEl.addClass("templater_search");
    });
  }
  add_internal_functions_setting() {
    const desc = document.createDocumentFragment();
    desc.append("Templater provides multiples predefined variables / functions that you can use.", desc.createEl("br"), "Check the ", desc.createEl("a", {
      href: "https://silentvoid13.github.io/Templater/",
      text: "documentation"
    }), " to get a list of all the available internal variables / functions.");
    new import_obsidian6.Setting(this.containerEl).setName("Internal Variables and Functions").setDesc(desc);
  }
  add_syntax_highlighting_setting() {
    const desc = document.createDocumentFragment();
    desc.append("Adds syntax highlighting for Templater commands in edit mode.");
    new import_obsidian6.Setting(this.containerEl).setName("Syntax Highlighting").setDesc(desc).addToggle((toggle) => {
      toggle.setValue(this.plugin.settings.syntax_highlighting).onChange((syntax_highlighting) => {
        this.plugin.settings.syntax_highlighting = syntax_highlighting;
        this.plugin.save_settings();
        this.plugin.event_handler.update_syntax_highlighting();
      });
    });
  }
  add_auto_jump_to_cursor() {
    const desc = document.createDocumentFragment();
    desc.append("Automatically triggers ", desc.createEl("code", { text: "tp.file.cursor" }), " after inserting a template.", desc.createEl("br"), "You can also set a hotkey to manually trigger ", desc.createEl("code", { text: "tp.file.cursor" }), ".");
    new import_obsidian6.Setting(this.containerEl).setName("Automatic jump to cursor").setDesc(desc).addToggle((toggle) => {
      toggle.setValue(this.plugin.settings.auto_jump_to_cursor).onChange((auto_jump_to_cursor) => {
        this.plugin.settings.auto_jump_to_cursor = auto_jump_to_cursor;
        this.plugin.save_settings();
      });
    });
  }
  add_trigger_on_new_file_creation_setting() {
    const desc = document.createDocumentFragment();
    desc.append("Templater will listen for the new file creation event, and replace every command it finds in the new file's content.", desc.createEl("br"), "This makes Templater compatible with other plugins like the Daily note core plugin, Calendar plugin, Review plugin, Note refactor plugin, ...", desc.createEl("br"), desc.createEl("b", {
      text: "Warning: "
    }), "This can be dangerous if you create new files with unknown / unsafe content on creation. Make sure that every new file's content is safe on creation.");
    new import_obsidian6.Setting(this.containerEl).setName("Trigger Templater on new file creation").setDesc(desc).addToggle((toggle) => {
      toggle.setValue(this.plugin.settings.trigger_on_file_creation).onChange((trigger_on_file_creation) => {
        this.plugin.settings.trigger_on_file_creation = trigger_on_file_creation;
        this.plugin.save_settings();
        this.plugin.event_handler.update_trigger_file_on_creation();
        this.display();
      });
    });
  }
  add_templates_hotkeys_setting() {
    this.containerEl.createEl("h2", { text: "Template Hotkeys" });
    const desc = document.createDocumentFragment();
    desc.append("Template Hotkeys allows you to bind a template to a hotkey.");
    new import_obsidian6.Setting(this.containerEl).setDesc(desc);
    this.plugin.settings.enabled_templates_hotkeys.forEach((template, index) => {
      const s = new import_obsidian6.Setting(this.containerEl).addSearch((cb) => {
        new FileSuggest(this.app, cb.inputEl, this.plugin, FileSuggestMode.TemplateFiles);
        cb.setPlaceholder("Example: folder1/template_file").setValue(template).onChange((new_template) => {
          if (new_template && this.plugin.settings.enabled_templates_hotkeys.contains(new_template)) {
            log_error(new TemplaterError("This template is already bound to a hotkey"));
            return;
          }
          this.plugin.command_handler.add_template_hotkey(this.plugin.settings.enabled_templates_hotkeys[index], new_template);
          this.plugin.settings.enabled_templates_hotkeys[index] = new_template;
          this.plugin.save_settings();
        });
        cb.containerEl.addClass("templater_search");
      }).addExtraButton((cb) => {
        cb.setIcon("any-key").setTooltip("Configure Hotkey").onClick(() => {
          this.app.setting.openTabById("hotkeys");
          const tab = this.app.setting.activeTab;
          tab.searchInputEl.value = "Templater: Insert";
          tab.updateHotkeyVisibility();
        });
      }).addExtraButton((cb) => {
        cb.setIcon("up-chevron-glyph").setTooltip("Move up").onClick(() => {
          arraymove(this.plugin.settings.enabled_templates_hotkeys, index, index - 1);
          this.plugin.save_settings();
          this.display();
        });
      }).addExtraButton((cb) => {
        cb.setIcon("down-chevron-glyph").setTooltip("Move down").onClick(() => {
          arraymove(this.plugin.settings.enabled_templates_hotkeys, index, index + 1);
          this.plugin.save_settings();
          this.display();
        });
      }).addExtraButton((cb) => {
        cb.setIcon("cross").setTooltip("Delete").onClick(() => {
          this.plugin.command_handler.remove_template_hotkey(this.plugin.settings.enabled_templates_hotkeys[index]);
          this.plugin.settings.enabled_templates_hotkeys.splice(index, 1);
          this.plugin.save_settings();
          this.display();
        });
      });
      s.infoEl.remove();
    });
    new import_obsidian6.Setting(this.containerEl).addButton((cb) => {
      cb.setButtonText("Add new hotkey for template").setCta().onClick(() => {
        this.plugin.settings.enabled_templates_hotkeys.push("");
        this.plugin.save_settings();
        this.display();
      });
    });
  }
  add_folder_templates_setting() {
    this.containerEl.createEl("h2", { text: "Folder Templates" });
    const descHeading = document.createDocumentFragment();
    descHeading.append("Folder Templates are triggered when a new ", descHeading.createEl("strong", { text: "empty " }), "file is created in a given folder.", descHeading.createEl("br"), "Templater will fill the empty file with the specified template.", descHeading.createEl("br"), "The deepest match is used. A global default template would be defined on the root ", descHeading.createEl("code", { text: "/" }), ".");
    new import_obsidian6.Setting(this.containerEl).setDesc(descHeading);
    const descUseNewFileTemplate = document.createDocumentFragment();
    descUseNewFileTemplate.append("When enabled Templater will make use of the folder templates defined below.");
    new import_obsidian6.Setting(this.containerEl).setName("Enable Folder Templates").setDesc(descUseNewFileTemplate).addToggle((toggle) => {
      toggle.setValue(this.plugin.settings.enable_folder_templates).onChange((use_new_file_templates) => {
        this.plugin.settings.enable_folder_templates = use_new_file_templates;
        this.plugin.save_settings();
        this.display();
      });
    });
    if (!this.plugin.settings.enable_folder_templates) {
      return;
    }
    new import_obsidian6.Setting(this.containerEl).setName("Add New").setDesc("Add new folder template").addButton((button) => {
      button.setTooltip("Add additional folder template").setButtonText("+").setCta().onClick(() => {
        this.plugin.settings.folder_templates.push({
          folder: "",
          template: ""
        });
        this.plugin.save_settings();
        this.display();
      });
    });
    this.plugin.settings.folder_templates.forEach((folder_template, index) => {
      const s = new import_obsidian6.Setting(this.containerEl).addSearch((cb) => {
        new FolderSuggest(this.app, cb.inputEl);
        cb.setPlaceholder("Folder").setValue(folder_template.folder).onChange((new_folder) => {
          if (new_folder && this.plugin.settings.folder_templates.some((e) => e.folder == new_folder)) {
            log_error(new TemplaterError("This folder already has a template associated with it"));
            return;
          }
          this.plugin.settings.folder_templates[index].folder = new_folder;
          this.plugin.save_settings();
        });
        cb.containerEl.addClass("templater_search");
      }).addSearch((cb) => {
        new FileSuggest(this.app, cb.inputEl, this.plugin, FileSuggestMode.TemplateFiles);
        cb.setPlaceholder("Template").setValue(folder_template.template).onChange((new_template) => {
          this.plugin.settings.folder_templates[index].template = new_template;
          this.plugin.save_settings();
        });
        cb.containerEl.addClass("templater_search");
      }).addExtraButton((cb) => {
        cb.setIcon("up-chevron-glyph").setTooltip("Move up").onClick(() => {
          arraymove(this.plugin.settings.folder_templates, index, index - 1);
          this.plugin.save_settings();
          this.display();
        });
      }).addExtraButton((cb) => {
        cb.setIcon("down-chevron-glyph").setTooltip("Move down").onClick(() => {
          arraymove(this.plugin.settings.folder_templates, index, index + 1);
          this.plugin.save_settings();
          this.display();
        });
      }).addExtraButton((cb) => {
        cb.setIcon("cross").setTooltip("Delete").onClick(() => {
          this.plugin.settings.folder_templates.splice(index, 1);
          this.plugin.save_settings();
          this.display();
        });
      });
      s.infoEl.remove();
    });
  }
  add_startup_templates_setting() {
    this.containerEl.createEl("h2", { text: "Startup Templates" });
    const desc = document.createDocumentFragment();
    desc.append("Startup Templates are templates that will get executed once when Templater starts.", desc.createEl("br"), "These templates won't output anything.", desc.createEl("br"), "This can be useful to set up templates adding hooks to obsidian events for example.");
    new import_obsidian6.Setting(this.containerEl).setDesc(desc);
    this.plugin.settings.startup_templates.forEach((template, index) => {
      const s = new import_obsidian6.Setting(this.containerEl).addSearch((cb) => {
        new FileSuggest(this.app, cb.inputEl, this.plugin, FileSuggestMode.TemplateFiles);
        cb.setPlaceholder("Example: folder1/template_file").setValue(template).onChange((new_template) => {
          if (new_template && this.plugin.settings.startup_templates.contains(new_template)) {
            log_error(new TemplaterError("This startup template already exist"));
            return;
          }
          this.plugin.settings.startup_templates[index] = new_template;
          this.plugin.save_settings();
        });
        cb.containerEl.addClass("templater_search");
      }).addExtraButton((cb) => {
        cb.setIcon("cross").setTooltip("Delete").onClick(() => {
          this.plugin.settings.startup_templates.splice(index, 1);
          this.plugin.save_settings();
          this.display();
        });
      });
      s.infoEl.remove();
    });
    new import_obsidian6.Setting(this.containerEl).addButton((cb) => {
      cb.setButtonText("Add new startup template").setCta().onClick(() => {
        this.plugin.settings.startup_templates.push("");
        this.plugin.save_settings();
        this.display();
      });
    });
  }
  add_user_script_functions_setting() {
    this.containerEl.createEl("h2", { text: "User Script Functions" });
    let desc = document.createDocumentFragment();
    desc.append("All JavaScript files in this folder will be loaded as CommonJS modules, to import custom user functions.", desc.createEl("br"), "The folder needs to be accessible from the vault.", desc.createEl("br"), "Check the ", desc.createEl("a", {
      href: "https://silentvoid13.github.io/Templater/",
      text: "documentation"
    }), " for more informations.");
    new import_obsidian6.Setting(this.containerEl).setName("Script files folder location").setDesc(desc).addSearch((cb) => {
      new FolderSuggest(this.app, cb.inputEl);
      cb.setPlaceholder("Example: folder1/folder2").setValue(this.plugin.settings.user_scripts_folder).onChange((new_folder) => {
        this.plugin.settings.user_scripts_folder = new_folder;
        this.plugin.save_settings();
      });
      cb.containerEl.addClass("templater_search");
    });
    desc = document.createDocumentFragment();
    let name;
    if (!this.plugin.settings.user_scripts_folder) {
      name = "No User Scripts folder set";
    } else {
      const files = errorWrapperSync(() => get_tfiles_from_folder(this.app, this.plugin.settings.user_scripts_folder), `User Scripts folder doesn't exist`);
      if (!files || files.length === 0) {
        name = "No User Scripts detected";
      } else {
        let count = 0;
        for (const file of files) {
          if (file.extension === "js") {
            count++;
            desc.append(desc.createEl("li", {
              text: `tp.user.${file.basename}`
            }));
          }
        }
        name = `Detected ${count} User Script(s)`;
      }
    }
    new import_obsidian6.Setting(this.containerEl).setName(name).setDesc(desc).addExtraButton((extra) => {
      extra.setIcon("sync").setTooltip("Refresh").onClick(() => {
        this.display();
      });
    });
  }
  add_user_system_command_functions_setting() {
    let desc = document.createDocumentFragment();
    desc.append("Allows you to create user functions linked to system commands.", desc.createEl("br"), desc.createEl("b", {
      text: "Warning: "
    }), "It can be dangerous to execute arbitrary system commands from untrusted sources. Only run system commands that you understand, from trusted sources.");
    this.containerEl.createEl("h2", {
      text: "User System Command Functions"
    });
    new import_obsidian6.Setting(this.containerEl).setName("Enable User System Command Functions").setDesc(desc).addToggle((toggle) => {
      toggle.setValue(this.plugin.settings.enable_system_commands).onChange((enable_system_commands) => {
        this.plugin.settings.enable_system_commands = enable_system_commands;
        this.plugin.save_settings();
        this.display();
      });
    });
    if (this.plugin.settings.enable_system_commands) {
      new import_obsidian6.Setting(this.containerEl).setName("Timeout").setDesc("Maximum timeout in seconds for a system command.").addText((text) => {
        text.setPlaceholder("Timeout").setValue(this.plugin.settings.command_timeout.toString()).onChange((new_value) => {
          const new_timeout = Number(new_value);
          if (isNaN(new_timeout)) {
            log_error(new TemplaterError("Timeout must be a number"));
            return;
          }
          this.plugin.settings.command_timeout = new_timeout;
          this.plugin.save_settings();
        });
      });
      desc = document.createDocumentFragment();
      desc.append("Full path to the shell binary to execute the command with.", desc.createEl("br"), "This setting is optional and will default to the system's default shell if not specified.", desc.createEl("br"), "You can use forward slashes ('/') as path separators on all platforms if in doubt.");
      new import_obsidian6.Setting(this.containerEl).setName("Shell binary location").setDesc(desc).addText((text) => {
        text.setPlaceholder("Example: /bin/bash, ...").setValue(this.plugin.settings.shell_path).onChange((shell_path) => {
          this.plugin.settings.shell_path = shell_path;
          this.plugin.save_settings();
        });
      });
      let i = 1;
      this.plugin.settings.templates_pairs.forEach((template_pair) => {
        const div2 = this.containerEl.createEl("div");
        div2.addClass("templater_div");
        const title = this.containerEl.createEl("h4", {
          text: "User Function n\xB0" + i
        });
        title.addClass("templater_title");
        const setting2 = new import_obsidian6.Setting(this.containerEl).addExtraButton((extra) => {
          extra.setIcon("cross").setTooltip("Delete").onClick(() => {
            const index = this.plugin.settings.templates_pairs.indexOf(template_pair);
            if (index > -1) {
              this.plugin.settings.templates_pairs.splice(index, 1);
              this.plugin.save_settings();
              this.display();
            }
          });
        }).addText((text) => {
          const t = text.setPlaceholder("Function name").setValue(template_pair[0]).onChange((new_value) => {
            const index = this.plugin.settings.templates_pairs.indexOf(template_pair);
            if (index > -1) {
              this.plugin.settings.templates_pairs[index][0] = new_value;
              this.plugin.save_settings();
            }
          });
          t.inputEl.addClass("templater_template");
          return t;
        }).addTextArea((text) => {
          const t = text.setPlaceholder("System Command").setValue(template_pair[1]).onChange((new_cmd) => {
            const index = this.plugin.settings.templates_pairs.indexOf(template_pair);
            if (index > -1) {
              this.plugin.settings.templates_pairs[index][1] = new_cmd;
              this.plugin.save_settings();
            }
          });
          t.inputEl.setAttr("rows", 2);
          t.inputEl.addClass("templater_cmd");
          return t;
        });
        setting2.infoEl.remove();
        div2.appendChild(title);
        div2.appendChild(this.containerEl.lastChild);
        i += 1;
      });
      const div = this.containerEl.createEl("div");
      div.addClass("templater_div2");
      const setting = new import_obsidian6.Setting(this.containerEl).addButton((button) => {
        button.setButtonText("Add New User Function").setCta().onClick(() => {
          this.plugin.settings.templates_pairs.push(["", ""]);
          this.plugin.save_settings();
          this.display();
        });
      });
      setting.infoEl.remove();
      div.appendChild(this.containerEl.lastChild);
    }
  }
};

// src/handlers/FuzzySuggester.ts
var import_obsidian7 = __toModule(require("obsidian"));
var OpenMode;
(function(OpenMode2) {
  OpenMode2[OpenMode2["InsertTemplate"] = 0] = "InsertTemplate";
  OpenMode2[OpenMode2["CreateNoteTemplate"] = 1] = "CreateNoteTemplate";
})(OpenMode || (OpenMode = {}));
var FuzzySuggester = class extends import_obsidian7.FuzzySuggestModal {
  constructor(app, plugin) {
    super(app);
    this.app = app;
    this.plugin = plugin;
    this.setPlaceholder("Type name of a template...");
  }
  getItems() {
    if (!this.plugin.settings.templates_folder) {
      return this.app.vault.getMarkdownFiles();
    }
    const files = errorWrapperSync(() => get_tfiles_from_folder(this.app, this.plugin.settings.templates_folder), `Couldn't retrieve template files from templates folder ${this.plugin.settings.templates_folder}`);
    if (!files) {
      return [];
    }
    return files;
  }
  getItemText(item) {
    return item.basename;
  }
  onChooseItem(item) {
    switch (this.open_mode) {
      case 0:
        this.plugin.templater.append_template_to_active_file(item);
        break;
      case 1:
        this.plugin.templater.create_new_note_from_template(item, this.creation_folder);
        break;
    }
  }
  start() {
    try {
      this.open();
    } catch (e) {
      log_error(e);
    }
  }
  insert_template() {
    this.open_mode = 0;
    this.start();
  }
  create_new_note_from_template(folder) {
    this.creation_folder = folder;
    this.open_mode = 1;
    this.start();
  }
};

// src/utils/Constants.ts
var UNSUPPORTED_MOBILE_TEMPLATE = "Error_MobileUnsupportedTemplate";
var ICON_DATA = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 51.1328 28.7"><path d="M0 15.14 0 10.15 18.67 1.51 18.67 6.03 4.72 12.33 4.72 12.76 18.67 19.22 18.67 23.74 0 15.14ZM33.6928 1.84C33.6928 1.84 33.9761 2.1467 34.5428 2.76C35.1094 3.38 35.3928 4.56 35.3928 6.3C35.3928 8.0466 34.8195 9.54 33.6728 10.78C32.5261 12.02 31.0995 12.64 29.3928 12.64C27.6862 12.64 26.2661 12.0267 25.1328 10.8C23.9928 9.5733 23.4228 8.0867 23.4228 6.34C23.4228 4.6 23.9995 3.1066 25.1528 1.86C26.2994.62 27.7261 0 29.4328 0C31.1395 0 32.5594.6133 33.6928 1.84M49.8228.67 29.5328 28.38 24.4128 28.38 44.7128.67 49.8228.67M31.0328 8.38C31.0328 8.38 31.1395 8.2467 31.3528 7.98C31.5662 7.7067 31.6728 7.1733 31.6728 6.38C31.6728 5.5867 31.4461 4.92 30.9928 4.38C30.5461 3.84 29.9995 3.57 29.3528 3.57C28.7061 3.57 28.1695 3.84 27.7428 4.38C27.3228 4.92 27.1128 5.5867 27.1128 6.38C27.1128 7.1733 27.3361 7.84 27.7828 8.38C28.2361 8.9267 28.7861 9.2 29.4328 9.2C30.0795 9.2 30.6128 8.9267 31.0328 8.38M49.4328 17.9C49.4328 17.9 49.7161 18.2067 50.2828 18.82C50.8495 19.4333 51.1328 20.6133 51.1328 22.36C51.1328 24.1 50.5594 25.59 49.4128 26.83C48.2595 28.0766 46.8295 28.7 45.1228 28.7C43.4228 28.7 42.0028 28.0833 40.8628 26.85C39.7295 25.6233 39.1628 24.1366 39.1628 22.39C39.1628 20.65 39.7361 19.16 40.8828 17.92C42.0361 16.6733 43.4628 16.05 45.1628 16.05C46.8694 16.05 48.2928 16.6667 49.4328 17.9M46.8528 24.52C46.8528 24.52 46.9595 24.3833 47.1728 24.11C47.3795 23.8367 47.4828 23.3033 47.4828 22.51C47.4828 21.7167 47.2595 21.05 46.8128 20.51C46.3661 19.97 45.8162 19.7 45.1628 19.7C44.5161 19.7 43.9828 19.97 43.5628 20.51C43.1428 21.05 42.9328 21.7167 42.9328 22.51C42.9328 23.3033 43.1561 23.9733 43.6028 24.52C44.0494 25.06 44.5961 25.33 45.2428 25.33C45.8895 25.33 46.4261 25.06 46.8528 24.52Z" fill="currentColor"/></svg>`;

// src/core/Templater.ts
var import_obsidian14 = __toModule(require("obsidian"));

// src/core/functions/internal_functions/InternalModule.ts
var InternalModule = class {
  constructor(app, plugin) {
    this.app = app;
    this.plugin = plugin;
    this.static_functions = new Map();
    this.dynamic_functions = new Map();
  }
  getName() {
    return this.name;
  }
  init() {
    return __async(this, null, function* () {
      yield this.create_static_templates();
      this.static_object = Object.fromEntries(this.static_functions);
    });
  }
  generate_object(new_config) {
    return __async(this, null, function* () {
      this.config = new_config;
      yield this.create_dynamic_templates();
      return __spreadValues(__spreadValues({}, this.static_object), Object.fromEntries(this.dynamic_functions));
    });
  }
};

// src/core/functions/internal_functions/date/InternalModuleDate.ts
var InternalModuleDate = class extends InternalModule {
  constructor() {
    super(...arguments);
    this.name = "date";
  }
  create_static_templates() {
    return __async(this, null, function* () {
      this.static_functions.set("now", this.generate_now());
      this.static_functions.set("tomorrow", this.generate_tomorrow());
      this.static_functions.set("weekday", this.generate_weekday());
      this.static_functions.set("yesterday", this.generate_yesterday());
    });
  }
  create_dynamic_templates() {
    return __async(this, null, function* () {
    });
  }
  generate_now() {
    return (format2 = "YYYY-MM-DD", offset2, reference2, reference_format) => {
      if (reference2 && !window.moment(reference2, reference_format).isValid()) {
        throw new TemplaterError("Invalid reference date format, try specifying one with the argument 'reference_format'");
      }
      let duration;
      if (typeof offset2 === "string") {
        duration = window.moment.duration(offset2);
      } else if (typeof offset2 === "number") {
        duration = window.moment.duration(offset2, "days");
      }
      return window.moment(reference2, reference_format).add(duration).format(format2);
    };
  }
  generate_tomorrow() {
    return (format2 = "YYYY-MM-DD") => {
      return window.moment().add(1, "days").format(format2);
    };
  }
  generate_weekday() {
    return (format2 = "YYYY-MM-DD", weekday, reference2, reference_format) => {
      if (reference2 && !window.moment(reference2, reference_format).isValid()) {
        throw new TemplaterError("Invalid reference date format, try specifying one with the argument 'reference_format'");
      }
      return window.moment(reference2, reference_format).weekday(weekday).format(format2);
    };
  }
  generate_yesterday() {
    return (format2 = "YYYY-MM-DD") => {
      return window.moment().add(-1, "days").format(format2);
    };
  }
};

// src/core/functions/internal_functions/file/InternalModuleFile.ts
var import_obsidian8 = __toModule(require("obsidian"));
var DEPTH_LIMIT = 10;
var InternalModuleFile = class extends InternalModule {
  constructor() {
    super(...arguments);
    this.name = "file";
    this.include_depth = 0;
    this.create_new_depth = 0;
    this.linkpath_regex = new RegExp("^\\[\\[(.*)\\]\\]$");
  }
  create_static_templates() {
    return __async(this, null, function* () {
      this.static_functions.set("creation_date", this.generate_creation_date());
      this.static_functions.set("create_new", this.generate_create_new());
      this.static_functions.set("cursor", this.generate_cursor());
      this.static_functions.set("cursor_append", this.generate_cursor_append());
      this.static_functions.set("exists", this.generate_exists());
      this.static_functions.set("find_tfile", this.generate_find_tfile());
      this.static_functions.set("folder", this.generate_folder());
      this.static_functions.set("include", this.generate_include());
      this.static_functions.set("last_modified_date", this.generate_last_modified_date());
      this.static_functions.set("move", this.generate_move());
      this.static_functions.set("path", this.generate_path());
      this.static_functions.set("rename", this.generate_rename());
      this.static_functions.set("selection", this.generate_selection());
    });
  }
  create_dynamic_templates() {
    return __async(this, null, function* () {
      this.dynamic_functions.set("content", yield this.generate_content());
      this.dynamic_functions.set("tags", this.generate_tags());
      this.dynamic_functions.set("title", this.generate_title());
    });
  }
  generate_content() {
    return __async(this, null, function* () {
      return yield this.app.vault.read(this.config.target_file);
    });
  }
  generate_create_new() {
    return (template, filename, open_new = false, folder) => __async(this, null, function* () {
      this.create_new_depth += 1;
      if (this.create_new_depth > DEPTH_LIMIT) {
        this.create_new_depth = 0;
        throw new TemplaterError("Reached create_new depth limit (max = 10)");
      }
      const new_file = yield this.plugin.templater.create_new_note_from_template(template, folder, filename, open_new);
      this.create_new_depth -= 1;
      return new_file;
    });
  }
  generate_creation_date() {
    return (format2 = "YYYY-MM-DD HH:mm") => {
      return window.moment(this.config.target_file.stat.ctime).format(format2);
    };
  }
  generate_cursor() {
    return (order2) => {
      return `<% tp.file.cursor(${order2 != null ? order2 : ""}) %>`;
    };
  }
  generate_cursor_append() {
    return (content) => {
      const active_view = this.app.workspace.getActiveViewOfType(import_obsidian8.MarkdownView);
      if (active_view === null) {
        log_error(new TemplaterError("No active view, can't append to cursor."));
        return;
      }
      const editor = active_view.editor;
      const doc = editor.getDoc();
      doc.replaceSelection(content);
      return "";
    };
  }
  generate_exists() {
    return (filename) => {
      let match;
      if ((match = this.linkpath_regex.exec(filename)) !== null) {
        filename = match[1];
      }
      const file = this.app.metadataCache.getFirstLinkpathDest(filename, "");
      return file != null;
    };
  }
  generate_find_tfile() {
    return (filename) => {
      const path = (0, import_obsidian8.normalizePath)(filename);
      return this.app.metadataCache.getFirstLinkpathDest(path, "");
    };
  }
  generate_folder() {
    return (relative = false) => {
      const parent = this.config.target_file.parent;
      let folder;
      if (relative) {
        folder = parent.path;
      } else {
        folder = parent.name;
      }
      return folder;
    };
  }
  generate_include() {
    return (include_link) => __async(this, null, function* () {
      var _a;
      this.include_depth += 1;
      if (this.include_depth > DEPTH_LIMIT) {
        this.include_depth -= 1;
        throw new TemplaterError("Reached inclusion depth limit (max = 10)");
      }
      let inc_file_content;
      if (include_link instanceof import_obsidian8.TFile) {
        inc_file_content = yield this.app.vault.read(include_link);
      } else {
        let match;
        if ((match = this.linkpath_regex.exec(include_link)) === null) {
          this.include_depth -= 1;
          throw new TemplaterError("Invalid file format, provide an obsidian link between quotes.");
        }
        const { path, subpath } = (0, import_obsidian8.parseLinktext)(match[1]);
        const inc_file = this.app.metadataCache.getFirstLinkpathDest(path, "");
        if (!inc_file) {
          this.include_depth -= 1;
          throw new TemplaterError(`File ${include_link} doesn't exist`);
        }
        inc_file_content = yield this.app.vault.read(inc_file);
        if (subpath) {
          const cache = this.app.metadataCache.getFileCache(inc_file);
          if (cache) {
            const result = (0, import_obsidian8.resolveSubpath)(cache, subpath);
            if (result) {
              inc_file_content = inc_file_content.slice(result.start.offset, (_a = result.end) == null ? void 0 : _a.offset);
            }
          }
        }
      }
      try {
        const parsed_content = yield this.plugin.templater.parser.parse_commands(inc_file_content, this.plugin.templater.current_functions_object);
        this.include_depth -= 1;
        return parsed_content;
      } catch (e) {
        this.include_depth -= 1;
        throw e;
      }
    });
  }
  generate_last_modified_date() {
    return (format2 = "YYYY-MM-DD HH:mm") => {
      return window.moment(this.config.target_file.stat.mtime).format(format2);
    };
  }
  generate_move() {
    return (path) => __async(this, null, function* () {
      const new_path = (0, import_obsidian8.normalizePath)(`${path}.${this.config.target_file.extension}`);
      yield this.app.fileManager.renameFile(this.config.target_file, new_path);
      return "";
    });
  }
  generate_path() {
    return (relative = false) => {
      if (import_obsidian8.Platform.isMobileApp) {
        return UNSUPPORTED_MOBILE_TEMPLATE;
      }
      if (!(this.app.vault.adapter instanceof import_obsidian8.FileSystemAdapter)) {
        throw new TemplaterError("app.vault is not a FileSystemAdapter instance");
      }
      const vault_path = this.app.vault.adapter.getBasePath();
      if (relative) {
        return this.config.target_file.path;
      } else {
        return `${vault_path}/${this.config.target_file.path}`;
      }
    };
  }
  generate_rename() {
    return (new_title) => __async(this, null, function* () {
      if (new_title.match(/[\\/:]+/g)) {
        throw new TemplaterError("File name cannot contain any of these characters: \\ / :");
      }
      const new_path = (0, import_obsidian8.normalizePath)(`${this.config.target_file.parent.path}/${new_title}.${this.config.target_file.extension}`);
      yield this.app.fileManager.renameFile(this.config.target_file, new_path);
      return "";
    });
  }
  generate_selection() {
    return () => {
      const active_view = this.app.workspace.getActiveViewOfType(import_obsidian8.MarkdownView);
      if (active_view == null) {
        throw new TemplaterError("Active view is null, can't read selection.");
      }
      const editor = active_view.editor;
      return editor.getSelection();
    };
  }
  generate_tags() {
    const cache = this.app.metadataCache.getFileCache(this.config.target_file);
    return (0, import_obsidian8.getAllTags)(cache);
  }
  generate_title() {
    return this.config.target_file.basename;
  }
};

// src/core/functions/internal_functions/web/InternalModuleWeb.ts
var InternalModuleWeb = class extends InternalModule {
  constructor() {
    super(...arguments);
    this.name = "web";
  }
  create_static_templates() {
    return __async(this, null, function* () {
      this.static_functions.set("daily_quote", this.generate_daily_quote());
      this.static_functions.set("random_picture", this.generate_random_picture());
    });
  }
  create_dynamic_templates() {
    return __async(this, null, function* () {
    });
  }
  getRequest(url) {
    return __async(this, null, function* () {
      const response = yield fetch(url);
      if (!response.ok) {
        throw new TemplaterError("Error performing GET request");
      }
      return response;
    });
  }
  generate_daily_quote() {
    return () => __async(this, null, function* () {
      const response = yield this.getRequest("https://api.quotable.io/random");
      const json = yield response.json();
      const author = json.author;
      const quote = json.content;
      const new_content = `> ${quote}
> \u2014 <cite>${author}</cite>`;
      return new_content;
    });
  }
  generate_random_picture() {
    return (size, query) => __async(this, null, function* () {
      const response = yield this.getRequest(`https://source.unsplash.com/random/${size != null ? size : ""}?${query != null ? query : ""}`);
      const url = response.url;
      return `![tp.web.random_picture](${url})`;
    });
  }
};

// src/core/functions/internal_functions/frontmatter/InternalModuleFrontmatter.ts
var InternalModuleFrontmatter = class extends InternalModule {
  constructor() {
    super(...arguments);
    this.name = "frontmatter";
  }
  create_static_templates() {
    return __async(this, null, function* () {
    });
  }
  create_dynamic_templates() {
    return __async(this, null, function* () {
      const cache = this.app.metadataCache.getFileCache(this.config.target_file);
      this.dynamic_functions = new Map(Object.entries((cache == null ? void 0 : cache.frontmatter) || {}));
    });
  }
};

// src/core/functions/internal_functions/system/InternalModuleSystem.ts
var import_obsidian11 = __toModule(require("obsidian"));

// src/core/functions/internal_functions/system/PromptModal.ts
var import_obsidian9 = __toModule(require("obsidian"));
var PromptModal = class extends import_obsidian9.Modal {
  constructor(app, prompt_text, default_value) {
    super(app);
    this.prompt_text = prompt_text;
    this.default_value = default_value;
    this.submitted = false;
  }
  onOpen() {
    this.titleEl.setText(this.prompt_text);
    this.createForm();
  }
  onClose() {
    this.contentEl.empty();
    if (!this.submitted) {
      this.reject(new TemplaterError("Cancelled prompt"));
    }
  }
  createForm() {
    var _a;
    const div = this.contentEl.createDiv();
    div.addClass("templater-prompt-div");
    const form = div.createEl("form");
    form.addClass("templater-prompt-form");
    form.type = "submit";
    form.onsubmit = (e) => {
      this.submitted = true;
      e.preventDefault();
      this.resolve(this.promptEl.value);
      this.close();
    };
    this.promptEl = form.createEl("input");
    this.promptEl.type = "text";
    this.promptEl.placeholder = "Type text here...";
    this.promptEl.value = (_a = this.default_value) != null ? _a : "";
    this.promptEl.addClass("templater-prompt-input");
    this.promptEl.select();
  }
  openAndGetValue(resolve2, reject) {
    return __async(this, null, function* () {
      this.resolve = resolve2;
      this.reject = reject;
      this.open();
    });
  }
};

// src/core/functions/internal_functions/system/SuggesterModal.ts
var import_obsidian10 = __toModule(require("obsidian"));
var SuggesterModal = class extends import_obsidian10.FuzzySuggestModal {
  constructor(app, text_items, items, placeholder) {
    super(app);
    this.text_items = text_items;
    this.items = items;
    this.submitted = false;
    this.setPlaceholder(placeholder);
  }
  getItems() {
    return this.items;
  }
  onClose() {
    if (!this.submitted) {
      this.reject(new TemplaterError("Cancelled prompt"));
    }
  }
  selectSuggestion(value, evt) {
    this.submitted = true;
    this.close();
    this.onChooseSuggestion(value, evt);
  }
  getItemText(item) {
    if (this.text_items instanceof Function) {
      return this.text_items(item);
    }
    return this.text_items[this.items.indexOf(item)] || "Undefined Text Item";
  }
  onChooseItem(item) {
    this.resolve(item);
  }
  openAndGetValue(resolve2, reject) {
    return __async(this, null, function* () {
      this.resolve = resolve2;
      this.reject = reject;
      this.open();
    });
  }
};

// src/core/functions/internal_functions/system/InternalModuleSystem.ts
var InternalModuleSystem = class extends InternalModule {
  constructor() {
    super(...arguments);
    this.name = "system";
  }
  create_static_templates() {
    return __async(this, null, function* () {
      this.static_functions.set("clipboard", this.generate_clipboard());
      this.static_functions.set("prompt", this.generate_prompt());
      this.static_functions.set("suggester", this.generate_suggester());
    });
  }
  create_dynamic_templates() {
    return __async(this, null, function* () {
    });
  }
  generate_clipboard() {
    return () => __async(this, null, function* () {
      if (import_obsidian11.Platform.isMobileApp) {
        return UNSUPPORTED_MOBILE_TEMPLATE;
      }
      return yield navigator.clipboard.readText();
    });
  }
  generate_prompt() {
    return (prompt_text, default_value, throw_on_cancel = false) => __async(this, null, function* () {
      const prompt = new PromptModal(this.app, prompt_text, default_value);
      const promise = new Promise((resolve2, reject) => prompt.openAndGetValue(resolve2, reject));
      try {
        return yield promise;
      } catch (error) {
        if (throw_on_cancel) {
          throw error;
        }
        return null;
      }
    });
  }
  generate_suggester() {
    return (text_items, items, throw_on_cancel = false, placeholder = "") => __async(this, null, function* () {
      const suggester = new SuggesterModal(this.app, text_items, items, placeholder);
      const promise = new Promise((resolve2, reject) => suggester.openAndGetValue(resolve2, reject));
      try {
        return yield promise;
      } catch (error) {
        if (throw_on_cancel) {
          throw error;
        }
        return null;
      }
    });
  }
};

// src/core/functions/internal_functions/config/InternalModuleConfig.ts
var InternalModuleConfig = class extends InternalModule {
  constructor() {
    super(...arguments);
    this.name = "config";
  }
  create_static_templates() {
    return __async(this, null, function* () {
    });
  }
  create_dynamic_templates() {
    return __async(this, null, function* () {
    });
  }
  generate_object(config2) {
    return __async(this, null, function* () {
      return config2;
    });
  }
};

// src/core/functions/internal_functions/InternalFunctions.ts
var InternalFunctions = class {
  constructor(app, plugin) {
    this.app = app;
    this.plugin = plugin;
    this.modules_array = [];
    this.modules_array.push(new InternalModuleDate(this.app, this.plugin));
    this.modules_array.push(new InternalModuleFile(this.app, this.plugin));
    this.modules_array.push(new InternalModuleWeb(this.app, this.plugin));
    this.modules_array.push(new InternalModuleFrontmatter(this.app, this.plugin));
    this.modules_array.push(new InternalModuleSystem(this.app, this.plugin));
    this.modules_array.push(new InternalModuleConfig(this.app, this.plugin));
  }
  init() {
    return __async(this, null, function* () {
      for (const mod of this.modules_array) {
        yield mod.init();
      }
    });
  }
  generate_object(config2) {
    return __async(this, null, function* () {
      const internal_functions_object = {};
      for (const mod of this.modules_array) {
        internal_functions_object[mod.getName()] = yield mod.generate_object(config2);
      }
      return internal_functions_object;
    });
  }
};

// src/core/functions/user_functions/UserFunctions.ts
var import_obsidian13 = __toModule(require("obsidian"));

// src/core/functions/user_functions/UserSystemFunctions.ts
var import_child_process = __toModule(require("child_process"));
var import_util = __toModule(require("util"));
var import_obsidian12 = __toModule(require("obsidian"));
var UserSystemFunctions = class {
  constructor(app, plugin) {
    this.plugin = plugin;
    if (import_obsidian12.Platform.isMobileApp || !(app.vault.adapter instanceof import_obsidian12.FileSystemAdapter)) {
      this.cwd = "";
    } else {
      this.cwd = app.vault.adapter.getBasePath();
      this.exec_promise = (0, import_util.promisify)(import_child_process.exec);
    }
  }
  generate_system_functions(config2) {
    return __async(this, null, function* () {
      const user_system_functions = new Map();
      const internal_functions_object = yield this.plugin.templater.functions_generator.generate_object(config2, FunctionsMode.INTERNAL);
      for (const template_pair of this.plugin.settings.templates_pairs) {
        const template = template_pair[0];
        let cmd = template_pair[1];
        if (!template || !cmd) {
          continue;
        }
        if (import_obsidian12.Platform.isMobileApp) {
          user_system_functions.set(template, () => {
            return new Promise((resolve2) => resolve2(UNSUPPORTED_MOBILE_TEMPLATE));
          });
        } else {
          cmd = yield this.plugin.templater.parser.parse_commands(cmd, internal_functions_object);
          user_system_functions.set(template, (user_args) => __async(this, null, function* () {
            const process_env = __spreadValues(__spreadValues({}, process.env), user_args);
            const cmd_options = __spreadValues({
              timeout: this.plugin.settings.command_timeout * 1e3,
              cwd: this.cwd,
              env: process_env
            }, this.plugin.settings.shell_path && {
              shell: this.plugin.settings.shell_path
            });
            try {
              const { stdout } = yield this.exec_promise(cmd, cmd_options);
              return stdout.trimRight();
            } catch (error) {
              throw new TemplaterError(`Error with User Template ${template}`, error);
            }
          }));
        }
      }
      return user_system_functions;
    });
  }
  generate_object(config2) {
    return __async(this, null, function* () {
      const user_system_functions = yield this.generate_system_functions(config2);
      return Object.fromEntries(user_system_functions);
    });
  }
};

// src/core/functions/user_functions/UserScriptFunctions.ts
var UserScriptFunctions = class {
  constructor(app, plugin) {
    this.app = app;
    this.plugin = plugin;
  }
  generate_user_script_functions() {
    return __async(this, null, function* () {
      const user_script_functions = new Map();
      const files = errorWrapperSync(() => get_tfiles_from_folder(this.app, this.plugin.settings.user_scripts_folder), `Couldn't find user script folder "${this.plugin.settings.user_scripts_folder}"`);
      if (!files) {
        return new Map();
      }
      for (const file of files) {
        if (file.extension.toLowerCase() === "js") {
          yield this.load_user_script_function(file, user_script_functions);
        }
      }
      return user_script_functions;
    });
  }
  load_user_script_function(file, user_script_functions) {
    return __async(this, null, function* () {
      let req = (s) => {
        return window.require && window.require(s);
      };
      let exp = {};
      let mod = {
        exports: exp
      };
      const file_content = yield this.app.vault.read(file);
      const wrapping_fn = window.eval("(function anonymous(require, module, exports){" + file_content + "\n})");
      wrapping_fn(req, mod, exp);
      const user_function = exp["default"] || mod.exports;
      if (!user_function) {
        throw new TemplaterError(`Failed to load user script ${file.path}. No exports detected.`);
      }
      if (!(user_function instanceof Function)) {
        throw new TemplaterError(`Failed to load user script ${file.path}. Default export is not a function.`);
      }
      user_script_functions.set(`${file.basename}`, user_function);
    });
  }
  generate_object() {
    return __async(this, null, function* () {
      const user_script_functions = yield this.generate_user_script_functions();
      return Object.fromEntries(user_script_functions);
    });
  }
};

// src/core/functions/user_functions/UserFunctions.ts
var UserFunctions = class {
  constructor(app, plugin) {
    this.plugin = plugin;
    this.user_system_functions = new UserSystemFunctions(app, plugin);
    this.user_script_functions = new UserScriptFunctions(app, plugin);
  }
  generate_object(config2) {
    return __async(this, null, function* () {
      let user_system_functions = {};
      let user_script_functions = {};
      if (this.plugin.settings.enable_system_commands) {
        user_system_functions = yield this.user_system_functions.generate_object(config2);
      }
      if (import_obsidian13.Platform.isDesktopApp && this.plugin.settings.user_scripts_folder) {
        user_script_functions = yield this.user_script_functions.generate_object(config2);
      }
      return __spreadValues(__spreadValues({}, user_system_functions), user_script_functions);
    });
  }
};

// src/core/functions/FunctionsGenerator.ts
var obsidian_module = __toModule(require("obsidian"));
var FunctionsMode;
(function(FunctionsMode2) {
  FunctionsMode2[FunctionsMode2["INTERNAL"] = 0] = "INTERNAL";
  FunctionsMode2[FunctionsMode2["USER_INTERNAL"] = 1] = "USER_INTERNAL";
})(FunctionsMode || (FunctionsMode = {}));
var FunctionsGenerator = class {
  constructor(app, plugin) {
    this.app = app;
    this.plugin = plugin;
    this.internal_functions = new InternalFunctions(this.app, this.plugin);
    this.user_functions = new UserFunctions(this.app, this.plugin);
  }
  init() {
    return __async(this, null, function* () {
      yield this.internal_functions.init();
    });
  }
  additional_functions() {
    return {
      obsidian: obsidian_module
    };
  }
  generate_object(config2, functions_mode = 1) {
    return __async(this, null, function* () {
      const final_object = {};
      const additional_functions_object = this.additional_functions();
      const internal_functions_object = yield this.internal_functions.generate_object(config2);
      let user_functions_object = {};
      Object.assign(final_object, additional_functions_object);
      switch (functions_mode) {
        case 0:
          Object.assign(final_object, internal_functions_object);
          break;
        case 1:
          user_functions_object = yield this.user_functions.generate_object(config2);
          Object.assign(final_object, __spreadProps(__spreadValues({}, internal_functions_object), {
            user: user_functions_object
          }));
          break;
      }
      return final_object;
    });
  }
};

// node_modules/eta/dist/eta.es.js
var import_fs = __toModule(require("fs"));
var import_path = __toModule(require("path"));
function setPrototypeOf(obj, proto) {
  if (Object.setPrototypeOf) {
    Object.setPrototypeOf(obj, proto);
  } else {
    obj.__proto__ = proto;
  }
}
function EtaErr(message) {
  var err = new Error(message);
  setPrototypeOf(err, EtaErr.prototype);
  return err;
}
EtaErr.prototype = Object.create(Error.prototype, {
  name: { value: "Eta Error", enumerable: false }
});
function ParseErr(message, str, indx) {
  var whitespace = str.slice(0, indx).split(/\n/);
  var lineNo = whitespace.length;
  var colNo = whitespace[lineNo - 1].length + 1;
  message += " at line " + lineNo + " col " + colNo + ":\n\n  " + str.split(/\n/)[lineNo - 1] + "\n  " + Array(colNo).join(" ") + "^";
  throw EtaErr(message);
}
var promiseImpl = new Function("return this")().Promise;
function getAsyncFunctionConstructor() {
  try {
    return new Function("return (async function(){}).constructor")();
  } catch (e) {
    if (e instanceof SyntaxError) {
      throw EtaErr("This environment doesn't support async/await");
    } else {
      throw e;
    }
  }
}
function trimLeft(str) {
  if (!!String.prototype.trimLeft) {
    return str.trimLeft();
  } else {
    return str.replace(/^\s+/, "");
  }
}
function trimRight(str) {
  if (!!String.prototype.trimRight) {
    return str.trimRight();
  } else {
    return str.replace(/\s+$/, "");
  }
}
function hasOwnProp(obj, prop) {
  return Object.prototype.hasOwnProperty.call(obj, prop);
}
function copyProps(toObj, fromObj) {
  for (var key in fromObj) {
    if (hasOwnProp(fromObj, key)) {
      toObj[key] = fromObj[key];
    }
  }
  return toObj;
}
function trimWS(str, config2, wsLeft, wsRight) {
  var leftTrim;
  var rightTrim;
  if (Array.isArray(config2.autoTrim)) {
    leftTrim = config2.autoTrim[1];
    rightTrim = config2.autoTrim[0];
  } else {
    leftTrim = rightTrim = config2.autoTrim;
  }
  if (wsLeft || wsLeft === false) {
    leftTrim = wsLeft;
  }
  if (wsRight || wsRight === false) {
    rightTrim = wsRight;
  }
  if (!rightTrim && !leftTrim) {
    return str;
  }
  if (leftTrim === "slurp" && rightTrim === "slurp") {
    return str.trim();
  }
  if (leftTrim === "_" || leftTrim === "slurp") {
    str = trimLeft(str);
  } else if (leftTrim === "-" || leftTrim === "nl") {
    str = str.replace(/^(?:\r\n|\n|\r)/, "");
  }
  if (rightTrim === "_" || rightTrim === "slurp") {
    str = trimRight(str);
  } else if (rightTrim === "-" || rightTrim === "nl") {
    str = str.replace(/(?:\r\n|\n|\r)$/, "");
  }
  return str;
}
var escMap = {
  "&": "&amp;",
  "<": "&lt;",
  ">": "&gt;",
  '"': "&quot;",
  "'": "&#39;"
};
function replaceChar(s) {
  return escMap[s];
}
function XMLEscape(str) {
  var newStr = String(str);
  if (/[&<>"']/.test(newStr)) {
    return newStr.replace(/[&<>"']/g, replaceChar);
  } else {
    return newStr;
  }
}
var templateLitReg = /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})*}|(?!\${)[^\\`])*`/g;
var singleQuoteReg = /'(?:\\[\s\w"'\\`]|[^\n\r'\\])*?'/g;
var doubleQuoteReg = /"(?:\\[\s\w"'\\`]|[^\n\r"\\])*?"/g;
function escapeRegExp(string) {
  return string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&");
}
function parse(str, config2) {
  var buffer = [];
  var trimLeftOfNextStr = false;
  var lastIndex = 0;
  var parseOptions = config2.parse;
  if (config2.plugins) {
    for (var i = 0; i < config2.plugins.length; i++) {
      var plugin = config2.plugins[i];
      if (plugin.processTemplate) {
        str = plugin.processTemplate(str, config2);
      }
    }
  }
  if (config2.rmWhitespace) {
    str = str.replace(/[\r\n]+/g, "\n").replace(/^\s+|\s+$/gm, "");
  }
  templateLitReg.lastIndex = 0;
  singleQuoteReg.lastIndex = 0;
  doubleQuoteReg.lastIndex = 0;
  function pushString(strng, shouldTrimRightOfString) {
    if (strng) {
      strng = trimWS(strng, config2, trimLeftOfNextStr, shouldTrimRightOfString);
      if (strng) {
        strng = strng.replace(/\\|'/g, "\\$&").replace(/\r\n|\n|\r/g, "\\n");
        buffer.push(strng);
      }
    }
  }
  var prefixes = [parseOptions.exec, parseOptions.interpolate, parseOptions.raw].reduce(function(accumulator, prefix2) {
    if (accumulator && prefix2) {
      return accumulator + "|" + escapeRegExp(prefix2);
    } else if (prefix2) {
      return escapeRegExp(prefix2);
    } else {
      return accumulator;
    }
  }, "");
  var parseOpenReg = new RegExp("([^]*?)" + escapeRegExp(config2.tags[0]) + "(-|_)?\\s*(" + prefixes + ")?\\s*(?![\\s+\\-_" + prefixes + "])", "g");
  var parseCloseReg = new RegExp("'|\"|`|\\/\\*|(\\s*(-|_)?" + escapeRegExp(config2.tags[1]) + ")", "g");
  var m;
  while (m = parseOpenReg.exec(str)) {
    lastIndex = m[0].length + m.index;
    var precedingString = m[1];
    var wsLeft = m[2];
    var prefix = m[3] || "";
    pushString(precedingString, wsLeft);
    parseCloseReg.lastIndex = lastIndex;
    var closeTag = void 0;
    var currentObj = false;
    while (closeTag = parseCloseReg.exec(str)) {
      if (closeTag[1]) {
        var content = str.slice(lastIndex, closeTag.index);
        parseOpenReg.lastIndex = lastIndex = parseCloseReg.lastIndex;
        trimLeftOfNextStr = closeTag[2];
        var currentType = prefix === parseOptions.exec ? "e" : prefix === parseOptions.raw ? "r" : prefix === parseOptions.interpolate ? "i" : "";
        currentObj = { t: currentType, val: content };
        break;
      } else {
        var char = closeTag[0];
        if (char === "/*") {
          var commentCloseInd = str.indexOf("*/", parseCloseReg.lastIndex);
          if (commentCloseInd === -1) {
            ParseErr("unclosed comment", str, closeTag.index);
          }
          parseCloseReg.lastIndex = commentCloseInd;
        } else if (char === "'") {
          singleQuoteReg.lastIndex = closeTag.index;
          var singleQuoteMatch = singleQuoteReg.exec(str);
          if (singleQuoteMatch) {
            parseCloseReg.lastIndex = singleQuoteReg.lastIndex;
          } else {
            ParseErr("unclosed string", str, closeTag.index);
          }
        } else if (char === '"') {
          doubleQuoteReg.lastIndex = closeTag.index;
          var doubleQuoteMatch = doubleQuoteReg.exec(str);
          if (doubleQuoteMatch) {
            parseCloseReg.lastIndex = doubleQuoteReg.lastIndex;
          } else {
            ParseErr("unclosed string", str, closeTag.index);
          }
        } else if (char === "`") {
          templateLitReg.lastIndex = closeTag.index;
          var templateLitMatch = templateLitReg.exec(str);
          if (templateLitMatch) {
            parseCloseReg.lastIndex = templateLitReg.lastIndex;
          } else {
            ParseErr("unclosed string", str, closeTag.index);
          }
        }
      }
    }
    if (currentObj) {
      buffer.push(currentObj);
    } else {
      ParseErr("unclosed tag", str, m.index + precedingString.length);
    }
  }
  pushString(str.slice(lastIndex, str.length), false);
  if (config2.plugins) {
    for (var i = 0; i < config2.plugins.length; i++) {
      var plugin = config2.plugins[i];
      if (plugin.processAST) {
        buffer = plugin.processAST(buffer, config2);
      }
    }
  }
  return buffer;
}
function compileToString(str, config2) {
  var buffer = parse(str, config2);
  var res = "var tR='',__l,__lP" + (config2.include ? ",include=E.include.bind(E)" : "") + (config2.includeFile ? ",includeFile=E.includeFile.bind(E)" : "") + "\nfunction layout(p,d){__l=p;__lP=d}\n" + (config2.globalAwait ? "const _prs = [];\n" : "") + (config2.useWith ? "with(" + config2.varName + "||{}){" : "") + compileScope(buffer, config2) + (config2.includeFile ? "if(__l)tR=" + (config2.async ? "await " : "") + ("includeFile(__l,Object.assign(" + config2.varName + ",{body:tR},__lP))\n") : config2.include ? "if(__l)tR=" + (config2.async ? "await " : "") + ("include(__l,Object.assign(" + config2.varName + ",{body:tR},__lP))\n") : "") + "if(cb){cb(null,tR)} return tR" + (config2.useWith ? "}" : "");
  if (config2.plugins) {
    for (var i = 0; i < config2.plugins.length; i++) {
      var plugin = config2.plugins[i];
      if (plugin.processFnString) {
        res = plugin.processFnString(res, config2);
      }
    }
  }
  return res;
}
function compileScope(buff, config2) {
  var i;
  var buffLength = buff.length;
  var returnStr = "";
  var REPLACEMENT_STR = "rJ2KqXzxQg";
  for (i = 0; i < buffLength; i++) {
    var currentBlock = buff[i];
    if (typeof currentBlock === "string") {
      var str = currentBlock;
      returnStr += "tR+='" + str + "'\n";
    } else {
      var type = currentBlock.t;
      var content = currentBlock.val || "";
      if (type === "r") {
        if (config2.globalAwait) {
          returnStr += "_prs.push(" + content + ");\n";
          returnStr += "tR+='" + REPLACEMENT_STR + "'\n";
        } else {
          if (config2.filter) {
            content = "E.filter(" + content + ")";
          }
          returnStr += "tR+=" + content + "\n";
        }
      } else if (type === "i") {
        if (config2.globalAwait) {
          returnStr += "_prs.push(" + content + ");\n";
          returnStr += "tR+='" + REPLACEMENT_STR + "'\n";
        } else {
          if (config2.filter) {
            content = "E.filter(" + content + ")";
          }
          returnStr += "tR+=" + content + "\n";
          if (config2.autoEscape) {
            content = "E.e(" + content + ")";
          }
          returnStr += "tR+=" + content + "\n";
        }
      } else if (type === "e") {
        returnStr += content + "\n";
      }
    }
  }
  if (config2.globalAwait) {
    returnStr += "const _rst = await Promise.all(_prs);\ntR = tR.replace(/" + REPLACEMENT_STR + "/g, () => _rst.shift());\n";
  }
  return returnStr;
}
var Cacher = function() {
  function Cacher2(cache) {
    this.cache = cache;
  }
  Cacher2.prototype.define = function(key, val) {
    this.cache[key] = val;
  };
  Cacher2.prototype.get = function(key) {
    return this.cache[key];
  };
  Cacher2.prototype.remove = function(key) {
    delete this.cache[key];
  };
  Cacher2.prototype.reset = function() {
    this.cache = {};
  };
  Cacher2.prototype.load = function(cacheObj) {
    copyProps(this.cache, cacheObj);
  };
  return Cacher2;
}();
var templates = new Cacher({});
function includeHelper(templateNameOrPath, data) {
  var template = this.templates.get(templateNameOrPath);
  if (!template) {
    throw EtaErr('Could not fetch template "' + templateNameOrPath + '"');
  }
  return template(data, this);
}
var config = {
  async: false,
  autoEscape: true,
  autoTrim: [false, "nl"],
  cache: false,
  e: XMLEscape,
  include: includeHelper,
  parse: {
    exec: "",
    interpolate: "=",
    raw: "~"
  },
  plugins: [],
  rmWhitespace: false,
  tags: ["<%", "%>"],
  templates,
  useWith: false,
  varName: "it"
};
function getConfig(override, baseConfig) {
  var res = {};
  copyProps(res, config);
  if (baseConfig) {
    copyProps(res, baseConfig);
  }
  if (override) {
    copyProps(res, override);
  }
  return res;
}
function compile(str, config2) {
  var options = getConfig(config2 || {});
  var ctor = options.async ? getAsyncFunctionConstructor() : Function;
  try {
    return new ctor(options.varName, "E", "cb", compileToString(str, options));
  } catch (e) {
    if (e instanceof SyntaxError) {
      throw EtaErr("Bad template syntax\n\n" + e.message + "\n" + Array(e.message.length + 1).join("=") + "\n" + compileToString(str, options) + "\n");
    } else {
      throw e;
    }
  }
}
var _BOM = /^\uFEFF/;
function getWholeFilePath(name, parentfile, isDirectory) {
  var includePath = (0, import_path.resolve)(isDirectory ? parentfile : (0, import_path.dirname)(parentfile), name) + ((0, import_path.extname)(name) ? "" : ".eta");
  return includePath;
}
function getPath(path, options) {
  var includePath = false;
  var views = options.views;
  var searchedPaths = [];
  var pathOptions = JSON.stringify({
    filename: options.filename,
    path,
    root: options.root,
    views: options.views
  });
  if (options.cache && options.filepathCache && options.filepathCache[pathOptions]) {
    return options.filepathCache[pathOptions];
  }
  function addPathToSearched(pathSearched) {
    if (!searchedPaths.includes(pathSearched)) {
      searchedPaths.push(pathSearched);
    }
  }
  function searchViews(views2, path2) {
    var filePath2;
    if (Array.isArray(views2) && views2.some(function(v) {
      filePath2 = getWholeFilePath(path2, v, true);
      addPathToSearched(filePath2);
      return (0, import_fs.existsSync)(filePath2);
    })) {
      return filePath2;
    } else if (typeof views2 === "string") {
      filePath2 = getWholeFilePath(path2, views2, true);
      addPathToSearched(filePath2);
      if ((0, import_fs.existsSync)(filePath2)) {
        return filePath2;
      }
    }
    return false;
  }
  var match = /^[A-Za-z]+:\\|^\//.exec(path);
  if (match && match.length) {
    var formattedPath = path.replace(/^\/*/, "");
    includePath = searchViews(views, formattedPath);
    if (!includePath) {
      var pathFromRoot = getWholeFilePath(formattedPath, options.root || "/", true);
      addPathToSearched(pathFromRoot);
      includePath = pathFromRoot;
    }
  } else {
    if (options.filename) {
      var filePath = getWholeFilePath(path, options.filename);
      addPathToSearched(filePath);
      if ((0, import_fs.existsSync)(filePath)) {
        includePath = filePath;
      }
    }
    if (!includePath) {
      includePath = searchViews(views, path);
    }
    if (!includePath) {
      throw EtaErr('Could not find the template "' + path + '". Paths tried: ' + searchedPaths);
    }
  }
  if (options.cache && options.filepathCache) {
    options.filepathCache[pathOptions] = includePath;
  }
  return includePath;
}
function readFile(filePath) {
  try {
    return (0, import_fs.readFileSync)(filePath).toString().replace(_BOM, "");
  } catch (_a) {
    throw EtaErr("Failed to read template at '" + filePath + "'");
  }
}
function loadFile(filePath, options, noCache) {
  var config2 = getConfig(options);
  var template = readFile(filePath);
  try {
    var compiledTemplate = compile(template, config2);
    if (!noCache) {
      config2.templates.define(config2.filename, compiledTemplate);
    }
    return compiledTemplate;
  } catch (e) {
    throw EtaErr("Loading file: " + filePath + " failed:\n\n" + e.message);
  }
}
function handleCache(options) {
  var filename = options.filename;
  if (options.cache) {
    var func = options.templates.get(filename);
    if (func) {
      return func;
    }
    return loadFile(filename, options);
  }
  return loadFile(filename, options, true);
}
function includeFile(path, options) {
  var newFileOptions = getConfig({ filename: getPath(path, options) }, options);
  return [handleCache(newFileOptions), newFileOptions];
}
function includeFileHelper(path, data) {
  var templateAndConfig = includeFile(path, this);
  return templateAndConfig[0](data, templateAndConfig[1]);
}
function handleCache$1(template, options) {
  if (options.cache && options.name && options.templates.get(options.name)) {
    return options.templates.get(options.name);
  }
  var templateFunc = typeof template === "function" ? template : compile(template, options);
  if (options.cache && options.name) {
    options.templates.define(options.name, templateFunc);
  }
  return templateFunc;
}
function render(template, data, config2, cb) {
  var options = getConfig(config2 || {});
  if (options.async) {
    if (cb) {
      try {
        var templateFn = handleCache$1(template, options);
        templateFn(data, options, cb);
      } catch (err) {
        return cb(err);
      }
    } else {
      if (typeof promiseImpl === "function") {
        return new promiseImpl(function(resolve2, reject) {
          try {
            resolve2(handleCache$1(template, options)(data, options));
          } catch (err) {
            reject(err);
          }
        });
      } else {
        throw EtaErr("Please provide a callback function, this env doesn't support Promises");
      }
    }
  } else {
    return handleCache$1(template, options)(data, options);
  }
}
function renderAsync(template, data, config2, cb) {
  return render(template, data, Object.assign({}, config2, { async: true }), cb);
}
config.includeFile = includeFileHelper;
config.filepathCache = {};

// src/core/parser/Parser.ts
var Parser = class {
  parse_commands(content, object) {
    return __async(this, null, function* () {
      content = yield renderAsync(content, object, {
        varName: "tp",
        parse: {
          exec: "*",
          interpolate: "~",
          raw: ""
        },
        autoTrim: false,
        globalAwait: true
      });
      return content;
    });
  }
};

// src/core/Templater.ts
var RunMode;
(function(RunMode2) {
  RunMode2[RunMode2["CreateNewFromTemplate"] = 0] = "CreateNewFromTemplate";
  RunMode2[RunMode2["AppendActiveFile"] = 1] = "AppendActiveFile";
  RunMode2[RunMode2["OverwriteFile"] = 2] = "OverwriteFile";
  RunMode2[RunMode2["OverwriteActiveFile"] = 3] = "OverwriteActiveFile";
  RunMode2[RunMode2["DynamicProcessor"] = 4] = "DynamicProcessor";
  RunMode2[RunMode2["StartupTemplate"] = 5] = "StartupTemplate";
})(RunMode || (RunMode = {}));
var Templater = class {
  constructor(app, plugin) {
    this.app = app;
    this.plugin = plugin;
    this.functions_generator = new FunctionsGenerator(this.app, this.plugin);
    this.parser = new Parser();
  }
  setup() {
    return __async(this, null, function* () {
      yield this.functions_generator.init();
      this.plugin.registerMarkdownPostProcessor((el, ctx) => this.process_dynamic_templates(el, ctx));
    });
  }
  create_running_config(template_file, target_file, run_mode) {
    const active_file = this.app.workspace.getActiveFile();
    return {
      template_file,
      target_file,
      run_mode,
      active_file
    };
  }
  read_and_parse_template(config2) {
    return __async(this, null, function* () {
      const template_content = yield this.app.vault.read(config2.template_file);
      return this.parse_template(config2, template_content);
    });
  }
  parse_template(config2, template_content) {
    return __async(this, null, function* () {
      const functions_object = yield this.functions_generator.generate_object(config2, FunctionsMode.USER_INTERNAL);
      this.current_functions_object = functions_object;
      const content = yield this.parser.parse_commands(template_content, functions_object);
      return content;
    });
  }
  create_new_note_from_template(template, folder, filename, open_new_note = true) {
    return __async(this, null, function* () {
      if (!folder) {
        const new_file_location = this.app.vault.getConfig("newFileLocation");
        switch (new_file_location) {
          case "current": {
            const active_file = this.app.workspace.getActiveFile();
            if (active_file) {
              folder = active_file.parent;
            }
            break;
          }
          case "folder":
            folder = this.app.fileManager.getNewFileParent("");
            break;
          case "root":
            folder = this.app.vault.getRoot();
            break;
          default:
            break;
        }
      }
      const created_note = yield this.app.fileManager.createNewMarkdownFile(folder, filename != null ? filename : "Untitled");
      let running_config;
      let output_content;
      if (template instanceof import_obsidian14.TFile) {
        running_config = this.create_running_config(template, created_note, 0);
        output_content = yield errorWrapper(() => __async(this, null, function* () {
          return this.read_and_parse_template(running_config);
        }), "Template parsing error, aborting.");
      } else {
        running_config = this.create_running_config(void 0, created_note, 0);
        output_content = yield errorWrapper(() => __async(this, null, function* () {
          return this.parse_template(running_config, template);
        }), "Template parsing error, aborting.");
      }
      if (output_content == null) {
        yield this.app.vault.delete(created_note);
        return;
      }
      yield this.app.vault.modify(created_note, output_content);
      if (open_new_note) {
        const active_leaf = this.app.workspace.activeLeaf;
        if (!active_leaf) {
          log_error(new TemplaterError("No active leaf"));
          return;
        }
        yield active_leaf.openFile(created_note, {
          state: { mode: "source" },
          eState: { rename: "all" }
        });
        yield this.plugin.editor_handler.jump_to_next_cursor_location(created_note, true);
      }
      return created_note;
    });
  }
  append_template_to_active_file(template_file) {
    return __async(this, null, function* () {
      const active_view = this.app.workspace.getActiveViewOfType(import_obsidian14.MarkdownView);
      if (active_view === null) {
        log_error(new TemplaterError("No active view, can't append templates."));
        return;
      }
      const running_config = this.create_running_config(template_file, active_view.file, 1);
      const output_content = yield errorWrapper(() => __async(this, null, function* () {
        return this.read_and_parse_template(running_config);
      }), "Template parsing error, aborting.");
      if (output_content == null) {
        return;
      }
      const editor = active_view.editor;
      const doc = editor.getDoc();
      doc.replaceSelection(output_content);
      yield this.plugin.editor_handler.jump_to_next_cursor_location(active_view.file, true);
    });
  }
  write_template_to_file(template_file, file) {
    return __async(this, null, function* () {
      const running_config = this.create_running_config(template_file, file, 2);
      const output_content = yield errorWrapper(() => __async(this, null, function* () {
        return this.read_and_parse_template(running_config);
      }), "Template parsing error, aborting.");
      if (output_content == null) {
        return;
      }
      yield this.app.vault.modify(file, output_content);
      yield this.plugin.editor_handler.jump_to_next_cursor_location(file, true);
    });
  }
  overwrite_active_file_commands() {
    const active_view = this.app.workspace.getActiveViewOfType(import_obsidian14.MarkdownView);
    if (active_view === null) {
      log_error(new TemplaterError("Active view is null, can't overwrite content"));
      return;
    }
    this.overwrite_file_commands(active_view.file, true);
  }
  overwrite_file_commands(file, active_file = false) {
    return __async(this, null, function* () {
      const running_config = this.create_running_config(file, file, active_file ? 3 : 2);
      const output_content = yield errorWrapper(() => __async(this, null, function* () {
        return this.read_and_parse_template(running_config);
      }), "Template parsing error, aborting.");
      if (output_content == null) {
        return;
      }
      yield this.app.vault.modify(file, output_content);
      yield this.plugin.editor_handler.jump_to_next_cursor_location(file, true);
    });
  }
  process_dynamic_templates(el, ctx) {
    return __async(this, null, function* () {
      const dynamic_command_regex = generate_dynamic_command_regex();
      const walker = document.createNodeIterator(el, NodeFilter.SHOW_TEXT);
      let node;
      let pass = false;
      let functions_object;
      while (node = walker.nextNode()) {
        let content = node.nodeValue;
        let match;
        if ((match = dynamic_command_regex.exec(content)) != null) {
          const file = this.app.metadataCache.getFirstLinkpathDest("", ctx.sourcePath);
          if (!file || !(file instanceof import_obsidian14.TFile)) {
            return;
          }
          if (!pass) {
            pass = true;
            const config2 = this.create_running_config(file, file, 4);
            functions_object = yield this.functions_generator.generate_object(config2, FunctionsMode.USER_INTERNAL);
            this.current_functions_object = functions_object;
          }
          while (match != null) {
            const complete_command = match[1] + match[2];
            const command_output = yield errorWrapper(() => __async(this, null, function* () {
              return yield this.parser.parse_commands(complete_command, functions_object);
            }), `Command Parsing error in dynamic command '${complete_command}'`);
            if (command_output == null) {
              return;
            }
            const start2 = dynamic_command_regex.lastIndex - match[0].length;
            const end2 = dynamic_command_regex.lastIndex;
            content = content.substring(0, start2) + command_output + content.substring(end2);
            dynamic_command_regex.lastIndex += command_output.length - match[0].length;
            match = dynamic_command_regex.exec(content);
          }
          node.nodeValue = content;
        }
      }
    });
  }
  get_new_file_template_for_folder(folder) {
    do {
      const match = this.plugin.settings.folder_templates.find((e) => e.folder == folder.path);
      if (match && match.template) {
        return match.template;
      }
      folder = folder.parent;
    } while (folder);
  }
  static on_file_creation(templater, file) {
    return __async(this, null, function* () {
      if (!(file instanceof import_obsidian14.TFile) || file.extension !== "md") {
        return;
      }
      const template_folder = (0, import_obsidian14.normalizePath)(templater.plugin.settings.templates_folder);
      if (file.path.includes(template_folder) && template_folder !== "/") {
        return;
      }
      yield delay(300);
      if (file.stat.size == 0 && templater.plugin.settings.enable_folder_templates) {
        const folder_template_match = templater.get_new_file_template_for_folder(file.parent);
        if (!folder_template_match) {
          return;
        }
        const template_file = yield errorWrapper(() => __async(this, null, function* () {
          return resolve_tfile(templater.app, folder_template_match);
        }), `Couldn't find template ${folder_template_match}`);
        if (template_file == null) {
          return;
        }
        yield templater.write_template_to_file(template_file, file);
      } else {
        yield templater.overwrite_file_commands(file);
      }
    });
  }
  execute_startup_scripts() {
    return __async(this, null, function* () {
      for (const template of this.plugin.settings.startup_templates) {
        if (!template) {
          continue;
        }
        const file = errorWrapperSync(() => resolve_tfile(this.app, template), `Couldn't find startup template "${template}"`);
        if (!file) {
          continue;
        }
        const running_config = this.create_running_config(file, file, 5);
        yield errorWrapper(() => __async(this, null, function* () {
          return this.read_and_parse_template(running_config);
        }), `Startup Template parsing error, aborting.`);
      }
    });
  }
};

// src/handlers/EventHandler.ts
var import_obsidian15 = __toModule(require("obsidian"));
var EventHandler = class {
  constructor(app, plugin, templater, settings) {
    this.app = app;
    this.plugin = plugin;
    this.templater = templater;
    this.settings = settings;
  }
  setup() {
    this.app.workspace.onLayoutReady(() => {
      this.update_trigger_file_on_creation();
    });
    this.update_syntax_highlighting();
    this.update_file_menu();
  }
  update_syntax_highlighting() {
    if (this.plugin.settings.syntax_highlighting) {
      this.syntax_highlighting_event = this.app.workspace.on("codemirror", (cm) => {
        cm.setOption("mode", "templater");
      });
      this.app.workspace.iterateCodeMirrors((cm) => {
        cm.setOption("mode", "templater");
      });
      this.plugin.registerEvent(this.syntax_highlighting_event);
    } else {
      if (this.syntax_highlighting_event) {
        this.app.vault.offref(this.syntax_highlighting_event);
      }
      this.app.workspace.iterateCodeMirrors((cm) => {
        cm.setOption("mode", "hypermd");
      });
    }
  }
  update_trigger_file_on_creation() {
    if (this.settings.trigger_on_file_creation) {
      this.trigger_on_file_creation_event = this.app.vault.on("create", (file) => Templater.on_file_creation(this.templater, file));
      this.plugin.registerEvent(this.trigger_on_file_creation_event);
    } else {
      if (this.trigger_on_file_creation_event) {
        this.app.vault.offref(this.trigger_on_file_creation_event);
        this.trigger_on_file_creation_event = void 0;
      }
    }
  }
  update_file_menu() {
    this.plugin.registerEvent(this.app.workspace.on("file-menu", (menu, file) => {
      if (file instanceof import_obsidian15.TFolder) {
        menu.addItem((item) => {
          item.setTitle("Create new note from template").setIcon("templater-icon").onClick(() => {
            this.plugin.fuzzy_suggester.create_new_note_from_template(file);
          });
        });
      }
    }));
  }
};

// src/handlers/CommandHandler.ts
var CommandHandler = class {
  constructor(app, plugin) {
    this.app = app;
    this.plugin = plugin;
  }
  setup() {
    this.plugin.addCommand({
      id: "insert-templater",
      name: "Open Insert Template modal",
      hotkeys: [
        {
          modifiers: ["Alt"],
          key: "e"
        }
      ],
      callback: () => {
        this.plugin.fuzzy_suggester.insert_template();
      }
    });
    this.plugin.addCommand({
      id: "replace-in-file-templater",
      name: "Replace templates in the active file",
      hotkeys: [
        {
          modifiers: ["Alt"],
          key: "r"
        }
      ],
      callback: () => {
        this.plugin.templater.overwrite_active_file_commands();
      }
    });
    this.plugin.addCommand({
      id: "jump-to-next-cursor-location",
      name: "Jump to next cursor location",
      hotkeys: [
        {
          modifiers: ["Alt"],
          key: "Tab"
        }
      ],
      callback: () => {
        this.plugin.editor_handler.jump_to_next_cursor_location();
      }
    });
    this.plugin.addCommand({
      id: "create-new-note-from-template",
      name: "Create new note from template",
      hotkeys: [
        {
          modifiers: ["Alt"],
          key: "n"
        }
      ],
      callback: () => {
        this.plugin.fuzzy_suggester.create_new_note_from_template();
      }
    });
    this.register_templates_hotkeys();
  }
  register_templates_hotkeys() {
    this.plugin.settings.enabled_templates_hotkeys.forEach((template) => {
      if (template) {
        this.add_template_hotkey(null, template);
      }
    });
  }
  add_template_hotkey(old_template, new_template) {
    this.remove_template_hotkey(old_template);
    if (new_template) {
      this.plugin.addCommand({
        id: new_template,
        name: `Insert ${new_template}`,
        callback: () => {
          const template = errorWrapperSync(() => resolve_tfile(this.app, new_template), `Couldn't find the template file associated with this hotkey`);
          if (!template) {
            return;
          }
          this.plugin.templater.append_template_to_active_file(template);
        }
      });
    }
  }
  remove_template_hotkey(template) {
    if (template) {
      this.app.commands.removeCommand(`${this.plugin.manifest.id}:${template}`);
    }
  }
};

// src/editor/Editor.ts
var import_obsidian18 = __toModule(require("obsidian"));

// src/editor/CursorJumper.ts
var import_obsidian16 = __toModule(require("obsidian"));
var CursorJumper = class {
  constructor(app) {
    this.app = app;
  }
  jump_to_next_cursor_location() {
    return __async(this, null, function* () {
      const active_view = this.app.workspace.getActiveViewOfType(import_obsidian16.MarkdownView);
      if (!active_view) {
        return;
      }
      const active_file = active_view.file;
      yield active_view.save();
      const content = yield this.app.vault.read(active_file);
      const { new_content, positions } = this.replace_and_get_cursor_positions(content);
      if (positions) {
        yield this.app.vault.modify(active_file, new_content);
        this.set_cursor_location(positions);
      }
    });
  }
  get_editor_position_from_index(content, index) {
    const substr = content.slice(0, index);
    let l = 0;
    let offset2 = -1;
    let r = -1;
    for (; (r = substr.indexOf("\n", r + 1)) !== -1; l++, offset2 = r)
      ;
    offset2 += 1;
    const ch = content.slice(offset2, index).length;
    return { line: l, ch };
  }
  replace_and_get_cursor_positions(content) {
    let cursor_matches = [];
    let match;
    const cursor_regex = new RegExp("<%\\s*tp.file.cursor\\((?<order>[0-9]{0,2})\\)\\s*%>", "g");
    while ((match = cursor_regex.exec(content)) != null) {
      cursor_matches.push(match);
    }
    if (cursor_matches.length === 0) {
      return {};
    }
    cursor_matches.sort((m1, m2) => {
      return Number(m1.groups["order"]) - Number(m2.groups["order"]);
    });
    const match_str = cursor_matches[0][0];
    cursor_matches = cursor_matches.filter((m) => {
      return m[0] === match_str;
    });
    const positions = [];
    let index_offset = 0;
    for (const match2 of cursor_matches) {
      const index = match2.index - index_offset;
      positions.push(this.get_editor_position_from_index(content, index));
      content = content.replace(new RegExp(escape_RegExp(match2[0])), "");
      index_offset += match2[0].length;
      if (match2[1] === "") {
        break;
      }
    }
    return { new_content: content, positions };
  }
  set_cursor_location(positions) {
    const active_view = this.app.workspace.getActiveViewOfType(import_obsidian16.MarkdownView);
    if (!active_view) {
      return;
    }
    const editor = active_view.editor;
    editor.focus();
    const selections = [];
    for (const pos of positions) {
      selections.push({ from: pos });
    }
    const transaction = {
      selections
    };
    editor.transaction(transaction);
  }
};

// src/editor/Autocomplete.ts
var import_obsidian17 = __toModule(require("obsidian"));

// toml:/home/runner/work/Templater/Templater/docs/documentation.toml
var tp = { config: { name: "config", description: "This module exposes Templater's running configuration.\n\nThis is mostly useful when writing scripts requiring some context informations.\n", functions: { template_file: { name: "template_file", description: "The `TFile` object representing the template file.", definition: "tp.file.template_file" }, target_file: { name: "target_file", description: "The `TFile` object representing the target file where the template will be inserted.", definition: "tp.config.target_file" }, run_mode: { name: "run_mode", description: "The `RunMode`, representing the way Templater was launched (Create new from template, Append to active file, ...)", definition: "tp.config.run_mode" }, active_file: { name: "active_file", description: "The active file (if existing) when launching Templater.", definition: "tp.config.active_file?" } } }, date: { name: "date", description: "This module contains every internal function related to dates.", functions: { now: { name: "now", description: "Retrieves the date.", definition: 'tp.date.now(format: string = "YYYY-MM-DD", offset?: number\u23AEstring, reference?: string, reference_format?: string)', args: { format: { name: "format", description: "Format for the date, refer to [format reference](https://momentjs.com/docs/#/displaying/format/)" }, offset: { name: "offset", description: "Offset for the day, e.g. set this to `-7` to get last week's date. You can also specify the offset as a string using the ISO 8601 format" }, reference: { name: "reference", description: "The date referential, e.g. set this to the note's title" }, reference_format: { name: "reference_format", description: "The date reference format." } } }, tomorrow: { name: "tomorrow", description: "Retrieves tomorrow's date.", definition: 'tp.date.tomorrow(format: string = "YYYY-MM-DD")', args: { format: { name: "format", description: "Format for the date, refer to [format reference](https://momentjs.com/docs/#/displaying/format/)" } } }, yesterday: { name: "yesterday", description: "Retrieves yesterday's date.", definition: 'tp.date.yesterday(format: string = "YYYY-MM-DD")', args: { format: { name: "format", description: "Format for the date, refer to [format reference](https://momentjs.com/docs/#/displaying/format/)" } } }, weekday: { name: "weekday", description: "", definition: 'tp.date.weekday(format: string = "YYYY-MM-DD", weekday: number, reference?: string, reference_format?: string)', args: { format: { name: "format", description: "Format for the date, refer to [format reference](https://momentjs.com/docs/#/displaying/format/)" }, weekday: { name: "weekday", description: "Week day number. If the locale assigns Monday as the first day of the week, `0` will be Monday, `-7` will be last week's day." }, reference: { name: "reference", description: "The date referential, e.g. set this to the note's title" }, reference_format: { name: "reference_format", description: "The date reference format." } } } } }, file: { name: "file", description: "This module contains every internal function related to files.", functions: { content: { name: "content", description: "Retrieves the file's content", definition: "tp.file.content" }, create_new: { name: "create_new", description: "Creates a new file using a specified template or with a specified content.", definition: "tp.file.create_new(template: TFile \u23AE string, filename?: string, open_new: boolean = false, folder?: TFolder)", args: { template: { name: "template", description: "Either the template used for the new file content, or the file content as a string." }, filename: { name: "filename", description: 'The filename of the new file, defaults to "Untitled".' }, open_new: { name: "open_new", description: "Whether to open or not the newly created file. Warning: if you use this option, since commands are executed asynchronously, the file can be opened first and then other commands are appended to that new file and not the previous file." }, folder: { name: "folder", description: "The folder to put the new file in, defaults to obsidian's default location." } } }, creation_date: { name: "creation_date", description: "Retrieves the file's creation date.", definition: 'tp.file.creation_date(format: string = "YYYY-MM-DD HH:mm")', args: { format: { name: "format", description: "Format for the date, refer to format reference" } } }, cursor: { name: "cursor", description: "Sets the cursor to this location after the template has been inserted. \n\nYou can navigate between the different tp.file.cursor using the configured hotkey in obsidian settings.\n", definition: "tp.file.cursor(order?: number)", args: { order: { name: "order", description: "The order of the different cursors jump, e.g. it will jump from 1 to 2 to 3, and so on.\nIf you specify multiple tp.file.cursor with the same order, the editor will switch to multi-cursor.\n" } } }, cursor_append: { name: "cursor_append", description: "Appends some content after the active cursor in the file.", definition: "tp.file.cursor_append(content: string)", args: { content: { name: "content", description: "The content to append after the active cursor" } } }, exists: { name: "exists", description: "Checks if a file exists or not. Returns a true / false boolean.", definition: "tp.file.exists(filename: string)", args: { filename: { name: "filename", description: "The filename of the file we want to check existence, e.g. MyFile." } } }, find_tfile: { name: "find_tfile", description: "Retrieves the file's folder name.", definition: "tp.file.folder(relative: boolean = false)", args: { relative: { name: "relative", description: "If set to true, appends the vault relative path to the folder name." } } }, include: { name: "include", description: "Includes the file's link content. Templates in the included content will be resolved.", definition: "tp.file.include(include_link: string \u23AE TFile)", args: { include_link: { name: "include_link", description: "The link to the file to include, e.g. [[MyFile]], or a TFile object. Also supports sections or blocks inclusions, e.g. [[MyFile#Section1]]" } } }, last_modified_date: { name: "last_modified_date", description: "Retrieves the file's last modification date.", definition: 'tp.file.last_modified_date(format: string = "YYYY-MM-DD HH:mm")', args: { format: { name: "format", description: "Format for the date, refer to format reference." } } }, move: { name: "functions.move", description: "Moves the file to the desired vault location.", definition: "tp.file.move(new_path: string)", args: { new_path: { name: "new_path", description: "The new vault relative path of the file, without the file extension. Note: the new path needs to include the folder and the filename, e.g. /Notes/MyNote" } } }, path: { name: "path", description: "Retrieves the file's absolute path on the system.", definition: "tp.file.path(relative: boolean = false)", args: { relative: { name: "relative", description: "If set to true, only retrieves the vault's relative path." } } }, rename: { name: "rename", description: "Renames the file (keeps the same file extension).", definition: "tp.file.rename(new_title: string)", args: { new_title: { name: "new_title", description: "The new file title." } } }, selection: { name: "selection", description: "Retrieves the active file's text selection.", definition: "tp.file.selection()" }, tags: { name: "tags", description: "Retrieves the file's tags (array of string)", definition: "tp.file.tags" }, title: { name: "title", definition: "tp.file.title", description: "Retrieves the file's title." } } }, frontmatter: { name: "frontmatter", description: "This modules exposes all the frontmatter variables of a file as variables." }, obsidian: { name: "obsidian", description: "This module exposes all the functions and classes from the obsidian API." }, system: { name: "system", description: "This module contains system related functions.", functions: { clipboard: { name: "clipboard", description: "Retrieves the clipboard's content", definition: "tp.system.clipboard()" }, prompt: { name: "prompt", description: "Spawns a prompt modal and returns the user's input.", definition: "tp.system.prompt(prompt_text?: string, default_value?: string, throw_on_cancel: boolean = false)", args: { prompt_text: { name: "prompt_text", description: "Text placed above the input field" }, default_value: { name: "default_value", description: "A default value for the input field" }, throw_on_cancel: { name: "throw_on_cancel", description: "Throws an error if the prompt is canceled, instead of returning a `null` value" } } }, suggester: { name: "suggester", description: "Spawns a suggester prompt and returns the user's chosen item.", definition: 'tp.system.suggester(text_items: string[] \u23AE ((item: T) => string), items: T[], throw_on_cancel: boolean = false, placeholder: string = "")', args: { text_items: { name: "text_items", description: "Array of strings representing the text that will be displayed for each item in the suggester prompt. This can also be a function that maps an item to its text representation." }, items: { name: "items", description: "Array containing the values of each item in the correct order." }, throw_on_cancel: { name: "throw_on_cancel", description: "Throws an error if the prompt is canceled, instead of returning a `null` value" }, placeholder: { name: "placeholder", description: "Placeholder string of the prompt" } } } } }, web: { name: "web", description: "This modules contains every internal function related to the web (making web requests).", functions: { daily_quote: { name: "daily_quote", description: "Retrieves and parses the daily quote from the API https://api.quotable.io", definition: "tp.web.daily_quote()" }, random_picture: { name: "random_picture", description: "Gets a random image from https://unsplash.com/", definition: "tp.web.random_picture(size?: string, query?: string)", args: { size: { name: "size", description: "Image size in the format `<width>x<height>`" }, query: { name: "query", description: "Limits selection to photos matching a search term. Multiple search terms can be passed separated by a comma `,`" } } } } } };
var documentation_default = { tp };

// src/editor/TpDocumentation.ts
var module_names = ["config", "date", "file", "frontmatter", "obsidian", "system", "user", "web"];
var module_names_checker = new Set(module_names);
function is_module_name(x) {
  return typeof x === "string" && module_names_checker.has(x);
}
function is_function_documentation(x) {
  if (x.definition) {
    return true;
  }
  return false;
}
var Documentation = class {
  constructor(app) {
    this.app = app;
    this.documentation = documentation_default;
  }
  get_all_modules_documentation() {
    return Object.values(this.documentation.tp);
  }
  get_all_functions_documentation(module_name) {
    if (!this.documentation.tp[module_name].functions) {
      return null;
    }
    return Object.values(this.documentation.tp[module_name].functions);
  }
  get_module_documentation(module_name) {
    return this.documentation.tp[module_name];
  }
  get_function_documentation(module_name, function_name) {
    return this.documentation.tp[module_name].functions[function_name];
  }
  get_argument_documentation(module_name, function_name, argument_name) {
    const function_doc = this.get_function_documentation(module_name, function_name);
    if (!function_doc || !function_doc.args) {
      return null;
    }
    return function_doc.args[argument_name];
  }
};

// src/editor/Autocomplete.ts
var Autocomplete = class extends import_obsidian17.EditorSuggest {
  constructor(app, plugin) {
    super(app);
    this.app = app;
    this.plugin = plugin;
    this.tp_keyword_regex = /tp\.(?<module>[a-z]*)?(?<fn_trigger>\.(?<fn>[a-z_]*)?)?$/;
    this.documentation = new Documentation(this.app);
  }
  onTrigger(cursor, editor, file) {
    const range = editor.getRange({ line: cursor.line, ch: 0 }, { line: cursor.line, ch: cursor.ch });
    const match = this.tp_keyword_regex.exec(range);
    if (!match) {
      return null;
    }
    let query;
    const module_name = match.groups["module"] || "";
    this.module_name = module_name;
    if (match.groups["fn_trigger"]) {
      if (module_name == "" || !is_module_name(module_name)) {
        return;
      }
      this.function_trigger = true;
      this.function_name = match.groups["fn"] || "";
      query = this.function_name;
    } else {
      this.function_trigger = false;
      query = this.module_name;
    }
    const trigger_info = {
      start: { line: cursor.line, ch: cursor.ch - query.length },
      end: { line: cursor.line, ch: cursor.ch },
      query
    };
    this.latest_trigger_info = trigger_info;
    return trigger_info;
  }
  getSuggestions(context) {
    let suggestions;
    if (this.module_name && this.function_trigger) {
      suggestions = this.documentation.get_all_functions_documentation(this.module_name);
    } else {
      suggestions = this.documentation.get_all_modules_documentation();
    }
    if (!suggestions) {
      return [];
    }
    return suggestions.filter((s) => s.name.startsWith(context.query));
  }
  renderSuggestion(value, el) {
    el.createEl("b", { text: value.name });
    el.createEl("br");
    if (this.function_trigger && is_function_documentation(value)) {
      el.createEl("code", { text: value.definition });
    }
    if (value.description) {
      el.createEl("div", { text: value.description });
    }
  }
  selectSuggestion(value, evt) {
    const active_view = this.app.workspace.getActiveViewOfType(import_obsidian17.MarkdownView);
    if (!active_view) {
      return;
    }
    active_view.editor.replaceRange(value.name, this.latest_trigger_info.start, this.latest_trigger_info.end);
    if (this.latest_trigger_info.start.ch == this.latest_trigger_info.end.ch) {
      const cursor_pos = this.latest_trigger_info.end;
      cursor_pos.ch += value.name.length;
      active_view.editor.setCursor(cursor_pos);
    }
  }
};

// src/editor/mode/javascript.js
(function(mod) {
  mod(window.CodeMirror);
})(function(CodeMirror) {
  "use strict";
  CodeMirror.defineMode("javascript", function(config2, parserConfig) {
    var indentUnit = config2.indentUnit;
    var statementIndent = parserConfig.statementIndent;
    var jsonldMode = parserConfig.jsonld;
    var jsonMode = parserConfig.json || jsonldMode;
    var trackScope = parserConfig.trackScope !== false;
    var isTS = parserConfig.typescript;
    var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
    var keywords = function() {
      function kw(type2) {
        return { type: type2, style: "keyword" };
      }
      var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d");
      var operator = kw("operator"), atom = { type: "atom", style: "atom" };
      return {
        if: kw("if"),
        while: A,
        with: A,
        else: B,
        do: B,
        try: B,
        finally: B,
        return: D,
        break: D,
        continue: D,
        new: kw("new"),
        delete: C,
        void: C,
        throw: C,
        debugger: kw("debugger"),
        var: kw("var"),
        const: kw("var"),
        let: kw("var"),
        function: kw("function"),
        catch: kw("catch"),
        for: kw("for"),
        switch: kw("switch"),
        case: kw("case"),
        default: kw("default"),
        in: operator,
        typeof: operator,
        instanceof: operator,
        true: atom,
        false: atom,
        null: atom,
        undefined: atom,
        NaN: atom,
        Infinity: atom,
        this: kw("this"),
        class: kw("class"),
        super: kw("atom"),
        yield: C,
        export: kw("export"),
        import: kw("import"),
        extends: C,
        await: C
      };
    }();
    var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
    var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
    function readRegexp(stream) {
      var escaped = false, next, inSet = false;
      while ((next = stream.next()) != null) {
        if (!escaped) {
          if (next == "/" && !inSet)
            return;
          if (next == "[")
            inSet = true;
          else if (inSet && next == "]")
            inSet = false;
        }
        escaped = !escaped && next == "\\";
      }
    }
    var type, content;
    function ret(tp2, style, cont2) {
      type = tp2;
      content = cont2;
      return style;
    }
    function tokenBase(stream, state) {
      var ch = stream.next();
      if (ch == '"' || ch == "'") {
        state.tokenize = tokenString(ch);
        return state.tokenize(stream, state);
      } else if (ch == "." && stream.match(/^\d[\d_]*(?:[eE][+\-]?[\d_]+)?/)) {
        return ret("number", "number");
      } else if (ch == "." && stream.match("..")) {
        return ret("spread", "meta");
      } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
        return ret(ch);
      } else if (ch == "=" && stream.eat(">")) {
        return ret("=>", "operator");
      } else if (ch == "0" && stream.match(/^(?:x[\dA-Fa-f_]+|o[0-7_]+|b[01_]+)n?/)) {
        return ret("number", "number");
      } else if (/\d/.test(ch)) {
        stream.match(/^[\d_]*(?:n|(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)?/);
        return ret("number", "number");
      } else if (ch == "/") {
        if (stream.eat("*")) {
          state.tokenize = tokenComment;
          return tokenComment(stream, state);
        } else if (stream.eat("/")) {
          stream.skipToEnd();
          return ret("comment", "comment");
        } else if (expressionAllowed(stream, state, 1)) {
          readRegexp(stream);
          stream.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/);
          return ret("regexp", "string-2");
        } else {
          stream.eat("=");
          return ret("operator", "operator", stream.current());
        }
      } else if (ch == "`") {
        state.tokenize = tokenQuasi;
        return tokenQuasi(stream, state);
      } else if (ch == "#" && stream.peek() == "!") {
        stream.skipToEnd();
        return ret("meta", "meta");
      } else if (ch == "#" && stream.eatWhile(wordRE)) {
        return ret("variable", "property");
      } else if (ch == "<" && stream.match("!--") || ch == "-" && stream.match("->") && !/\S/.test(stream.string.slice(0, stream.start))) {
        stream.skipToEnd();
        return ret("comment", "comment");
      } else if (isOperatorChar.test(ch)) {
        if (ch != ">" || !state.lexical || state.lexical.type != ">") {
          if (stream.eat("=")) {
            if (ch == "!" || ch == "=")
              stream.eat("=");
          } else if (/[<>*+\-|&?]/.test(ch)) {
            stream.eat(ch);
            if (ch == ">")
              stream.eat(ch);
          }
        }
        if (ch == "?" && stream.eat("."))
          return ret(".");
        return ret("operator", "operator", stream.current());
      } else if (wordRE.test(ch)) {
        stream.eatWhile(wordRE);
        var word = stream.current();
        if (state.lastType != ".") {
          if (keywords.propertyIsEnumerable(word)) {
            var kw = keywords[word];
            return ret(kw.type, kw.style, word);
          }
          if (word == "async" && stream.match(/^(\s|\/\*([^*]|\*(?!\/))*?\*\/)*[\[\(\w]/, false))
            return ret("async", "keyword", word);
        }
        return ret("variable", "variable", word);
      }
    }
    function tokenString(quote) {
      return function(stream, state) {
        var escaped = false, next;
        if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)) {
          state.tokenize = tokenBase;
          return ret("jsonld-keyword", "meta");
        }
        while ((next = stream.next()) != null) {
          if (next == quote && !escaped)
            break;
          escaped = !escaped && next == "\\";
        }
        if (!escaped)
          state.tokenize = tokenBase;
        return ret("string", "string");
      };
    }
    function tokenComment(stream, state) {
      var maybeEnd = false, ch;
      while (ch = stream.next()) {
        if (ch == "/" && maybeEnd) {
          state.tokenize = tokenBase;
          break;
        }
        maybeEnd = ch == "*";
      }
      return ret("comment", "comment");
    }
    function tokenQuasi(stream, state) {
      var escaped = false, next;
      while ((next = stream.next()) != null) {
        if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
          state.tokenize = tokenBase;
          break;
        }
        escaped = !escaped && next == "\\";
      }
      return ret("quasi", "string-2", stream.current());
    }
    var brackets = "([{}])";
    function findFatArrow(stream, state) {
      if (state.fatArrowAt)
        state.fatArrowAt = null;
      var arrow2 = stream.string.indexOf("=>", stream.start);
      if (arrow2 < 0)
        return;
      if (isTS) {
        var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(stream.string.slice(stream.start, arrow2));
        if (m)
          arrow2 = m.index;
      }
      var depth = 0, sawSomething = false;
      for (var pos = arrow2 - 1; pos >= 0; --pos) {
        var ch = stream.string.charAt(pos);
        var bracket = brackets.indexOf(ch);
        if (bracket >= 0 && bracket < 3) {
          if (!depth) {
            ++pos;
            break;
          }
          if (--depth == 0) {
            if (ch == "(")
              sawSomething = true;
            break;
          }
        } else if (bracket >= 3 && bracket < 6) {
          ++depth;
        } else if (wordRE.test(ch)) {
          sawSomething = true;
        } else if (/["'\/`]/.test(ch)) {
          for (; ; --pos) {
            if (pos == 0)
              return;
            var next = stream.string.charAt(pos - 1);
            if (next == ch && stream.string.charAt(pos - 2) != "\\") {
              pos--;
              break;
            }
          }
        } else if (sawSomething && !depth) {
          ++pos;
          break;
        }
      }
      if (sawSomething && !depth)
        state.fatArrowAt = pos;
    }
    var atomicTypes = {
      atom: true,
      number: true,
      variable: true,
      string: true,
      regexp: true,
      this: true,
      import: true,
      "jsonld-keyword": true
    };
    function JSLexical(indented, column, type2, align, prev, info) {
      this.indented = indented;
      this.column = column;
      this.type = type2;
      this.prev = prev;
      this.info = info;
      if (align != null)
        this.align = align;
    }
    function inScope(state, varname) {
      if (!trackScope)
        return false;
      for (var v = state.localVars; v; v = v.next)
        if (v.name == varname)
          return true;
      for (var cx2 = state.context; cx2; cx2 = cx2.prev) {
        for (var v = cx2.vars; v; v = v.next)
          if (v.name == varname)
            return true;
      }
    }
    function parseJS(state, style, type2, content2, stream) {
      var cc = state.cc;
      cx.state = state;
      cx.stream = stream;
      cx.marked = null, cx.cc = cc;
      cx.style = style;
      if (!state.lexical.hasOwnProperty("align"))
        state.lexical.align = true;
      while (true) {
        var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
        if (combinator(type2, content2)) {
          while (cc.length && cc[cc.length - 1].lex)
            cc.pop()();
          if (cx.marked)
            return cx.marked;
          if (type2 == "variable" && inScope(state, content2))
            return "variable-2";
          return style;
        }
      }
    }
    var cx = { state: null, column: null, marked: null, cc: null };
    function pass() {
      for (var i = arguments.length - 1; i >= 0; i--)
        cx.cc.push(arguments[i]);
    }
    function cont() {
      pass.apply(null, arguments);
      return true;
    }
    function inList(name, list) {
      for (var v = list; v; v = v.next)
        if (v.name == name)
          return true;
      return false;
    }
    function register(varname) {
      var state = cx.state;
      cx.marked = "def";
      if (!trackScope)
        return;
      if (state.context) {
        if (state.lexical.info == "var" && state.context && state.context.block) {
          var newContext = registerVarScoped(varname, state.context);
          if (newContext != null) {
            state.context = newContext;
            return;
          }
        } else if (!inList(varname, state.localVars)) {
          state.localVars = new Var(varname, state.localVars);
          return;
        }
      }
      if (parserConfig.globalVars && !inList(varname, state.globalVars))
        state.globalVars = new Var(varname, state.globalVars);
    }
    function registerVarScoped(varname, context) {
      if (!context) {
        return null;
      } else if (context.block) {
        var inner = registerVarScoped(varname, context.prev);
        if (!inner)
          return null;
        if (inner == context.prev)
          return context;
        return new Context(inner, context.vars, true);
      } else if (inList(varname, context.vars)) {
        return context;
      } else {
        return new Context(context.prev, new Var(varname, context.vars), false);
      }
    }
    function isModifier(name) {
      return name == "public" || name == "private" || name == "protected" || name == "abstract" || name == "readonly";
    }
    function Context(prev, vars, block2) {
      this.prev = prev;
      this.vars = vars;
      this.block = block2;
    }
    function Var(name, next) {
      this.name = name;
      this.next = next;
    }
    var defaultVars = new Var("this", new Var("arguments", null));
    function pushcontext() {
      cx.state.context = new Context(cx.state.context, cx.state.localVars, false);
      cx.state.localVars = defaultVars;
    }
    function pushblockcontext() {
      cx.state.context = new Context(cx.state.context, cx.state.localVars, true);
      cx.state.localVars = null;
    }
    function popcontext() {
      cx.state.localVars = cx.state.context.vars;
      cx.state.context = cx.state.context.prev;
    }
    popcontext.lex = true;
    function pushlex(type2, info) {
      var result = function() {
        var state = cx.state, indent = state.indented;
        if (state.lexical.type == "stat")
          indent = state.lexical.indented;
        else
          for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
            indent = outer.indented;
        state.lexical = new JSLexical(indent, cx.stream.column(), type2, null, state.lexical, info);
      };
      result.lex = true;
      return result;
    }
    function poplex() {
      var state = cx.state;
      if (state.lexical.prev) {
        if (state.lexical.type == ")")
          state.indented = state.lexical.indented;
        state.lexical = state.lexical.prev;
      }
    }
    poplex.lex = true;
    function expect(wanted) {
      function exp(type2) {
        if (type2 == wanted)
          return cont();
        else if (wanted == ";" || type2 == "}" || type2 == ")" || type2 == "]")
          return pass();
        else
          return cont(exp);
      }
      return exp;
    }
    function statement(type2, value) {
      if (type2 == "var")
        return cont(pushlex("vardef", value), vardef, expect(";"), poplex);
      if (type2 == "keyword a")
        return cont(pushlex("form"), parenExpr, statement, poplex);
      if (type2 == "keyword b")
        return cont(pushlex("form"), statement, poplex);
      if (type2 == "keyword d")
        return cx.stream.match(/^\s*$/, false) ? cont() : cont(pushlex("stat"), maybeexpression, expect(";"), poplex);
      if (type2 == "debugger")
        return cont(expect(";"));
      if (type2 == "{")
        return cont(pushlex("}"), pushblockcontext, block, poplex, popcontext);
      if (type2 == ";")
        return cont();
      if (type2 == "if") {
        if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
          cx.state.cc.pop()();
        return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
      }
      if (type2 == "function")
        return cont(functiondef);
      if (type2 == "for")
        return cont(pushlex("form"), pushblockcontext, forspec, statement, popcontext, poplex);
      if (type2 == "class" || isTS && value == "interface") {
        cx.marked = "keyword";
        return cont(pushlex("form", type2 == "class" ? type2 : value), className, poplex);
      }
      if (type2 == "variable") {
        if (isTS && value == "declare") {
          cx.marked = "keyword";
          return cont(statement);
        } else if (isTS && (value == "module" || value == "enum" || value == "type") && cx.stream.match(/^\s*\w/, false)) {
          cx.marked = "keyword";
          if (value == "enum")
            return cont(enumdef);
          else if (value == "type")
            return cont(typename, expect("operator"), typeexpr, expect(";"));
          else
            return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex);
        } else if (isTS && value == "namespace") {
          cx.marked = "keyword";
          return cont(pushlex("form"), expression, statement, poplex);
        } else if (isTS && value == "abstract") {
          cx.marked = "keyword";
          return cont(statement);
        } else {
          return cont(pushlex("stat"), maybelabel);
        }
      }
      if (type2 == "switch")
        return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"), pushblockcontext, block, poplex, poplex, popcontext);
      if (type2 == "case")
        return cont(expression, expect(":"));
      if (type2 == "default")
        return cont(expect(":"));
      if (type2 == "catch")
        return cont(pushlex("form"), pushcontext, maybeCatchBinding, statement, poplex, popcontext);
      if (type2 == "export")
        return cont(pushlex("stat"), afterExport, poplex);
      if (type2 == "import")
        return cont(pushlex("stat"), afterImport, poplex);
      if (type2 == "async")
        return cont(statement);
      if (value == "@")
        return cont(expression, statement);
      return pass(pushlex("stat"), expression, expect(";"), poplex);
    }
    function maybeCatchBinding(type2) {
      if (type2 == "(")
        return cont(funarg, expect(")"));
    }
    function expression(type2, value) {
      return expressionInner(type2, value, false);
    }
    function expressionNoComma(type2, value) {
      return expressionInner(type2, value, true);
    }
    function parenExpr(type2) {
      if (type2 != "(")
        return pass();
      return cont(pushlex(")"), maybeexpression, expect(")"), poplex);
    }
    function expressionInner(type2, value, noComma) {
      if (cx.state.fatArrowAt == cx.stream.start) {
        var body = noComma ? arrowBodyNoComma : arrowBody;
        if (type2 == "(")
          return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext);
        else if (type2 == "variable")
          return pass(pushcontext, pattern, expect("=>"), body, popcontext);
      }
      var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
      if (atomicTypes.hasOwnProperty(type2))
        return cont(maybeop);
      if (type2 == "function")
        return cont(functiondef, maybeop);
      if (type2 == "class" || isTS && value == "interface") {
        cx.marked = "keyword";
        return cont(pushlex("form"), classExpression, poplex);
      }
      if (type2 == "keyword c" || type2 == "async")
        return cont(noComma ? expressionNoComma : expression);
      if (type2 == "(")
        return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
      if (type2 == "operator" || type2 == "spread")
        return cont(noComma ? expressionNoComma : expression);
      if (type2 == "[")
        return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
      if (type2 == "{")
        return contCommasep(objprop, "}", null, maybeop);
      if (type2 == "quasi")
        return pass(quasi, maybeop);
      if (type2 == "new")
        return cont(maybeTarget(noComma));
      return cont();
    }
    function maybeexpression(type2) {
      if (type2.match(/[;\}\)\],]/))
        return pass();
      return pass(expression);
    }
    function maybeoperatorComma(type2, value) {
      if (type2 == ",")
        return cont(maybeexpression);
      return maybeoperatorNoComma(type2, value, false);
    }
    function maybeoperatorNoComma(type2, value, noComma) {
      var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
      var expr = noComma == false ? expression : expressionNoComma;
      if (type2 == "=>")
        return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
      if (type2 == "operator") {
        if (/\+\+|--/.test(value) || isTS && value == "!")
          return cont(me);
        if (isTS && value == "<" && cx.stream.match(/^([^<>]|<[^<>]*>)*>\s*\(/, false))
          return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, me);
        if (value == "?")
          return cont(expression, expect(":"), expr);
        return cont(expr);
      }
      if (type2 == "quasi") {
        return pass(quasi, me);
      }
      if (type2 == ";")
        return;
      if (type2 == "(")
        return contCommasep(expressionNoComma, ")", "call", me);
      if (type2 == ".")
        return cont(property, me);
      if (type2 == "[")
        return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
      if (isTS && value == "as") {
        cx.marked = "keyword";
        return cont(typeexpr, me);
      }
      if (type2 == "regexp") {
        cx.state.lastType = cx.marked = "operator";
        cx.stream.backUp(cx.stream.pos - cx.stream.start - 1);
        return cont(expr);
      }
    }
    function quasi(type2, value) {
      if (type2 != "quasi")
        return pass();
      if (value.slice(value.length - 2) != "${")
        return cont(quasi);
      return cont(maybeexpression, continueQuasi);
    }
    function continueQuasi(type2) {
      if (type2 == "}") {
        cx.marked = "string-2";
        cx.state.tokenize = tokenQuasi;
        return cont(quasi);
      }
    }
    function arrowBody(type2) {
      findFatArrow(cx.stream, cx.state);
      return pass(type2 == "{" ? statement : expression);
    }
    function arrowBodyNoComma(type2) {
      findFatArrow(cx.stream, cx.state);
      return pass(type2 == "{" ? statement : expressionNoComma);
    }
    function maybeTarget(noComma) {
      return function(type2) {
        if (type2 == ".")
          return cont(noComma ? targetNoComma : target);
        else if (type2 == "variable" && isTS)
          return cont(maybeTypeArgs, noComma ? maybeoperatorNoComma : maybeoperatorComma);
        else
          return pass(noComma ? expressionNoComma : expression);
      };
    }
    function target(_, value) {
      if (value == "target") {
        cx.marked = "keyword";
        return cont(maybeoperatorComma);
      }
    }
    function targetNoComma(_, value) {
      if (value == "target") {
        cx.marked = "keyword";
        return cont(maybeoperatorNoComma);
      }
    }
    function maybelabel(type2) {
      if (type2 == ":")
        return cont(poplex, statement);
      return pass(maybeoperatorComma, expect(";"), poplex);
    }
    function property(type2) {
      if (type2 == "variable") {
        cx.marked = "property";
        return cont();
      }
    }
    function objprop(type2, value) {
      if (type2 == "async") {
        cx.marked = "property";
        return cont(objprop);
      } else if (type2 == "variable" || cx.style == "keyword") {
        cx.marked = "property";
        if (value == "get" || value == "set")
          return cont(getterSetter);
        var m;
        if (isTS && cx.state.fatArrowAt == cx.stream.start && (m = cx.stream.match(/^\s*:\s*/, false)))
          cx.state.fatArrowAt = cx.stream.pos + m[0].length;
        return cont(afterprop);
      } else if (type2 == "number" || type2 == "string") {
        cx.marked = jsonldMode ? "property" : cx.style + " property";
        return cont(afterprop);
      } else if (type2 == "jsonld-keyword") {
        return cont(afterprop);
      } else if (isTS && isModifier(value)) {
        cx.marked = "keyword";
        return cont(objprop);
      } else if (type2 == "[") {
        return cont(expression, maybetype, expect("]"), afterprop);
      } else if (type2 == "spread") {
        return cont(expressionNoComma, afterprop);
      } else if (value == "*") {
        cx.marked = "keyword";
        return cont(objprop);
      } else if (type2 == ":") {
        return pass(afterprop);
      }
    }
    function getterSetter(type2) {
      if (type2 != "variable")
        return pass(afterprop);
      cx.marked = "property";
      return cont(functiondef);
    }
    function afterprop(type2) {
      if (type2 == ":")
        return cont(expressionNoComma);
      if (type2 == "(")
        return pass(functiondef);
    }
    function commasep(what, end2, sep) {
      function proceed(type2, value) {
        if (sep ? sep.indexOf(type2) > -1 : type2 == ",") {
          var lex = cx.state.lexical;
          if (lex.info == "call")
            lex.pos = (lex.pos || 0) + 1;
          return cont(function(type3, value2) {
            if (type3 == end2 || value2 == end2)
              return pass();
            return pass(what);
          }, proceed);
        }
        if (type2 == end2 || value == end2)
          return cont();
        if (sep && sep.indexOf(";") > -1)
          return pass(what);
        return cont(expect(end2));
      }
      return function(type2, value) {
        if (type2 == end2 || value == end2)
          return cont();
        return pass(what, proceed);
      };
    }
    function contCommasep(what, end2, info) {
      for (var i = 3; i < arguments.length; i++)
        cx.cc.push(arguments[i]);
      return cont(pushlex(end2, info), commasep(what, end2), poplex);
    }
    function block(type2) {
      if (type2 == "}")
        return cont();
      return pass(statement, block);
    }
    function maybetype(type2, value) {
      if (isTS) {
        if (type2 == ":")
          return cont(typeexpr);
        if (value == "?")
          return cont(maybetype);
      }
    }
    function maybetypeOrIn(type2, value) {
      if (isTS && (type2 == ":" || value == "in"))
        return cont(typeexpr);
    }
    function mayberettype(type2) {
      if (isTS && type2 == ":") {
        if (cx.stream.match(/^\s*\w+\s+is\b/, false))
          return cont(expression, isKW, typeexpr);
        else
          return cont(typeexpr);
      }
    }
    function isKW(_, value) {
      if (value == "is") {
        cx.marked = "keyword";
        return cont();
      }
    }
    function typeexpr(type2, value) {
      if (value == "keyof" || value == "typeof" || value == "infer" || value == "readonly") {
        cx.marked = "keyword";
        return cont(value == "typeof" ? expressionNoComma : typeexpr);
      }
      if (type2 == "variable" || value == "void") {
        cx.marked = "type";
        return cont(afterType);
      }
      if (value == "|" || value == "&")
        return cont(typeexpr);
      if (type2 == "string" || type2 == "number" || type2 == "atom")
        return cont(afterType);
      if (type2 == "[")
        return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType);
      if (type2 == "{")
        return cont(pushlex("}"), typeprops, poplex, afterType);
      if (type2 == "(")
        return cont(commasep(typearg, ")"), maybeReturnType, afterType);
      if (type2 == "<")
        return cont(commasep(typeexpr, ">"), typeexpr);
      if (type2 == "quasi") {
        return pass(quasiType, afterType);
      }
    }
    function maybeReturnType(type2) {
      if (type2 == "=>")
        return cont(typeexpr);
    }
    function typeprops(type2) {
      if (type2.match(/[\}\)\]]/))
        return cont();
      if (type2 == "," || type2 == ";")
        return cont(typeprops);
      return pass(typeprop, typeprops);
    }
    function typeprop(type2, value) {
      if (type2 == "variable" || cx.style == "keyword") {
        cx.marked = "property";
        return cont(typeprop);
      } else if (value == "?" || type2 == "number" || type2 == "string") {
        return cont(typeprop);
      } else if (type2 == ":") {
        return cont(typeexpr);
      } else if (type2 == "[") {
        return cont(expect("variable"), maybetypeOrIn, expect("]"), typeprop);
      } else if (type2 == "(") {
        return pass(functiondecl, typeprop);
      } else if (!type2.match(/[;\}\)\],]/)) {
        return cont();
      }
    }
    function quasiType(type2, value) {
      if (type2 != "quasi")
        return pass();
      if (value.slice(value.length - 2) != "${")
        return cont(quasiType);
      return cont(typeexpr, continueQuasiType);
    }
    function continueQuasiType(type2) {
      if (type2 == "}") {
        cx.marked = "string-2";
        cx.state.tokenize = tokenQuasi;
        return cont(quasiType);
      }
    }
    function typearg(type2, value) {
      if (type2 == "variable" && cx.stream.match(/^\s*[?:]/, false) || value == "?")
        return cont(typearg);
      if (type2 == ":")
        return cont(typeexpr);
      if (type2 == "spread")
        return cont(typearg);
      return pass(typeexpr);
    }
    function afterType(type2, value) {
      if (value == "<")
        return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType);
      if (value == "|" || type2 == "." || value == "&")
        return cont(typeexpr);
      if (type2 == "[")
        return cont(typeexpr, expect("]"), afterType);
      if (value == "extends" || value == "implements") {
        cx.marked = "keyword";
        return cont(typeexpr);
      }
      if (value == "?")
        return cont(typeexpr, expect(":"), typeexpr);
    }
    function maybeTypeArgs(_, value) {
      if (value == "<")
        return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType);
    }
    function typeparam() {
      return pass(typeexpr, maybeTypeDefault);
    }
    function maybeTypeDefault(_, value) {
      if (value == "=")
        return cont(typeexpr);
    }
    function vardef(_, value) {
      if (value == "enum") {
        cx.marked = "keyword";
        return cont(enumdef);
      }
      return pass(pattern, maybetype, maybeAssign, vardefCont);
    }
    function pattern(type2, value) {
      if (isTS && isModifier(value)) {
        cx.marked = "keyword";
        return cont(pattern);
      }
      if (type2 == "variable") {
        register(value);
        return cont();
      }
      if (type2 == "spread")
        return cont(pattern);
      if (type2 == "[")
        return contCommasep(eltpattern, "]");
      if (type2 == "{")
        return contCommasep(proppattern, "}");
    }
    function proppattern(type2, value) {
      if (type2 == "variable" && !cx.stream.match(/^\s*:/, false)) {
        register(value);
        return cont(maybeAssign);
      }
      if (type2 == "variable")
        cx.marked = "property";
      if (type2 == "spread")
        return cont(pattern);
      if (type2 == "}")
        return pass();
      if (type2 == "[")
        return cont(expression, expect("]"), expect(":"), proppattern);
      return cont(expect(":"), pattern, maybeAssign);
    }
    function eltpattern() {
      return pass(pattern, maybeAssign);
    }
    function maybeAssign(_type, value) {
      if (value == "=")
        return cont(expressionNoComma);
    }
    function vardefCont(type2) {
      if (type2 == ",")
        return cont(vardef);
    }
    function maybeelse(type2, value) {
      if (type2 == "keyword b" && value == "else")
        return cont(pushlex("form", "else"), statement, poplex);
    }
    function forspec(type2, value) {
      if (value == "await")
        return cont(forspec);
      if (type2 == "(")
        return cont(pushlex(")"), forspec1, poplex);
    }
    function forspec1(type2) {
      if (type2 == "var")
        return cont(vardef, forspec2);
      if (type2 == "variable")
        return cont(forspec2);
      return pass(forspec2);
    }
    function forspec2(type2, value) {
      if (type2 == ")")
        return cont();
      if (type2 == ";")
        return cont(forspec2);
      if (value == "in" || value == "of") {
        cx.marked = "keyword";
        return cont(expression, forspec2);
      }
      return pass(expression, forspec2);
    }
    function functiondef(type2, value) {
      if (value == "*") {
        cx.marked = "keyword";
        return cont(functiondef);
      }
      if (type2 == "variable") {
        register(value);
        return cont(functiondef);
      }
      if (type2 == "(")
        return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, statement, popcontext);
      if (isTS && value == "<")
        return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondef);
    }
    function functiondecl(type2, value) {
      if (value == "*") {
        cx.marked = "keyword";
        return cont(functiondecl);
      }
      if (type2 == "variable") {
        register(value);
        return cont(functiondecl);
      }
      if (type2 == "(")
        return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, popcontext);
      if (isTS && value == "<")
        return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondecl);
    }
    function typename(type2, value) {
      if (type2 == "keyword" || type2 == "variable") {
        cx.marked = "type";
        return cont(typename);
      } else if (value == "<") {
        return cont(pushlex(">"), commasep(typeparam, ">"), poplex);
      }
    }
    function funarg(type2, value) {
      if (value == "@")
        cont(expression, funarg);
      if (type2 == "spread")
        return cont(funarg);
      if (isTS && isModifier(value)) {
        cx.marked = "keyword";
        return cont(funarg);
      }
      if (isTS && type2 == "this")
        return cont(maybetype, maybeAssign);
      return pass(pattern, maybetype, maybeAssign);
    }
    function classExpression(type2, value) {
      if (type2 == "variable")
        return className(type2, value);
      return classNameAfter(type2, value);
    }
    function className(type2, value) {
      if (type2 == "variable") {
        register(value);
        return cont(classNameAfter);
      }
    }
    function classNameAfter(type2, value) {
      if (value == "<")
        return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter);
      if (value == "extends" || value == "implements" || isTS && type2 == ",") {
        if (value == "implements")
          cx.marked = "keyword";
        return cont(isTS ? typeexpr : expression, classNameAfter);
      }
      if (type2 == "{")
        return cont(pushlex("}"), classBody, poplex);
    }
    function classBody(type2, value) {
      if (type2 == "async" || type2 == "variable" && (value == "static" || value == "get" || value == "set" || isTS && isModifier(value)) && cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false)) {
        cx.marked = "keyword";
        return cont(classBody);
      }
      if (type2 == "variable" || cx.style == "keyword") {
        cx.marked = "property";
        return cont(classfield, classBody);
      }
      if (type2 == "number" || type2 == "string")
        return cont(classfield, classBody);
      if (type2 == "[")
        return cont(expression, maybetype, expect("]"), classfield, classBody);
      if (value == "*") {
        cx.marked = "keyword";
        return cont(classBody);
      }
      if (isTS && type2 == "(")
        return pass(functiondecl, classBody);
      if (type2 == ";" || type2 == ",")
        return cont(classBody);
      if (type2 == "}")
        return cont();
      if (value == "@")
        return cont(expression, classBody);
    }
    function classfield(type2, value) {
      if (value == "!")
        return cont(classfield);
      if (value == "?")
        return cont(classfield);
      if (type2 == ":")
        return cont(typeexpr, maybeAssign);
      if (value == "=")
        return cont(expressionNoComma);
      var context = cx.state.lexical.prev, isInterface = context && context.info == "interface";
      return pass(isInterface ? functiondecl : functiondef);
    }
    function afterExport(type2, value) {
      if (value == "*") {
        cx.marked = "keyword";
        return cont(maybeFrom, expect(";"));
      }
      if (value == "default") {
        cx.marked = "keyword";
        return cont(expression, expect(";"));
      }
      if (type2 == "{")
        return cont(commasep(exportField, "}"), maybeFrom, expect(";"));
      return pass(statement);
    }
    function exportField(type2, value) {
      if (value == "as") {
        cx.marked = "keyword";
        return cont(expect("variable"));
      }
      if (type2 == "variable")
        return pass(expressionNoComma, exportField);
    }
    function afterImport(type2) {
      if (type2 == "string")
        return cont();
      if (type2 == "(")
        return pass(expression);
      if (type2 == ".")
        return pass(maybeoperatorComma);
      return pass(importSpec, maybeMoreImports, maybeFrom);
    }
    function importSpec(type2, value) {
      if (type2 == "{")
        return contCommasep(importSpec, "}");
      if (type2 == "variable")
        register(value);
      if (value == "*")
        cx.marked = "keyword";
      return cont(maybeAs);
    }
    function maybeMoreImports(type2) {
      if (type2 == ",")
        return cont(importSpec, maybeMoreImports);
    }
    function maybeAs(_type, value) {
      if (value == "as") {
        cx.marked = "keyword";
        return cont(importSpec);
      }
    }
    function maybeFrom(_type, value) {
      if (value == "from") {
        cx.marked = "keyword";
        return cont(expression);
      }
    }
    function arrayLiteral(type2) {
      if (type2 == "]")
        return cont();
      return pass(commasep(expressionNoComma, "]"));
    }
    function enumdef() {
      return pass(pushlex("form"), pattern, expect("{"), pushlex("}"), commasep(enummember, "}"), poplex, poplex);
    }
    function enummember() {
      return pass(pattern, maybeAssign);
    }
    function isContinuedStatement(state, textAfter) {
      return state.lastType == "operator" || state.lastType == "," || isOperatorChar.test(textAfter.charAt(0)) || /[,.]/.test(textAfter.charAt(0));
    }
    function expressionAllowed(stream, state, backUp) {
      return state.tokenize == tokenBase && /^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(state.lastType) || state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0)));
    }
    return {
      startState: function(basecolumn) {
        var state = {
          tokenize: tokenBase,
          lastType: "sof",
          cc: [],
          lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
          localVars: parserConfig.localVars,
          context: parserConfig.localVars && new Context(null, null, false),
          indented: basecolumn || 0
        };
        if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
          state.globalVars = parserConfig.globalVars;
        return state;
      },
      token: function(stream, state) {
        if (stream.sol()) {
          if (!state.lexical.hasOwnProperty("align"))
            state.lexical.align = false;
          state.indented = stream.indentation();
          findFatArrow(stream, state);
        }
        if (state.tokenize != tokenComment && stream.eatSpace())
          return null;
        var style = state.tokenize(stream, state);
        if (type == "comment")
          return style;
        state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
        return parseJS(state, style, type, content, stream);
      },
      indent: function(state, textAfter) {
        if (state.tokenize == tokenComment || state.tokenize == tokenQuasi)
          return CodeMirror.Pass;
        if (state.tokenize != tokenBase)
          return 0;
        var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top2;
        if (!/^\s*else\b/.test(textAfter))
          for (var i = state.cc.length - 1; i >= 0; --i) {
            var c = state.cc[i];
            if (c == poplex)
              lexical = lexical.prev;
            else if (c != maybeelse && c != popcontext)
              break;
          }
        while ((lexical.type == "stat" || lexical.type == "form") && (firstChar == "}" || (top2 = state.cc[state.cc.length - 1]) && (top2 == maybeoperatorComma || top2 == maybeoperatorNoComma) && !/^[,\.=+\-*:?[\(]/.test(textAfter)))
          lexical = lexical.prev;
        if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
          lexical = lexical.prev;
        var type2 = lexical.type, closing = firstChar == type2;
        if (type2 == "vardef")
          return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info.length + 1 : 0);
        else if (type2 == "form" && firstChar == "{")
          return lexical.indented;
        else if (type2 == "form")
          return lexical.indented + indentUnit;
        else if (type2 == "stat")
          return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
        else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
          return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
        else if (lexical.align)
          return lexical.column + (closing ? 0 : 1);
        else
          return lexical.indented + (closing ? 0 : indentUnit);
      },
      electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
      blockCommentStart: jsonMode ? null : "/*",
      blockCommentEnd: jsonMode ? null : "*/",
      blockCommentContinue: jsonMode ? null : " * ",
      lineComment: jsonMode ? null : "//",
      fold: "brace",
      closeBrackets: "()[]{}''\"\"``",
      helperType: jsonMode ? "json" : "javascript",
      jsonldMode,
      jsonMode,
      expressionAllowed,
      skipExpression: function(state) {
        parseJS(state, "atom", "atom", "true", new CodeMirror.StringStream("", 2, null));
      }
    };
  });
  CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
  CodeMirror.defineMIME("text/javascript", "javascript");
  CodeMirror.defineMIME("text/ecmascript", "javascript");
  CodeMirror.defineMIME("application/javascript", "javascript");
  CodeMirror.defineMIME("application/x-javascript", "javascript");
  CodeMirror.defineMIME("application/ecmascript", "javascript");
  CodeMirror.defineMIME("application/json", {
    name: "javascript",
    json: true
  });
  CodeMirror.defineMIME("application/x-json", {
    name: "javascript",
    json: true
  });
  CodeMirror.defineMIME("application/manifest+json", {
    name: "javascript",
    json: true
  });
  CodeMirror.defineMIME("application/ld+json", {
    name: "javascript",
    jsonld: true
  });
  CodeMirror.defineMIME("text/typescript", {
    name: "javascript",
    typescript: true
  });
  CodeMirror.defineMIME("application/typescript", {
    name: "javascript",
    typescript: true
  });
});

// src/editor/mode/custom_overlay.js
(function(mod) {
  mod(window.CodeMirror);
})(function(CodeMirror) {
  "use strict";
  CodeMirror.customOverlayMode = function(base, overlay, combine) {
    return {
      startState: function() {
        return {
          base: CodeMirror.startState(base),
          overlay: CodeMirror.startState(overlay),
          basePos: 0,
          baseCur: null,
          overlayPos: 0,
          overlayCur: null,
          streamSeen: null
        };
      },
      copyState: function(state) {
        return {
          base: CodeMirror.copyState(base, state.base),
          overlay: CodeMirror.copyState(overlay, state.overlay),
          basePos: state.basePos,
          baseCur: null,
          overlayPos: state.overlayPos,
          overlayCur: null
        };
      },
      token: function(stream, state) {
        if (stream != state.streamSeen || Math.min(state.basePos, state.overlayPos) < stream.start) {
          state.streamSeen = stream;
          state.basePos = state.overlayPos = stream.start;
        }
        if (stream.start == state.basePos) {
          state.baseCur = base.token(stream, state.base);
          state.basePos = stream.pos;
        }
        if (stream.start == state.overlayPos) {
          stream.pos = stream.start;
          state.overlayCur = overlay.token(stream, state.overlay);
          state.overlayPos = stream.pos;
        }
        stream.pos = Math.min(state.basePos, state.overlayPos);
        if (state.baseCur && state.overlayCur && state.baseCur.contains("line-HyperMD-codeblock")) {
          state.overlayCur = state.overlayCur.replace("line-templater-inline", "");
          state.overlayCur += ` line-background-HyperMD-codeblock-bg`;
        }
        if (state.overlayCur == null)
          return state.baseCur;
        else if (state.baseCur != null && state.overlay.combineTokens || combine && state.overlay.combineTokens == null)
          return state.baseCur + " " + state.overlayCur;
        else
          return state.overlayCur;
      },
      indent: base.indent && function(state, textAfter, line) {
        return base.indent(state.base, textAfter, line);
      },
      electricChars: base.electricChars,
      innerMode: function(state) {
        return { state: state.base, mode: base };
      },
      blankLine: function(state) {
        var baseToken, overlayToken;
        if (base.blankLine)
          baseToken = base.blankLine(state.base);
        if (overlay.blankLine)
          overlayToken = overlay.blankLine(state.overlay);
        return overlayToken == null ? baseToken : combine && baseToken != null ? baseToken + " " + overlayToken : overlayToken;
      }
    };
  };
});

// src/editor/Editor.ts
var TP_CMD_TOKEN_CLASS = "templater-command";
var TP_INLINE_CLASS = "templater-inline";
var TP_OPENING_TAG_TOKEN_CLASS = "templater-opening-tag";
var TP_CLOSING_TAG_TOKEN_CLASS = "templater-closing-tag";
var TP_INTERPOLATION_TAG_TOKEN_CLASS = "templater-interpolation-tag";
var TP_RAW_TAG_TOKEN_CLASS = "templater-raw-tag";
var TP_EXEC_TAG_TOKEN_CLASS = "templater-execution-tag";
var Editor2 = class {
  constructor(app, plugin) {
    this.app = app;
    this.plugin = plugin;
    this.cursor_jumper = new CursorJumper(this.app);
  }
  setup() {
    return __async(this, null, function* () {
      yield this.registerCodeMirrorMode();
      this.plugin.registerEditorSuggest(new Autocomplete(this.app, this.plugin));
    });
  }
  jump_to_next_cursor_location(file = null, auto_jump = false) {
    return __async(this, null, function* () {
      if (auto_jump && !this.plugin.settings.auto_jump_to_cursor) {
        return;
      }
      if (file && this.app.workspace.getActiveFile() !== file) {
        return;
      }
      this.cursor_jumper.jump_to_next_cursor_location();
    });
  }
  registerCodeMirrorMode() {
    return __async(this, null, function* () {
      if (!this.plugin.settings.syntax_highlighting) {
        return;
      }
      if (import_obsidian18.Platform.isMobileApp) {
        return;
      }
      const js_mode = window.CodeMirror.getMode({}, "javascript");
      if (js_mode.name === "null") {
        log_error(new TemplaterError("Javascript syntax mode couldn't be found, can't enable syntax highlighting."));
        return;
      }
      const overlay_mode = window.CodeMirror.customOverlayMode;
      if (overlay_mode == null) {
        log_error(new TemplaterError("Couldn't find customOverlayMode, can't enable syntax highlighting."));
        return;
      }
      window.CodeMirror.defineMode("templater", function(config2) {
        const templaterOverlay = {
          startState: function() {
            const js_state = window.CodeMirror.startState(js_mode);
            return __spreadProps(__spreadValues({}, js_state), {
              inCommand: false,
              tag_class: "",
              freeLine: false
            });
          },
          copyState: function(state) {
            const js_state = window.CodeMirror.startState(js_mode);
            const new_state = __spreadProps(__spreadValues({}, js_state), {
              inCommand: state.inCommand,
              tag_class: state.tag_class,
              freeLine: state.freeLine
            });
            return new_state;
          },
          blankLine: function(state) {
            if (state.inCommand) {
              return `line-background-templater-command-bg`;
            }
            return null;
          },
          token: function(stream, state) {
            if (stream.sol() && state.inCommand) {
              state.freeLine = true;
            }
            if (state.inCommand) {
              let keywords = "";
              if (stream.match(/[-_]{0,1}%>/, true)) {
                state.inCommand = false;
                state.freeLine = false;
                const tag_class = state.tag_class;
                state.tag_class = "";
                return `line-${TP_INLINE_CLASS} ${TP_CMD_TOKEN_CLASS} ${TP_CLOSING_TAG_TOKEN_CLASS} ${tag_class}`;
              }
              const js_result = js_mode.token(stream, state);
              if (stream.peek() == null && state.freeLine) {
                keywords += ` line-background-templater-command-bg`;
              }
              if (!state.freeLine) {
                keywords += ` line-${TP_INLINE_CLASS}`;
              }
              return `${keywords} ${TP_CMD_TOKEN_CLASS} ${js_result}`;
            }
            const match = stream.match(/<%[-_]{0,1}\s*([*~+]{0,1})/, true);
            if (match != null) {
              switch (match[1]) {
                case "*":
                  state.tag_class = TP_EXEC_TAG_TOKEN_CLASS;
                  break;
                case "~":
                  state.tag_class = TP_RAW_TAG_TOKEN_CLASS;
                  break;
                default:
                  state.tag_class = TP_INTERPOLATION_TAG_TOKEN_CLASS;
                  break;
              }
              state.inCommand = true;
              return `line-${TP_INLINE_CLASS} ${TP_CMD_TOKEN_CLASS} ${TP_OPENING_TAG_TOKEN_CLASS} ${state.tag_class}`;
            }
            while (stream.next() != null && !stream.match(/<%/, false))
              ;
            return null;
          }
        };
        return overlay_mode(window.CodeMirror.getMode(config2, "hypermd"), templaterOverlay);
      });
    });
  }
};

// src/main.ts
var TemplaterPlugin = class extends import_obsidian19.Plugin {
  onload() {
    return __async(this, null, function* () {
      yield this.load_settings();
      this.templater = new Templater(this.app, this);
      yield this.templater.setup();
      this.editor_handler = new Editor2(this.app, this);
      yield this.editor_handler.setup();
      this.fuzzy_suggester = new FuzzySuggester(this.app, this);
      this.event_handler = new EventHandler(this.app, this, this.templater, this.settings);
      this.event_handler.setup();
      this.command_handler = new CommandHandler(this.app, this);
      this.command_handler.setup();
      (0, import_obsidian19.addIcon)("templater-icon", ICON_DATA);
      this.addRibbonIcon("templater-icon", "Templater", () => __async(this, null, function* () {
        this.fuzzy_suggester.insert_template();
      }));
      this.addSettingTab(new TemplaterSettingTab(this.app, this));
      this.app.workspace.onLayoutReady(() => {
        this.templater.execute_startup_scripts();
      });
    });
  }
  save_settings() {
    return __async(this, null, function* () {
      yield this.saveData(this.settings);
    });
  }
  load_settings() {
    return __async(this, null, function* () {
      this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
    });
  }
};
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
