var ERRORCLASS = "error";
function wordRegexp(e) {
  return /* @__PURE__ */ RegExp("^((" + e.join(")|(") + "))\\b");
}
var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/, delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/, identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/, atProp = /^@[_A-Za-z$][_A-Za-z$0-9]*/, wordOperators = wordRegexp([
  "and",
  "or",
  "not",
  "is",
  "isnt",
  "in",
  "instanceof",
  "typeof"
]), indentKeywords = [
  "for",
  "while",
  "loop",
  "if",
  "unless",
  "else",
  "switch",
  "try",
  "catch",
  "finally",
  "class"
], keywords = wordRegexp(indentKeywords.concat([
  "break",
  "by",
  "continue",
  "debugger",
  "delete",
  "do",
  "in",
  "of",
  "new",
  "return",
  "then",
  "this",
  "@",
  "throw",
  "when",
  "until",
  "extends"
]));
indentKeywords = wordRegexp(indentKeywords);
var stringPrefixes = /^('{3}|\"{3}|['\"])/, regexPrefixes = /^(\/{3}|\/)/, constants = wordRegexp([
  "Infinity",
  "NaN",
  "undefined",
  "null",
  "true",
  "false",
  "on",
  "off",
  "yes",
  "no"
]);
function tokenBase(c, m) {
  if (c.sol()) {
    m.scope.align === null && (m.scope.align = false);
    var h = m.scope.offset;
    if (c.eatSpace()) {
      var g = c.indentation();
      return g > h && m.scope.type == "coffee" ? "indent" : g < h ? "dedent" : null;
    } else h > 0 && dedent(c, m);
  }
  if (c.eatSpace()) return null;
  var _ = c.peek();
  if (c.match("####")) return c.skipToEnd(), "comment";
  if (c.match("###")) return m.tokenize = longComment, m.tokenize(c, m);
  if (_ === "#") return c.skipToEnd(), "comment";
  if (c.match(/^-?[0-9\.]/, false)) {
    var v = false;
    if (c.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i) && (v = true), c.match(/^-?\d+\.\d*/) && (v = true), c.match(/^-?\.\d+/) && (v = true), v) return c.peek() == "." && c.backUp(1), "number";
    var y = false;
    if (c.match(/^-?0x[0-9a-f]+/i) && (y = true), c.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/) && (y = true), c.match(/^-?0(?![\dx])/i) && (y = true), y) return "number";
  }
  if (c.match(stringPrefixes)) return m.tokenize = tokenFactory(c.current(), false, "string"), m.tokenize(c, m);
  if (c.match(regexPrefixes)) {
    if (c.current() != "/" || c.match(/^.*\//, false)) return m.tokenize = tokenFactory(c.current(), true, "string.special"), m.tokenize(c, m);
    c.backUp(1);
  }
  return c.match(operators) || c.match(wordOperators) ? "operator" : c.match(delimiters) ? "punctuation" : c.match(constants) ? "atom" : c.match(atProp) || m.prop && c.match(identifiers) ? "property" : c.match(keywords) ? "keyword" : c.match(identifiers) ? "variable" : (c.next(), ERRORCLASS);
}
function tokenFactory(e, c, l) {
  return function(u, d) {
    for (; !u.eol(); ) if (u.eatWhile(/[^'"\/\\]/), u.eat("\\")) {
      if (u.next(), c && u.eol()) return l;
    } else if (u.match(e)) return d.tokenize = tokenBase, l;
    else u.eat(/['"\/]/);
    return c && (d.tokenize = tokenBase), l;
  };
}
function longComment(e, c) {
  for (; !e.eol(); ) {
    if (e.eatWhile(/[^#]/), e.match("###")) {
      c.tokenize = tokenBase;
      break;
    }
    e.eatWhile("#");
  }
  return "comment";
}
function indent(e, c, l = "coffee") {
  for (var u = 0, d = false, f = null, p = c.scope; p; p = p.prev) if (p.type === "coffee" || p.type == "}") {
    u = p.offset + e.indentUnit;
    break;
  }
  l === "coffee" ? c.scope.align && (c.scope.align = false) : (d = null, f = e.column() + e.current().length), c.scope = {
    offset: u,
    type: l,
    prev: c.scope,
    align: d,
    alignOffset: f
  };
}
function dedent(e, c) {
  if (c.scope.prev) if (c.scope.type === "coffee") {
    for (var l = e.indentation(), u = false, d = c.scope; d; d = d.prev) if (l === d.offset) {
      u = true;
      break;
    }
    if (!u) return true;
    for (; c.scope.prev && c.scope.offset !== l; ) c.scope = c.scope.prev;
    return false;
  } else return c.scope = c.scope.prev, false;
}
function tokenLexer(c, l) {
  var u = l.tokenize(c, l), d = c.current();
  d === "return" && (l.dedent = true), ((d === "->" || d === "=>") && c.eol() || u === "indent") && indent(c, l);
  var f = "[({".indexOf(d);
  if (f !== -1 && indent(c, l, "])}".slice(f, f + 1)), indentKeywords.exec(d) && indent(c, l), d == "then" && dedent(c, l), u === "dedent" && dedent(c, l)) return ERRORCLASS;
  if (f = "])}".indexOf(d), f !== -1) {
    for (; l.scope.type == "coffee" && l.scope.prev; ) l.scope = l.scope.prev;
    l.scope.type == d && (l.scope = l.scope.prev);
  }
  return l.dedent && c.eol() && (l.scope.type == "coffee" && l.scope.prev && (l.scope = l.scope.prev), l.dedent = false), u == "indent" || u == "dedent" ? null : u;
}
const coffeeScript = {
  name: "coffeescript",
  startState: function() {
    return {
      tokenize: tokenBase,
      scope: {
        offset: 0,
        type: "coffee",
        prev: null,
        align: false
      },
      prop: false,
      dedent: 0
    };
  },
  token: function(e, c) {
    var l = c.scope.align === null && c.scope;
    l && e.sol() && (l.align = false);
    var u = tokenLexer(e, c);
    return u && u != "comment" && (l && (l.align = true), c.prop = u == "punctuation" && e.current() == "."), u;
  },
  indent: function(e, c) {
    if (e.tokenize != tokenBase) return 0;
    var l = e.scope, u = c && "])}".indexOf(c.charAt(0)) > -1;
    if (u) for (; l.type == "coffee" && l.prev; ) l = l.prev;
    var d = u && l.type === c.charAt(0);
    return l.align ? l.alignOffset - (d ? 1 : 0) : (d ? l.prev : l).offset;
  },
  languageData: { commentTokens: { line: "#" } }
};
export {
  coffeeScript as t
};
