import { __require as S } from "./at-rule.js";
import { __require as x } from "./comment.js";
import { __require as A } from "./declaration.js";
import { __require as T } from "./root.js";
import { __require as R } from "./rule.js";
import { __require as W } from "./tokenize.js";
var m, g;
function U() {
  if (g) return m;
  g = 1;
  let b = S(), _ = x(), F = A(), q = T(), w = R(), y = W();
  const d = {
    empty: !0,
    space: !0
  };
  function z(u) {
    for (let e = u.length - 1; e >= 0; e--) {
      let t = u[e], r = t[3] || t[2];
      if (r) return r;
    }
  }
  class P {
    constructor(e) {
      this.input = e, this.root = new q(), this.current = this.root, this.spaces = "", this.semicolon = !1, this.createTokenizer(), this.root.source = { input: e, start: { column: 1, line: 1, offset: 0 } };
    }
    atrule(e) {
      let t = new b();
      t.name = e[1].slice(1), t.name === "" && this.unnamedAtrule(t, e), this.init(t, e[2]);
      let r, s, i, o = !1, h = !1, n = [], l = [];
      for (; !this.tokenizer.endOfFile(); ) {
        if (e = this.tokenizer.nextToken(), r = e[0], r === "(" || r === "[" ? l.push(r === "(" ? ")" : "]") : r === "{" && l.length > 0 ? l.push("}") : r === l[l.length - 1] && l.pop(), l.length === 0)
          if (r === ";") {
            t.source.end = this.getPosition(e[2]), t.source.end.offset++, this.semicolon = !0;
            break;
          } else if (r === "{") {
            h = !0;
            break;
          } else if (r === "}") {
            if (n.length > 0) {
              for (i = n.length - 1, s = n[i]; s && s[0] === "space"; )
                s = n[--i];
              s && (t.source.end = this.getPosition(s[3] || s[2]), t.source.end.offset++);
            }
            this.end(e);
            break;
          } else
            n.push(e);
        else
          n.push(e);
        if (this.tokenizer.endOfFile()) {
          o = !0;
          break;
        }
      }
      t.raws.between = this.spacesAndCommentsFromEnd(n), n.length ? (t.raws.afterName = this.spacesAndCommentsFromStart(n), this.raw(t, "params", n), o && (e = n[n.length - 1], t.source.end = this.getPosition(e[3] || e[2]), t.source.end.offset++, this.spaces = t.raws.between, t.raws.between = "")) : (t.raws.afterName = "", t.params = ""), h && (t.nodes = [], this.current = t);
    }
    checkMissedSemicolon(e) {
      let t = this.colon(e);
      if (t === !1) return;
      let r = 0, s;
      for (let i = t - 1; i >= 0 && (s = e[i], !(s[0] !== "space" && (r += 1, r === 2))); i--)
        ;
      throw this.input.error(
        "Missed semicolon",
        s[0] === "word" ? s[3] + 1 : s[2]
      );
    }
    colon(e) {
      let t = 0, r, s, i;
      for (let [o, h] of e.entries()) {
        if (s = h, i = s[0], i === "(" && (t += 1), i === ")" && (t -= 1), t === 0 && i === ":")
          if (!r)
            this.doubleColon(s);
          else {
            if (r[0] === "word" && r[1] === "progid")
              continue;
            return o;
          }
        r = s;
      }
      return !1;
    }
    comment(e) {
      let t = new _();
      this.init(t, e[2]), t.source.end = this.getPosition(e[3] || e[2]), t.source.end.offset++;
      let r = e[1].slice(2, -2);
      if (/^\s*$/.test(r))
        t.text = "", t.raws.left = r, t.raws.right = "";
      else {
        let s = r.match(/^(\s*)([^]*\S)(\s*)$/);
        t.text = s[2], t.raws.left = s[1], t.raws.right = s[3];
      }
    }
    createTokenizer() {
      this.tokenizer = y(this.input);
    }
    decl(e, t) {
      let r = new F();
      this.init(r, e[0][2]);
      let s = e[e.length - 1];
      for (s[0] === ";" && (this.semicolon = !0, e.pop()), r.source.end = this.getPosition(
        s[3] || s[2] || z(e)
      ), r.source.end.offset++; e[0][0] !== "word"; )
        e.length === 1 && this.unknownWord(e), r.raws.before += e.shift()[1];
      for (r.source.start = this.getPosition(e[0][2]), r.prop = ""; e.length; ) {
        let l = e[0][0];
        if (l === ":" || l === "space" || l === "comment")
          break;
        r.prop += e.shift()[1];
      }
      r.raws.between = "";
      let i;
      for (; e.length; )
        if (i = e.shift(), i[0] === ":") {
          r.raws.between += i[1];
          break;
        } else
          i[0] === "word" && /\w/.test(i[1]) && this.unknownWord([i]), r.raws.between += i[1];
      (r.prop[0] === "_" || r.prop[0] === "*") && (r.raws.before += r.prop[0], r.prop = r.prop.slice(1));
      let o = [], h;
      for (; e.length && (h = e[0][0], !(h !== "space" && h !== "comment")); )
        o.push(e.shift());
      this.precheckMissedSemicolon(e);
      for (let l = e.length - 1; l >= 0; l--) {
        if (i = e[l], i[1].toLowerCase() === "!important") {
          r.important = !0;
          let c = this.stringFrom(e, l);
          c = this.spacesFromEnd(e) + c, c !== " !important" && (r.raws.important = c);
          break;
        } else if (i[1].toLowerCase() === "important") {
          let c = e.slice(0), f = "";
          for (let a = l; a > 0; a--) {
            let p = c[a][0];
            if (f.trim().startsWith("!") && p !== "space")
              break;
            f = c.pop()[1] + f;
          }
          f.trim().startsWith("!") && (r.important = !0, r.raws.important = f, e = c);
        }
        if (i[0] !== "space" && i[0] !== "comment")
          break;
      }
      e.some((l) => l[0] !== "space" && l[0] !== "comment") && (r.raws.between += o.map((l) => l[1]).join(""), o = []), this.raw(r, "value", o.concat(e), t), r.value.includes(":") && !t && this.checkMissedSemicolon(e);
    }
    doubleColon(e) {
      throw this.input.error(
        "Double colon",
        { offset: e[2] },
        { offset: e[2] + e[1].length }
      );
    }
    emptyRule(e) {
      let t = new w();
      this.init(t, e[2]), t.selector = "", t.raws.between = "", this.current = t;
    }
    end(e) {
      this.current.nodes && this.current.nodes.length && (this.current.raws.semicolon = this.semicolon), this.semicolon = !1, this.current.raws.after = (this.current.raws.after || "") + this.spaces, this.spaces = "", this.current.parent ? (this.current.source.end = this.getPosition(e[2]), this.current.source.end.offset++, this.current = this.current.parent) : this.unexpectedClose(e);
    }
    endFile() {
      this.current.parent && this.unclosedBlock(), this.current.nodes && this.current.nodes.length && (this.current.raws.semicolon = this.semicolon), this.current.raws.after = (this.current.raws.after || "") + this.spaces, this.root.source.end = this.getPosition(this.tokenizer.position());
    }
    freeSemicolon(e) {
      if (this.spaces += e[1], this.current.nodes) {
        let t = this.current.nodes[this.current.nodes.length - 1];
        t && t.type === "rule" && !t.raws.ownSemicolon && (t.raws.ownSemicolon = this.spaces, this.spaces = "", t.source.end = this.getPosition(e[2]), t.source.end.offset += t.raws.ownSemicolon.length);
      }
    }
    // Helpers
    getPosition(e) {
      let t = this.input.fromOffset(e);
      return {
        column: t.col,
        line: t.line,
        offset: e
      };
    }
    init(e, t) {
      this.current.push(e), e.source = {
        input: this.input,
        start: this.getPosition(t)
      }, e.raws.before = this.spaces, this.spaces = "", e.type !== "comment" && (this.semicolon = !1);
    }
    other(e) {
      let t = !1, r = null, s = !1, i = null, o = [], h = e[1].startsWith("--"), n = [], l = e;
      for (; l; ) {
        if (r = l[0], n.push(l), r === "(" || r === "[")
          i || (i = l), o.push(r === "(" ? ")" : "]");
        else if (h && s && r === "{")
          i || (i = l), o.push("}");
        else if (o.length === 0)
          if (r === ";")
            if (s) {
              this.decl(n, h);
              return;
            } else
              break;
          else if (r === "{") {
            this.rule(n);
            return;
          } else if (r === "}") {
            this.tokenizer.back(n.pop()), t = !0;
            break;
          } else r === ":" && (s = !0);
        else r === o[o.length - 1] && (o.pop(), o.length === 0 && (i = null));
        l = this.tokenizer.nextToken();
      }
      if (this.tokenizer.endOfFile() && (t = !0), o.length > 0 && this.unclosedBracket(i), t && s) {
        if (!h)
          for (; n.length && (l = n[n.length - 1][0], !(l !== "space" && l !== "comment")); )
            this.tokenizer.back(n.pop());
        this.decl(n, h);
      } else
        this.unknownWord(n);
    }
    parse() {
      let e;
      for (; !this.tokenizer.endOfFile(); )
        switch (e = this.tokenizer.nextToken(), e[0]) {
          case "space":
            this.spaces += e[1];
            break;
          case ";":
            this.freeSemicolon(e);
            break;
          case "}":
            this.end(e);
            break;
          case "comment":
            this.comment(e);
            break;
          case "at-word":
            this.atrule(e);
            break;
          case "{":
            this.emptyRule(e);
            break;
          default:
            this.other(e);
            break;
        }
      this.endFile();
    }
    precheckMissedSemicolon() {
    }
    raw(e, t, r, s) {
      let i, o, h = r.length, n = "", l = !0, c, f;
      for (let a = 0; a < h; a += 1)
        i = r[a], o = i[0], o === "space" && a === h - 1 && !s ? l = !1 : o === "comment" ? (f = r[a - 1] ? r[a - 1][0] : "empty", c = r[a + 1] ? r[a + 1][0] : "empty", !d[f] && !d[c] ? n.slice(-1) === "," ? l = !1 : n += i[1] : l = !1) : n += i[1];
      if (!l) {
        let a = r.reduce((p, C) => p + C[1], "");
        e.raws[t] = { raw: a, value: n };
      }
      e[t] = n;
    }
    rule(e) {
      e.pop();
      let t = new w();
      this.init(t, e[0][2]), t.raws.between = this.spacesAndCommentsFromEnd(e), this.raw(t, "selector", e), this.current = t;
    }
    spacesAndCommentsFromEnd(e) {
      let t, r = "";
      for (; e.length && (t = e[e.length - 1][0], !(t !== "space" && t !== "comment")); )
        r = e.pop()[1] + r;
      return r;
    }
    // Errors
    spacesAndCommentsFromStart(e) {
      let t, r = "";
      for (; e.length && (t = e[0][0], !(t !== "space" && t !== "comment")); )
        r += e.shift()[1];
      return r;
    }
    spacesFromEnd(e) {
      let t, r = "";
      for (; e.length && (t = e[e.length - 1][0], t === "space"); )
        r = e.pop()[1] + r;
      return r;
    }
    stringFrom(e, t) {
      let r = "";
      for (let s = t; s < e.length; s++)
        r += e[s][1];
      return e.splice(t, e.length - t), r;
    }
    unclosedBlock() {
      let e = this.current.source.start;
      throw this.input.error("Unclosed block", e.line, e.column);
    }
    unclosedBracket(e) {
      throw this.input.error(
        "Unclosed bracket",
        { offset: e[2] },
        { offset: e[2] + 1 }
      );
    }
    unexpectedClose(e) {
      throw this.input.error(
        "Unexpected }",
        { offset: e[2] },
        { offset: e[2] + 1 }
      );
    }
    unknownWord(e) {
      throw this.input.error(
        "Unknown word " + e[0][1],
        { offset: e[0][2] },
        { offset: e[0][2] + e[0][1].length }
      );
    }
    unnamedAtrule(e, t) {
      throw this.input.error(
        "At-rule without name",
        { offset: t[2] },
        { offset: t[2] + t[1].length }
      );
    }
  }
  return m = P, m;
}
export {
  U as __require
};
//# sourceMappingURL=parser.js.map
