const T = /^class[ {]/;
function z(c) {
  return T.test(c.toString());
}
function y(c) {
  return Array.isArray(c);
}
function x(c, o) {
  return Object.prototype.hasOwnProperty.call(c, o);
}
function v(...c) {
  c.length === 1 && y(c[0]) && (c = c[0]), c = [...c];
  const o = c.pop();
  return o.$inject = c, o;
}
const G = /constructor\s*[^(]*\(\s*([^)]*)\)/m, U = /^(?:async\s+)?(?:function\s*[^(]*)?(?:\(\s*([^)]*)\)|(\w+))/m, L = /\/\*([^*]*)\*\//m;
function N(c) {
  if (typeof c != "function")
    throw new Error(`Cannot annotate "${c}". Expected a function!`);
  const o = c.toString().match(z(c) ? G : U);
  if (!o)
    return [];
  const _ = o[1] || o[2];
  return _ && _.split(",").map((s) => {
    const h = s.match(L);
    return (h && h[1] || s).trim();
  }) || [];
}
function q(c, o) {
  o = o || {
    get: function(t, r) {
      if (_.push(t), r === false)
        return null;
      throw j(`No provider for "${t}"!`);
    }
  };
  const _ = [], s = this._providers = Object.create(o._providers || null), h = this._instances = /* @__PURE__ */ Object.create(null), E = h.injector = this, j = function(t) {
    const r = _.join(" -> ");
    return _.length = 0, new Error(r ? `${t} (Resolving: ${r})` : t);
  };
  function O(t, r) {
    if (!s[t] && t.indexOf(".") !== -1) {
      const n = t.split(".");
      let e = O(n.shift());
      for (; n.length; )
        e = e[n.shift()];
      return e;
    }
    if (x(h, t))
      return h[t];
    if (x(s, t)) {
      if (_.indexOf(t) !== -1)
        throw _.push(t), j("Cannot resolve circular dependency!");
      return _.push(t), h[t] = s[t][0](s[t][1]), _.pop(), h[t];
    }
    return o.get(t, r);
  }
  function b(t, r) {
    if (typeof r > "u" && (r = {}), typeof t != "function")
      if (y(t))
        t = v(t.slice());
      else
        throw j(`Cannot invoke "${t}". Expected a function!`);
    const e = (t.$inject || N(t)).map((u) => x(r, u) ? r[u] : O(u));
    return {
      fn: t,
      dependencies: e
    };
  }
  function g(t) {
    const {
      fn: r,
      dependencies: n
    } = b(t), e = Function.prototype.bind.apply(r, [null].concat(n));
    return new e();
  }
  function w(t, r, n) {
    const {
      fn: e,
      dependencies: u
    } = b(t, n);
    return e.apply(r, u);
  }
  function F(t) {
    return v((r) => t.get(r));
  }
  function A(t, r) {
    if (r && r.length) {
      const n = /* @__PURE__ */ Object.create(null), e = /* @__PURE__ */ Object.create(null), u = [], l = [], d = [];
      let i, p, f, C;
      for (let a in s)
        i = s[a], r.indexOf(a) !== -1 && (i[2] === "private" ? (p = u.indexOf(i[3]), p === -1 ? (f = i[3].createChild([], r), C = F(f), u.push(i[3]), l.push(f), d.push(C), n[a] = [C, a, "private", f]) : n[a] = [d[p], a, "private", l[p]]) : n[a] = [i[2], i[1]], e[a] = true), (i[2] === "factory" || i[2] === "type") && i[1].$scope && r.forEach((S) => {
          i[1].$scope.indexOf(S) !== -1 && (n[a] = [i[2], i[1]], e[S] = true);
        });
      r.forEach((a) => {
        if (!e[a])
          throw new Error('No provider for "' + a + '". Cannot use provider from the parent!');
      }), t.unshift(n);
    }
    return new q(t, E);
  }
  const M = {
    factory: w,
    type: g,
    value: function(t) {
      return t;
    }
  };
  function $(t, r) {
    const n = t.__init__ || [];
    return function() {
      n.forEach((e) => {
        typeof e == "string" ? r.get(e) : r.invoke(e);
      });
    };
  }
  function P(t) {
    const r = t.__exports__;
    if (r) {
      const n = t.__modules__, e = Object.keys(t).reduce((p, f) => (f !== "__exports__" && f !== "__modules__" && f !== "__init__" && f !== "__depends__" && (p[f] = t[f]), p), /* @__PURE__ */ Object.create(null)), u = (n || []).concat(e), l = A(u), d = v(function(p) {
        return l.get(p);
      });
      r.forEach(function(p) {
        s[p] = [d, p, "private", l];
      });
      const i = (t.__init__ || []).slice();
      return i.unshift(function() {
        l.init();
      }), t = Object.assign({}, t, {
        __init__: i
      }), $(t, l);
    }
    return Object.keys(t).forEach(function(n) {
      if (n === "__init__" || n === "__depends__")
        return;
      if (t[n][2] === "private") {
        s[n] = t[n];
        return;
      }
      const e = t[n][0], u = t[n][1];
      s[n] = [M[e], B(e, u), e];
    }), $(t, E);
  }
  function R(t, r) {
    return t.indexOf(r) !== -1 || (t = (r.__depends__ || []).reduce(R, t), t.indexOf(r) !== -1) ? t : t.concat(r);
  }
  function I(t) {
    const r = t.reduce(R, []).map(P);
    let n = false;
    return function() {
      n || (n = true, r.forEach((e) => e()));
    };
  }
  this.get = O, this.invoke = w, this.instantiate = g, this.createChild = A, this.init = I(c);
}
function B(c, o) {
  return c !== "value" && y(o) && (o = v(o.slice())), o;
}
export {
  q as Injector,
  v as annotate,
  N as parseAnnotations
};
