var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// node_modules/merge/lib/src/index.js
var require_src = __commonJS({
  "node_modules/merge/lib/src/index.js"(exports2, module2) {
    "use strict";
    Object.defineProperty(exports2, "__esModule", { value: true });
    exports2.isPlainObject = exports2.clone = exports2.recursive = exports2.merge = exports2.main = void 0;
    module2.exports = exports2 = main;
    exports2.default = main;
    function main() {
      var items = [];
      for (var _i = 0; _i < arguments.length; _i++) {
        items[_i] = arguments[_i];
      }
      return merge2.apply(void 0, items);
    }
    exports2.main = main;
    main.clone = clone;
    main.isPlainObject = isPlainObject;
    main.recursive = recursive;
    function merge2() {
      var items = [];
      for (var _i = 0; _i < arguments.length; _i++) {
        items[_i] = arguments[_i];
      }
      return _merge(items[0] === true, false, items);
    }
    exports2.merge = merge2;
    function recursive() {
      var items = [];
      for (var _i = 0; _i < arguments.length; _i++) {
        items[_i] = arguments[_i];
      }
      return _merge(items[0] === true, true, items);
    }
    exports2.recursive = recursive;
    function clone(input) {
      if (Array.isArray(input)) {
        var output = [];
        for (var index = 0; index < input.length; ++index)
          output.push(clone(input[index]));
        return output;
      } else if (isPlainObject(input)) {
        var output = {};
        for (var index in input)
          output[index] = clone(input[index]);
        return output;
      } else {
        return input;
      }
    }
    exports2.clone = clone;
    function isPlainObject(input) {
      return input && typeof input === "object" && !Array.isArray(input);
    }
    exports2.isPlainObject = isPlainObject;
    function _recursiveMerge(base, extend) {
      if (!isPlainObject(base))
        return extend;
      for (var key in extend) {
        if (key === "__proto__" || key === "constructor" || key === "prototype")
          continue;
        base[key] = isPlainObject(base[key]) && isPlainObject(extend[key]) ? _recursiveMerge(base[key], extend[key]) : extend[key];
      }
      return base;
    }
    function _merge(isClone, isRecursive, items) {
      var result;
      if (isClone || !isPlainObject(result = items.shift()))
        result = {};
      for (var index = 0; index < items.length; ++index) {
        var item = items[index];
        if (!isPlainObject(item))
          continue;
        for (var key in item) {
          if (key === "__proto__" || key === "constructor" || key === "prototype")
            continue;
          var value = isClone ? clone(item[key]) : item[key];
          result[key] = isRecursive ? _recursiveMerge(result[key], value) : value;
        }
      }
      return result;
    }
  }
});

// node_modules/minimatch/lib/path.js
var require_path = __commonJS({
  "node_modules/minimatch/lib/path.js"(exports2, module2) {
    var isWindows = typeof process === "object" && process && process.platform === "win32";
    module2.exports = isWindows ? { sep: "\\" } : { sep: "/" };
  }
});

// node_modules/balanced-match/index.js
var require_balanced_match = __commonJS({
  "node_modules/balanced-match/index.js"(exports2, module2) {
    "use strict";
    module2.exports = balanced;
    function balanced(a, b, str) {
      if (a instanceof RegExp) a = maybeMatch(a, str);
      if (b instanceof RegExp) b = maybeMatch(b, str);
      var r = range(a, b, str);
      return r && {
        start: r[0],
        end: r[1],
        pre: str.slice(0, r[0]),
        body: str.slice(r[0] + a.length, r[1]),
        post: str.slice(r[1] + b.length)
      };
    }
    function maybeMatch(reg, str) {
      var m = str.match(reg);
      return m ? m[0] : null;
    }
    balanced.range = range;
    function range(a, b, str) {
      var begs, beg, left, right, result;
      var ai = str.indexOf(a);
      var bi = str.indexOf(b, ai + 1);
      var i = ai;
      if (ai >= 0 && bi > 0) {
        if (a === b) {
          return [ai, bi];
        }
        begs = [];
        left = str.length;
        while (i >= 0 && !result) {
          if (i == ai) {
            begs.push(i);
            ai = str.indexOf(a, i + 1);
          } else if (begs.length == 1) {
            result = [begs.pop(), bi];
          } else {
            beg = begs.pop();
            if (beg < left) {
              left = beg;
              right = bi;
            }
            bi = str.indexOf(b, i + 1);
          }
          i = ai < bi && ai >= 0 ? ai : bi;
        }
        if (begs.length) {
          result = [left, right];
        }
      }
      return result;
    }
  }
});

// node_modules/brace-expansion/index.js
var require_brace_expansion = __commonJS({
  "node_modules/brace-expansion/index.js"(exports2, module2) {
    var balanced = require_balanced_match();
    module2.exports = expandTop;
    var escSlash = "\0SLASH" + Math.random() + "\0";
    var escOpen = "\0OPEN" + Math.random() + "\0";
    var escClose = "\0CLOSE" + Math.random() + "\0";
    var escComma = "\0COMMA" + Math.random() + "\0";
    var escPeriod = "\0PERIOD" + Math.random() + "\0";
    function numeric(str) {
      return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0);
    }
    function escapeBraces(str) {
      return str.split("\\\\").join(escSlash).split("\\{").join(escOpen).split("\\}").join(escClose).split("\\,").join(escComma).split("\\.").join(escPeriod);
    }
    function unescapeBraces(str) {
      return str.split(escSlash).join("\\").split(escOpen).join("{").split(escClose).join("}").split(escComma).join(",").split(escPeriod).join(".");
    }
    function parseCommaParts(str) {
      if (!str)
        return [""];
      var parts = [];
      var m = balanced("{", "}", str);
      if (!m)
        return str.split(",");
      var pre = m.pre;
      var body = m.body;
      var post = m.post;
      var p = pre.split(",");
      p[p.length - 1] += "{" + body + "}";
      var postParts = parseCommaParts(post);
      if (post.length) {
        p[p.length - 1] += postParts.shift();
        p.push.apply(p, postParts);
      }
      parts.push.apply(parts, p);
      return parts;
    }
    function expandTop(str) {
      if (!str)
        return [];
      if (str.substr(0, 2) === "{}") {
        str = "\\{\\}" + str.substr(2);
      }
      return expand(escapeBraces(str), true).map(unescapeBraces);
    }
    function embrace(str) {
      return "{" + str + "}";
    }
    function isPadded(el) {
      return /^-?0\d/.test(el);
    }
    function lte(i, y) {
      return i <= y;
    }
    function gte(i, y) {
      return i >= y;
    }
    function expand(str, isTop) {
      var expansions = [];
      var m = balanced("{", "}", str);
      if (!m) return [str];
      var pre = m.pre;
      var post = m.post.length ? expand(m.post, false) : [""];
      if (/\$$/.test(m.pre)) {
        for (var k = 0; k < post.length; k++) {
          var expansion = pre + "{" + m.body + "}" + post[k];
          expansions.push(expansion);
        }
      } else {
        var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
        var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
        var isSequence = isNumericSequence || isAlphaSequence;
        var isOptions = m.body.indexOf(",") >= 0;
        if (!isSequence && !isOptions) {
          if (m.post.match(/,.*\}/)) {
            str = m.pre + "{" + m.body + escClose + m.post;
            return expand(str);
          }
          return [str];
        }
        var n;
        if (isSequence) {
          n = m.body.split(/\.\./);
        } else {
          n = parseCommaParts(m.body);
          if (n.length === 1) {
            n = expand(n[0], false).map(embrace);
            if (n.length === 1) {
              return post.map(function(p) {
                return m.pre + n[0] + p;
              });
            }
          }
        }
        var N;
        if (isSequence) {
          var x = numeric(n[0]);
          var y = numeric(n[1]);
          var width = Math.max(n[0].length, n[1].length);
          var incr = n.length == 3 ? Math.abs(numeric(n[2])) : 1;
          var test = lte;
          var reverse = y < x;
          if (reverse) {
            incr *= -1;
            test = gte;
          }
          var pad = n.some(isPadded);
          N = [];
          for (var i = x; test(i, y); i += incr) {
            var c;
            if (isAlphaSequence) {
              c = String.fromCharCode(i);
              if (c === "\\")
                c = "";
            } else {
              c = String(i);
              if (pad) {
                var need = width - c.length;
                if (need > 0) {
                  var z = new Array(need + 1).join("0");
                  if (i < 0)
                    c = "-" + z + c.slice(1);
                  else
                    c = z + c;
                }
              }
            }
            N.push(c);
          }
        } else {
          N = [];
          for (var j = 0; j < n.length; j++) {
            N.push.apply(N, expand(n[j], false));
          }
        }
        for (var j = 0; j < N.length; j++) {
          for (var k = 0; k < post.length; k++) {
            var expansion = pre + N[j] + post[k];
            if (!isTop || isSequence || expansion)
              expansions.push(expansion);
          }
        }
      }
      return expansions;
    }
  }
});

// node_modules/minimatch/minimatch.js
var require_minimatch = __commonJS({
  "node_modules/minimatch/minimatch.js"(exports2, module2) {
    var minimatch2 = module2.exports = (p, pattern, options = {}) => {
      assertValidPattern(pattern);
      if (!options.nocomment && pattern.charAt(0) === "#") {
        return false;
      }
      return new Minimatch(pattern, options).match(p);
    };
    module2.exports = minimatch2;
    var path7 = require_path();
    minimatch2.sep = path7.sep;
    var GLOBSTAR = Symbol("globstar **");
    minimatch2.GLOBSTAR = GLOBSTAR;
    var expand = require_brace_expansion();
    var plTypes = {
      "!": { open: "(?:(?!(?:", close: "))[^/]*?)" },
      "?": { open: "(?:", close: ")?" },
      "+": { open: "(?:", close: ")+" },
      "*": { open: "(?:", close: ")*" },
      "@": { open: "(?:", close: ")" }
    };
    var qmark = "[^/]";
    var star = qmark + "*?";
    var twoStarDot = "(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?";
    var twoStarNoDot = "(?:(?!(?:\\/|^)\\.).)*?";
    var charSet = (s) => s.split("").reduce((set, c) => {
      set[c] = true;
      return set;
    }, {});
    var reSpecials = charSet("().*{}+?[]^$\\!");
    var addPatternStartSet = charSet("[.(");
    var slashSplit = /\/+/;
    minimatch2.filter = (pattern, options = {}) => (p, i, list) => minimatch2(p, pattern, options);
    var ext = (a, b = {}) => {
      const t = {};
      Object.keys(a).forEach((k) => t[k] = a[k]);
      Object.keys(b).forEach((k) => t[k] = b[k]);
      return t;
    };
    minimatch2.defaults = (def) => {
      if (!def || typeof def !== "object" || !Object.keys(def).length) {
        return minimatch2;
      }
      const orig = minimatch2;
      const m = (p, pattern, options) => orig(p, pattern, ext(def, options));
      m.Minimatch = class Minimatch extends orig.Minimatch {
        constructor(pattern, options) {
          super(pattern, ext(def, options));
        }
      };
      m.Minimatch.defaults = (options) => orig.defaults(ext(def, options)).Minimatch;
      m.filter = (pattern, options) => orig.filter(pattern, ext(def, options));
      m.defaults = (options) => orig.defaults(ext(def, options));
      m.makeRe = (pattern, options) => orig.makeRe(pattern, ext(def, options));
      m.braceExpand = (pattern, options) => orig.braceExpand(pattern, ext(def, options));
      m.match = (list, pattern, options) => orig.match(list, pattern, ext(def, options));
      return m;
    };
    minimatch2.braceExpand = (pattern, options) => braceExpand(pattern, options);
    var braceExpand = (pattern, options = {}) => {
      assertValidPattern(pattern);
      if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
        return [pattern];
      }
      return expand(pattern);
    };
    var MAX_PATTERN_LENGTH = 1024 * 64;
    var assertValidPattern = (pattern) => {
      if (typeof pattern !== "string") {
        throw new TypeError("invalid pattern");
      }
      if (pattern.length > MAX_PATTERN_LENGTH) {
        throw new TypeError("pattern is too long");
      }
    };
    var SUBPARSE = Symbol("subparse");
    minimatch2.makeRe = (pattern, options) => new Minimatch(pattern, options || {}).makeRe();
    minimatch2.match = (list, pattern, options = {}) => {
      const mm = new Minimatch(pattern, options);
      list = list.filter((f) => mm.match(f));
      if (mm.options.nonull && !list.length) {
        list.push(pattern);
      }
      return list;
    };
    var globUnescape = (s) => s.replace(/\\(.)/g, "$1");
    var charUnescape = (s) => s.replace(/\\([^-\]])/g, "$1");
    var regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
    var braExpEscape = (s) => s.replace(/[[\]\\]/g, "\\$&");
    var Minimatch = class {
      constructor(pattern, options) {
        assertValidPattern(pattern);
        if (!options) options = {};
        this.options = options;
        this.set = [];
        this.pattern = pattern;
        this.windowsPathsNoEscape = !!options.windowsPathsNoEscape || options.allowWindowsEscape === false;
        if (this.windowsPathsNoEscape) {
          this.pattern = this.pattern.replace(/\\/g, "/");
        }
        this.regexp = null;
        this.negate = false;
        this.comment = false;
        this.empty = false;
        this.partial = !!options.partial;
        this.make();
      }
      debug() {
      }
      make() {
        const pattern = this.pattern;
        const options = this.options;
        if (!options.nocomment && pattern.charAt(0) === "#") {
          this.comment = true;
          return;
        }
        if (!pattern) {
          this.empty = true;
          return;
        }
        this.parseNegate();
        let set = this.globSet = this.braceExpand();
        if (options.debug) this.debug = (...args) => console.error(...args);
        this.debug(this.pattern, set);
        set = this.globParts = set.map((s) => s.split(slashSplit));
        this.debug(this.pattern, set);
        set = set.map((s, si, set2) => s.map(this.parse, this));
        this.debug(this.pattern, set);
        set = set.filter((s) => s.indexOf(false) === -1);
        this.debug(this.pattern, set);
        this.set = set;
      }
      parseNegate() {
        if (this.options.nonegate) return;
        const pattern = this.pattern;
        let negate = false;
        let negateOffset = 0;
        for (let i = 0; i < pattern.length && pattern.charAt(i) === "!"; i++) {
          negate = !negate;
          negateOffset++;
        }
        if (negateOffset) this.pattern = pattern.slice(negateOffset);
        this.negate = negate;
      }
      // set partial to true to test if, for example,
      // "/a/b" matches the start of "/*/b/*/d"
      // Partial means, if you run out of file before you run
      // out of pattern, then that's fine, as long as all
      // the parts match.
      matchOne(file, pattern, partial) {
        var options = this.options;
        this.debug(
          "matchOne",
          { "this": this, file, pattern }
        );
        this.debug("matchOne", file.length, pattern.length);
        for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
          this.debug("matchOne loop");
          var p = pattern[pi];
          var f = file[fi];
          this.debug(pattern, p, f);
          if (p === false) return false;
          if (p === GLOBSTAR) {
            this.debug("GLOBSTAR", [pattern, p, f]);
            var fr = fi;
            var pr = pi + 1;
            if (pr === pl) {
              this.debug("** at the end");
              for (; fi < fl; fi++) {
                if (file[fi] === "." || file[fi] === ".." || !options.dot && file[fi].charAt(0) === ".") return false;
              }
              return true;
            }
            while (fr < fl) {
              var swallowee = file[fr];
              this.debug("\nglobstar while", file, fr, pattern, pr, swallowee);
              if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
                this.debug("globstar found match!", fr, fl, swallowee);
                return true;
              } else {
                if (swallowee === "." || swallowee === ".." || !options.dot && swallowee.charAt(0) === ".") {
                  this.debug("dot detected!", file, fr, pattern, pr);
                  break;
                }
                this.debug("globstar swallow a segment, and continue");
                fr++;
              }
            }
            if (partial) {
              this.debug("\n>>> no match, partial?", file, fr, pattern, pr);
              if (fr === fl) return true;
            }
            return false;
          }
          var hit;
          if (typeof p === "string") {
            hit = f === p;
            this.debug("string match", p, f, hit);
          } else {
            hit = f.match(p);
            this.debug("pattern match", p, f, hit);
          }
          if (!hit) return false;
        }
        if (fi === fl && pi === pl) {
          return true;
        } else if (fi === fl) {
          return partial;
        } else if (pi === pl) {
          return fi === fl - 1 && file[fi] === "";
        }
        throw new Error("wtf?");
      }
      braceExpand() {
        return braceExpand(this.pattern, this.options);
      }
      parse(pattern, isSub) {
        assertValidPattern(pattern);
        const options = this.options;
        if (pattern === "**") {
          if (!options.noglobstar)
            return GLOBSTAR;
          else
            pattern = "*";
        }
        if (pattern === "") return "";
        let re = "";
        let hasMagic = false;
        let escaping = false;
        const patternListStack = [];
        const negativeLists = [];
        let stateChar;
        let inClass = false;
        let reClassStart = -1;
        let classStart = -1;
        let cs;
        let pl;
        let sp;
        let dotTravAllowed = pattern.charAt(0) === ".";
        let dotFileAllowed = options.dot || dotTravAllowed;
        const patternStart = () => dotTravAllowed ? "" : dotFileAllowed ? "(?!(?:^|\\/)\\.{1,2}(?:$|\\/))" : "(?!\\.)";
        const subPatternStart = (p) => p.charAt(0) === "." ? "" : options.dot ? "(?!(?:^|\\/)\\.{1,2}(?:$|\\/))" : "(?!\\.)";
        const clearStateChar = () => {
          if (stateChar) {
            switch (stateChar) {
              case "*":
                re += star;
                hasMagic = true;
                break;
              case "?":
                re += qmark;
                hasMagic = true;
                break;
              default:
                re += "\\" + stateChar;
                break;
            }
            this.debug("clearStateChar %j %j", stateChar, re);
            stateChar = false;
          }
        };
        for (let i = 0, c; i < pattern.length && (c = pattern.charAt(i)); i++) {
          this.debug("%s	%s %s %j", pattern, i, re, c);
          if (escaping) {
            if (c === "/") {
              return false;
            }
            if (reSpecials[c]) {
              re += "\\";
            }
            re += c;
            escaping = false;
            continue;
          }
          switch (c) {
            /* istanbul ignore next */
            case "/": {
              return false;
            }
            case "\\":
              if (inClass && pattern.charAt(i + 1) === "-") {
                re += c;
                continue;
              }
              clearStateChar();
              escaping = true;
              continue;
            // the various stateChar values
            // for the "extglob" stuff.
            case "?":
            case "*":
            case "+":
            case "@":
            case "!":
              this.debug("%s	%s %s %j <-- stateChar", pattern, i, re, c);
              if (inClass) {
                this.debug("  in class");
                if (c === "!" && i === classStart + 1) c = "^";
                re += c;
                continue;
              }
              this.debug("call clearStateChar %j", stateChar);
              clearStateChar();
              stateChar = c;
              if (options.noext) clearStateChar();
              continue;
            case "(": {
              if (inClass) {
                re += "(";
                continue;
              }
              if (!stateChar) {
                re += "\\(";
                continue;
              }
              const plEntry = {
                type: stateChar,
                start: i - 1,
                reStart: re.length,
                open: plTypes[stateChar].open,
                close: plTypes[stateChar].close
              };
              this.debug(this.pattern, "	", plEntry);
              patternListStack.push(plEntry);
              re += plEntry.open;
              if (plEntry.start === 0 && plEntry.type !== "!") {
                dotTravAllowed = true;
                re += subPatternStart(pattern.slice(i + 1));
              }
              this.debug("plType %j %j", stateChar, re);
              stateChar = false;
              continue;
            }
            case ")": {
              const plEntry = patternListStack[patternListStack.length - 1];
              if (inClass || !plEntry) {
                re += "\\)";
                continue;
              }
              patternListStack.pop();
              clearStateChar();
              hasMagic = true;
              pl = plEntry;
              re += pl.close;
              if (pl.type === "!") {
                negativeLists.push(Object.assign(pl, { reEnd: re.length }));
              }
              continue;
            }
            case "|": {
              const plEntry = patternListStack[patternListStack.length - 1];
              if (inClass || !plEntry) {
                re += "\\|";
                continue;
              }
              clearStateChar();
              re += "|";
              if (plEntry.start === 0 && plEntry.type !== "!") {
                dotTravAllowed = true;
                re += subPatternStart(pattern.slice(i + 1));
              }
              continue;
            }
            // these are mostly the same in regexp and glob
            case "[":
              clearStateChar();
              if (inClass) {
                re += "\\" + c;
                continue;
              }
              inClass = true;
              classStart = i;
              reClassStart = re.length;
              re += c;
              continue;
            case "]":
              if (i === classStart + 1 || !inClass) {
                re += "\\" + c;
                continue;
              }
              cs = pattern.substring(classStart + 1, i);
              try {
                RegExp("[" + braExpEscape(charUnescape(cs)) + "]");
                re += c;
              } catch (er) {
                re = re.substring(0, reClassStart) + "(?:$.)";
              }
              hasMagic = true;
              inClass = false;
              continue;
            default:
              clearStateChar();
              if (reSpecials[c] && !(c === "^" && inClass)) {
                re += "\\";
              }
              re += c;
              break;
          }
        }
        if (inClass) {
          cs = pattern.slice(classStart + 1);
          sp = this.parse(cs, SUBPARSE);
          re = re.substring(0, reClassStart) + "\\[" + sp[0];
          hasMagic = hasMagic || sp[1];
        }
        for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {
          let tail;
          tail = re.slice(pl.reStart + pl.open.length);
          this.debug("setting tail", re, pl);
          tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, (_, $1, $2) => {
            if (!$2) {
              $2 = "\\";
            }
            return $1 + $1 + $2 + "|";
          });
          this.debug("tail=%j\n   %s", tail, tail, pl, re);
          const t = pl.type === "*" ? star : pl.type === "?" ? qmark : "\\" + pl.type;
          hasMagic = true;
          re = re.slice(0, pl.reStart) + t + "\\(" + tail;
        }
        clearStateChar();
        if (escaping) {
          re += "\\\\";
        }
        const addPatternStart = addPatternStartSet[re.charAt(0)];
        for (let n = negativeLists.length - 1; n > -1; n--) {
          const nl = negativeLists[n];
          const nlBefore = re.slice(0, nl.reStart);
          const nlFirst = re.slice(nl.reStart, nl.reEnd - 8);
          let nlAfter = re.slice(nl.reEnd);
          const nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + nlAfter;
          const closeParensBefore = nlBefore.split(")").length;
          const openParensBefore = nlBefore.split("(").length - closeParensBefore;
          let cleanAfter = nlAfter;
          for (let i = 0; i < openParensBefore; i++) {
            cleanAfter = cleanAfter.replace(/\)[+*?]?/, "");
          }
          nlAfter = cleanAfter;
          const dollar = nlAfter === "" && isSub !== SUBPARSE ? "(?:$|\\/)" : "";
          re = nlBefore + nlFirst + nlAfter + dollar + nlLast;
        }
        if (re !== "" && hasMagic) {
          re = "(?=.)" + re;
        }
        if (addPatternStart) {
          re = patternStart() + re;
        }
        if (isSub === SUBPARSE) {
          return [re, hasMagic];
        }
        if (options.nocase && !hasMagic) {
          hasMagic = pattern.toUpperCase() !== pattern.toLowerCase();
        }
        if (!hasMagic) {
          return globUnescape(pattern);
        }
        const flags = options.nocase ? "i" : "";
        try {
          return Object.assign(new RegExp("^" + re + "$", flags), {
            _glob: pattern,
            _src: re
          });
        } catch (er) {
          return new RegExp("$.");
        }
      }
      makeRe() {
        if (this.regexp || this.regexp === false) return this.regexp;
        const set = this.set;
        if (!set.length) {
          this.regexp = false;
          return this.regexp;
        }
        const options = this.options;
        const twoStar = options.noglobstar ? star : options.dot ? twoStarDot : twoStarNoDot;
        const flags = options.nocase ? "i" : "";
        let re = set.map((pattern) => {
          pattern = pattern.map(
            (p) => typeof p === "string" ? regExpEscape(p) : p === GLOBSTAR ? GLOBSTAR : p._src
          ).reduce((set2, p) => {
            if (!(set2[set2.length - 1] === GLOBSTAR && p === GLOBSTAR)) {
              set2.push(p);
            }
            return set2;
          }, []);
          pattern.forEach((p, i) => {
            if (p !== GLOBSTAR || pattern[i - 1] === GLOBSTAR) {
              return;
            }
            if (i === 0) {
              if (pattern.length > 1) {
                pattern[i + 1] = "(?:\\/|" + twoStar + "\\/)?" + pattern[i + 1];
              } else {
                pattern[i] = twoStar;
              }
            } else if (i === pattern.length - 1) {
              pattern[i - 1] += "(?:\\/|" + twoStar + ")?";
            } else {
              pattern[i - 1] += "(?:\\/|\\/" + twoStar + "\\/)" + pattern[i + 1];
              pattern[i + 1] = GLOBSTAR;
            }
          });
          return pattern.filter((p) => p !== GLOBSTAR).join("/");
        }).join("|");
        re = "^(?:" + re + ")$";
        if (this.negate) re = "^(?!" + re + ").*$";
        try {
          this.regexp = new RegExp(re, flags);
        } catch (ex) {
          this.regexp = false;
        }
        return this.regexp;
      }
      match(f, partial = this.partial) {
        this.debug("match", f, this.pattern);
        if (this.comment) return false;
        if (this.empty) return f === "";
        if (f === "/" && partial) return true;
        const options = this.options;
        if (path7.sep !== "/") {
          f = f.split(path7.sep).join("/");
        }
        f = f.split(slashSplit);
        this.debug(this.pattern, "split", f);
        const set = this.set;
        this.debug(this.pattern, "set", set);
        let filename;
        for (let i = f.length - 1; i >= 0; i--) {
          filename = f[i];
          if (filename) break;
        }
        for (let i = 0; i < set.length; i++) {
          const pattern = set[i];
          let file = f;
          if (options.matchBase && pattern.length === 1) {
            file = [filename];
          }
          const hit = this.matchOne(file, pattern, partial);
          if (hit) {
            if (options.flipNegate) return true;
            return !this.negate;
          }
        }
        if (options.flipNegate) return false;
        return this.negate;
      }
      static defaults(def) {
        return minimatch2.defaults(def).Minimatch;
      }
    };
    minimatch2.Minimatch = Minimatch;
  }
});

// src/index.ts
var index_exports = {};
__export(index_exports, {
  activate: () => activate
});
module.exports = __toCommonJS(index_exports);
var import_coc9 = require("coc.nvim");
var import_merge = __toESM(require_src());
var import_path6 = __toESM(require("path"));

// src/languages.ts
var import_coc2 = require("coc.nvim");

// src/util.ts
var import_coc = require("coc.nvim");
var import_crypto = __toESM(require("crypto"));
var import_fs = __toESM(require("fs"));
var import_os = __toESM(require("os"));
var import_path = __toESM(require("path"));
var import_util = require("util");
var pythonCodes = /* @__PURE__ */ new Map();
var caseInsensitive = import_os.default.platform() == "win32" || import_os.default.platform() == "darwin";
var additionalFiletypes = /* @__PURE__ */ new Map();
var lastSnippet = void 0;
function setLastSnippet(filepath, lnum) {
  lastSnippet = { filepath, lnum };
}
function getLastSnippet() {
  return lastSnippet;
}
async function insertSnippetEdit(edit) {
  var _a;
  let ultisnips = edit.source == "ultisnips" || edit.source == "snipmate";
  let option;
  if (ultisnips) {
    let formatOptions = (_a = edit.formatOptions) != null ? _a : {};
    option = {
      regex: edit.regex,
      actions: edit.actions,
      context: edit.context,
      noExpand: formatOptions.noExpand,
      trimTrailingWhitespace: formatOptions.trimTrailingWhitespace,
      removeWhiteSpace: formatOptions.removeWhiteSpace
    };
  }
  setLastSnippet(edit.location, edit.lnum);
  await import_coc.commands.executeCommand("editor.action.insertSnippet", import_coc.TextEdit.replace(edit.range, edit.newText), option);
}
function addFiletypes(bufnr, filetypes) {
  var _a;
  let curr = (_a = additionalFiletypes.get(bufnr)) != null ? _a : [];
  filetypes.forEach((filetype) => {
    if (filetype && !curr.includes(filetype)) curr.push(filetype);
  });
  additionalFiletypes.set(bufnr, curr);
}
function getAdditionalFiletype(bufnr) {
  var _a;
  return (_a = additionalFiletypes.get(bufnr)) != null ? _a : [];
}
function getAllAdditionalFiletype() {
  let filetypes = [];
  import_coc.workspace.documents.forEach((doc) => {
    let arr = getAdditionalFiletype(doc.bufnr);
    if (arr.length) filetypes.push(...arr);
  });
  return filetypes;
}
function getSnippetFiletype(doc) {
  let filetypes = getAdditionalFiletype(doc.bufnr);
  return [doc.filetype, ...filetypes].join(".");
}
function createMD5(input) {
  return import_crypto.default.createHash("md5").update(input).digest("hex");
}
var documentation = `# A valid snippet should starts with:
#
#		snippet trigger_word [ "description" [ options ] ]
#
# and end with:
#
#		endsnippet
#
# Snippet options:
#
#		b - Beginning of line.
#		i - In-word expansion.
#		w - Word boundary.
#		r - Regular expression
#		e - Custom context snippet
#		A - Snippet will be triggered automatically, when condition matches.
#
# Basic example:
#
#		snippet emitter "emitter properties" b
#		private readonly \${1} = new Emitter<$2>()
#		public readonly \${1/^_(.*)/$1/}: Event<$2> = this.$1.event
#		endsnippet
#
# Online reference: https://github.com/SirVer/ultisnips/blob/master/doc/UltiSnips.txt
`;
async function statAsync(filepath) {
  try {
    return await (0, import_util.promisify)(import_fs.default.stat)(filepath);
  } catch (e) {
    return null;
  }
}
async function readdirAsync(filepath) {
  try {
    return await (0, import_util.promisify)(import_fs.default.readdir)(filepath);
  } catch (e) {
    return null;
  }
}
function headTail(line) {
  line = line.trim();
  let ms = line.match(/^(\S+)\s+(.*)/);
  if (!ms) return [line, ""];
  return [ms[1], ms[2]];
}
function trimQuote(str) {
  if (/^(["']).*\1$/.test(str)) return str.slice(1, -1);
  return str;
}
function distinct(array, keyFn) {
  if (!keyFn) {
    return array.filter((element, position) => {
      return array.indexOf(element) === position;
    });
  }
  const seen = /* @__PURE__ */ Object.create(null);
  return array.filter((elem) => {
    const key = keyFn(elem);
    if (seen[key]) {
      return false;
    }
    seen[key] = true;
    return true;
  });
}
var stringStartRe = /\\A/;
var conditionRe = /\(\?\(\w+\).+\|/;
var commentRe = /\(\?#.*?\)/;
var namedCaptureRe = /\(\?P<\w+>.*?\)/;
var namedReferenceRe = /\(\?P=(\w+)\)/;
var regex = new RegExp(`${commentRe.source}|${stringStartRe.source}|${namedCaptureRe.source}|${namedReferenceRe.source}`, "g");
function convertRegex(str) {
  if (str.indexOf("\\z") !== -1) {
    throw new Error("pattern \\z not supported");
  }
  if (str.indexOf("(?s)") !== -1) {
    throw new Error("pattern (?s) not supported");
  }
  if (str.indexOf("(?x)") !== -1) {
    throw new Error("pattern (?x) not supported");
  }
  if (str.indexOf("\n") !== -1) {
    throw new Error("multiple line pattern not supported");
  }
  if (conditionRe.test(str)) {
    throw new Error("(?id/name)yes-pattern|no-pattern not supported");
  }
  return str.replace(regex, (match, p1) => {
    if (match.startsWith("(?#")) return "";
    if (match == "\\A") return "^";
    if (match.startsWith("(?P<")) return "(?" + match.slice(3);
    if (match.startsWith("(?P=")) return `\\k<${p1}>`;
    return "";
  });
}
function getRegexText(prefix) {
  if (prefix.startsWith("^")) prefix = prefix.slice(1);
  if (prefix.endsWith("$")) prefix = prefix.slice(0, -1);
  let content = prefix.replace(/\((\w+)\)\?/g, "$1").replace(/\(.*\)\??/g, "");
  content = content.replace(/\\/g, "");
  return content;
}
function getTriggerText(text, regex2) {
  if (!text || /\w/.test(text[0]) || text.length <= 2) return text != null ? text : "";
  if (text[0] == text[text.length - 1] && (regex2 || text.includes(" ") || text[0] == "/")) return text.slice(1, -1);
  return text;
}
function markdownBlock(code, filetype) {
  filetype = filetype == "javascriptreact" ? "javascript" : filetype;
  filetype = filetype == "typescriptreact" ? "typescript" : filetype;
  return "``` " + filetype + "\n" + code + "\n```";
}
async function waitDocument(doc, changedtick) {
  if (doc.changedtick >= changedtick) return Promise.resolve(doc.changedtick === changedtick);
  return new Promise((resolve) => {
    let timeout = setTimeout(() => {
      disposable.dispose();
      resolve(doc.changedtick == changedtick);
    }, 200);
    let disposable = doc.onDocumentChange(() => {
      clearTimeout(timeout);
      disposable.dispose();
      resolve(doc.changedtick == changedtick);
    });
  });
}
function sameFile(fullpath, other) {
  if (!fullpath || !other) return false;
  if (caseInsensitive) return fullpath.toLowerCase() === other.toLowerCase();
  return fullpath === other;
}
function characterIndex(content, byteIndex) {
  let buf = Buffer.from(content, "utf8");
  return buf.slice(0, byteIndex).toString("utf8").length;
}
function languageIdFromComments(lines) {
  for (let i = 0; i < Math.min(5, lines.length); i++) {
    let ms = lines[i].match(/^\s*\/\/\sPlace\syour\s(\w+)\sworkspace/);
    if (ms) return ms[1];
  }
  return void 0;
}
function omit(obj, properties) {
  let o = {};
  for (let key of Object.keys(obj)) {
    if (!properties.includes(key)) {
      o[key] = obj[key];
    }
  }
  return o;
}
function normalizeFilePath(filepath) {
  return import_coc.Uri.file(import_path.default.resolve(import_path.default.normalize(filepath))).fsPath;
}
function filetypeFromBasename(basename) {
  if (basename == "typescript_react") return "typescriptreact";
  if (basename == "javascript_react") return "javascriptreact";
  if (basename.includes("_")) return basename.split("_", 2)[0];
  return basename.split("-", 2)[0];
}

// src/languages.ts
var codesMap = /* @__PURE__ */ new Map();
codesMap.set(1, "invalid snippet line, trigger required.");
codesMap.set(2, 'invalid snippet option, option "$1" not supported.');
codesMap.set(3, "invalid python expression, $1");
codesMap.set(4, "invalid code interpolation, #! not supported.");
var validOptions = ["b", "i", "w", "r", "e", "A", "t", "m", "s"];
var LanguageProvider = class {
  constructor(channel, trace = "error") {
    this.channel = channel;
    this.trace = trace;
    this.disposables = [];
    this.collection = import_coc2.languages.createDiagnosticCollection("snippets");
    for (let doc of import_coc2.workspace.documents) {
      if (this.shouldValidate(doc.uri)) {
        this.validate(doc.uri, doc.getDocumentContent()).catch((e) => {
          channel.appendLine(`[Error ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}]: ${e.message}`);
        });
      }
    }
    import_coc2.workspace.onDidOpenTextDocument(async (textDocument) => {
      let doc = import_coc2.workspace.getDocument(textDocument.uri);
      if (!this.shouldValidate(doc.uri)) return;
      await this.validate(doc.uri, doc.getDocumentContent());
    }, null, this.disposables);
    import_coc2.workspace.onDidChangeTextDocument(async (ev) => {
      let doc = import_coc2.workspace.getDocument(ev.textDocument.uri);
      if (!doc || !this.shouldValidate(doc.uri)) return;
      await this.validate(doc.uri, doc.getDocumentContent());
    }, null, this.disposables);
    import_coc2.workspace.onDidCloseTextDocument((e) => {
      this.collection.delete(e.uri);
    }, null, this.disposables);
  }
  shouldValidate(uri) {
    return uri.endsWith(".snippets");
  }
  async validate(uri, content) {
    let lines = content.split("\n");
    let diagnostics = [];
    let curr = 0;
    for (let line of lines) {
      if (/^snippet\s*$/.test(line)) {
        let range = import_coc2.Range.create(curr, 0, curr, line.length);
        diagnostics.push(import_coc2.Diagnostic.create(range, codesMap.get(1), import_coc2.DiagnosticSeverity.Error, 1));
        continue;
      }
      if (line.startsWith("snippet ")) {
        let content2 = headTail(line)[1];
        let ms = content2.match(/^(.+?)(?:\s+(?:"(.*?)")?(?:\s+"(.*?)")?(?:\s+(\w+))?)?$/);
        let prefix = ms[1];
        if (prefix.length > 2 && prefix[0] == prefix[prefix.length - 1] && !/\w/.test(prefix[0])) {
          prefix = prefix.slice(1, prefix.length - 1);
        }
        let option = ms[4] || "";
        let isExpression = option.indexOf("r") !== -1;
        let startCharacter = line.length - option.length;
        for (let ch of option) {
          if (validOptions.indexOf(ch) == -1) {
            let range = import_coc2.Range.create(curr, startCharacter, curr, startCharacter + 1);
            let message = codesMap.get(2).replace("$1", ch);
            diagnostics.push(import_coc2.Diagnostic.create(range, message, import_coc2.DiagnosticSeverity.Error, 2));
          }
          startCharacter = startCharacter + 1;
        }
        if (isExpression) {
          try {
            convertRegex(prefix);
          } catch (e) {
            let start = line.indexOf(prefix);
            let range = import_coc2.Range.create(curr, start, curr, start + prefix.length);
            let message = codesMap.get(3).replace("$1", e.message);
            diagnostics.push(import_coc2.Diagnostic.create(range, message, import_coc2.DiagnosticSeverity.Error, 3));
          }
        }
      } else {
        let idx = line.indexOf("`#!");
        if (idx !== -1) {
          let range = import_coc2.Range.create(curr, idx, curr, idx + 3);
          let message = codesMap.get(4);
          diagnostics.push(import_coc2.Diagnostic.create(range, message, import_coc2.DiagnosticSeverity.Error, 4));
        }
      }
      curr++;
    }
    if (this.trace == "verbose") {
      this.channel.appendLine(`[Debug ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}] diagnostics of ${uri} -> ${JSON.stringify(diagnostics)}`);
    }
    this.collection.set(uri, diagnostics);
  }
  provideCompletionItems(_document, position, _token, context) {
    let { input, col } = context.option;
    if (context.triggerCharacter == "$") {
      return [{
        label: "$VISUAL",
        kind: import_coc2.CompletionItemKind.Snippet,
        // tslint:disable-next-line: no-invalid-template-strings
        detail: "${VISUAL}",
        insertTextFormat: import_coc2.InsertTextFormat.Snippet,
        textEdit: {
          range: import_coc2.Range.create(position.line, position.character - 1, position.line, position.character),
          // tslint:disable-next-line: no-invalid-template-strings
          newText: "\\${VISUAL${1::default}\\}"
        }
      }];
    }
    if (col == 0 && "snippet".startsWith(input)) {
      return [{
        label: "snippet",
        kind: import_coc2.CompletionItemKind.Snippet,
        detail: "Snippet definition",
        insertTextFormat: import_coc2.InsertTextFormat.Snippet,
        // tslint:disable-next-line: no-invalid-template-strings
        insertText: 'snippet ${1:Tab_trigger} "${2:Description}" ${3:b}\n$0\nendsnippet'
      }];
    }
    return [];
  }
  async resolveCompletionItem(item) {
    let text = item.insertText || item.textEdit.newText;
    let snip = await Promise.resolve(import_coc2.snippetManager.resolveSnippet(text));
    item.documentation = {
      kind: "markdown",
      value: markdownBlock(snip.toString(), "snippets")
    };
    return item;
  }
};
function registerLanguageProvider(subscriptions, channel, configuration) {
  let trace = configuration.get("trace", "error");
  let languageProvider = new LanguageProvider(channel, trace);
  subscriptions.push(import_coc2.languages.registerCompletionItemProvider(
    "snippets-source",
    configuration.get("shortcut", "S"),
    ["snippets"],
    languageProvider,
    ["$"],
    configuration.get("priority", 90)
  ));
}

// src/list/snippet.ts
var import_coc3 = require("coc.nvim");
var import_os2 = __toESM(require("os"));
function formatPrefix(prefix) {
  if (prefix.length >= 20) return prefix.slice(0, 17) + "...";
  return prefix + " ".repeat(20 - prefix.length);
}
var SnippetsList = class extends import_coc3.BasicList {
  constructor(_nvim, manager) {
    super();
    this.manager = manager;
    this.name = "snippets";
    this.description = "snippets list";
    this.addLocationActions();
  }
  async loadItems(context) {
    var _a;
    let { window: window5 } = context;
    let valid = await window5.valid;
    if (!valid) return;
    let buf = await window5.buffer;
    let doc = import_coc3.workspace.getDocument(buf.id);
    if (!doc) return [];
    let filetype = getSnippetFiletype(doc);
    let snippets = this.manager.getSnippets(filetype);
    let res = [];
    let last = getLastSnippet();
    for (let snip of snippets) {
      let pos = import_coc3.Position.create(snip.lnum, 0);
      let location = import_coc3.Location.create(import_coc3.Uri.file(snip.filepath).toString(), import_coc3.Range.create(pos, import_coc3.Position.create(snip.lnum, 1)));
      let prefix = snip.prefix.length ? snip.prefix : (_a = snip.originRegex) != null ? _a : "";
      let preselect = last && last.filepath == snip.filepath && last.lnum == snip.lnum;
      res.push({
        label: `${formatPrefix(prefix)}	${snip.description}	${snip.filepath.replace(import_os2.default.homedir(), "~")}:${snip.lnum}`,
        filterText: `${snip.prefix} ${snip.description}`,
        preselect,
        location,
        data: { prefix }
      });
    }
    res.sort((a, b) => a.data.prefix.localeCompare(b.data.prefix));
    return res;
  }
  async doHighlight() {
    let { nvim } = import_coc3.workspace;
    nvim.pauseNotification();
    nvim.command("syntax match CocSnippetsPrefix /\\v^.{1,20}/ contained containedin=CocSnippetsLine", true);
    nvim.command("syntax match CocSnippetsFile /\\v\\t\\S+$/ contained containedin=CocSnippetsLine", true);
    nvim.command("highlight default link CocSnippetsPrefix Identifier", true);
    nvim.command("highlight default link CocSnippetsFile Comment", true);
    void nvim.resumeNotification(false, true);
  }
};

// src/massCodeProvider.ts
var import_coc4 = require("coc.nvim");
var import_http = __toESM(require("http"));

// src/baseProvider.ts
var import_minimatch = __toESM(require_minimatch());
var BaseProvider = class {
  constructor(config, channel) {
    this.config = config;
    this.channel = channel;
  }
  async checkContext(_context) {
    return true;
  }
  // load new snippets by filetype
  async loadSnippetsByFiletype(_filetype) {
  }
  async onFiletypeChange(_bufnr, _filetype) {
  }
  getDocumentSnippets(doc) {
    let filetype = getSnippetFiletype(doc);
    return this.getSnippets(filetype);
  }
  isIgnored(filepath) {
    let ignored = false;
    let { excludes } = this.config;
    for (let p of excludes) {
      if ((0, import_minimatch.default)(filepath, p, { dot: true })) {
        ignored = true;
        this.info(`File ignored by excludePatterns: ${filepath}`);
        break;
      }
    }
    return ignored;
  }
  getExtendsFiletypes(filetype, exists = /* @__PURE__ */ new Set()) {
    if (exists.has(filetype)) return [];
    let extend = this.config.extends ? this.config.extends[filetype] : null;
    exists.add(filetype);
    if (!extend || extend.length == 0) return [];
    return extend.reduce((arr, curr) => {
      return arr.concat([curr], this.getExtendsFiletypes(curr, exists));
    }, []);
  }
  getFiletypes(filetype) {
    let filetypes = [filetype];
    if (filetype.indexOf(".") !== -1) {
      filetypes.push(...filetype.split("."));
    }
    if (filetype == "latex") filetypes.push("tex");
    if (filetype == "javascriptreact" && !filetypes.includes("javascript")) {
      filetypes.push("javascript");
    }
    if (filetype == "typescriptreact" && !filetypes.includes("typescript")) {
      filetypes.push("typescript");
    }
    let extendFiletypes = filetypes.reduce((arr, curr) => {
      return arr.concat(this.getExtendsFiletypes(curr));
    }, []);
    filetypes.push(...extendFiletypes);
    return distinct(filetypes);
  }
  message(kind, msg, data) {
    let str = (/* @__PURE__ */ new Date()).toISOString().replace(/^.*T/, "").replace(/Z$/, "");
    this.channel.appendLine(`[${kind} - ${str}] ${msg}`);
    if (data !== void 0) {
      let s = typeof data === "string" ? data : JSON.stringify(data, null, 2);
      this.channel.appendLine(s);
    }
  }
  info(msg, data) {
    this.message("Info ", msg, data);
  }
  warn(msg, data) {
    this.message("Warn ", msg, data);
  }
  error(msg, data) {
    this.message("Error", msg, data);
  }
  trace(msg, data) {
    if (this.config.trace) {
      this.message("Trace", msg, data);
    }
  }
};

// src/massCodeProvider.ts
function getMatched(snippet, line) {
  let { prefix, regex: regex2 } = snippet;
  if (regex2) {
    let ms = line.match(regex2);
    if (!ms) return void 0;
    return ms[0];
  }
  if (!line.endsWith(prefix)) return void 0;
  return prefix;
}
var unknownFileTypes = ["typescriptreact", "javascriptreact"];
var MassCodeProvider = class extends BaseProvider {
  constructor(channel, config) {
    super(config, channel);
    this.config = config;
    this.massCodeItems = [];
  }
  async init() {
    this.baseHttpConfig = { host: this.config.host, port: this.config.port, method: "GET" };
    this.massCodeItems = await this.loadAllSnippets();
  }
  async getSnippetFiles(filetype) {
    let filetypes = this.getFiletypes(filetype);
    filetypes.push("all");
    let res = [];
    for (let s of this.massCodeItems) {
      for (let c of s.content) {
        if (filetypes.includes(c.language)) {
          res.push(s.folderId);
        }
      }
    }
    return res;
  }
  async getTriggerSnippets(document, position, autoTrigger) {
    if (autoTrigger) return [];
    const line = document.getline(position.line);
    if (line.length == 0) return [];
    const snippets = this.getDocumentSnippets(document).filter((s) => {
      if (autoTrigger && !s.autoTrigger) return false;
      let match = getMatched(s, line);
      if (match == null) return false;
      if (s.triggerKind == 3 /* InWord */) return true;
      let pre = line.slice(0, line.length - match.length);
      if (s.triggerKind == 1 /* LineBegin */) return pre.trim() == "";
      if (s.triggerKind == 0 /* SpaceBefore */) return pre.length == 0 || /\s$/.test(pre);
      if (s.triggerKind == 2 /* WordBoundary */) return pre.length == 0 || !document.isWord(pre[pre.length - 1]);
      return false;
    });
    snippets.sort((a, b) => {
      if (a.context && !b.context) return -1;
      if (b.context && !a.context) return 1;
      return 0;
    });
    let edits = [];
    let hasContext = false;
    for (let s of snippets) {
      let character;
      if (s.context) {
        let valid = await this.checkContext(s.context);
        if (!valid) continue;
        hasContext = true;
      } else if (hasContext) {
        break;
      }
      if (s.regex == null) {
        character = position.character - s.prefix.length;
      } else {
        let len = line.match(s.regex)[0].length;
        character = position.character - len;
      }
      let range = import_coc4.Range.create(position.line, character, position.line, position.character);
      edits.push({
        range,
        newText: s.body,
        prefix: s.prefix,
        description: s.description,
        location: s.filepath,
        lnum: s.lnum,
        priority: s.priority,
        regex: s.originRegex,
        context: s.context
      });
    }
    return edits;
  }
  async loadAllSnippets() {
    this.info(`Loading all massCode snippets from http://${this.config.host}:${this.config.port}/snippets/embed-folder`);
    const options = {
      ...this.baseHttpConfig,
      path: "/snippets/embed-folder"
    };
    const onEnd = (resolve, reject, body) => {
      try {
        resolve(JSON.parse(Buffer.concat(body).toString()));
      } catch (e) {
        reject(e);
      }
    };
    return promisifyHttpRequest(options, onEnd);
  }
  mapItems() {
    let counter = 0;
    return this.massCodeItems.filter((item) => !item.isDeleted).flatMap((item) => {
      return item.content.map((content) => {
        const snippet = {
          filepath: item.id,
          lnum: counter,
          body: content.value,
          prefix: item.name,
          description: item.name,
          triggerKind: 2 /* WordBoundary */,
          filetype: content.language
        };
        counter = counter + 1;
        return snippet;
      });
    });
  }
  getSnippets(filetype) {
    return this.mapItems().filter((snippet) => this.getFiletypes(filetype).includes(snippet.filetype));
  }
  async createSnippet(text) {
    const doc = await import_coc4.workspace.document;
    const name = await import_coc4.window.requestInput("Snippet Name");
    if (!name) {
      return Promise.resolve();
    }
    await this.init();
    const filetypes = this.getFiletypes(doc.filetype).filter((filetype) => {
      return !unknownFileTypes.includes(filetype);
    });
    if (this.mapItems().some((item) => item.prefix === name && filetypes.includes(item.filetype))) {
      import_coc4.window.showWarningMessage(`Snippet with name ${name} for this filetype already exists`);
      return Promise.resolve();
    }
    const config = {
      ...this.baseHttpConfig,
      method: "POST",
      path: "/snippets/create"
    };
    const onEnd = (resolve, reject, body) => {
      try {
        resolve(body);
      } catch (e) {
        reject(e);
      }
    };
    const requests = filetypes.map((filetype) => {
      const newIndex = Math.max(...this.mapItems().map((item) => item.lnum)) + 1;
      const newSnippet = {
        content: [{
          label: "Fragment 1",
          value: text.replace(/\n$/, ""),
          language: filetype
        }],
        createdAt: Date.now(),
        folderId: `${newIndex}`,
        id: `${newIndex}`,
        isDeleted: false,
        isFavorites: false,
        name,
        updatedAt: Date.now()
      };
      this.massCodeItems.push(newSnippet);
      return promisifyHttpRequest(config, onEnd, JSON.stringify(newSnippet));
    });
    await Promise.all(requests);
  }
};
async function promisifyHttpRequest(config, onEnd, body) {
  const options = { ...config };
  if (options.method === "POST" && body.length) {
    options.headers = {
      "Content-Type": "application/json",
      "Content-Length": body.length
    };
  }
  return new Promise(function(resolve, reject) {
    const req = import_http.default.request(options, function(res) {
      if (res.statusCode < 200 || res.statusCode >= 300) {
        return reject(new Error("statusCode=" + res.statusCode));
      }
      const body2 = [];
      res.on("data", function(chunk) {
        body2.push(chunk);
      });
      res.on("end", function() {
        onEnd(resolve, reject, body2);
      });
    });
    req.on("error", function(err) {
      if (err.code === "ECONNREFUSED") {
        import_coc4.window.showErrorMessage("massCode is not running");
      } else {
        reject(err);
      }
    });
    if (body) {
      req.write(body);
    }
    req.end();
  });
}

// src/provider.ts
var import_coc5 = require("coc.nvim");
var import_path2 = __toESM(require("path"));
var ProviderManager = class {
  constructor(channel, subscriptions, configuration) {
    this.channel = channel;
    this.subscriptions = subscriptions;
    this.configuration = configuration;
    this.providers = /* @__PURE__ */ new Map();
    this.subscriptions.push(import_coc5.Disposable.create(() => {
      this.providers.clear();
    }));
  }
  regist(provider, name) {
    this.providers.set(name, provider);
    return import_coc5.Disposable.create(() => {
      this.providers.delete(name);
    });
  }
  get hasProvider() {
    return this.providers.size > 0;
  }
  async init() {
    var _a;
    let providers = Array.from(this.providers.values());
    await Promise.allSettled(providers.map((provider) => provider.init().catch((e) => {
      import_coc5.workspace.nvim.echoError(e);
      this.appendError("Error on provider init:", e);
    })));
    let promises = [];
    import_coc5.workspace.documents.forEach((doc2) => {
      let filetype2 = getSnippetFiletype(doc2);
      promises.push(this.loadSnippetsByFiletype(filetype2));
    });
    let filetype;
    let doc = (_a = import_coc5.window.activeTextEditor) == null ? void 0 : _a.document;
    if (doc) filetype = doc.filetype;
    import_coc5.window.onDidChangeActiveTextEditor(async (e) => {
      var _a2;
      let newFiletype = (_a2 = e.document) == null ? void 0 : _a2.filetype;
      if (newFiletype && newFiletype != filetype) {
        filetype = newFiletype;
        let bufnr = e.document.bufnr;
        await Promise.allSettled(providers.map((provider) => provider.onFiletypeChange(bufnr, filetype).catch((e2) => {
          this.appendError("Error on filetype change:", e2);
        })));
      }
    }, null, this.subscriptions);
    import_coc5.workspace.onDidOpenTextDocument(async (doc2) => {
      let filetype2 = getSnippetFiletype({ bufnr: doc2.bufnr, filetype: doc2.languageId });
      await this.loadSnippetsByFiletype(filetype2);
    }, null, this.subscriptions);
    await Promise.allSettled(promises);
  }
  async loadSnippetsByFiletype(filetype) {
    let promises = [];
    for (let [name, provider] of this.providers.entries()) {
      promises.push(provider.loadSnippetsByFiletype(filetype).catch((e) => {
        this.appendError(`Error on load "${name}" snippets:`, e);
      }));
    }
    await Promise.allSettled(promises);
  }
  getSnippets(filetype) {
    let names = Array.from(this.providers.keys());
    let list = [];
    for (let name of names) {
      let provider = this.providers.get(name);
      try {
        let snippets = provider.getSnippets(filetype);
        snippets.map((s) => s.provider = name);
        list.push(...snippets);
      } catch (e) {
        this.appendError(`getSnippets of ${name}`, e);
      }
    }
    list.sort((a, b) => {
      if (a.filetype != b.filetype && (a.filetype == filetype || b.filetype == filetype)) {
        return a.filetype == filetype ? -1 : 1;
      }
      if (a.priority != b.priority) {
        return b.priority - a.priority;
      }
      if (a.filepath != b.filepath) {
        return b.filepath > a.filepath ? 1 : -1;
      }
      return a.lnum - b.lnum;
    });
    return list;
  }
  async getSnippetFiles(filetype) {
    let files = [];
    for (let [name, provider] of this.providers.entries()) {
      try {
        let res = await provider.getSnippetFiles(filetype);
        files = files.concat(res);
      } catch (e) {
        this.appendError(`getSnippetFiles of ${name}`, e);
      }
    }
    return files;
  }
  async getTriggerSnippets(bufnr, autoTrigger = false, position) {
    let doc = import_coc5.workspace.getDocument(bufnr);
    if (!doc) return [];
    if (!position) position = await import_coc5.window.getCursorPosition();
    let names = Array.from(this.providers.keys());
    let list = [];
    for (let name of names) {
      let provider = this.providers.get(name);
      try {
        let items = await provider.getTriggerSnippets(doc, position, autoTrigger);
        for (let item of items) {
          list.push(Object.assign({ source: name }, item));
        }
      } catch (e) {
        this.appendError(`get trigger snippets of ${name}`, e);
      }
    }
    list.sort((a, b) => b.priority - a.priority);
    if (list.length > 1) {
      let priority = list[0].priority;
      list = list.filter((o) => o.priority == priority);
    }
    return list;
  }
  appendError(name, e) {
    this.channel.appendLine(`[Error ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}] Error on ${name}: ${typeof e === "string" ? e : e.message}`);
    if (e instanceof Error) {
      this.channel.appendLine(e.stack);
    }
  }
  checkSyntax(syntax) {
    var _a;
    let syntaxes = (_a = this.configuration.inspect("disableSyntaxes").globalValue) != null ? _a : [];
    if (syntaxes.length == 0) return true;
    try {
      for (let str of syntaxes) {
        let r = new RegExp(str, "i");
        if (r.test(syntax)) return false;
      }
    } catch (e) {
    }
    return true;
  }
  async provideCompletionItems(document, position, _token, context) {
    var _a, _b, _c;
    let doc = import_coc5.workspace.getDocument(document.uri);
    if (!doc || !this.checkSyntax(context.option.synname)) return [];
    let bufnr = doc.bufnr;
    let filetype = getSnippetFiletype(doc);
    let snippets = this.getSnippets(filetype);
    let currline = doc.getline(position.line, true);
    let { input, col, line, colnr } = context.option;
    let character = characterIndex(line, col);
    let before_content = currline.slice(0, character);
    let after = line.slice(characterIndex(line, colnr - 1));
    let res = [];
    let noneWords = before_content.endsWith(" ") ? "" : before_content.match(/\W*$/)[0];
    let contextPrefixes = [];
    const execContext = (_a = this.configuration.inspect("execContext").globalValue) != null ? _a : false;
    for (let snip of snippets) {
      if (!execContext && snip.context) continue;
      if (snip.prefix === "") continue;
      if (input.length == 0 && (!snip.special || !before_content.endsWith(snip.special))) continue;
      if (contextPrefixes.indexOf(snip.prefix) !== -1) continue;
      let contentBefore = before_content;
      if (snip.context) {
        let provider = this.providers.get(snip.provider);
        let valid;
        try {
          valid = await provider.checkContext(snip.context);
        } catch (e) {
          this.appendError(`checkContext of ${snip.provider}`, e);
          valid = false;
        }
        if (!valid) continue;
        contextPrefixes.push(snip.prefix);
      }
      let head = this.getPrefixHead(doc, snip.prefix);
      let ultisnip = snip.provider == "ultisnips" || snip.provider == "snipmate";
      let startCharacter = character;
      let item = {
        label: snip.prefix,
        kind: import_coc5.CompletionItemKind.Snippet,
        filterText: snip.prefix,
        detail: snip.description,
        insertTextFormat: import_coc5.InsertTextFormat.Snippet
      };
      if (noneWords && snip.special) {
        if (noneWords.endsWith(snip.special)) {
          let len = snip.special.length;
          item.filterText = item.filterText.slice(len);
          startCharacter = character - len;
          contentBefore = contentBefore.slice(0, -len);
        } else {
          continue;
        }
      }
      item.data = {
        bufnr,
        snip,
        provider: snip.provider,
        filepath: `${import_path2.default.basename(snip.filepath)}:${snip.lnum}`
      };
      if (ultisnip) {
        let formatOptions = (_b = snip.formatOptions) != null ? _b : {};
        let actions = (_c = snip.actions) != null ? _c : {};
        item.data.ultisnip = {
          actions,
          context: snip.context,
          regex: snip.originRegex,
          range: import_coc5.Range.create(position.line, startCharacter, position.line, character + snip.prefix.length),
          line: before_content + snip.prefix + after,
          noExpand: formatOptions.noExpand,
          trimTrailingWhitespace: formatOptions.trimTrailingWhitespace,
          removeWhiteSpace: formatOptions.removeWhiteSpace
        };
      }
      if (snip.regex) {
        if (!input.length || snip.prefix && input[0] != snip.prefix[0]) continue;
        let content = before_content + snip.prefix;
        let ms = content.match(snip.regex);
        if (!ms) continue;
      } else if (head && before_content.endsWith(head)) {
        contentBefore = before_content.slice(0, -head.length);
        Object.assign(item, {
          textEdit: {
            range: import_coc5.Range.create({ line: position.line, character: startCharacter }, position),
            newText: snip.prefix
          }
        });
      } else if (input.length == 0) {
        Object.assign(item, {
          preselect: true,
          textEdit: {
            range: import_coc5.Range.create({ line: position.line, character: startCharacter }, position),
            newText: snip.prefix
          }
        });
      }
      if (snip.triggerKind == 1 /* LineBegin */ && contentBefore.trim().length) continue;
      if (snip.triggerKind == 0 /* SpaceBefore */) {
        if (contentBefore.length && !/\s/.test(contentBefore[contentBefore.length - 1])) {
          continue;
        }
      }
      if (!item.textEdit) {
        item.textEdit = {
          range: import_coc5.Range.create({ line: position.line, character: startCharacter }, position),
          newText: snip.prefix
        };
      }
      res.push(item);
    }
    return res;
  }
  async resolveCompletionItem(item) {
    let provider = this.providers.get(item.data.provider);
    if (provider) {
      let doc = import_coc5.workspace.getDocument(item.data.bufnr);
      let filetype = doc ? doc.filetype : void 0;
      let insertSnippet = item.data.snip.body;
      if (import_coc5.snippetManager && insertSnippet) {
        if (typeof provider.resolveSnippetBody === "function") {
          insertSnippet = await Promise.resolve(provider.resolveSnippetBody(insertSnippet));
        }
        item.textEdit.newText = insertSnippet;
        let resolved = await import_coc5.snippetManager.resolveSnippet(insertSnippet, item.data.ultisnip);
        if (typeof resolved !== "string") {
          import_coc5.window.showErrorMessage(`Please upgrade your coc.nvim to use coc-snippets`);
          return;
        }
        let ms = filetype == null ? void 0 : filetype.match(/^\w+/);
        let block = markdownBlock(resolved, ms == null ? "txt" : ms[0]);
        item.documentation = {
          kind: "markdown",
          value: block + (item.data.filepath ? `
${item.data.filepath}` : "")
        };
      }
    }
    return item;
  }
  getPrefixHead(doc, prefix) {
    let res = 0;
    for (let idx = prefix.length - 1; idx >= 0; idx--) {
      if (!doc.isWord(prefix[idx])) {
        res = idx;
        break;
      }
    }
    return res == 0 ? "" : prefix.slice(0, res + 1);
  }
};

// src/snipmateProvider.ts
var import_coc6 = require("coc.nvim");
var import_fs2 = __toESM(require("fs"));
var import_path3 = __toESM(require("path"));
var import_readline = __toESM(require("readline"));
function convertBody(body) {
  return body.replace(/`(.*?)(?<!\\)`/g, (_, p1) => {
    if (p1.startsWith("Filename(")) {
      p1 = p1.replace(/^Filename/, "vim_snippets#Filename");
    }
    return "`!v " + p1 + "`";
  });
}
var SnipmateProvider = class extends BaseProvider {
  constructor(channel, config, subscriptions) {
    super(config, channel);
    this.config = config;
    this.subscriptions = subscriptions;
    this.fileItems = [];
    this.snippetFiles = [];
    this.loadedLanguageIds = /* @__PURE__ */ new Set();
    import_coc6.workspace.onDidSaveTextDocument(async (doc) => {
      let uri = import_coc6.Uri.parse(doc.uri);
      if (uri.scheme != "file") return;
      let filepath = uri.fsPath;
      if (!import_fs2.default.existsSync(filepath)) return;
      let idx = this.snippetFiles.findIndex((s) => sameFile(s.filepath, filepath));
      if (idx !== -1) {
        let filetype = this.snippetFiles[idx].filetype;
        this.snippetFiles.splice(idx, 1);
        await this.loadSnippetsFromFile(filetype, filepath);
      }
    }, null, this.subscriptions);
  }
  async init() {
    let { nvim } = import_coc6.workspace;
    let author = await nvim.getVar("snips_author");
    if (!author) nvim.setVar("snips_author", this.config.author, true);
    this.fileItems = await this.loadAllSnippetFiles();
    import_coc6.workspace.onDidRuntimePathChange(async (e) => {
      for (let rtp of e) {
        let items = await this.getSnippetFileItems(import_path3.default.join(rtp, "snippets"));
        if (items == null ? void 0 : items.length) {
          this.fileItems.push(...items);
          for (let item of items) {
            if (import_coc6.workspace.filetypes.has(item.filetype)) {
              await this.loadSnippetsFromFile(item.filetype, item.filepath);
            }
          }
        }
      }
    }, null, this.subscriptions);
  }
  async loadSnippetsByFiletype(filetype) {
    let filetypes = filetype ? this.getFiletypes(filetype) : [];
    filetypes.push("_");
    filetypes = filetypes.filter((filetype2) => !this.loadedLanguageIds.has(filetype2));
    if (filetypes.length == 0) return;
    filetypes.forEach((filetype2) => this.loadedLanguageIds.add(filetype2));
    for (let item of this.fileItems) {
      if (!filetypes.includes(item.filetype)) continue;
      await this.loadSnippetsFromFile(item.filetype, item.filepath);
    }
  }
  async loadSnippetsFromFile(filetype, filepath) {
    let idx = this.snippetFiles.findIndex((o) => sameFile(o.filepath, filepath));
    if (idx !== -1) return;
    idx = this.fileItems.findIndex((o) => o.filepath == filepath);
    if (idx !== -1) this.fileItems.splice(idx, 1);
    if (this.isIgnored(filepath)) return;
    let res = await this.parseSnippetsFile(filetype, filepath);
    if (this.snippetFiles.findIndex((o) => sameFile(o.filepath, filepath)) == -1) {
      this.snippetFiles.push({ filepath, filetype, snippets: res.snippets });
      this.info(`Loaded ${res.snippets.length} ${filetype} snipmate snippets from: ${filepath}`);
      if (res.extends.length) {
        let fts = res.extends;
        let curr = this.config.extends[filetype] || [];
        for (let ft of fts) {
          await this.loadSnippetsByFiletype(ft);
          if (!curr.includes(ft)) {
            curr.push(ft);
          }
        }
        this.config.extends[filetype] = curr;
      }
    }
  }
  /**
   * Parse snippets from snippets file.
   */
  parseSnippetsFile(filetype, filepath) {
    let res = [];
    let extendsFiletypes = [];
    const rl = import_readline.default.createInterface({
      input: import_fs2.default.createReadStream(filepath, "utf8"),
      crlfDelay: Infinity
    });
    let lnum = 0;
    let lines = [];
    let prefix = "";
    let description = "";
    rl.on("line", (line) => {
      lnum += 1;
      if (line.startsWith("#")) return;
      if (/^extends\s/.test(line)) {
        let ft = line.replace(/^extends\s+/, "");
        if (ft) extendsFiletypes.push(ft);
        return;
      }
      if (line.startsWith("snippet")) {
        line = line.replace(/\s*$/, "");
        if (lines.length && prefix) {
          let body = lines.join("\n").replace(/\s+$/, "");
          res.push({
            filepath,
            filetype,
            lnum: lnum - lines.length - 1,
            body: convertBody(body),
            prefix,
            description,
            triggerKind: 2 /* WordBoundary */,
            provider: "snipmate"
          });
          lines = [];
        }
        let ms = line.match(/^snippet\s+(\S+)(?:\s(.+))?$/);
        if (!ms) {
          prefix = "";
          this.error(`Broken line on ${filepath}:${lnum}`);
          return;
        }
        prefix = ms[1];
        description = ms[2] || "";
        return;
      }
      if (prefix) {
        if (line.startsWith("	")) {
          lines.push(line.slice(1));
        } else {
          lines.push(line);
        }
      }
    });
    return new Promise((resolve) => {
      rl.on("close", async () => {
        if (lines.length) {
          let body = lines.join("\n").replace(/\s+$/, "");
          res.push({
            filepath,
            lnum: lnum - lines.length - 1,
            filetype,
            body: convertBody(body),
            prefix,
            description,
            triggerKind: 2 /* WordBoundary */
          });
        }
        this.trace("snipmate snippets", res);
        resolve({ snippets: res, extends: extendsFiletypes });
      });
    });
  }
  async getTriggerSnippets(document, position, autoTrigger) {
    if (autoTrigger) return [];
    let snippets = this.getDocumentSnippets(document);
    let line = document.getline(position.line);
    line = line.slice(0, position.character);
    if (!line) return [];
    snippets = snippets.filter((s) => {
      let { prefix } = s;
      if (!line.endsWith(prefix)) return false;
      let pre = line.slice(0, line.length - prefix.length);
      return pre.length == 0 || !document.isWord(pre[pre.length - 1]);
    });
    let edits = [];
    for (let s of snippets) {
      let character = position.character - s.prefix.length;
      let range = import_coc6.Range.create(position.line, character, position.line, position.character);
      edits.push({
        prefix: s.prefix,
        description: s.description,
        location: s.filepath,
        lnum: s.lnum,
        range,
        newText: s.body,
        priority: -1
      });
    }
    return edits;
  }
  async getSnippetFiles(filetype) {
    let filetypes = filetype ? this.getFiletypes(filetype) : [];
    filetypes.push("_");
    let res = [];
    for (let s of this.snippetFiles) {
      if (filetypes.indexOf(s.filetype) !== -1) {
        res.push(s.filepath);
      }
    }
    return res;
  }
  getSnippets(filetype) {
    let filetypes = this.getFiletypes(filetype);
    filetypes.push("_");
    let snippetFiles = this.snippetFiles.filter((o) => filetypes.includes(o.filetype));
    let result = [];
    snippetFiles.sort((a, b) => {
      if (a.filetype == b.filetype) return 1;
      if (a.filetype == filetype) return -1;
      return 1;
    });
    for (let file of snippetFiles) {
      let { snippets } = file;
      for (let snip of snippets) {
        result.push(snip);
      }
    }
    return result;
  }
  async loadAllSnippetFiles() {
    let { env } = import_coc6.workspace;
    let rtps = env.runtimepath.split(",");
    let res = [];
    for (let rtp of rtps) {
      let items = await this.getSnippetFileItems(import_path3.default.join(rtp, "snippets"));
      res.push(...items);
    }
    return res;
  }
  async getSnippetFileItems(directory) {
    let res = [];
    let stat = await statAsync(directory);
    if (stat && stat.isDirectory()) {
      let files = await readdirAsync(directory);
      if (files.length) {
        for (let f of files) {
          let file = import_path3.default.join(directory, f);
          if (file.endsWith(".snippets")) {
            let basename = import_path3.default.basename(f, ".snippets");
            let filetype = basename.split("-", 2)[0];
            res.push({ filepath: file, directory, filetype });
          } else {
            let stat2 = await statAsync(file);
            if (stat2 && stat2.isDirectory()) {
              let files2 = await readdirAsync(file);
              for (let filename of files2) {
                if (filename.endsWith(".snippets")) {
                  res.push({ filepath: import_path3.default.join(file, filename), directory, filetype: f });
                }
              }
            }
          }
        }
      }
    }
    return res;
  }
};

// src/textmateProvider.ts
var import_coc7 = require("coc.nvim");
var import_fs3 = __toESM(require("fs"));

// node_modules/jsonc-parser/lib/esm/impl/scanner.js
function createScanner(text, ignoreTrivia = false) {
  const len = text.length;
  let pos = 0, value = "", tokenOffset = 0, token = 16, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0;
  function scanHexDigits(count, exact) {
    let digits = 0;
    let value2 = 0;
    while (digits < count || !exact) {
      let ch = text.charCodeAt(pos);
      if (ch >= 48 && ch <= 57) {
        value2 = value2 * 16 + ch - 48;
      } else if (ch >= 65 && ch <= 70) {
        value2 = value2 * 16 + ch - 65 + 10;
      } else if (ch >= 97 && ch <= 102) {
        value2 = value2 * 16 + ch - 97 + 10;
      } else {
        break;
      }
      pos++;
      digits++;
    }
    if (digits < count) {
      value2 = -1;
    }
    return value2;
  }
  function setPosition(newPosition) {
    pos = newPosition;
    value = "";
    tokenOffset = 0;
    token = 16;
    scanError = 0;
  }
  function scanNumber() {
    let start = pos;
    if (text.charCodeAt(pos) === 48) {
      pos++;
    } else {
      pos++;
      while (pos < text.length && isDigit(text.charCodeAt(pos))) {
        pos++;
      }
    }
    if (pos < text.length && text.charCodeAt(pos) === 46) {
      pos++;
      if (pos < text.length && isDigit(text.charCodeAt(pos))) {
        pos++;
        while (pos < text.length && isDigit(text.charCodeAt(pos))) {
          pos++;
        }
      } else {
        scanError = 3;
        return text.substring(start, pos);
      }
    }
    let end = pos;
    if (pos < text.length && (text.charCodeAt(pos) === 69 || text.charCodeAt(pos) === 101)) {
      pos++;
      if (pos < text.length && text.charCodeAt(pos) === 43 || text.charCodeAt(pos) === 45) {
        pos++;
      }
      if (pos < text.length && isDigit(text.charCodeAt(pos))) {
        pos++;
        while (pos < text.length && isDigit(text.charCodeAt(pos))) {
          pos++;
        }
        end = pos;
      } else {
        scanError = 3;
      }
    }
    return text.substring(start, end);
  }
  function scanString() {
    let result = "", start = pos;
    while (true) {
      if (pos >= len) {
        result += text.substring(start, pos);
        scanError = 2;
        break;
      }
      const ch = text.charCodeAt(pos);
      if (ch === 34) {
        result += text.substring(start, pos);
        pos++;
        break;
      }
      if (ch === 92) {
        result += text.substring(start, pos);
        pos++;
        if (pos >= len) {
          scanError = 2;
          break;
        }
        const ch2 = text.charCodeAt(pos++);
        switch (ch2) {
          case 34:
            result += '"';
            break;
          case 92:
            result += "\\";
            break;
          case 47:
            result += "/";
            break;
          case 98:
            result += "\b";
            break;
          case 102:
            result += "\f";
            break;
          case 110:
            result += "\n";
            break;
          case 114:
            result += "\r";
            break;
          case 116:
            result += "	";
            break;
          case 117:
            const ch3 = scanHexDigits(4, true);
            if (ch3 >= 0) {
              result += String.fromCharCode(ch3);
            } else {
              scanError = 4;
            }
            break;
          default:
            scanError = 5;
        }
        start = pos;
        continue;
      }
      if (ch >= 0 && ch <= 31) {
        if (isLineBreak(ch)) {
          result += text.substring(start, pos);
          scanError = 2;
          break;
        } else {
          scanError = 6;
        }
      }
      pos++;
    }
    return result;
  }
  function scanNext() {
    value = "";
    scanError = 0;
    tokenOffset = pos;
    lineStartOffset = lineNumber;
    prevTokenLineStartOffset = tokenLineStartOffset;
    if (pos >= len) {
      tokenOffset = len;
      return token = 17;
    }
    let code = text.charCodeAt(pos);
    if (isWhiteSpace(code)) {
      do {
        pos++;
        value += String.fromCharCode(code);
        code = text.charCodeAt(pos);
      } while (isWhiteSpace(code));
      return token = 15;
    }
    if (isLineBreak(code)) {
      pos++;
      value += String.fromCharCode(code);
      if (code === 13 && text.charCodeAt(pos) === 10) {
        pos++;
        value += "\n";
      }
      lineNumber++;
      tokenLineStartOffset = pos;
      return token = 14;
    }
    switch (code) {
      // tokens: []{}:,
      case 123:
        pos++;
        return token = 1;
      case 125:
        pos++;
        return token = 2;
      case 91:
        pos++;
        return token = 3;
      case 93:
        pos++;
        return token = 4;
      case 58:
        pos++;
        return token = 6;
      case 44:
        pos++;
        return token = 5;
      // strings
      case 34:
        pos++;
        value = scanString();
        return token = 10;
      // comments
      case 47:
        const start = pos - 1;
        if (text.charCodeAt(pos + 1) === 47) {
          pos += 2;
          while (pos < len) {
            if (isLineBreak(text.charCodeAt(pos))) {
              break;
            }
            pos++;
          }
          value = text.substring(start, pos);
          return token = 12;
        }
        if (text.charCodeAt(pos + 1) === 42) {
          pos += 2;
          const safeLength = len - 1;
          let commentClosed = false;
          while (pos < safeLength) {
            const ch = text.charCodeAt(pos);
            if (ch === 42 && text.charCodeAt(pos + 1) === 47) {
              pos += 2;
              commentClosed = true;
              break;
            }
            pos++;
            if (isLineBreak(ch)) {
              if (ch === 13 && text.charCodeAt(pos) === 10) {
                pos++;
              }
              lineNumber++;
              tokenLineStartOffset = pos;
            }
          }
          if (!commentClosed) {
            pos++;
            scanError = 1;
          }
          value = text.substring(start, pos);
          return token = 13;
        }
        value += String.fromCharCode(code);
        pos++;
        return token = 16;
      // numbers
      case 45:
        value += String.fromCharCode(code);
        pos++;
        if (pos === len || !isDigit(text.charCodeAt(pos))) {
          return token = 16;
        }
      // found a minus, followed by a number so
      // we fall through to proceed with scanning
      // numbers
      case 48:
      case 49:
      case 50:
      case 51:
      case 52:
      case 53:
      case 54:
      case 55:
      case 56:
      case 57:
        value += scanNumber();
        return token = 11;
      // literals and unknown symbols
      default:
        while (pos < len && isUnknownContentCharacter(code)) {
          pos++;
          code = text.charCodeAt(pos);
        }
        if (tokenOffset !== pos) {
          value = text.substring(tokenOffset, pos);
          switch (value) {
            case "true":
              return token = 8;
            case "false":
              return token = 9;
            case "null":
              return token = 7;
          }
          return token = 16;
        }
        value += String.fromCharCode(code);
        pos++;
        return token = 16;
    }
  }
  function isUnknownContentCharacter(code) {
    if (isWhiteSpace(code) || isLineBreak(code)) {
      return false;
    }
    switch (code) {
      case 125:
      case 93:
      case 123:
      case 91:
      case 34:
      case 58:
      case 44:
      case 47:
        return false;
    }
    return true;
  }
  function scanNextNonTrivia() {
    let result;
    do {
      result = scanNext();
    } while (result >= 12 && result <= 15);
    return result;
  }
  return {
    setPosition,
    getPosition: () => pos,
    scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
    getToken: () => token,
    getTokenValue: () => value,
    getTokenOffset: () => tokenOffset,
    getTokenLength: () => pos - tokenOffset,
    getTokenStartLine: () => lineStartOffset,
    getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,
    getTokenError: () => scanError
  };
}
function isWhiteSpace(ch) {
  return ch === 32 || ch === 9;
}
function isLineBreak(ch) {
  return ch === 10 || ch === 13;
}
function isDigit(ch) {
  return ch >= 48 && ch <= 57;
}
var CharacterCodes;
(function(CharacterCodes2) {
  CharacterCodes2[CharacterCodes2["lineFeed"] = 10] = "lineFeed";
  CharacterCodes2[CharacterCodes2["carriageReturn"] = 13] = "carriageReturn";
  CharacterCodes2[CharacterCodes2["space"] = 32] = "space";
  CharacterCodes2[CharacterCodes2["_0"] = 48] = "_0";
  CharacterCodes2[CharacterCodes2["_1"] = 49] = "_1";
  CharacterCodes2[CharacterCodes2["_2"] = 50] = "_2";
  CharacterCodes2[CharacterCodes2["_3"] = 51] = "_3";
  CharacterCodes2[CharacterCodes2["_4"] = 52] = "_4";
  CharacterCodes2[CharacterCodes2["_5"] = 53] = "_5";
  CharacterCodes2[CharacterCodes2["_6"] = 54] = "_6";
  CharacterCodes2[CharacterCodes2["_7"] = 55] = "_7";
  CharacterCodes2[CharacterCodes2["_8"] = 56] = "_8";
  CharacterCodes2[CharacterCodes2["_9"] = 57] = "_9";
  CharacterCodes2[CharacterCodes2["a"] = 97] = "a";
  CharacterCodes2[CharacterCodes2["b"] = 98] = "b";
  CharacterCodes2[CharacterCodes2["c"] = 99] = "c";
  CharacterCodes2[CharacterCodes2["d"] = 100] = "d";
  CharacterCodes2[CharacterCodes2["e"] = 101] = "e";
  CharacterCodes2[CharacterCodes2["f"] = 102] = "f";
  CharacterCodes2[CharacterCodes2["g"] = 103] = "g";
  CharacterCodes2[CharacterCodes2["h"] = 104] = "h";
  CharacterCodes2[CharacterCodes2["i"] = 105] = "i";
  CharacterCodes2[CharacterCodes2["j"] = 106] = "j";
  CharacterCodes2[CharacterCodes2["k"] = 107] = "k";
  CharacterCodes2[CharacterCodes2["l"] = 108] = "l";
  CharacterCodes2[CharacterCodes2["m"] = 109] = "m";
  CharacterCodes2[CharacterCodes2["n"] = 110] = "n";
  CharacterCodes2[CharacterCodes2["o"] = 111] = "o";
  CharacterCodes2[CharacterCodes2["p"] = 112] = "p";
  CharacterCodes2[CharacterCodes2["q"] = 113] = "q";
  CharacterCodes2[CharacterCodes2["r"] = 114] = "r";
  CharacterCodes2[CharacterCodes2["s"] = 115] = "s";
  CharacterCodes2[CharacterCodes2["t"] = 116] = "t";
  CharacterCodes2[CharacterCodes2["u"] = 117] = "u";
  CharacterCodes2[CharacterCodes2["v"] = 118] = "v";
  CharacterCodes2[CharacterCodes2["w"] = 119] = "w";
  CharacterCodes2[CharacterCodes2["x"] = 120] = "x";
  CharacterCodes2[CharacterCodes2["y"] = 121] = "y";
  CharacterCodes2[CharacterCodes2["z"] = 122] = "z";
  CharacterCodes2[CharacterCodes2["A"] = 65] = "A";
  CharacterCodes2[CharacterCodes2["B"] = 66] = "B";
  CharacterCodes2[CharacterCodes2["C"] = 67] = "C";
  CharacterCodes2[CharacterCodes2["D"] = 68] = "D";
  CharacterCodes2[CharacterCodes2["E"] = 69] = "E";
  CharacterCodes2[CharacterCodes2["F"] = 70] = "F";
  CharacterCodes2[CharacterCodes2["G"] = 71] = "G";
  CharacterCodes2[CharacterCodes2["H"] = 72] = "H";
  CharacterCodes2[CharacterCodes2["I"] = 73] = "I";
  CharacterCodes2[CharacterCodes2["J"] = 74] = "J";
  CharacterCodes2[CharacterCodes2["K"] = 75] = "K";
  CharacterCodes2[CharacterCodes2["L"] = 76] = "L";
  CharacterCodes2[CharacterCodes2["M"] = 77] = "M";
  CharacterCodes2[CharacterCodes2["N"] = 78] = "N";
  CharacterCodes2[CharacterCodes2["O"] = 79] = "O";
  CharacterCodes2[CharacterCodes2["P"] = 80] = "P";
  CharacterCodes2[CharacterCodes2["Q"] = 81] = "Q";
  CharacterCodes2[CharacterCodes2["R"] = 82] = "R";
  CharacterCodes2[CharacterCodes2["S"] = 83] = "S";
  CharacterCodes2[CharacterCodes2["T"] = 84] = "T";
  CharacterCodes2[CharacterCodes2["U"] = 85] = "U";
  CharacterCodes2[CharacterCodes2["V"] = 86] = "V";
  CharacterCodes2[CharacterCodes2["W"] = 87] = "W";
  CharacterCodes2[CharacterCodes2["X"] = 88] = "X";
  CharacterCodes2[CharacterCodes2["Y"] = 89] = "Y";
  CharacterCodes2[CharacterCodes2["Z"] = 90] = "Z";
  CharacterCodes2[CharacterCodes2["asterisk"] = 42] = "asterisk";
  CharacterCodes2[CharacterCodes2["backslash"] = 92] = "backslash";
  CharacterCodes2[CharacterCodes2["closeBrace"] = 125] = "closeBrace";
  CharacterCodes2[CharacterCodes2["closeBracket"] = 93] = "closeBracket";
  CharacterCodes2[CharacterCodes2["colon"] = 58] = "colon";
  CharacterCodes2[CharacterCodes2["comma"] = 44] = "comma";
  CharacterCodes2[CharacterCodes2["dot"] = 46] = "dot";
  CharacterCodes2[CharacterCodes2["doubleQuote"] = 34] = "doubleQuote";
  CharacterCodes2[CharacterCodes2["minus"] = 45] = "minus";
  CharacterCodes2[CharacterCodes2["openBrace"] = 123] = "openBrace";
  CharacterCodes2[CharacterCodes2["openBracket"] = 91] = "openBracket";
  CharacterCodes2[CharacterCodes2["plus"] = 43] = "plus";
  CharacterCodes2[CharacterCodes2["slash"] = 47] = "slash";
  CharacterCodes2[CharacterCodes2["formFeed"] = 12] = "formFeed";
  CharacterCodes2[CharacterCodes2["tab"] = 9] = "tab";
})(CharacterCodes || (CharacterCodes = {}));

// node_modules/jsonc-parser/lib/esm/impl/string-intern.js
var cachedSpaces = new Array(20).fill(0).map((_, index) => {
  return " ".repeat(index);
});
var maxCachedValues = 200;
var cachedBreakLinesWithSpaces = {
  " ": {
    "\n": new Array(maxCachedValues).fill(0).map((_, index) => {
      return "\n" + " ".repeat(index);
    }),
    "\r": new Array(maxCachedValues).fill(0).map((_, index) => {
      return "\r" + " ".repeat(index);
    }),
    "\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
      return "\r\n" + " ".repeat(index);
    })
  },
  "	": {
    "\n": new Array(maxCachedValues).fill(0).map((_, index) => {
      return "\n" + "	".repeat(index);
    }),
    "\r": new Array(maxCachedValues).fill(0).map((_, index) => {
      return "\r" + "	".repeat(index);
    }),
    "\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
      return "\r\n" + "	".repeat(index);
    })
  }
};

// node_modules/jsonc-parser/lib/esm/impl/parser.js
var ParseOptions;
(function(ParseOptions2) {
  ParseOptions2.DEFAULT = {
    allowTrailingComma: false
  };
})(ParseOptions || (ParseOptions = {}));
function parse(text, errors = [], options = ParseOptions.DEFAULT) {
  let currentProperty = null;
  let currentParent = [];
  const previousParents = [];
  function onValue(value) {
    if (Array.isArray(currentParent)) {
      currentParent.push(value);
    } else if (currentProperty !== null) {
      currentParent[currentProperty] = value;
    }
  }
  const visitor = {
    onObjectBegin: () => {
      const object = {};
      onValue(object);
      previousParents.push(currentParent);
      currentParent = object;
      currentProperty = null;
    },
    onObjectProperty: (name) => {
      currentProperty = name;
    },
    onObjectEnd: () => {
      currentParent = previousParents.pop();
    },
    onArrayBegin: () => {
      const array = [];
      onValue(array);
      previousParents.push(currentParent);
      currentParent = array;
      currentProperty = null;
    },
    onArrayEnd: () => {
      currentParent = previousParents.pop();
    },
    onLiteralValue: onValue,
    onError: (error, offset, length) => {
      errors.push({ error, offset, length });
    }
  };
  visit(text, visitor, options);
  return currentParent[0];
}
function visit(text, visitor, options = ParseOptions.DEFAULT) {
  const _scanner = createScanner(text, false);
  const _jsonPath = [];
  let suppressedCallbacks = 0;
  function toNoArgVisit(visitFunction) {
    return visitFunction ? () => suppressedCallbacks === 0 && visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
  }
  function toOneArgVisit(visitFunction) {
    return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
  }
  function toOneArgVisitWithPath(visitFunction) {
    return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice()) : () => true;
  }
  function toBeginVisit(visitFunction) {
    return visitFunction ? () => {
      if (suppressedCallbacks > 0) {
        suppressedCallbacks++;
      } else {
        let cbReturn = visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice());
        if (cbReturn === false) {
          suppressedCallbacks = 1;
        }
      }
    } : () => true;
  }
  function toEndVisit(visitFunction) {
    return visitFunction ? () => {
      if (suppressedCallbacks > 0) {
        suppressedCallbacks--;
      }
      if (suppressedCallbacks === 0) {
        visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter());
      }
    } : () => true;
  }
  const onObjectBegin = toBeginVisit(visitor.onObjectBegin), onObjectProperty = toOneArgVisitWithPath(visitor.onObjectProperty), onObjectEnd = toEndVisit(visitor.onObjectEnd), onArrayBegin = toBeginVisit(visitor.onArrayBegin), onArrayEnd = toEndVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisitWithPath(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError);
  const disallowComments = options && options.disallowComments;
  const allowTrailingComma = options && options.allowTrailingComma;
  function scanNext() {
    while (true) {
      const token = _scanner.scan();
      switch (_scanner.getTokenError()) {
        case 4:
          handleError(
            14
            /* ParseErrorCode.InvalidUnicode */
          );
          break;
        case 5:
          handleError(
            15
            /* ParseErrorCode.InvalidEscapeCharacter */
          );
          break;
        case 3:
          handleError(
            13
            /* ParseErrorCode.UnexpectedEndOfNumber */
          );
          break;
        case 1:
          if (!disallowComments) {
            handleError(
              11
              /* ParseErrorCode.UnexpectedEndOfComment */
            );
          }
          break;
        case 2:
          handleError(
            12
            /* ParseErrorCode.UnexpectedEndOfString */
          );
          break;
        case 6:
          handleError(
            16
            /* ParseErrorCode.InvalidCharacter */
          );
          break;
      }
      switch (token) {
        case 12:
        case 13:
          if (disallowComments) {
            handleError(
              10
              /* ParseErrorCode.InvalidCommentToken */
            );
          } else {
            onComment();
          }
          break;
        case 16:
          handleError(
            1
            /* ParseErrorCode.InvalidSymbol */
          );
          break;
        case 15:
        case 14:
          break;
        default:
          return token;
      }
    }
  }
  function handleError(error, skipUntilAfter = [], skipUntil = []) {
    onError(error);
    if (skipUntilAfter.length + skipUntil.length > 0) {
      let token = _scanner.getToken();
      while (token !== 17) {
        if (skipUntilAfter.indexOf(token) !== -1) {
          scanNext();
          break;
        } else if (skipUntil.indexOf(token) !== -1) {
          break;
        }
        token = scanNext();
      }
    }
  }
  function parseString(isValue) {
    const value = _scanner.getTokenValue();
    if (isValue) {
      onLiteralValue(value);
    } else {
      onObjectProperty(value);
      _jsonPath.push(value);
    }
    scanNext();
    return true;
  }
  function parseLiteral() {
    switch (_scanner.getToken()) {
      case 11:
        const tokenValue = _scanner.getTokenValue();
        let value = Number(tokenValue);
        if (isNaN(value)) {
          handleError(
            2
            /* ParseErrorCode.InvalidNumberFormat */
          );
          value = 0;
        }
        onLiteralValue(value);
        break;
      case 7:
        onLiteralValue(null);
        break;
      case 8:
        onLiteralValue(true);
        break;
      case 9:
        onLiteralValue(false);
        break;
      default:
        return false;
    }
    scanNext();
    return true;
  }
  function parseProperty() {
    if (_scanner.getToken() !== 10) {
      handleError(3, [], [
        2,
        5
        /* SyntaxKind.CommaToken */
      ]);
      return false;
    }
    parseString(false);
    if (_scanner.getToken() === 6) {
      onSeparator(":");
      scanNext();
      if (!parseValue()) {
        handleError(4, [], [
          2,
          5
          /* SyntaxKind.CommaToken */
        ]);
      }
    } else {
      handleError(5, [], [
        2,
        5
        /* SyntaxKind.CommaToken */
      ]);
    }
    _jsonPath.pop();
    return true;
  }
  function parseObject() {
    onObjectBegin();
    scanNext();
    let needsComma = false;
    while (_scanner.getToken() !== 2 && _scanner.getToken() !== 17) {
      if (_scanner.getToken() === 5) {
        if (!needsComma) {
          handleError(4, [], []);
        }
        onSeparator(",");
        scanNext();
        if (_scanner.getToken() === 2 && allowTrailingComma) {
          break;
        }
      } else if (needsComma) {
        handleError(6, [], []);
      }
      if (!parseProperty()) {
        handleError(4, [], [
          2,
          5
          /* SyntaxKind.CommaToken */
        ]);
      }
      needsComma = true;
    }
    onObjectEnd();
    if (_scanner.getToken() !== 2) {
      handleError(7, [
        2
        /* SyntaxKind.CloseBraceToken */
      ], []);
    } else {
      scanNext();
    }
    return true;
  }
  function parseArray() {
    onArrayBegin();
    scanNext();
    let isFirstElement = true;
    let needsComma = false;
    while (_scanner.getToken() !== 4 && _scanner.getToken() !== 17) {
      if (_scanner.getToken() === 5) {
        if (!needsComma) {
          handleError(4, [], []);
        }
        onSeparator(",");
        scanNext();
        if (_scanner.getToken() === 4 && allowTrailingComma) {
          break;
        }
      } else if (needsComma) {
        handleError(6, [], []);
      }
      if (isFirstElement) {
        _jsonPath.push(0);
        isFirstElement = false;
      } else {
        _jsonPath[_jsonPath.length - 1]++;
      }
      if (!parseValue()) {
        handleError(4, [], [
          4,
          5
          /* SyntaxKind.CommaToken */
        ]);
      }
      needsComma = true;
    }
    onArrayEnd();
    if (!isFirstElement) {
      _jsonPath.pop();
    }
    if (_scanner.getToken() !== 4) {
      handleError(8, [
        4
        /* SyntaxKind.CloseBracketToken */
      ], []);
    } else {
      scanNext();
    }
    return true;
  }
  function parseValue() {
    switch (_scanner.getToken()) {
      case 3:
        return parseArray();
      case 1:
        return parseObject();
      case 10:
        return parseString(true);
      default:
        return parseLiteral();
    }
  }
  scanNext();
  if (_scanner.getToken() === 17) {
    if (options.allowEmptyContent) {
      return true;
    }
    handleError(4, [], []);
    return false;
  }
  if (!parseValue()) {
    handleError(4, [], []);
    return false;
  }
  if (_scanner.getToken() !== 17) {
    handleError(9, [], []);
  }
  return true;
}

// node_modules/jsonc-parser/lib/esm/main.js
var ScanError;
(function(ScanError2) {
  ScanError2[ScanError2["None"] = 0] = "None";
  ScanError2[ScanError2["UnexpectedEndOfComment"] = 1] = "UnexpectedEndOfComment";
  ScanError2[ScanError2["UnexpectedEndOfString"] = 2] = "UnexpectedEndOfString";
  ScanError2[ScanError2["UnexpectedEndOfNumber"] = 3] = "UnexpectedEndOfNumber";
  ScanError2[ScanError2["InvalidUnicode"] = 4] = "InvalidUnicode";
  ScanError2[ScanError2["InvalidEscapeCharacter"] = 5] = "InvalidEscapeCharacter";
  ScanError2[ScanError2["InvalidCharacter"] = 6] = "InvalidCharacter";
})(ScanError || (ScanError = {}));
var SyntaxKind;
(function(SyntaxKind2) {
  SyntaxKind2[SyntaxKind2["OpenBraceToken"] = 1] = "OpenBraceToken";
  SyntaxKind2[SyntaxKind2["CloseBraceToken"] = 2] = "CloseBraceToken";
  SyntaxKind2[SyntaxKind2["OpenBracketToken"] = 3] = "OpenBracketToken";
  SyntaxKind2[SyntaxKind2["CloseBracketToken"] = 4] = "CloseBracketToken";
  SyntaxKind2[SyntaxKind2["CommaToken"] = 5] = "CommaToken";
  SyntaxKind2[SyntaxKind2["ColonToken"] = 6] = "ColonToken";
  SyntaxKind2[SyntaxKind2["NullKeyword"] = 7] = "NullKeyword";
  SyntaxKind2[SyntaxKind2["TrueKeyword"] = 8] = "TrueKeyword";
  SyntaxKind2[SyntaxKind2["FalseKeyword"] = 9] = "FalseKeyword";
  SyntaxKind2[SyntaxKind2["StringLiteral"] = 10] = "StringLiteral";
  SyntaxKind2[SyntaxKind2["NumericLiteral"] = 11] = "NumericLiteral";
  SyntaxKind2[SyntaxKind2["LineCommentTrivia"] = 12] = "LineCommentTrivia";
  SyntaxKind2[SyntaxKind2["BlockCommentTrivia"] = 13] = "BlockCommentTrivia";
  SyntaxKind2[SyntaxKind2["LineBreakTrivia"] = 14] = "LineBreakTrivia";
  SyntaxKind2[SyntaxKind2["Trivia"] = 15] = "Trivia";
  SyntaxKind2[SyntaxKind2["Unknown"] = 16] = "Unknown";
  SyntaxKind2[SyntaxKind2["EOF"] = 17] = "EOF";
})(SyntaxKind || (SyntaxKind = {}));
var parse2 = parse;
var ParseErrorCode;
(function(ParseErrorCode2) {
  ParseErrorCode2[ParseErrorCode2["InvalidSymbol"] = 1] = "InvalidSymbol";
  ParseErrorCode2[ParseErrorCode2["InvalidNumberFormat"] = 2] = "InvalidNumberFormat";
  ParseErrorCode2[ParseErrorCode2["PropertyNameExpected"] = 3] = "PropertyNameExpected";
  ParseErrorCode2[ParseErrorCode2["ValueExpected"] = 4] = "ValueExpected";
  ParseErrorCode2[ParseErrorCode2["ColonExpected"] = 5] = "ColonExpected";
  ParseErrorCode2[ParseErrorCode2["CommaExpected"] = 6] = "CommaExpected";
  ParseErrorCode2[ParseErrorCode2["CloseBraceExpected"] = 7] = "CloseBraceExpected";
  ParseErrorCode2[ParseErrorCode2["CloseBracketExpected"] = 8] = "CloseBracketExpected";
  ParseErrorCode2[ParseErrorCode2["EndOfFileExpected"] = 9] = "EndOfFileExpected";
  ParseErrorCode2[ParseErrorCode2["InvalidCommentToken"] = 10] = "InvalidCommentToken";
  ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfComment"] = 11] = "UnexpectedEndOfComment";
  ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfString"] = 12] = "UnexpectedEndOfString";
  ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfNumber"] = 13] = "UnexpectedEndOfNumber";
  ParseErrorCode2[ParseErrorCode2["InvalidUnicode"] = 14] = "InvalidUnicode";
  ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
  ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
})(ParseErrorCode || (ParseErrorCode = {}));

// src/textmateProvider.ts
var import_path4 = __toESM(require("path"));
var TextmateProvider = class extends BaseProvider {
  constructor(channel, config, subscriptions) {
    super(config, channel);
    this.config = config;
    this.subscriptions = subscriptions;
    this.loadedFiles = /* @__PURE__ */ new Set();
    this.loadedSnippets = [];
    this.loadedLanguageIds = /* @__PURE__ */ new Set();
    this.definitions = /* @__PURE__ */ new Map();
    this.loadedRoots = /* @__PURE__ */ new Set();
  }
  async init() {
    if (this.config.loadFromExtensions) {
      for (let extension of import_coc7.extensions.all) {
        this.loadSnippetDefinition(extension).then((items) => {
          if (items == null ? void 0 : items.length) {
            items = items.filter((o) => o.languageIds.includes("all") || o.languageIds.some((id) => import_coc7.workspace.languageIds.has(id)));
            this.loadSnippetsFromDefinition(extension.id, items);
          }
        }, (e) => {
          this.error(`Error on load textmate snippets: ${e.message}`, e.stack);
        });
      }
      import_coc7.extensions.onDidLoadExtension((extension) => {
        this.loadSnippetDefinition(extension).then((items) => {
          if (items == null ? void 0 : items.length) {
            items = items.filter((o) => o.languageIds.includes("all") || o.languageIds.some((id) => import_coc7.workspace.languageIds.has(id)));
            this.loadSnippetsFromDefinition(extension.id, items);
          }
        }, (e) => {
          this.error(`Error on load textmate snippets: ${e.message}`, e.stack);
        });
      }, null, this.subscriptions);
      import_coc7.extensions.onDidUnloadExtension((id) => {
        this.loadedSnippets = this.loadedSnippets.filter((item) => {
          return item.extensionId !== id;
        });
      }, null, this.subscriptions);
    }
    let paths = this.config.snippetsRoots;
    for (let dir of paths != null ? paths : []) {
      await this.loadDefinitionFromRoot(dir);
    }
    if (this.config.projectSnippets) {
      import_coc7.workspace.workspaceFolders.forEach((folder) => {
        let fsPath = import_coc7.Uri.parse(folder.uri).fsPath;
        void this.loadFromWorkspace(fsPath);
      });
      import_coc7.workspace.onDidChangeWorkspaceFolders((e) => {
        e.removed.forEach((folder) => {
          let fsPath = import_coc7.Uri.parse(folder.uri).fsPath;
          this.loadedSnippets = this.loadedSnippets.filter((o) => {
            return !o.filepath.startsWith(fsPath + import_path4.default.sep);
          });
        });
        e.added.forEach((folder) => {
          let fsPath = import_coc7.Uri.parse(folder.uri).fsPath;
          void this.loadFromWorkspace(fsPath);
        });
      });
    }
  }
  async loadFromWorkspace(fsPath) {
    let root = import_path4.default.join(fsPath, ".vscode");
    await this.loadDefinitionFromRoot(root, false);
  }
  async loadSnippetsByFiletype(languageId) {
    if (this.loadedLanguageIds.has(languageId)) return;
    let filetypes = this.getFiletypes(languageId);
    this.info(`Loading textmate snippets from filetypes: ${filetypes.join(", ")}`);
    for (let languageId2 of filetypes) {
      if (this.loadedLanguageIds.has(languageId2)) continue;
      this.loadedLanguageIds.add(languageId2);
      for (let [extensionId, items] of this.definitions.entries()) {
        for (let item of items) {
          if (!item.languageIds.includes(languageId2)) continue;
          await this.loadSnippetsFromFile(item.filepath, item.languageIds, extensionId);
        }
      }
    }
  }
  async getSnippetFiles(filetype) {
    let filetypes = this.getFiletypes(filetype);
    filetypes.push("all");
    let filepaths = [];
    for (let def of this.loadedSnippets) {
      if (filepaths.includes(def.filepath)) continue;
      if (def.filetypes.some((ft) => filetypes.includes(ft))) {
        filepaths.push(def.filepath);
      }
    }
    return filepaths;
  }
  async getTriggerSnippets(document, position, autoTrigger) {
    var _a;
    if (autoTrigger) return [];
    let line = document.getline(position.line);
    line = line.slice(0, position.character);
    let snippets = this.getDocumentSnippets(document);
    if (!snippets || !snippets.length) return [];
    let edits = [];
    for (let snip of snippets) {
      let { prefix } = snip;
      if (!line.endsWith(prefix)) continue;
      let pre = line.slice(0, line.length - prefix.length);
      if (pre.length && /\w/.test(pre[pre.length - 1])) continue;
      edits.push({
        prefix,
        range: import_coc7.Range.create(position.line, position.character - prefix.length, position.line, position.character),
        newText: snip.body,
        location: snip.filepath,
        lnum: snip.lnum,
        description: snip.description,
        priority: (_a = snip.priority) != null ? _a : -1
      });
    }
    return edits;
  }
  getSnippets(filetype) {
    let res = [];
    let filetypes = this.getFiletypes(filetype);
    filetypes.push("all");
    for (let def of this.loadedSnippets) {
      if (filetypes.some((ft) => def.filetypes.includes(ft))) {
        let languageId = def.filetypes.includes(filetype) ? filetype : def.filetypes.find((ft) => filetypes.includes(ft));
        res.push(...toSnippets(def, languageId));
      }
    }
    res.sort((a, b) => {
      if (a.filetype != b.filetype) {
        if (a.filetype == filetype || b.filetype == filetype) {
          return a.filetype == filetype ? -1 : 1;
        }
        if (a.filetype == "all" || b.filetype == "all") {
          return a.filetype == "all" ? 1 : -1;
        }
        if (a.priority != b.priority) {
          return b.priority - a.priority;
        }
        return 0;
      }
    });
    let filtered = [];
    for (let item of res) {
      if (!filtered.find((o) => o.prefix == item.prefix && o.description == item.description)) {
        filtered.push(item);
      }
    }
    return filtered;
  }
  async loadSnippetDefinition(extension) {
    let { packageJSON } = extension;
    const arr = [];
    if (packageJSON.contributes && packageJSON.contributes.snippets) {
      let { snippets } = packageJSON.contributes;
      const extensionId = extension.id;
      for (let item of snippets) {
        let p = import_path4.default.join(extension.extensionPath, item.path);
        let exists = arr.find((o) => o.filepath == p);
        let languages3 = Array.isArray(item.language) ? item.language : [item.language];
        if (exists) {
          languages3.forEach((s) => {
            if (!exists.languageIds.includes(s)) {
              exists.languageIds.push(s);
            }
          });
          continue;
        }
        if (import_fs3.default.existsSync(p)) arr.push({ languageIds: languages3, filepath: p });
      }
      if (snippets && snippets.length) {
        this.definitions.set(extensionId, arr);
      }
    }
    return arr;
  }
  async loadDefinitionFromRoot(configPath, showWarningMessage = true) {
    var _a;
    let root = import_coc7.workspace.expand(configPath);
    let stat = await statAsync(root);
    if (!stat || !stat.isDirectory()) {
      if (showWarningMessage) this.warn(`${configPath} not a valid directory.`);
      return;
    }
    root = normalizeFilePath(root);
    if (this.loadedRoots.has(root)) return;
    this.loadedRoots.add(root);
    let files = await import_fs3.default.promises.readdir(root, "utf8");
    files = files.filter((f) => f.endsWith(".json") || f.endsWith(".code-snippets"));
    let items = (_a = this.definitions.get("")) != null ? _a : [];
    for (let file of files) {
      let filepath = import_path4.default.join(root, file);
      if (file.endsWith(".code-snippets")) {
        this.info(`Loading global snippets from: ${filepath}`);
        await this.loadSnippetsFromFile(filepath, void 0, void 0);
      } else {
        let basename = import_path4.default.basename(file, ".json");
        items.push({ languageIds: [basename], filepath });
      }
    }
    this.definitions.set("", items);
  }
  async loadSnippetsFromDefinition(extensionId, items) {
    for (let item of items) {
      if (!import_fs3.default.existsSync(item.filepath)) continue;
      await this.loadSnippetsFromFile(item.filepath, item.languageIds, extensionId);
    }
  }
  async loadSnippetsFromFile(snippetFilePath, languageIds, extensionId) {
    if (this.isLoaded(snippetFilePath) || this.isIgnored(snippetFilePath)) return;
    let contents;
    try {
      contents = await import_fs3.default.promises.readFile(snippetFilePath, "utf8");
    } catch (e) {
      this.error(`Error on readFile "${snippetFilePath}": ${e.message}`);
      return;
    }
    try {
      this.loadSnippetsFromText(snippetFilePath, extensionId, languageIds, contents);
    } catch (e) {
      this.error(`Error on load snippets from "${snippetFilePath}": ${e.message}`, e.stack);
    }
  }
  isLoaded(filepath) {
    for (let file of this.loadedFiles) {
      if (sameFile(file, filepath)) {
        return true;
      }
    }
    return false;
  }
  loadSnippetsFromText(filepath, extensionId, ids, contents) {
    let snippets = [];
    let commentLanguageId;
    let isGlobal = isGlobalSnippet(filepath);
    this.loadedFiles.add(filepath);
    try {
      let errors = [];
      let lines = contents.split(/\r?\n/);
      if (isGlobal) commentLanguageId = languageIdFromComments(lines);
      let snippetObject = parse2(contents, errors, { allowTrailingComma: true });
      if (errors.length) this.error(`Parse error of ${filepath}`, errors);
      if (snippetObject) {
        for (let key of Object.keys(snippetObject)) {
          let p = '"' + key + '"';
          let idx = lines.findIndex((line) => line.trim().startsWith(p));
          let lnum = idx == -1 ? 0 : idx;
          snippets.push(Object.assign({ lnum }, snippetObject[key]));
        }
      }
    } catch (ex) {
      this.error(`Error on parse "${filepath}": ${ex.message}`, ex.stack);
      return;
    }
    const normalizedSnippets = [];
    snippets.forEach((snip) => {
      if (!snip.prefix) return;
      let languageIds;
      if (ids && ids.length > 0) {
        languageIds = ids;
      } else if (isGlobal) {
        languageIds = snip.scope ? snip.scope.split(",") : void 0;
        if (!languageIds && commentLanguageId) languageIds = [commentLanguageId];
      }
      if (!languageIds && isGlobal) languageIds = ["all"];
      let obj = {
        prefixes: Array.isArray(snip.prefix) ? snip.prefix : [snip.prefix],
        filetypes: languageIds,
        extensionId,
        filepath,
        lnum: snip.lnum,
        body: typeof snip.body === "string" ? snip.body : snip.body.join("\n"),
        description: getDescription(snip.description),
        triggerKind: 2 /* WordBoundary */,
        priority: languageIds.includes("all") ? -60 : extensionId ? -2 : -1
      };
      normalizedSnippets.push(obj);
      this.trace(`Snippet:`, obj);
    });
    this.loadedSnippets.push(...normalizedSnippets);
    this.info(`Loaded ${normalizedSnippets.length} textmate snippets from ${filepath}`, ids);
  }
};
function getDescription(description) {
  if (typeof description === "string") return description;
  if (Array.isArray(description) && description.every((s) => typeof s === "string")) return description.join("\n");
  return void 0;
}
function toSnippets(def, languageId) {
  return def.prefixes.map((prefix) => {
    return Object.assign(omit(def, ["filetypes", "prefixes"]), {
      prefix,
      filetype: languageId
    });
  });
}
function isGlobalSnippet(filepath) {
  return filepath.endsWith(".code-snippets");
}

// src/ultisnipsProvider.ts
var import_coc8 = require("coc.nvim");
var import_fs5 = __toESM(require("fs"));
var import_os3 = __toESM(require("os"));
var import_path5 = __toESM(require("path"));
var import_util9 = __toESM(require("util"));

// src/ultisnipsParser.ts
var import_fs4 = __toESM(require("fs"));
var import_readline2 = __toESM(require("readline"));
function fixFiletype(filetype) {
  if (filetype === "javascript_react") return "javascriptreact";
  return filetype;
}
var actionMap = {
  "pre_expand": "preExpand",
  "post_expand": "postExpand",
  "post_jump": "postJump"
};
var UltiSnipsParser = class {
  constructor(channel, trace = false) {
    this.channel = channel;
    this.trace = trace;
  }
  parseUltisnipsFile(filetype, filepath) {
    const rl = import_readline2.default.createInterface({
      input: import_fs4.default.createReadStream(filepath, "utf8"),
      crlfDelay: Infinity
    });
    let actions = [];
    let pycodes = [];
    let snippets = [];
    let block;
    let preLines = [];
    let first;
    let priority = 0;
    let lnum = 0;
    let clearsnippets = null;
    let parsedContext = null;
    let extendFiletypes = [];
    rl.on("line", (line) => {
      lnum += 1;
      if (!block && (line.startsWith("#") || line.length == 0)) return;
      const [head, tail] = headTail(line);
      if (!block) {
        switch (head) {
          case "priority":
            let n = parseInt(tail.trim(), 10);
            if (!isNaN(n)) priority = n;
            break;
          case "extends":
            let fts = tail.trim().split(/,\s+/);
            for (let ft of fts) {
              ft = fixFiletype(ft);
              if (extendFiletypes.indexOf(ft) == -1) {
                extendFiletypes.push(ft);
              }
            }
            break;
          case "pre_expand":
          case "post_expand":
          case "post_jump":
            actions.push(line);
            break;
          case "clearsnippets":
            clearsnippets = priority;
            break;
          case "context":
            parsedContext = tail.replace(/^"(.+)"$/, "$1");
            break;
          case "snippet":
          case "global":
            block = head;
            first = tail;
            break;
        }
        return;
      }
      if (head == "endglobal" && block == "global") {
        block = null;
        pycodes.push(`# ${lnum - preLines.length}`, ...preLines);
        preLines = [];
        return;
      }
      if (head == "endsnippet" && block == "snippet") {
        block = null;
        try {
          let body = preLines.join("\n");
          let ms = first.match(/^(.+?)(?:\s+(?:"(.*?)")?(?:\s+"(.*?)")?(?:\s+(\w+))?)?\s*$/);
          let description = ms[2] || "";
          let option = ms[4] || "";
          let trigger = getTriggerText(ms[1], option.includes("r"));
          let regex2 = null;
          let originRegex;
          let triggers = [];
          if (option.indexOf("r") !== -1) {
            originRegex = trigger;
            let pattern = convertRegex(trigger);
            if (pattern.endsWith("$")) pattern = pattern.slice(0, -1);
            regex2 = new RegExp(`(?:${pattern})$`);
            let parsed = getRegexText(trigger);
            if (!parsed.includes("|")) {
              triggers.push(parsed);
            } else {
              triggers = parsed.split(/\|/);
            }
          } else {
            triggers.push(trigger);
          }
          for (let prefix of triggers) {
            let pm = prefix.match(/^\W+/);
            let snippet = {
              originRegex,
              context: parsedContext ? parsedContext : option.includes("e") ? ms[3] : void 0,
              filepath,
              filetype,
              prefix,
              special: pm == null ? void 0 : pm[0],
              autoTrigger: option.indexOf("A") !== -1,
              lnum: lnum - preLines.length - 2,
              triggerKind: getTriggerKind(option),
              description,
              regex: regex2,
              body,
              priority,
              actions: {},
              formatOptions: {
                noExpand: option.includes("t"),
                trimTrailingWhitespace: option.includes("m"),
                removeWhiteSpace: option.includes("s")
              }
            };
            while (actions.length) {
              const line2 = actions.pop();
              const [head2, tail2] = headTail(line2);
              let key = actionMap[head2];
              if (key) {
                snippet.actions[key] = trimQuote(tail2);
              } else {
                this.error(`Unknown UltiSnips action: ${head2}`);
              }
            }
            this.debug(`Loaded snippet`, snippet);
            snippets.push(snippet);
          }
        } catch (e) {
          this.error(`Create snippet error on: ${filepath}:${lnum - preLines.length - 1} ${e.message}`);
        } finally {
          parsedContext = null;
          preLines = [];
        }
      }
      if (block == "snippet" || block == "global") {
        preLines.push(line);
        return;
      }
    });
    return new Promise((resolve) => {
      rl.on("close", async () => {
        resolve({ snippets, clearsnippets, pythonCode: pycodes.join("\n"), extendFiletypes });
      });
    });
  }
  error(str) {
    if (!this.channel) return;
    this.channel.appendLine(`[Error ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}] ${str}`);
  }
  debug(str, data) {
    if (!this.channel || !this.trace) return;
    this.channel.appendLine(`[Debug ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}] ${str}: ${JSON.stringify(data, null, 2)}`);
  }
};
function getTriggerKind(option) {
  if (option.indexOf("i") !== -1 || option === "r") {
    return 3 /* InWord */;
  }
  if (option.indexOf("w") !== -1) {
    return 2 /* WordBoundary */;
  }
  if (option.indexOf("b") !== -1) {
    return 1 /* LineBegin */;
  }
  return 0 /* SpaceBefore */;
}

// src/ultisnipsProvider.ts
var UltiSnippetsProvider = class extends BaseProvider {
  constructor(channel, config, context) {
    super(config, channel);
    this.config = config;
    this.context = context;
    this.loadedLanguageIds = /* @__PURE__ */ new Set();
    this.errorFiles = /* @__PURE__ */ new Set();
    this.snippetFiles = [];
    this.fileItems = [];
    this.pythonSupport = true;
    import_coc8.workspace.onDidSaveTextDocument(async (doc) => {
      let uri = import_coc8.Uri.parse(doc.uri);
      if (uri.scheme != "file" || !doc.uri.endsWith(".snippets")) return;
      let filepath = uri.fsPath;
      if (!import_fs5.default.existsSync(filepath)) return;
      let idx = this.snippetFiles.findIndex((s) => sameFile(s.filepath, filepath));
      if (idx !== -1) {
        const snippetFile = this.snippetFiles[idx];
        this.snippetFiles.splice(idx, 1);
        await this.loadSnippetsFromFile({ filetype: snippetFile.filetype, filepath, directory: snippetFile.directory });
      } else {
        let filetype = filetypeFromBasename(import_path5.default.basename(filepath, ".snippets"));
        if (this.allFiletypes.includes(filetype)) await this.loadSnippetsFromFile({ filetype, filepath, directory: import_path5.default.dirname(filepath) });
      }
    }, null, this.context.subscriptions);
  }
  get directories() {
    let dirs = this.config.directories || [];
    return dirs.map((dir) => import_coc8.workspace.expand(dir));
  }
  async showPrompt() {
    if (!this.config.pythonPrompt) return;
    let name = import_coc8.workspace.isVim ? `python` : `provider-python`;
    await import_coc8.window.showWarningMessage(`The Ultisnips feature of coc-snippets requires Python support on Vim, see :h ${name}`, {
      title: "I understand, don't show this message again",
      isCloseAffordance: true
    });
    let config = import_coc8.workspace.getConfiguration("snippets.ultisnips", null);
    config.update("pythonPrompt", false, true);
  }
  async init() {
    let { nvim, env } = import_coc8.workspace;
    this.info(`Using ultisnips directories:`, this.directories);
    try {
      await nvim.call("pyxeval", ["1"]);
    } catch (e) {
      this.pythonSupport = false;
      void this.showPrompt();
    }
    this.parser = new UltiSnipsParser(this.channel, this.config.trace);
    this.fileItems = await this.loadAllFileItems(env.runtimepath);
    import_coc8.workspace.onDidRuntimePathChange(async (e) => {
      let subFolders = await this.getSubFolders();
      const newItems = [];
      for (const dir of e) {
        let res = await this.getFilesFromDirectory(dir, subFolders);
        if (res == null ? void 0 : res.length) newItems.push(...res);
      }
      let items = newItems.filter((item) => !this.fileItems.find((o) => o.filepath === item.filepath));
      if (items.length) {
        this.fileItems.push(...items);
        let { allFiletypes } = this;
        for (let item of items) {
          if (allFiletypes.includes(item.filetype)) {
            await this.loadSnippetsFromFile(item);
          }
        }
      }
    }, null, this.context.subscriptions);
    if (this.pythonSupport) {
      let filepath = this.context.asAbsolutePath("python/ultisnips.py");
      await import_coc8.workspace.nvim.call("coc#util#open_file", ["pyxfile", filepath]);
    }
  }
  async loadSnippetsByFiletype(filetype) {
    let filetypes = this.getFiletypes(filetype);
    if (!filetypes.includes("all")) filetypes.push("all");
    filetypes = filetypes.filter((filetype2) => !this.loadedLanguageIds.has(filetype2));
    if (filetypes.length == 0) return;
    let sorted = getSortedFiletypes(filetype, filetypes);
    sorted.forEach((filetype2) => this.loadedLanguageIds.add(filetype2));
    for (let ft of sorted) {
      for (let item of this.fileItems) {
        if (item.filetype === ft) {
          await this.loadSnippetsFromFile(item);
        }
      }
    }
  }
  get allFiletypes() {
    let filetypes = Array.from(import_coc8.workspace.filetypes).concat(getAllAdditionalFiletype());
    let res = /* @__PURE__ */ new Set();
    for (let ft of filetypes) {
      let arr = this.getFiletypes(ft);
      arr.forEach((val) => res.add(val));
    }
    res.add("all");
    return Array.from(res);
  }
  async loadSnippetsFromFile(fileItem) {
    let { filepath, directory, filetype } = fileItem;
    let idx = this.snippetFiles.findIndex((o) => sameFile(o.filepath, filepath));
    if (idx !== -1 || this.isIgnored(filepath)) return;
    let { snippets, pythonCode, extendFiletypes, clearsnippets } = await this.parser.parseUltisnipsFile(filetype, filepath);
    if (!this.pythonSupport) {
      snippets = snippets.filter((s) => s.regex == null && s.context == null && !s.body.includes("`!p"));
    }
    this.snippetFiles.push({
      extendFiletypes,
      clearsnippets,
      directory,
      filepath,
      filetype,
      snippets
    });
    if (extendFiletypes == null ? void 0 : extendFiletypes.length) {
      let filetypes = this.config.extends[filetype] || [];
      filetypes = filetypes.concat(extendFiletypes);
      this.config.extends[filetype] = distinct(filetypes);
      let fts = /* @__PURE__ */ new Set();
      for (let ft of extendFiletypes) {
        this.getFiletypes(ft).forEach((s) => fts.add(s));
      }
      let promises = [];
      this.fileItems.forEach((item) => {
        if (!fts.has(item.filetype)) return;
        promises.push(this.loadSnippetsFromFile(item));
      });
      await Promise.allSettled(promises);
    }
    this.info(`Loaded ${snippets.length} UltiSnip snippets from: ${filepath}`);
    if (pythonCode.trim().length > 0) {
      pythonCodes.set(filepath, { hash: createMD5(pythonCode), code: pythonCode });
      this.executePyCodesForFile(filepath).catch((e) => {
        this.error(e.message);
      });
    }
  }
  async checkContext(context) {
    if (!this.pythonSupport) return false;
    let pyCodes = [
      "import re, os, vim, string, random",
      "def __check_context():",
      `  snip = coc_ultisnips_dict['ContextSnippet']()`,
      `  context = ${context}`,
      `  vim.vars['__coc_context_result'] = True if context else False`,
      `__check_context()`
    ];
    await this.executePyCodes(pyCodes);
    return await import_coc8.workspace.nvim.getVar("__coc_context_result");
  }
  async executePyCodes(lines) {
    try {
      await import_coc8.workspace.nvim.command(`pyx ${addPythonTryCatch(lines.join("\n"))}`);
    } catch (e) {
      let err = new Error(e.message);
      err.stack = `Error on execute python code:
${lines}
` + e.stack;
      throw err;
    }
  }
  async getTriggerSnippets(document, position, autoTrigger) {
    let snippets = this.getDocumentSnippets(document);
    let line = document.getline(position.line);
    line = line.slice(0, position.character);
    if (line.length == 0) return [];
    snippets = snippets.filter((s) => {
      if (autoTrigger && !s.autoTrigger) return false;
      let match = getMatched2(s, line);
      if (match == null) return false;
      if (s.triggerKind == 3 /* InWord */) return true;
      let pre = line.slice(0, line.length - match.length);
      if (s.triggerKind == 1 /* LineBegin */) return pre.trim() == "";
      if (s.triggerKind == 0 /* SpaceBefore */) return pre.length == 0 || /\s$/.test(pre);
      if (s.triggerKind == 2 /* WordBoundary */) return pre.length == 0 || !document.isWord(pre[pre.length - 1]);
      return false;
    });
    snippets.sort((a, b) => {
      if (a.context && !b.context) return -1;
      if (b.context && !a.context) return 1;
      return 0;
    });
    let edits = [];
    let hasContext = false;
    for (let s of snippets) {
      let character;
      if (s.context) {
        let valid = await this.checkContext(s.context);
        if (!valid) continue;
        hasContext = true;
      } else if (hasContext) {
        break;
      }
      if (s.regex == null) {
        character = position.character - s.prefix.length;
      } else {
        let len = line.match(s.regex)[0].length;
        character = position.character - len;
      }
      let range = import_coc8.Range.create(position.line, character, position.line, position.character);
      edits.push({
        range,
        actions: s.actions,
        newText: s.body,
        prefix: s.prefix,
        description: s.description,
        location: s.filepath,
        lnum: s.lnum,
        priority: s.priority,
        regex: s.originRegex,
        context: s.context,
        formatOptions: s.formatOptions
      });
    }
    return edits;
  }
  async getSnippetFiles(filetype) {
    let filetypes = this.getFiletypes(filetype);
    filetypes.push("all");
    let res = [];
    for (let s of this.snippetFiles) {
      if (filetypes.includes(s.filetype)) {
        res.push(s.filepath);
      }
    }
    return res;
  }
  getSnippets(filetype) {
    let filetypes = this.getFiletypes(filetype);
    filetypes.push("all");
    let snippetFiles = this.snippetFiles.filter((o) => filetypes.indexOf(o.filetype) !== -1);
    let min = null;
    let result = [];
    snippetFiles.sort((a, b) => {
      if (a.filetype == b.filetype) return 1;
      if (a.filetype == filetype) return -1;
      return 1;
    });
    for (let file of snippetFiles) {
      let { snippets, clearsnippets } = file;
      if (typeof clearsnippets == "number") {
        min = min ? Math.max(min, clearsnippets) : clearsnippets;
      }
      for (let snip of snippets) {
        if (snip.regex || snip.context) {
          result.push(snip);
        } else {
          let idx = result.findIndex((o) => o.prefix == snip.prefix && o.triggerKind == snip.triggerKind);
          if (idx == -1) {
            result.push(snip);
          } else {
            let item = result[idx];
            if (snip.priority > item.priority) {
              result[idx] = item;
            }
          }
        }
      }
    }
    if (min != null) result = result.filter((o) => o.priority >= min);
    result.sort((a, b) => {
      if (a.context && !b.context) return -1;
      if (b.context && !a.context) return 1;
      return 0;
    });
    return result;
  }
  async loadAllFileItems(runtimepath) {
    let { directories } = this;
    let res = [];
    for (let directory of directories) {
      if (import_path5.default.isAbsolute(directory)) {
        let items = await this.getSnippetFileItems(directory);
        res.push(...items);
      }
    }
    let subFolders = await this.getSubFolders();
    let rtps = runtimepath.split(",");
    for (let rtp of rtps) {
      let items = await this.getFilesFromDirectory(rtp, subFolders);
      res.push(...items);
    }
    return res;
  }
  async getSubFolders() {
    let { directories } = this;
    directories = directories.filter((s) => !import_path5.default.isAbsolute(s));
    let dirs = await import_coc8.workspace.nvim.eval('get(g:, "UltiSnipsSnippetDirectories", [])');
    for (let dir of dirs) {
      if (directories.indexOf(dir) == -1) {
        directories.push(dir);
      }
    }
    return directories;
  }
  async getFiletype() {
    let buf = await import_coc8.workspace.nvim.buffer;
    if (buf) {
      let doc = import_coc8.workspace.getDocument(buf.id);
      if (doc) return doc.filetype;
    }
    return null;
  }
  async editSnippets(text) {
    const configuration = import_coc8.workspace.getConfiguration("snippets");
    let filetype = await this.getFiletype();
    filetype = filetype != null ? filetype : "all";
    filetype = filetype.indexOf(".") == -1 ? filetype : filetype.split(".")[0];
    const snippetsDir = await getSnippetsDirectory(configuration);
    let { nvim } = import_coc8.workspace;
    let file = import_path5.default.join(snippetsDir, `${filetype}.snippets`);
    if (!import_fs5.default.existsSync(file)) {
      await import_util9.default.promisify(import_fs5.default.writeFile)(file, documentation, "utf8");
    }
    let uri = import_coc8.Uri.file(file).toString();
    await import_coc8.workspace.jumpTo(uri, null, configuration.get("editSnippetsCommand"));
    if (text) {
      await nvim.command("normal! G");
      await nvim.command("normal! 2o");
      let position = await import_coc8.window.getCursorPosition();
      let indent = text.match(/^\s*/)[0];
      text = text.split(/\r?\n/).map((s) => s.startsWith(indent) ? s.slice(indent.length) : s).join("\n");
      let escaped = text.replace(/([$}\]])/g, "\\$1");
      let snippet = 'snippet ${1:Tab_trigger} "${2:Description}" ${3:b}\n' + escaped + "\nendsnippet";
      let edit = import_coc8.TextEdit.insert(position, snippet);
      await import_coc8.commands.executeCommand("editor.action.insertSnippet", edit, false);
    }
  }
  async getFilesFromDirectory(directory, subFolders) {
    let res = [];
    for (let folder of subFolders) {
      let items = await this.getSnippetFileItems(import_path5.default.join(directory, folder));
      res.push(...items);
    }
    return res;
  }
  /**
   * Get files in directory.
   */
  async getSnippetFileItems(directory) {
    let res = [];
    let stat = await statAsync(directory);
    if (stat && stat.isDirectory()) {
      let files = await readdirAsync(directory);
      if (files.length) {
        for (let filename of files) {
          let file = import_path5.default.join(directory, filename);
          if (file.endsWith(".snippets")) {
            let basename = import_path5.default.basename(filename, ".snippets");
            let filetype = filetypeFromBasename(basename);
            res.push({ filepath: file, directory, filetype });
          } else {
            let stat2 = await statAsync(file);
            if (stat2 && stat2.isDirectory()) {
              let files2 = await readdirAsync(file);
              for (let filename2 of files2) {
                if (filename2.endsWith(".snippets")) {
                  res.push({ filepath: import_path5.default.join(file, filename2), directory, filetype: import_path5.default.basename(file) });
                }
              }
            }
          }
        }
      }
    }
    return res;
  }
  async executePyCodesForFile(filepath) {
    let info = pythonCodes.get(filepath);
    if (!info) return;
    let { code, hash } = info;
    const tmpfile = import_path5.default.join(import_os3.default.tmpdir(), `coc-snippets-${hash}.py`);
    try {
      if (this.errorFiles.has(tmpfile)) return;
      if (!import_fs5.default.existsSync(tmpfile)) {
        let prefix = [
          "# -*- coding: utf-8 -*-\n",
          `# ${filepath}
`
        ];
        import_fs5.default.writeFileSync(tmpfile, prefix.join("\n") + code, "utf8");
      }
      this.info(`Execute python file ${tmpfile} from: ${filepath}`);
      await import_coc8.workspace.nvim.call("coc#util#open_file", ["pyxfile", tmpfile]);
    } catch (e) {
      this.errorFiles.add(tmpfile);
      this.error(`Error on execute python script ${e.stack}:`, code);
      void import_coc8.window.showErrorMessage(`Error python code from file ${filepath}: ${e.message}`);
    }
  }
  async onFiletypeChange(bufnr, filetype) {
    let filetypes = distinct([...getAdditionalFiletype(bufnr), ...this.getFiletypes(filetype)]);
    let sorted = getSortedFiletypes(filetype, filetypes);
    let files = [];
    sorted.forEach((ft) => {
      this.snippetFiles.forEach((s) => {
        if (s.filetype === ft) {
          files.push(s.filepath);
        }
      });
    });
    for (let file of files) {
      await this.executePyCodesForFile(file);
    }
  }
};
function getSortedFiletypes(filetype, filetypes) {
  let res = [];
  if (filetypes.includes("all")) res.push("all");
  let mainFiletype = filetype.split(".")[0];
  res.push(...filetypes.filter((s) => s !== mainFiletype && s !== "all"));
  if (mainFiletype.length > 0) res.push(mainFiletype);
  return res;
}
function addPythonTryCatch(code) {
  if (!import_coc8.workspace.isVim) return code;
  let lines = [
    "import traceback, vim",
    `vim.vars['errmsg'] = ''`,
    "try:"
  ];
  lines.push(...code.split("\n").map((line) => "    " + line));
  lines.push("except Exception as e:");
  lines.push(`    vim.vars['errmsg'] = traceback.format_exc()`);
  return lines.join("\n");
}
function getMatched2(snippet, line) {
  let { prefix, regex: regex2 } = snippet;
  if (regex2) {
    let ms = line.match(regex2);
    if (!ms) return void 0;
    return ms[0];
  }
  if (!line.endsWith(prefix)) return void 0;
  return prefix;
}
async function getSnippetsDirectory(configuration) {
  let snippetsDir = configuration.get("userSnippetsDirectory");
  if (snippetsDir) {
    snippetsDir = import_coc8.workspace.expand(snippetsDir);
    if (!import_path5.default.isAbsolute(snippetsDir)) {
      import_coc8.window.showWarningMessage(`snippets.userSnippetsDirectory => ${snippetsDir} should be absolute path`);
      snippetsDir = null;
    }
  }
  if (!snippetsDir) snippetsDir = import_path5.default.join(import_path5.default.dirname(import_coc8.workspace.env.extensionRoot), "ultisnips");
  if (!import_fs5.default.existsSync(snippetsDir)) {
    await import_fs5.default.promises.mkdir(snippetsDir, { recursive: true });
  }
  return snippetsDir;
}

// src/index.ts
function checkBufferVariable(doc) {
  let filetypes = doc.getVar("snippets_filetypes", void 0);
  if (!Array.isArray(filetypes)) filetypes = void 0;
  if (!filetypes) {
    let arr = getAdditionalFiletype(doc.bufnr);
    if (arr) doc.buffer.setVar("coc_snippets_filetypes", arr, true);
  } else if (filetypes.length > 0) {
    addFiletypes(doc.bufnr, filetypes);
  }
}
function enableSnippetsFiletype(subscriptions) {
  let { nvim } = import_coc9.workspace;
  const rtp = import_coc9.workspace.env.runtimepath;
  let paths = rtp.split(",");
  let idx = paths.findIndex((s) => /^ultisnips$/i.test(import_path6.default.basename(s)));
  if (idx === -1 && !import_coc9.workspace.env.isCygwin) {
    let directory = import_path6.default.resolve(__dirname, "..");
    nvim.command("autocmd BufNewFile,BufRead *.snippets setf snippets", true);
    nvim.command(`execute 'noa set rtp+='.fnameescape('${directory.replace(/'/g, "''")}')`, true);
  }
  import_coc9.workspace.documents.forEach((doc) => {
    if (doc.uri.endsWith(".snippets")) {
      doc.buffer.setOption("filetype", "snippets", true);
    }
    checkBufferVariable(doc);
  });
  import_coc9.workspace.onDidOpenTextDocument(async (document) => {
    if (document.uri.endsWith(".snippets")) {
      let doc = import_coc9.workspace.getDocument(document.uri);
      let buf = nvim.createBuffer(doc.bufnr);
      buf.setOption("filetype", "snippets", true);
    }
    checkBufferVariable(import_coc9.workspace.getDocument(document.bufnr));
  }, null, subscriptions);
}
async function snippetSelect() {
  let doc = await import_coc9.workspace.document;
  if (!doc) return;
  let { nvim } = import_coc9.workspace;
  let mode = await nvim.call("visualmode");
  if (["v", "V"].indexOf(mode) == -1) {
    import_coc9.window.showWarningMessage(`visual mode ${mode} not supported`);
    return;
  }
  let range = await import_coc9.window.getSelectedRange(mode);
  if (mode == "V" && range.end.character == 0) {
    let line = range.end.line - 1;
    let character = doc.getline(line).length;
    range.end = import_coc9.Position.create(line, character);
  }
  let text = doc.textDocument.getText(range);
  const { start, end } = range;
  await nvim.call("feedkeys", ["i", "in"]);
  if (mode == "v") {
    await doc.applyEdits([{ range, newText: "" }]);
  } else {
    let currline = doc.getline(start.line);
    let indent = currline.match(/^\s*/)[0];
    let lines = text.split(/\r?\n/);
    lines = lines.map((s) => s.startsWith(indent) ? s.slice(indent.length) : s);
    text = lines.join("\n");
    range = import_coc9.Range.create(import_coc9.Position.create(start.line, indent.length), end);
    await doc.applyEdits([{ range, newText: "" }]);
  }
  await nvim.setVar("coc_selected_text", text);
  await import_coc9.window.moveTo(range.start);
}
async function activate(context) {
  var _a;
  let { subscriptions } = context;
  const { nvim } = import_coc9.workspace;
  const configuration = import_coc9.workspace.getConfiguration("snippets", null);
  const filetypeExtends = configuration.get("extends", {});
  const trace = configuration.get("trace", "error");
  const channel = import_coc9.window.createOutputChannel("snippets");
  subscriptions.push(channel);
  const manager = new ProviderManager(channel, subscriptions, configuration);
  import_coc9.events.on("ready", () => {
    enableSnippetsFiletype(subscriptions);
  }, null, subscriptions);
  subscriptions.push(import_coc9.commands.registerCommand("snippets.addFiletypes", async (...args) => {
    let list = args.filter((s) => typeof s === "string");
    if (list.length === 0) {
      let res = await import_coc9.window.requestInput("Filetype to add", "", { position: "center" });
      if (res == "") return;
      list = res.split(".");
    }
    let filetypes = list.join(".").split(".");
    let buf = await nvim.buffer;
    addFiletypes(buf.id, filetypes);
    let curr = getAdditionalFiletype(buf.id);
    buf.setVar("coc_snippets_filetypes", curr, true);
    manager.loadSnippetsByFiletype(filetypes.join("."));
  }));
  import_coc9.events.on("CompleteDone", (item) => {
    if (item && item["data"] && item["data"]["snip"]) {
      let snip = item["data"]["snip"];
      setLastSnippet(snip.filepath, snip.lnum);
    }
  }, null, context.subscriptions);
  let excludes = configuration.get("excludePatterns", []);
  if (!Array.isArray(excludes)) excludes = [];
  excludes = excludes.map((p) => import_coc9.workspace.expand(p));
  if (configuration.get("ultisnips.enable", true)) {
    const snippetsDir = await getSnippetsDirectory(configuration);
    let config = configuration.get("ultisnips", {});
    let c = import_merge.default.recursive(true, config, {
      excludes,
      pythonPrompt: configuration.get("ultisnips.pythonPrompt", true),
      extends: import_merge.default.recursive(true, {}, filetypeExtends)
    });
    c.directories = c.directories ? c.directories.slice() : [];
    if (Array.isArray(c.directories) && snippetsDir && c.directories.findIndex((dir) => sameFile(dir, snippetsDir)) == -1) {
      c.directories.push(snippetsDir);
    }
    let provider = new UltiSnippetsProvider(channel, c, context);
    manager.regist(provider, "ultisnips");
    subscriptions.push(import_coc9.commands.registerCommand("snippets.editSnippets", provider.editSnippets.bind(provider)));
  }
  if (configuration.loadFromExtensions || ((_a = configuration.textmateSnippetsRoots) == null ? void 0 : _a.length) > 0) {
    const config = {
      loadFromExtensions: configuration.get("loadFromExtensions", true),
      snippetsRoots: configuration.get("textmateSnippetsRoots", []),
      projectSnippets: configuration.get("loadVSCodeProjectSnippets", true),
      extends: import_merge.default.recursive(true, {}, filetypeExtends),
      trace: trace == "verbose",
      excludes
    };
    let provider = new TextmateProvider(channel, config, subscriptions);
    manager.regist(provider, "snippets");
  }
  if (configuration.get("snipmate.enable", true)) {
    let config = {
      author: configuration.get("snipmate.author", ""),
      extends: import_merge.default.recursive(true, {}, filetypeExtends),
      trace: configuration.get("snipmate.trace", false),
      excludes
    };
    let provider = new SnipmateProvider(channel, config, subscriptions);
    manager.regist(provider, "snipmate");
  }
  if (configuration.get("massCode.enable", false)) {
    let config = {
      host: configuration.get("massCode.host", "localhost"),
      port: configuration.get("massCode.port", 3033),
      extends: import_merge.default.recursive(true, {}, filetypeExtends),
      trace: configuration.get("massCode.trace", false),
      excludes
    };
    let provider = new MassCodeProvider(channel, config);
    manager.regist(provider, "massCode");
    subscriptions.push(import_coc9.commands.registerCommand("snippets.editMassCodeSnippets", provider.createSnippet.bind(provider)));
  }
  if (configuration.get("autoTrigger", true)) {
    import_coc9.events.on("TextInsert", async (bufnr, info) => {
      let changedtick = info.changedtick;
      let doc = import_coc9.workspace.getDocument(bufnr);
      if (!doc || doc.isCommandLine || !doc.attached) return;
      let res = await waitDocument(doc, changedtick);
      if (!res) return;
      changedtick = doc.changedtick;
      let position = import_coc9.Position.create(info.lnum - 1, info.pre.length);
      let edits = await manager.getTriggerSnippets(bufnr, true, position);
      if (doc.changedtick != changedtick) return;
      if (edits.length == 0) return;
      if (edits.length > 1) {
        channel.appendLine(`Multiple snippets found on auto trigger: ${JSON.stringify(edits, null, 2)}`);
        import_coc9.window.showWarningMessage("Multiple snippets found on auto trigger");
        await import_coc9.commands.executeCommand("workspace.showOutput", "snippets");
      }
      await insertSnippetEdit(edits[0]);
    }, null, subscriptions);
  }
  manager.init().catch((e) => {
    channel.appendLine(`[Error ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}] Error on init: ${e.stack}`);
  });
  if (manager.hasProvider) {
    let disposable = import_coc9.languages.registerCompletionItemProvider(
      "snippets",
      configuration.get("shortcut", "S"),
      null,
      manager,
      configuration.get("triggerCharacters", []),
      configuration.get("priority", 90)
    );
    subscriptions.push(disposable);
  }
  async function fallback() {
    await nvim.call("coc#start", [{ source: "snippets" }]);
  }
  async function doExpand(bufnr) {
    let edits = await manager.getTriggerSnippets(bufnr);
    if (edits.length == 0) return false;
    if (edits.length == 1) {
      await insertSnippetEdit(edits[0]);
    } else {
      setTimeout(async () => {
        let idx = await import_coc9.window.showMenuPicker(edits.map((e) => e.description || e.prefix), { title: "choose snippet" });
        if (idx == -1) return;
        await insertSnippetEdit(edits[idx]);
      }, 10);
      return true;
    }
    return true;
  }
  subscriptions.push(import_coc9.workspace.registerKeymap(["x"], "convert-snippet", async () => {
    let mode = await import_coc9.workspace.nvim.call("visualmode");
    if (!mode) return;
    let doc = await import_coc9.workspace.document;
    if (!doc) return;
    let range = await import_coc9.window.getSelectedRange(mode);
    let text = doc.textDocument.getText(range);
    if (text) await import_coc9.commands.executeCommand("snippets.editSnippets", text);
  }, { sync: false }));
  subscriptions.push(import_coc9.commands.registerCommand("snippets.openOutput", () => {
    void import_coc9.window.showOutputChannel("snippets", false);
  }));
  subscriptions.push(import_coc9.commands.registerCommand("snippets.openSnippetFiles", async () => {
    let buf = await nvim.buffer;
    let doc = import_coc9.workspace.getDocument(buf.id);
    if (!doc) {
      import_coc9.window.showErrorMessage("Document not found");
      return;
    }
    let filetype = getSnippetFiletype(doc);
    let files = await manager.getSnippetFiles(filetype);
    if (!files.length) {
      import_coc9.window.showWarningMessage("No related snippet file found");
      return;
    }
    let file = await import_coc9.window.showQuickPick(files, { title: "choose snippet file:" });
    if (!file) return;
    let uri = import_coc9.Uri.file(file).toString();
    await import_coc9.workspace.jumpTo(uri, null, configuration.get("editSnippetsCommand"));
  }));
  const expand = async () => {
    let bufnr = await nvim.eval('bufnr("%")');
    let expanded = await doExpand(bufnr);
    if (!expanded) await fallback();
  };
  const expandJump = async () => {
    let bufnr = await nvim.eval('bufnr("%")');
    let expanded = await doExpand(bufnr);
    if (!expanded) {
      let session = import_coc9.snippetManager.getSession(bufnr);
      if (session && session.isActive) {
        await nvim.call("coc#_cancel", []);
        await import_coc9.snippetManager.nextPlaceholder();
        return;
      }
      await fallback();
    }
  };
  subscriptions.push(import_coc9.workspace.registerKeymap(["i"], "snippets-expand", expand, { silent: true, sync: true, cancel: true }));
  subscriptions.push(import_coc9.workspace.registerKeymap(["i"], "snippets-expand-async", expand, { silent: true, sync: false, cancel: true }));
  subscriptions.push(import_coc9.workspace.registerKeymap(["i"], "snippets-expand-jump", expandJump, { silent: true, sync: true, cancel: true }));
  subscriptions.push(import_coc9.workspace.registerKeymap(["i"], "snippets-expand-jump-async", expandJump, { silent: true, sync: false, cancel: true }));
  subscriptions.push(import_coc9.workspace.registerKeymap(["v"], "snippets-select", snippetSelect, { silent: true, sync: false, cancel: true }));
  registerLanguageProvider(subscriptions, channel, configuration);
  subscriptions.push(import_coc9.listManager.registerList(new SnippetsList(import_coc9.workspace.nvim, manager)));
  return {
    expandable: async () => {
      let bufnr = await nvim.eval('bufnr("%")');
      let edits = await manager.getTriggerSnippets(bufnr);
      return edits && edits.length > 0;
    }
  };
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  activate
});
