UNPKG

mobx

Version:

Simple, scalable state management.

5,391 lines 180 kB
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

const niceErrors = {
  0: `Invalid value for configuration 'enforceActions', expected 'never', 'always' or 'observed'`,
  1(annotationType, key) {
    return `Cannot apply '${annotationType}' to '${key.toString()}': Field not found.`;
  },
  /*
  2(prop) {
      return `invalid decorator for '${prop.toString()}'`
  },
  3(prop) {
      return `Cannot decorate '${prop.toString()}': action can only be used on properties with a function value.`
  },
  4(prop) {
      return `Cannot decorate '${prop.toString()}': computed can only be used on getter properties.`
  },
  */
  5: "'keys()' can only be used on observable objects, arrays, sets and maps",
  6: "'values()' can only be used on observable objects, arrays, sets and maps",
  7: "'entries()' can only be used on observable objects, arrays and maps",
  8: "'set()' can only be used on observable objects, arrays and maps",
  9: "'remove()' can only be used on observable objects, arrays and maps",
  10: "'has()' can only be used on observable objects, arrays and maps",
  11: "'get()' can only be used on observable objects, arrays and maps",
  12: `Invalid annotation`,
  13: `Dynamic observable objects cannot be frozen. If you're passing observables to 3rd party component/function that calls Object.freeze, pass copy instead: toJS(observable)`,
  14: "Intercept handlers should return nothing or a change object",
  15: `Observable arrays cannot be frozen. If you're passing observables to 3rd party component/function that calls Object.freeze, pass copy instead: toJS(observable)`,
  16: `Modification exception: the internal structure of an observable array was changed.`,
  19(other) {
    return "Cannot initialize from classes that inherit from Map: " + other.constructor.name;
  },
  20(other) {
    return "Cannot initialize map from " + other;
  },
  21(dataStructure) {
    return `Cannot convert to map from '${dataStructure}'`;
  },
  23: "It is not possible to get index atoms from arrays",
  24(thing) {
    return "Cannot obtain administration from " + thing;
  },
  25(property, name) {
    return `the entry '${property}' does not exist in the observable map '${name}'`;
  },
  26: "please specify a property",
  27(property, name) {
    return `no observable property '${property.toString()}' found on the observable object '${name}'`;
  },
  28(thing) {
    return "Cannot obtain atom from " + thing;
  },
  29: "Expecting some object",
  30: "invalid action stack. did you forget to finish an action?",
  31: "missing option for computed: get",
  32(name, derivation) {
    return `Cycle detected in computation ${name}: ${derivation}`;
  },
  33(name) {
    return `The setter of computed value '${name}' is trying to update itself. Did you intend to update an _observable_ value, instead of the computed property?`;
  },
  34(name) {
    return `[ComputedValue '${name}'] It is not possible to assign a new value to a computed value.`;
  },
  35: "There are multiple, different versions of MobX active. Make sure MobX is loaded only once or use `configure({ isolateGlobalState: true })`",
  36: "isolateGlobalState should be called before MobX is running any reactions",
  37(method) {
    return `[mobx] \`observableArray.${method}()\` mutates the array in-place, which is not allowed inside a derivation. Use \`array.slice().${method}()\` instead`;
  },
  38: "'ownKeys()' can only be used on observable objects",
  39: "'defineProperty()' can only be used on observable objects",
  40(length) {
    return "Out of range: " + length;
  },
  41(other) {
    return "Cannot initialize set from " + other;
  },
  42(key) {
    return `Invalid index: '${key}'`;
  },
  43(annotationType, name, kind) {
    return `Cannot apply '${annotationType}' to '${name}' (kind: ${kind}):` + `\n'${annotationType}' can only be used on properties with a function value.`;
  },
  44(annotationType) {
    return `'${annotationType}' can only be used with 'makeObservable'`;
  }
};
const errors = niceErrors ;
function die(error, ...args) {
  {
    let e = typeof error === "string" ? error : errors[error];
    if (typeof e === "function") e = e.apply(null, args);
    throw new Error(`[MobX] ${e}`);
  }
}

// We shorten anything used > 5 times
const assign = Object.assign;
const getDescriptor = Object.getOwnPropertyDescriptor;
const defineProperty = Object.defineProperty;
const objectPrototype = Object.prototype;
const EMPTY_ARRAY = [];
Object.freeze(EMPTY_ARRAY);
const EMPTY_OBJECT = {};
Object.freeze(EMPTY_OBJECT);
const plainObjectString = /*#__PURE__*/Object.toString();
function getNextId() {
  return ++globalState.mobxGuid;
}
/**
 * Makes sure that the provided function is invoked at most once.
 */
function once(func) {
  let invoked = false;
  return function () {
    if (invoked) {
      return;
    }
    invoked = true;
    return func.apply(this, arguments);
  };
}
const noop = () => {};
function isFunction(fn) {
  return typeof fn === "function";
}
function isStringish(value) {
  const t = typeof value;
  switch (t) {
    case "string":
    case "symbol":
    case "number":
      return true;
  }
  return false;
}
function isObject(value) {
  return value !== null && typeof value === "object";
}
function isPlainObject(value) {
  if (!isObject(value)) {
    return false;
  }
  const proto = Object.getPrototypeOf(value);
  if (proto == null) {
    return true;
  }
  const protoConstructor = hasProp(proto, "constructor") && proto.constructor;
  return typeof protoConstructor === "function" && protoConstructor.toString() === plainObjectString;
}
// https://stackoverflow.com/a/37865170
function isGenerator(obj) {
  const constructor = obj == null ? void 0 : obj.constructor;
  if (!constructor) {
    return false;
  }
  if ("GeneratorFunction" === constructor.name || "GeneratorFunction" === constructor.displayName) {
    return true;
  }
  return false;
}
function addHiddenProp(object, propName, value) {
  defineProperty(object, propName, {
    enumerable: false,
    writable: true,
    configurable: true,
    value
  });
}
function addHiddenFinalProp(object, propName, value) {
  defineProperty(object, propName, {
    enumerable: false,
    writable: false,
    configurable: true,
    value
  });
}
function createInstanceofPredicate(name, theClass) {
  const propName = "isMobX" + name;
  theClass.prototype[propName] = true;
  return function (x) {
    return isObject(x) && x[propName] === true;
  };
}
/**
 * Yields true for both native and observable Map, even across different windows.
 */
function isES6Map(thing) {
  return thing != null && Object.prototype.toString.call(thing) === "[object Map]";
}
/**
 * Makes sure a Map is an instance of non-inherited native or observable Map.
 */
function isPlainES6Map(thing) {
  const mapProto = Object.getPrototypeOf(thing);
  const objectProto = Object.getPrototypeOf(mapProto);
  const nullProto = Object.getPrototypeOf(objectProto);
  return nullProto === null;
}
/**
 * Yields true for both native and observable Set, even across different windows.
 */
function isES6Set(thing) {
  return thing != null && Object.prototype.toString.call(thing) === "[object Set]";
}
/**
 * Returns the following: own enumerable keys and symbols.
 */
function getPlainObjectKeys(object) {
  const keys = Object.keys(object);
  const symbols = Object.getOwnPropertySymbols(object);
  if (!symbols.length) {
    return keys;
  }
  return [...keys, ...symbols.filter(s => objectPrototype.propertyIsEnumerable.call(object, s))];
}
// From Immer utils
// Returns all own keys, including non-enumerable and symbolic
const ownKeys = Reflect.ownKeys;
function stringifyKey(key) {
  if (typeof key === "string") {
    return key;
  }
  if (typeof key === "symbol") {
    return key.toString();
  }
  return new String(key).toString();
}
function toPrimitive(value) {
  return value === null ? null : typeof value === "object" ? "" + value : value;
}
function hasProp(target, prop) {
  return objectPrototype.hasOwnProperty.call(target, prop);
}
const getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors;
function getFlag(flags, mask) {
  return !!(flags & mask);
}
function setFlag(flags, mask, newValue) {
  if (newValue) {
    flags |= mask;
  } else {
    flags &= ~mask;
  }
  return flags;
}

function assert20223DecoratorType(context, types) {
  if (!types.includes(context.kind)) {
    die(`The decorator applied to '${String(context.name)}' cannot be used on a ${context.kind} element`);
  }
}

const $mobx = /*#__PURE__*/Symbol("mobx administration");
class Atom {
  /**
   * Create a new atom. For debugging purposes it is recommended to give it a name.
   * The onBecomeObserved and onBecomeUnobserved callbacks can be used for resource management.
   */
  constructor(name_ = "Atom@" + getNextId() ) {
    this.name_ = void 0;
    this.flags_ = 0b000;
    // Allocated lazily on first observer to save memory.
    this.observers_ = null;
    this.lastAccessedBy_ = 0;
    this.lowestObserverState_ = -1 /* IDerivationState_.NOT_TRACKING_ */;
    // onBecomeObservedListeners
    this.onBOL = void 0;
    // onBecomeUnobservedListeners
    this.onBUOL = void 0;
    this.name_ = name_;
  }
  // for effective unobserving. BaseAtom has true, for extra optimization, so its onBecomeUnobserved never gets called, because it's not needed
  get isBeingObserved() {
    return getFlag(this.flags_, 1 /* AtomFlags.isBeingObserved */);
  }
  set isBeingObserved(newValue) {
    this.flags_ = setFlag(this.flags_, 1 /* AtomFlags.isBeingObserved */, newValue);
  }
  get isPendingUnobservation() {
    return getFlag(this.flags_, 2 /* AtomFlags.isPendingUnobservation */);
  }
  set isPendingUnobservation(newValue) {
    this.flags_ = setFlag(this.flags_, 2 /* AtomFlags.isPendingUnobservation */, newValue);
  }
  get diffValue() {
    return getFlag(this.flags_, 4 /* AtomFlags.diffValue */) ? 1 : 0;
  }
  set diffValue(newValue) {
    this.flags_ = setFlag(this.flags_, 4 /* AtomFlags.diffValue */, newValue === 1 ? true : false);
  }
  onBO() {
    if (this.onBOL) {
      this.onBOL.forEach(listener => listener());
    }
  }
  onBUO() {
    if (this.onBUOL) {
      this.onBUOL.forEach(listener => listener());
    }
  }
  /**
   * Invoke this method to notify mobx that your atom has been used somehow.
   * Returns true if there is currently a reactive context.
   */
  reportObserved() {
    return reportObserved(this);
  }
  /**
   * Invoke this method _after_ this method has changed to signal mobx that all its observers should invalidate.
   */
  reportChanged() {
    startBatch();
    propagateChanged(this);
    endBatch();
  }
  toString() {
    return this.name_;
  }
}
const isAtom = /*#__PURE__*/createInstanceofPredicate("Atom", Atom);
function createAtom(name, onBecomeObservedHandler = noop, onBecomeUnobservedHandler = noop) {
  const atom = new Atom(name);
  // default `noop` listener will not initialize the hook Set
  if (onBecomeObservedHandler !== noop) {
    atom.onBOL = new Set([onBecomeObservedHandler]);
  }
  if (onBecomeUnobservedHandler !== noop) {
    atom.onBUOL = new Set([onBecomeUnobservedHandler]);
  }
  return atom;
}

function compareIdentity(a, b) {
  return a === b;
}
function compareStructural(a, b) {
  return deepEqual(a, b);
}
function compareShallow(a, b) {
  return deepEqual(a, b, 1);
}
const compareDefault = Object.is;

function deepEnhancer(v, _, name) {
  // primitives can never be made observable; skip the type checks below
  if (v === null || typeof v !== "object" && typeof v !== "function") {
    return v;
  }
  // it is an observable already, done
  if (isObservable(v)) {
    return v;
  }
  // something that can be converted and mutated?
  if (Array.isArray(v)) {
    return observable.array(v, {
      name
    });
  }
  if (isPlainObject(v)) {
    return observable.object(v, undefined, {
      name
    });
  }
  if (isES6Map(v)) {
    return observable.map(v, {
      name
    });
  }
  if (isES6Set(v)) {
    return observable.set(v, {
      name
    });
  }
  if (typeof v === "function" && !isAction(v) && !isFlow(v)) {
    if (isGenerator(v)) {
      return flow(v);
    } else {
      return autoAction(name, v);
    }
  }
  return v;
}
function shallowEnhancer(v, _, name) {
  if (v === undefined || v === null) {
    return v;
  }
  if (isObservableObject(v) || isObservableArray(v) || isObservableMap(v) || isObservableSet(v)) {
    return v;
  }
  if (Array.isArray(v)) {
    return observable.array(v, {
      name,
      deep: false
    });
  }
  if (isPlainObject(v)) {
    return observable.object(v, undefined, {
      name,
      deep: false
    });
  }
  if (isES6Map(v)) {
    return observable.map(v, {
      name,
      deep: false
    });
  }
  if (isES6Set(v)) {
    return observable.set(v, {
      name,
      deep: false
    });
  }
  {
    die("The shallow modifier / decorator can only used in combination with arrays, objects, maps and sets");
  }
}
function referenceEnhancer(newValue) {
  // never turn into an observable
  return newValue;
}
function refStructEnhancer(v, oldValue) {
  if (isObservable(v)) {
    die(`observable.struct should not be used with observable values`);
  }
  if (deepEqual(v, oldValue)) {
    return oldValue;
  }
  return v;
}

const OVERRIDE = "override";
const override = {
  annotationType_: OVERRIDE,
  make_: make_$6,
  extend_: extend_$5
};
function isOverride(annotation) {
  return annotation.annotationType_ === OVERRIDE;
}
function make_$6(adm, key) {
  // Must not be plain object
  if (adm.isPlainObject_) {
    die(`Cannot apply '${this.annotationType_}' to '${adm.name_}.${key.toString()}':` + `\n'${this.annotationType_}' cannot be used on plain objects.`);
  }
  // Must override something
  if (!hasProp(adm.appliedAnnotations_, key)) {
    die(`'${adm.name_}.${key.toString()}' is annotated with '${this.annotationType_}', ` + `but no such annotated member was found on prototype.`);
  }
  return 0 /* MakeResult.Cancel */;
}
function extend_$5(adm, key, descriptor, proxyTrap) {
  die(44, this.annotationType_);
}

function createActionAnnotation(name, options) {
  return {
    annotationType_: name,
    options_: options,
    make_: make_$5,
    extend_: extend_$4
  };
}
function make_$5(adm, key, descriptor, source) {
  var _this$options_;
  // bound
  if ((_this$options_ = this.options_) != null && _this$options_.bound) {
    return this.extend_(adm, key, descriptor, false) === null ? 0 /* MakeResult.Cancel */ : 1 /* MakeResult.Break */;
  }
  // own
  if (source === adm.target_) {
    return this.extend_(adm, key, descriptor, false) === null ? 0 /* MakeResult.Cancel */ : 2 /* MakeResult.Continue */;
  }
  // prototype
  if (isAction(descriptor.value)) {
    // A prototype could have been annotated already by other constructor,
    // rest of the proto chain must be annotated already
    return 1 /* MakeResult.Break */;
  }
  const actionDescriptor = createActionDescriptor(adm, this, key, descriptor, false);
  defineProperty(source, key, actionDescriptor);
  return 2 /* MakeResult.Continue */;
}
function extend_$4(adm, key, descriptor, proxyTrap) {
  const actionDescriptor = createActionDescriptor(adm, this, key, descriptor);
  return adm.defineProperty_(key, actionDescriptor, proxyTrap);
}
function decorateAction20223_(annotation, mthd, context) {
  {
    assert20223DecoratorType(context, ["method", "field"]);
  }
  const {
    kind,
    name,
    addInitializer
  } = context;
  const ann = annotation;
  const _createAction = m => {
    var _ann$options_$name, _ann$options_, _ann$options_$autoAct, _ann$options_2;
    return createAction((_ann$options_$name = (_ann$options_ = ann.options_) == null ? void 0 : _ann$options_.name) != null ? _ann$options_$name : name.toString(), m, (_ann$options_$autoAct = (_ann$options_2 = ann.options_) == null ? void 0 : _ann$options_2.autoAction) != null ? _ann$options_$autoAct : false);
  };
  if (kind == "field") {
    return function (initMthd) {
      var _ann$options_3;
      let mthd = initMthd;
      if (!isAction(mthd)) {
        mthd = _createAction(mthd);
      }
      if ((_ann$options_3 = ann.options_) != null && _ann$options_3.bound) {
        mthd = mthd.bind(this);
        mthd.isMobxAction = true;
      }
      return mthd;
    };
  }
  if (kind == "method") {
    var _ann$options_4;
    if (!isAction(mthd)) {
      mthd = _createAction(mthd);
    }
    if ((_ann$options_4 = ann.options_) != null && _ann$options_4.bound) {
      addInitializer(function () {
        const self = this;
        const bound = self[name].bind(self);
        bound.isMobxAction = true;
        self[name] = bound;
      });
    }
    return mthd;
  }
  die(43, ann.annotationType_, String(name), kind);
}
function assertActionDescriptor(adm, {
  annotationType_
}, key, {
  value
}) {
  if (!isFunction(value)) {
    die(`Cannot apply '${annotationType_}' to '${adm.name_}.${key.toString()}':` + `\n'${annotationType_}' can only be used on properties with a function value.`);
  }
}
function createActionDescriptor(adm, annotation, key, descriptor,
// provides ability to disable safeDescriptors for prototypes
safeDescriptors = globalState.safeDescriptors) {
  var _annotation$options_, _annotation$options_$, _annotation$options_2, _annotation$options_$2, _annotation$options_3, _annotation$options_4, _adm$proxy_2;
  assertActionDescriptor(adm, annotation, key, descriptor);
  let {
    value
  } = descriptor;
  if ((_annotation$options_ = annotation.options_) != null && _annotation$options_.bound) {
    var _adm$proxy_;
    value = value.bind((_adm$proxy_ = adm.proxy_) != null ? _adm$proxy_ : adm.target_);
  }
  return {
    value: createAction((_annotation$options_$ = (_annotation$options_2 = annotation.options_) == null ? void 0 : _annotation$options_2.name) != null ? _annotation$options_$ : key.toString(), value, (_annotation$options_$2 = (_annotation$options_3 = annotation.options_) == null ? void 0 : _annotation$options_3.autoAction) != null ? _annotation$options_$2 : false,
    // https://github.com/mobxjs/mobx/discussions/3140
    (_annotation$options_4 = annotation.options_) != null && _annotation$options_4.bound ? (_adm$proxy_2 = adm.proxy_) != null ? _adm$proxy_2 : adm.target_ : undefined),
    // Non-configurable for classes
    // prevents accidental field redefinition in subclass
    configurable: safeDescriptors ? adm.isPlainObject_ : true,
    // https://github.com/mobxjs/mobx/pull/2641#issuecomment-737292058
    enumerable: false,
    // Non-obsevable, therefore non-writable
    // Also prevents rewriting in subclass constructor
    writable: safeDescriptors ? false : true
  };
}

function createFlowAnnotation(name, options) {
  return {
    annotationType_: name,
    options_: options,
    make_: make_$4,
    extend_: extend_$3
  };
}
function make_$4(adm, key, descriptor, source) {
  var _this$options_;
  // own
  if (source === adm.target_) {
    return this.extend_(adm, key, descriptor, false) === null ? 0 /* MakeResult.Cancel */ : 2 /* MakeResult.Continue */;
  }
  // prototype
  // bound - must annotate protos to support super.flow()
  if ((_this$options_ = this.options_) != null && _this$options_.bound && (!hasProp(adm.target_, key) || !isFlow(adm.target_[key]))) {
    if (this.extend_(adm, key, descriptor, false) === null) {
      return 0 /* MakeResult.Cancel */;
    }
  }
  if (isFlow(descriptor.value)) {
    // A prototype could have been annotated already by other constructor,
    // rest of the proto chain must be annotated already
    return 1 /* MakeResult.Break */;
  }
  const flowDescriptor = createFlowDescriptor(adm, this, key, descriptor, false, false);
  defineProperty(source, key, flowDescriptor);
  return 2 /* MakeResult.Continue */;
}
function extend_$3(adm, key, descriptor, proxyTrap) {
  var _this$options_2;
  const flowDescriptor = createFlowDescriptor(adm, this, key, descriptor, (_this$options_2 = this.options_) == null ? void 0 : _this$options_2.bound);
  return adm.defineProperty_(key, flowDescriptor, proxyTrap);
}
function decorateFlow20223_(annotation, mthd, context) {
  var _annotation$options_;
  {
    assert20223DecoratorType(context, ["method"]);
  }
  const {
    name,
    addInitializer
  } = context;
  if (!isFlow(mthd)) {
    mthd = flow(mthd);
  }
  if ((_annotation$options_ = annotation.options_) != null && _annotation$options_.bound) {
    addInitializer(function () {
      const self = this;
      const bound = self[name].bind(self);
      bound.isMobXFlow = true;
      self[name] = bound;
    });
  }
  return mthd;
}
function assertFlowDescriptor(adm, {
  annotationType_
}, key, {
  value
}) {
  if (!isFunction(value)) {
    die(`Cannot apply '${annotationType_}' to '${adm.name_}.${key.toString()}':` + `\n'${annotationType_}' can only be used on properties with a generator function value.`);
  }
}
function createFlowDescriptor(adm, annotation, key, descriptor, bound,
// provides ability to disable safeDescriptors for prototypes
safeDescriptors = globalState.safeDescriptors) {
  assertFlowDescriptor(adm, annotation, key, descriptor);
  let {
    value
  } = descriptor;
  // In case of flow.bound, the descriptor can be from already annotated prototype
  if (!isFlow(value)) {
    value = flow(value);
  }
  if (bound) {
    var _adm$proxy_;
    // We do not keep original function around, so we bind the existing flow
    value = value.bind((_adm$proxy_ = adm.proxy_) != null ? _adm$proxy_ : adm.target_);
    // This is normally set by `flow`, but `bind` returns new function...
    value.isMobXFlow = true;
  }
  return {
    value,
    // Non-configurable for classes
    // prevents accidental field redefinition in subclass
    configurable: safeDescriptors ? adm.isPlainObject_ : true,
    // https://github.com/mobxjs/mobx/pull/2641#issuecomment-737292058
    enumerable: false,
    // Non-obsevable, therefore non-writable
    // Also prevents rewriting in subclass constructor
    writable: safeDescriptors ? false : true
  };
}

function createComputedAnnotation(name, options) {
  return {
    annotationType_: name,
    options_: options,
    make_: make_$3,
    extend_: extend_$2
  };
}
function make_$3(adm, key, descriptor) {
  return this.extend_(adm, key, descriptor, false) === null ? 0 /* MakeResult.Cancel */ : 1 /* MakeResult.Break */;
}
function extend_$2(adm, key, descriptor, proxyTrap) {
  assertComputedDescriptor(adm, this, key, descriptor);
  return adm.defineComputedProperty_(key, assign({}, this.options_, {
    get: descriptor.get,
    set: descriptor.set
  }), proxyTrap);
}
function decorateComputed20223_(annotation, get, context) {
  {
    assert20223DecoratorType(context, ["getter"]);
  }
  const ann = annotation;
  const {
    name: key,
    addInitializer
  } = context;
  let computedValues;
  // Defer ComputedValue creation until first access — avoids allocating
  // ComputedValues for getters that are never read on a given instance.
  // The factory is materialised by ObservableObjectAdministration on demand.
  function createComputedValue(target, adm) {
    const options = assign({}, ann.options_, {
      get,
      context: target
    });
    options.name || (options.name = `${adm.name_}.${key.toString()}` );
    return new ComputedValue(options);
  }
  addInitializer(function () {
    var _adm$lazyComputedKeys;
    const adm = asObservableObject(this)[$mobx];
    const target = this;
    const observable = adm.values_.get(key);
    if (observable instanceof ComputedValue && observable.derivation !== get) {
      adm.values_.delete(key);
    }
    ((_adm$lazyComputedKeys = adm.lazyComputedKeys_) != null ? _adm$lazyComputedKeys : adm.lazyComputedKeys_ = new Map()).set(key, () => createComputedValue(target, adm));
  });
  return function () {
    const adm = this[$mobx];
    const observable = adm.values_.get(key);
    if (observable instanceof ComputedValue && observable.derivation !== get) {
      var _computedValues;
      let computed = (_computedValues = computedValues) == null ? void 0 : _computedValues.get(this);
      if (!computed) {
        var _computedValues2;
        computed = createComputedValue(this, adm);
        ((_computedValues2 = computedValues) != null ? _computedValues2 : computedValues = new WeakMap()).set(this, computed);
      }
      return computed.get();
    }
    return adm.getObservablePropValue_(key);
  };
}
function assertComputedDescriptor(adm, {
  annotationType_
}, key, {
  get
}) {
  if (!get) {
    die(`Cannot apply '${annotationType_}' to '${adm.name_}.${key.toString()}':` + `\n'${annotationType_}' can only be used on getter(+setter) properties.`);
  }
}

function createObservableAnnotation(name, options) {
  return {
    annotationType_: name,
    options_: options,
    make_: make_$2,
    extend_: extend_$1
  };
}
function make_$2(adm, key, descriptor) {
  return this.extend_(adm, key, descriptor, false) === null ? 0 /* MakeResult.Cancel */ : 1 /* MakeResult.Break */;
}
function extend_$1(adm, key, descriptor, proxyTrap) {
  var _this$options_$enhanc, _this$options_;
  assertObservableDescriptor(adm, this, key, descriptor);
  return adm.defineObservableProperty_(key, descriptor.value, (_this$options_$enhanc = (_this$options_ = this.options_) == null ? void 0 : _this$options_.enhancer_) != null ? _this$options_$enhanc : deepEnhancer, proxyTrap);
}
function decorateObservable20223_(annotation, desc, context) {
  {
    if (context.kind === "field") {
      throw die(`Please use \`@observable accessor ${String(context.name)}\` instead of \`@observable ${String(context.name)}\``);
    }
    assert20223DecoratorType(context, ["accessor"]);
  }
  const ann = annotation;
  const {
    kind,
    name
  } = context;
  if (kind !== "accessor") {
    return;
  }
  // Defer ObservableValue construction until first access. The factory is
  // materialised by ObservableObjectAdministration on demand, so unused
  // fields on wide classes never pay the per-instance allocation cost.
  function registerLazy(target, value) {
    var _adm$lazyObservableKe;
    const adm = asObservableObject(target)[$mobx];
    ((_adm$lazyObservableKe = adm.lazyObservableKeys_) != null ? _adm$lazyObservableKe : adm.lazyObservableKeys_ = new Map()).set(name, () => {
      var _ann$options_$enhance, _ann$options_;
      return new ObservableValue(value, (_ann$options_$enhance = (_ann$options_ = ann.options_) == null ? void 0 : _ann$options_.enhancer_) != null ? _ann$options_$enhance : deepEnhancer, `${adm.name_}.${name.toString()}` , false);
    });
    return adm;
  }
  return {
    get() {
      var _this$$mobx;
      const adm = (_this$$mobx = this[$mobx]) != null ? _this$$mobx : registerLazy(this, desc.get.call(this));
      return adm.getObservablePropValue_(name);
    },
    set(value) {
      var _this$$mobx2;
      const adm = (_this$$mobx2 = this[$mobx]) != null ? _this$$mobx2 : registerLazy(this, value);
      return adm.setObservablePropValue_(name, value);
    },
    init(value) {
      registerLazy(this, value);
      return value;
    }
  };
}
function assertObservableDescriptor(adm, {
  annotationType_
}, key, descriptor) {
  if (!("value" in descriptor)) {
    die(`Cannot apply '${annotationType_}' to '${adm.name_}.${key.toString()}':` + `\n'${annotationType_}' cannot be used on getter/setter properties`);
  }
}

const AUTO = "true";
const autoAnnotation = /*#__PURE__*/createAutoAnnotation();
function createAutoAnnotation(options) {
  return {
    annotationType_: AUTO,
    options_: options,
    make_: make_$1,
    extend_
  };
}
function make_$1(adm, key, descriptor, source) {
  var _this$options_3, _this$options_4;
  // getter -> computed
  if (descriptor.get) {
    return computed.make_(adm, key, descriptor, source);
  }
  // lone setter -> action setter
  if (descriptor.set) {
    // TODO make action applicable to setter and delegate to action.make_
    const set = isAction(descriptor.set) ? descriptor.set // See #4553
    : createAction(key.toString(), descriptor.set);
    // own
    if (source === adm.target_) {
      return adm.defineProperty_(key, {
        configurable: globalState.safeDescriptors ? adm.isPlainObject_ : true,
        set
      }) === null ? 0 /* MakeResult.Cancel */ : 2 /* MakeResult.Continue */;
    }
    // proto
    defineProperty(source, key, {
      configurable: true,
      set
    });
    return 2 /* MakeResult.Continue */;
  }
  // function on proto -> autoAction/flow
  if (source !== adm.target_ && typeof descriptor.value === "function") {
    var _this$options_2;
    if (isGenerator(descriptor.value)) {
      var _this$options_;
      const flowAnnotation = (_this$options_ = this.options_) != null && _this$options_.autoBind ? flowBound : flow;
      return flowAnnotation.make_(adm, key, descriptor, source);
    }
    const actionAnnotation = (_this$options_2 = this.options_) != null && _this$options_2.autoBind ? autoActionBound : autoAction;
    return actionAnnotation.make_(adm, key, descriptor, source);
  }
  // other -> observable
  // Copy props from proto as well, see test:
  // "decorate should work with Object.create"
  let observableAnnotation = ((_this$options_3 = this.options_) == null ? void 0 : _this$options_3.deep) === false ? observableRef : observable;
  // if function respect autoBind option
  if (typeof descriptor.value === "function" && (_this$options_4 = this.options_) != null && _this$options_4.autoBind) {
    var _adm$proxy_;
    descriptor.value = descriptor.value.bind((_adm$proxy_ = adm.proxy_) != null ? _adm$proxy_ : adm.target_);
  }
  return observableAnnotation.make_(adm, key, descriptor, source);
}
function extend_(adm, key, descriptor, proxyTrap) {
  var _this$options_5, _this$options_6;
  // getter -> computed
  if (descriptor.get) {
    return computed.extend_(adm, key, descriptor, proxyTrap);
  }
  // lone setter -> action setter
  if (descriptor.set) {
    // TODO make action applicable to setter and delegate to action.extend_
    return adm.defineProperty_(key, {
      configurable: globalState.safeDescriptors ? adm.isPlainObject_ : true,
      set: createAction(key.toString(), descriptor.set)
    }, proxyTrap);
  }
  // other -> observable
  // if function respect autoBind option
  if (typeof descriptor.value === "function" && (_this$options_5 = this.options_) != null && _this$options_5.autoBind) {
    var _adm$proxy_2;
    descriptor.value = descriptor.value.bind((_adm$proxy_2 = adm.proxy_) != null ? _adm$proxy_2 : adm.target_);
  }
  let observableAnnotation = ((_this$options_6 = this.options_) == null ? void 0 : _this$options_6.deep) === false ? observableRef : observable;
  return observableAnnotation.extend_(adm, key, descriptor, proxyTrap);
}

function createDecoratorAnnotation(annotation, decorate) {
  return assign(function decoratorAnnotation(value, context) {
    if (context && typeof context.kind === "string") {
      return decorate(annotation, value, context);
    }
    {
      die(`Invalid arguments for \`${annotation.annotationType_}\``);
    }
    return undefined;
  }, annotation);
}

const OBSERVABLE = "observable";
const OBSERVABLE_REF = "observable.ref";
const OBSERVABLE_SHALLOW = "observable.shallow";
const OBSERVABLE_STRUCT = "observable.struct";
// Predefined bags of create observable options, to avoid allocating temporarily option objects
// in the majority of cases
const defaultCreateObservableOptions = {
  deep: true,
  name: undefined,
  defaultDecorator: undefined
};
Object.freeze(defaultCreateObservableOptions);
function asCreateObservableOptions(thing) {
  return thing || defaultCreateObservableOptions;
}
const observableAnnotation = /*#__PURE__*/createObservableAnnotation(OBSERVABLE);
const observableRefAnnotation = /*#__PURE__*/createObservableAnnotation(OBSERVABLE_REF, {
  enhancer_: referenceEnhancer
});
const observableShallowAnnotation = /*#__PURE__*/createObservableAnnotation(OBSERVABLE_SHALLOW, {
  enhancer_: shallowEnhancer
});
const observableStructAnnotation = /*#__PURE__*/createObservableAnnotation(OBSERVABLE_STRUCT, {
  enhancer_: refStructEnhancer
});
function createObservableDecoratorAnnotation(annotation) {
  return createDecoratorAnnotation(annotation, decorateObservable20223_);
}
function getEnhancerFromOptions(options) {
  return options.deep === true ? deepEnhancer : options.deep === false ? referenceEnhancer : getEnhancerFromAnnotation(options.defaultDecorator);
}
function getAnnotationFromOptions(options) {
  var _options$defaultDecor;
  return options ? (_options$defaultDecor = options.defaultDecorator) != null ? _options$defaultDecor : createAutoAnnotation(options) : undefined;
}
function getEnhancerFromAnnotation(annotation) {
  var _annotation$options_$, _annotation$options_;
  return !annotation ? deepEnhancer : (_annotation$options_$ = (_annotation$options_ = annotation.options_) == null ? void 0 : _annotation$options_.enhancer_) != null ? _annotation$options_$ : deepEnhancer;
}
/**
 * Turns an object, array or function into a reactive structure.
 * @param v the value which should become observable.
 */
function createObservable(v, arg2, arg3) {
  if (arg2 && typeof arg2.kind === "string") {
    return decorateObservable20223_(observableAnnotation, v, arg2);
  }
  // already observable - ignore
  if (isObservable(v)) {
    return v;
  }
  // plain object
  if (isPlainObject(v)) {
    return observable.object(v, arg2, arg3);
  }
  // Array
  if (Array.isArray(v)) {
    return observable.array(v, arg2);
  }
  // Map
  if (isES6Map(v)) {
    return observable.map(v, arg2);
  }
  // Set
  if (isES6Set(v)) {
    return observable.set(v, arg2);
  }
  // other object - ignore
  if (typeof v === "object" && v !== null) {
    return v;
  }
  // anything else
  return observable.box(v, arg2);
}
const observableFactories = {
  box(value, options) {
    const o = asCreateObservableOptions(options);
    return new ObservableValue(value, getEnhancerFromOptions(o), o.name, true, o.equals);
  },
  array(initialValues, options) {
    const o = asCreateObservableOptions(options);
    return createObservableArray(initialValues, getEnhancerFromOptions(o), o.name);
  },
  map(initialValues, options) {
    const o = asCreateObservableOptions(options);
    return new ObservableMap(initialValues, getEnhancerFromOptions(o), o.name);
  },
  set(initialValues, options) {
    const o = asCreateObservableOptions(options);
    return new ObservableSet(initialValues, getEnhancerFromOptions(o), o.name);
  },
  object(props, annotations, options) {
    return initObservable(() => extendObservable(asDynamicObservableObject({}, options), props, annotations));
  }
};
const observableRef = /*#__PURE__*/createObservableDecoratorAnnotation(observableRefAnnotation);
const observableShallow = /*#__PURE__*/createObservableDecoratorAnnotation(observableShallowAnnotation);
const observableDeep = /*#__PURE__*/createObservableDecoratorAnnotation(observableAnnotation);
const observableStruct = /*#__PURE__*/createObservableDecoratorAnnotation(observableStructAnnotation);
// eslint-disable-next-line
var observable = /*#__PURE__*/assign(createObservable, observableAnnotation, observableFactories);

const COMPUTED = "computed";
const COMPUTED_STRUCT = "computed.struct";
function createComputedDecoratorAnnotation(annotation) {
  return createDecoratorAnnotation(annotation, decorateComputed20223_);
}
const computedAnnotation = /*#__PURE__*/createComputedAnnotation(COMPUTED);
const computedStructAnnotation = /*#__PURE__*/createComputedAnnotation(COMPUTED_STRUCT, {
  equals: compareStructural
});
const computedStruct = /*#__PURE__*/createComputedDecoratorAnnotation(computedStructAnnotation);
const computed = function computed(arg1, arg2) {
  if (arg2 && typeof arg2.kind === "string") {
    return decorateComputed20223_(computedAnnotation, arg1, arg2);
  }
  if (isPlainObject(arg1)) {
    // computed annotation with options
    return createComputedDecoratorAnnotation(createComputedAnnotation(COMPUTED, arg1));
  }
  // computed(expr, options?)
  {
    if (!isFunction(arg1)) {
      die("First argument to `computed` should be an expression.");
    }
    if (isFunction(arg2)) {
      die("A setter as second argument is no longer supported, use `{ set: fn }` option instead");
    }
  }
  const opts = isPlainObject(arg2) ? arg2 : {};
  opts.get = arg1;
  opts.name || (opts.name = arg1.name || ""); /* for generated name */
  return new ComputedValue(opts);
};
assign(computed, computedAnnotation);

var _getDescriptor$config, _getDescriptor;
// we don't use globalState for these in order to avoid possible issues with multiple
// mobx versions
let currentActionId = 0;
let nextActionId = 1;
const isFunctionNameConfigurable = (_getDescriptor$config = (_getDescriptor = /*#__PURE__*/getDescriptor(() => {}, "name")) == null ? void 0 : _getDescriptor.configurable) != null ? _getDescriptor$config : false;
// we can safely recycle this object
const tmpNameDescriptor = {
  value: "action",
  configurable: true,
  writable: false,
  enumerable: false
};
function createAction(actionName, fn, autoAction = false, ref) {
  {
    if (!isFunction(fn)) {
      die("`action` can only be invoked on functions");
    }
    if (typeof actionName !== "string" || !actionName) {
      die(`actions should have valid names, got: '${actionName}'`);
    }
  }
  function res() {
    return executeAction(actionName, autoAction, fn, ref || this, arguments);
  }
  res.isMobxAction = true;
  res.toString = () => fn.toString();
  if (isFunctionNameConfigurable) {
    tmpNameDescriptor.value = actionName;
    defineProperty(res, "name", tmpNameDescriptor);
  }
  return res;
}
function executeAction(actionName, canRunAsDerivation, fn, scope, args) {
  const runInfo = _startAction(actionName, canRunAsDerivation, scope, args);
  try {
    return fn.apply(scope, args);
  } catch (err) {
    runInfo.error_ = err;
    throw err;
  } finally {
    _endAction(runInfo);
  }
}
function _startAction(actionName, canRunAsDerivation,
// true for autoAction
scope, args) {
  const notifySpy_ = isSpyEnabled() && !!actionName;
  let startTime_ = 0;
  if (notifySpy_) {
    startTime_ = Date.now();
    const flattenedArgs = args ? Array.from(args) : EMPTY_ARRAY;
    spyReportStart({
      type: ACTION,
      name: actionName,
      object: scope,
      arguments: flattenedArgs
    });
  }
  const prevDerivation_ = globalState.trackingDerivation;
  const runAsAction = !canRunAsDerivation || !prevDerivation_;
  startBatch();
  let prevAllowStateChanges_ = globalState.allowStateChanges; // by default preserve previous allow
  if (runAsAction) {
    untrackedStart();
    {
      prevAllowStateChanges_ = allowStateChangesStart(true);
    }
  }
  const prevAllowStateReads_ = globalState.allowStateReads;
  {
    allowStateReadsStart(true);
  }
  const runInfo = {
    runAsAction_: runAsAction,
    prevDerivation_,
    prevAllowStateChanges_,
    prevAllowStateReads_,
    notifySpy_,
    startTime_,
    actionId_: nextActionId++,
    parentActionId_: currentActionId
  };
  currentActionId = runInfo.actionId_;
  return runInfo;
}
function _endAction(runInfo) {
  if (currentActionId !== runInfo.actionId_) {
    die(30);
  }
  currentActionId = runInfo.parentActionId_;
  if (runInfo.error_ !== undefined) {
    globalState.suppressReactionErrors = true;
  }
  {
    allowStateChangesEnd(runInfo.prevAllowStateChanges_);
    allowStateReadsEnd(runInfo.prevAllowStateReads_);
  }
  endBatch();
  if (runInfo.runAsAction_) {
    untrackedEnd(runInfo.prevDerivation_);
  }
  if (runInfo.notifySpy_) {
    spyReportEnd({
      time: Date.now() - runInfo.startTime_
    });
  }
  globalState.suppressReactionErrors = false;
}
function allowStateChanges(allowStateChanges, func) {
  const prev = allowStateChangesStart(allowStateChanges);
  try {
    return func();
  } finally {
    allowStateChangesEnd(prev);
  }
}
function allowStateChangesStart(allowStateChanges) {
  const prev = globalState.allowStateChanges;
  globalState.allowStateChanges = allowStateChanges;
  return prev;
}
function allowStateChangesEnd(prev) {
  globalState.allowStateChanges = prev;
}

const CREATE = "create";
class ObservableValue extends Atom {
  constructor(value, enhancer_, name_ = "ObservableValue@" + getNextId() , notifySpy = true, equals_ = compareDefault) {
    super(name_);
    this.enhancer_ = void 0;
    this.name_ = void 0;
    this.equals_ = void 0;
    this.hasUnreportedChange_ = false;
    this.interceptors_ = void 0;
    this.changeListeners_ = void 0;
    this.value_ = void 0;
    this.dehancer = void 0;
    this.enhancer_ = enhancer_;
    this.name_ = name_;
    this.equals_ = equals_;
    this.value_ = enhancer_(value, undefined, name_);
    if (notifySpy && isSpyEnabled()) {
      var _this$value_;
      // only notify spy if this is a stand-alone observable
      spyReport({
        type: CREATE,
        object: this,
        observableKind: "value",
        debugObjectName: this.name_,
        newValue: "" + ((_this$value_ = this.value_) == null ? void 0 : _this$value_.toString())
      });
    }
  }
  dehanceValue(value) {
    if (this.dehancer !== undefined) {
      return this.dehancer(value);
    }
    return value;
  }
  set(newValue) {
    const oldValue = this.value_;
    newValue = this.prepareNewValue_(newValue);
    if (newValue !== globalState.UNCHANGED) {
      const notifySpy = isSpyEnabled();
      if (notifySpy) {
        spyReportStart({
          type: UPDATE,
          object: this,
          observableKind: "value",
          debugObjectName: this.name_,
          newValue,
          oldValue
        });
      }
      this.setNewValue_(newValue);
      if (notifySpy) {
        spyReportEnd();
      }
    }
  }
  prepareNewValue_(newValue) {
    checkIfStateModificationsAreAllowed(this);
    if (hasInterceptors(this)) {
      const change = interceptChange(this, {
        object: this,
        type: UPDATE,
        newValue
      });
      if (!change) {
        return globalState.UNCHANGED;
      }
      newValue = change.newValue;
    }
    // apply modifier
    newValue = this.enhancer_(newValue, this.value_, this.name_);
    return this.equals_(this.value_, newValue) ? globalState.UNCHANGED : newValue;
  }
  setNewValue_(newValue) {
    const oldValue = this.value_;
    this.value_ = newValue;
    this.reportChanged();
    if (hasListeners(this)) {
      notifyListeners(this, {
        type: UPDATE,
        object: this,
        newValue,
        oldValue
      });
    }
  }
  get() {
    this.reportObserved();
    return this.dehanceValue(this.value_);
  }
  raw() {
    // used by MST ot get undehanced value
    return this.value_;
  }
  toJSON() {
    return this.get();
  }
  toString() {
    return `${this.name_}[${this.value_}]`;
  }
  valueOf() {
    return toPrimitive(this.get());
  }
  [Symbol.toPrimitive]() {
    return this.valueOf();
  }
}
const isObservableValue = /*#__PURE__*/createInstanceofPredicate("ObservableValue", ObservableValue);

class ComputedValue {
  /**
   * Create a new computed value based on a function expression.
   *
   * The `name` property is for debug purposes only.
   *
   * The `equals` property specifies the comparer function used to determine if a newly produced
   * value differs from the previous value. Structural comparison can be convenient if you always
   * produce a new aggregated object and don't want to notify observers if it is structurally the same.
   * This is useful for working with vectors, mouse coordinates etc.
   */
  constructor(options) {
    this.dependenciesState_ = -1 /* IDerivationState_.NOT_TRACKING_ */;
    this.observing_ = [];
    // nodes we are looking at. Our value depends on these nodes
    this.newObserving_ = null;
    // during tracking it's an array with new observed observers
    // Lazily allocated on first observer - see Atom.observers_.
    this.observers_ = null;
    this.runId_ = 0;
    this.lastAccessedBy_ = 0;
    this.lowestObserverState_ = 0 /* IDerivationState_.UP_TO_DATE_ */;
    this.unboundDepsCount_ = 0;
    this.value_ = new CaughtException(null);
    this.name_ = void 0;
    this.triggeredBy_ = void 0;
    this.flags_ = 0b00000;
    this.derivation = void 0;
    // N.B: unminified as it is used by MST
    this.setter_ = void 0;
    this.scope_ = void 0;
    this.equals_ = void 0;
    this.requiresReaction_ = void 0;
    this.keepAlive_ = void 0;
    this.onBOL = void 0;
    this.onBUOL = void 0;
    if (!options.get) {
      die(31);
    }
    this.derivation = options.get;
    this.name_ = options.name || ("ComputedValue@" + getNextId() );
    if (options.set) {
      this.setter_ = createAction(this.name_ + "-setter" , options.set);
    }
    this.equals_ = options.equals || compareDefault;
    this.scope_ = options.context;
    this.requiresReaction_ = options.requiresReaction;
    this.keepAlive_ = !!options.keepAlive;
  }
  onBecomeStale_() {
    propagateMaybeChanged(this);
  }
  onBO() {
    if (this.onBOL) {
      this.onBOL.forEach(listener => listener());
    }
  }
  onBUO() {
    if (this.onBUOL) {
      this.onBUOL.forEach(listener => listener());
    }
  }
  // to check for cycles
  get isComputing() {
    return getFlag(this.flags_, 1 /* ComputedValueFlags.isComputing */);
  }
  set isComputing(newValue) {
    this.flags_ = setFlag(this.flags_, 1 /* ComputedValueFlags.isComputing */, newValue);
  }
  get isRunningSetter() {
    return getFlag(this.flags_, 2 /* ComputedValueFlags.isRunningSetter */);
  }
  set isRunningSetter(newValue) {
    this.flags_ = setFlag(this.flags_, 2 /* ComputedValueFlags.isRunningSetter */, newValue);
  }
  get isBeingObserved() {
    return getFlag(this.flags_, 4 /* ComputedValueFlags.isBeingObserved */);
  }
  set isBeingObserved(newValue) {
    this.flags_ = setFlag(this.flags_, 4 /* ComputedValueFlags.isBeingObserved */, newValue);
  }
  get isPendingUnobservation() {
    return getFlag(this.flags_, 8 /* ComputedValueFlags.isPendingUnobservation */);
  }
  set isPendingUnobservation(newValue) {
    this.flags_ = setFlag(this.flags_, 8 /* ComputedValueFlags.isPendingUnobservation */, newValue);
  }
  get diffValue() {
    return getFlag(this.flags_, 16 /* ComputedValueFlags.diffValue */) ? 1 : 0;
  }
  set diffValue(newValue) {
    this.flags_ = setFlag(this.flags_, 16 /* ComputedValueFlags.diffValue */, newValue === 1 ? true : false);
  }
  /**
   * Returns the current value of this computed value.
   * Will evaluate its computation first if needed.
   */
  get() {
    if (this.isComputing) {
      die(32, this.name_, this.derivation);
    }
    if (globalState.inBatch === 0 && (
    // !globalState.trackingDerivatpion &&
    !this.observers_ || this.observers_.size === 0) && !this.keepAlive_) {
      if (shouldCompute(this)) {
        this.warnAboutUntrackedRead_();
        startBatch(); // See perf test 'computed memoization'
        this.value_ = this.computeValue_(false);
        endBatch();
      }
    } else {
      const wasBeingObserved = this.isBeingObserved;
      reportObserved(this);
      if (shouldCompute(this)) {
        let prevTrackingContext = globalState.trackingContext;
        if (this.keepAlive_ && !prevTrackingContext) {
          globalState.trackingContext = this;
        }
        if (this.trackAndCompute()) {
          propagateChangeConfirmed(this);
        }
        globalState.trackingContext = prevTrackingContext;
      } else if (!wasBeingObserved && this.isBeingObserved) {
        // We just became observed while serving a cached value, so the getter
        // won't run and won't re-report our dependencies. Cascade to them. #4547
        this.observing_.forEach(markObserved);
      }
    }
    const result = this.value_;
    if (isCaughtException(result)) {
      throw result.cause;
    }
    return result;
  }
  set(value) {
    if (this.setter_) {
      if (this.isRunningSetter) {
        die(33, this.name_);
      }
      this.isRunningSetter = true;
      try {
        this.setter_.call(this.scope_, value);
      } finally {
        this.isRunningSetter = false;
      }
    } else {
      die(34, this.name_);
    }
  }
  trackAndCompute() {
    // N.B: unminified as it is used by MST
    const oldValue = this.value_;
    const wasSuspended = /* see #1208 */this.dependenciesState_ === -1 /* IDerivationState_.NOT_TRACKING_ */;
    const newValue = this.computeValue_(true);
    const changed = wasSuspended || isCaughtException(oldValue) || isCaughtException(newValue) || !this.equals_(oldValue, newValue);
    if (changed) {
      this.value_ = newValue;
      if (isSpyEnabled()) {
        spyReport({
          observableKind: "computed",
          debugObjectName: this.name_,
          object: this.scope_,
          type: "update",
          oldValue,
          newValue
        });
      }
    }
    return changed;
  }
  computeValue_(track) {
    this.isComputing = true;
    // don't allow state changes during computation
    const prev = allowStateChangesStart(false) ;
    let res;
    if (track) {
      res = trackDerivedFunction(this, this.derivation, this.scope_);
    } else {
      if (globalState.disableErrorBoundaries === true) {
        res = this.derivation.call(this.scope_);
      } else {
        try {
          res = this.derivation.call(this.scope_);
        } catch (e) {
          res = new CaughtException(e);
        }
      }
    }
    {
      allowStateChangesEnd(prev);
    }
    this.isComputing = false;
    return res;
  }
  suspend_() {
    if (!this.keepAlive_) {
      clearObserving(this);
      this.value_ = undefined; // don't hold on to computed value!
    }
  }
  warnAboutUntrackedRead_() {
    if (typeof this.requiresReaction_ === "boolean" ? this.requiresReaction_ : globalState.computedRequiresReaction) {
      console.warn(`[mobx] Computed value '${this.name_}' is being read outside a reactive context. Doing a full recompute.`);
    }
  }
  toString() {
    return `${this.name_}[${this.derivation.toString()}]`;
  }
  valueOf() {
    return toPrimitive(this.get());
  }
  [Symbol.toPrimitive]() {
    return this.valueOf();
  }
}
const isComputedValue = /*#__PURE__*/createInstanceofPredicate("ComputedValue", ComputedValue);

class CaughtException {
  constructor(cause) {
    this.cause = void 0;
    this.cause = cause;
    // Empty
  }
}
function isCaughtException(e) {
  return e instanceof CaughtException;
}
/**
 * Finds out whether any dependency of the derivation has actually changed.
 * If dependenciesState is 1 then it will recalculate dependencies,
 * if any dependency changed it will propagate it by changing dependenciesState to 2.
 *
 * By iterating over the dependencies in the same order that they were reported and
 * stopping on the first change, all the recalculations are only called for ComputedValues
 * that will be tracked by derivation. That is because we assume that if the first x
 * dependencies of the derivation doesn't change then the derivation should run the same way
 * up until accessing x-th dependency.
 */
function shouldCompute(derivation) {
  switch (derivation.dependenciesState_) {
    case 0 /* IDerivationState_.UP_TO_DATE_ */:
      return false;
    case -1 /* IDerivationState_.NOT_TRACKING_ */:
    case 2 /* IDerivationState_.STALE_ */:
      return true;
    case 1 /* IDerivationState_.POSSIBLY_STALE_ */:
      {
        // state propagation can occur outside of action/reactive context #2195
        const prevAllowStateReads = allowStateReadsStart(true) ;
        const prevUntracked = untrackedStart(); // no need for those computeds to be reported, they will be picked up in trackDerivedFunction.
        const obs = derivation.observing_,
          l = obs.length;
        for (let i = 0; i < l; i++) {
          const obj = obs[i];
          if (isComputedValue(obj)) {
            if (globalState.disableErrorBoundaries) {
              obj.get();
            } else {
              try {
                obj.get();
              } catch (e) {
                // we are not interested in the value *or* exception at this moment, but if there is one, notify all
                untrackedEnd(prevUntracked);
                {
                  allowStateReadsEnd(prevAllowStateReads);
                }
                return true;
              }
            }
            // if ComputedValue `obj` actually changed it will be computed and propagated to its observers.
            // and `derivation` is an observer of `obj`
            // invariantShouldCompute(derivation)
            if (derivation.dependenciesState_ === 2 /* IDerivationState_.STALE_ */) {
              untrackedEnd(prevUntracked);
              {
                allowStateReadsEnd(prevAllowStateReads);
              }
              return true;
            }
          }
        }
        changeDependenciesStateTo0(derivation);
        untrackedEnd(prevUntracked);
        {
          allowStateReadsEnd(prevAllowStateReads);
        }
        return false;
      }
  }
}
function isComputingDerivation() {
  return globalState.trackingDerivation !== null; // filter out actions inside computations
}
function checkIfStateModificationsAreAllowed(atom) {
  const hasObservers = !!atom.observers_ && atom.observers_.size > 0;
  // Should not be possible to change observed state outside strict mode, except during initialization, see #563
  if (!globalState.allowStateChanges && (hasObservers || globalState.enforceActions === "always")) {
    console.warn("[MobX] " + (globalState.enforceActions ? "Since strict-mode is enabled, changing (observed) observable values without using an action is not allowed. Tried to modify: " : "Side effects like changing state are not allowed at this point. Are you trying to modify state from, for example, a computed value or the render function of a React component? You can wrap side effects in 'runInAction' (or decorate functions with 'action') if needed. Tried to modify: ") + atom.name_);
  }
}
function checkIfStateReadsAreAllowed(observable) {
  if (!globalState.allowStateReads && globalState.observableRequiresReaction) {
    console.warn(`[mobx] Observable '${observable.name_}' being read outside a reactive context.`);
  }
}
/**
 * Executes the provided function `f` and tracks which observables are being accessed.
 * The tracking information is stored on the `derivation` object and the derivation is registered
 * as observer of any of the accessed observables.
 */
function trackDerivedFunction(derivation, f, context) {
  const prevAllowStateReads = allowStateReadsStart(true) ;
  changeDependenciesStateTo0(derivation);
  // Preallocate array; will be trimmed by bindDependencies.
  derivation.newObserving_ = new Array(
  // Reserve constant space for initial dependencies, dynamic space otherwise.
  // See https://github.com/mobxjs/mobx/pull/3833
  derivation.runId_ === 0 ? 100 : derivation.observing_.length);
  derivation.unboundDepsCount_ = 0;
  derivation.runId_ = ++globalState.runId;
  const prevTracking = globalState.trackingDerivation;
  globalState.trackingDerivation = derivation;
  globalState.inBatch++;
  let result;
  if (globalState.disableErrorBoundaries === true) {
    result = f.call(context);
  } else {
    try {
      result = f.call(context);
    } catch (e) {
      result = new CaughtException(e);
    }
  }
  globalState.inBatch--;
  globalState.trackingDerivation = prevTracking;
  bindDependencies(derivation);
  warnAboutDerivationWithoutDependencies(derivation);
  {
    allowStateReadsEnd(prevAllowStateReads);
  }
  return result;
}
function warnAboutDerivationWithoutDependencies(derivation) {
  if (derivation.observing_.length !== 0) {
    return;
  }
  if (typeof derivation.requiresObservable_ === "boolean" ? derivation.requiresObservable_ : globalState.reactionRequiresObservable) {
    console.warn(`[mobx] Derivation '${derivation.name_}' is created/updated without reading any observable value.`);
  }
}
/**
 * diffs newObserving with observing.
 * update observing to be newObserving with unique observables
 * notify observers that become observed/unobserved
 */
function bindDependencies(derivation) {
  // invariant(derivation.dependenciesState !== IDerivationState.NOT_TRACKING, "INTERNAL ERROR bindDependencies expects derivation.dependenciesState !== -1");
  const prevObserving = derivation.observing_;
  const observing = derivation.observing_ = derivation.newObserving_;
  let lowestNewObservingDerivationState = 0 /* IDerivationState_.UP_TO_DATE_ */;
  // Go through all new observables and check diffValue: (this list can contain duplicates):
  //   0: first occurrence, change to 1 and keep it
  //   1: extra occurrence, drop it
  let i0 = 0,
    l = derivation.unboundDepsCount_;
  for (let i = 0; i < l; i++) {
    const dep = observing[i];
    if (dep.diffValue === 0) {
      dep.diffValue = 1;
      if (i0 !== i) {
        observing[i0] = dep;
      }
      i0++;
    }
    // Upcast is 'safe' here, because if dep is IObservable, `dependenciesState` will be undefined,
    // not hitting the condition
    if (dep.dependenciesState_ > lowestNewObservingDerivationState) {
      lowestNewObservingDerivationState = dep.dependenciesState_;
    }
  }
  observing.length = i0;
  derivation.newObserving_ = null; // newObserving shouldn't be needed outside tracking (statement moved down to work around FF bug, see #614)
  // Go through all old observables and check diffValue: (it is unique after last bindDependencies)
  //   0: it's not in new observables, unobserve it
  //   1: it keeps being observed, don't want to notify it. change to 0
  l = prevObserving.length;
  while (l--) {
    const dep = prevObserving[l];
    if (dep.diffValue === 0) {
      removeObserver(dep, derivation);
    }
    dep.diffValue = 0;
  }
  // Go through all new observables and check diffValue: (now it should be unique)
  //   0: it was set to 0 in last loop. don't need to do anything.
  //   1: it wasn't observed, let's observe it. set back to 0
  while (i0--) {
    const dep = observing[i0];
    if (dep.diffValue === 1) {
      dep.diffValue = 0;
      addObserver(dep, derivation);
    }
  }
  // Some new observed derivations may become stale during this derivation computation
  // so they have had no chance to propagate staleness (#916)
  if (lowestNewObservingDerivationState !== 0 /* IDerivationState_.UP_TO_DATE_ */) {
    derivation.dependenciesState_ = lowestNewObservingDerivationState;
    derivation.onBecomeStale_();
  }
}
function clearObserving(derivation) {
  // invariant(globalState.inBatch > 0, "INTERNAL ERROR clearObserving should be called only inside batch");
  const obs = derivation.observing_;
  derivation.observing_ = [];
  let i = obs.length;
  while (i--) {
    removeObserver(obs[i], derivation);
  }
  derivation.dependenciesState_ = -1 /* IDerivationState_.NOT_TRACKING_ */;
}
function untracked(action) {
  const prev = untrackedStart();
  try {
    return action();
  } finally {
    untrackedEnd(prev);
  }
}
function untrackedStart() {
  const prev = globalState.trackingDerivation;
  globalState.trackingDerivation = null;
  return prev;
}
function untrackedEnd(prev) {
  globalState.trackingDerivation = prev;
}
function allowStateReadsStart(allowStateReads) {
  const prev = globalState.allowStateReads;
  globalState.allowStateReads = allowStateReads;
  return prev;
}
function allowStateReadsEnd(prev) {
  globalState.allowStateReads = prev;
}
/**
 * needed to keep `lowestObserverState` correct. when changing from (2 or 1) to 0
 *
 */
function changeDependenciesStateTo0(derivation) {
  if (derivation.dependenciesState_ === 0 /* IDerivationState_.UP_TO_DATE_ */) {
    return;
  }
  derivation.dependenciesState_ = 0 /* IDerivationState_.UP_TO_DATE_ */;
  const obs = derivation.observing_;
  let i = obs.length;
  while (i--) {
    obs[i].lowestObserverState_ = 0 /* IDerivationState_.UP_TO_DATE_ */;
  }
}

const MOBX_GLOBALS_VERSION = 7;
/**
 * These values will persist if global state is reset
 */
const persistentKeys = ["mobxGuid", "spyListeners", "enforceActions", "computedRequiresReaction", "reactionRequiresObservable", "observableRequiresReaction", "allowStateReads", "disableErrorBoundaries", "runId", "UNCHANGED"];
class MobXGlobals {
  constructor() {
    /**
     * MobXGlobals version.
     * MobX compatiblity with other versions loaded in memory as long as this version matches.
     * It indicates that the global state still stores similar information
     *
     * N.B: this version is unrelated to the package version of MobX, and is only the version of the
     * internal state storage of MobX, and can be the same across many different package versions
     */
    this.version = MOBX_GLOBALS_VERSION;
    /**
     * globally unique token to signal unchanged
     */
    this.UNCHANGED = {};
    /**
     * Currently running derivation
     */
    this.trackingDerivation = null;
    /**
     * Currently running reaction. This determines if we currently have a reactive context.
     * (Tracking derivation is also set for temporal tracking of computed values inside actions,
     * but trackingReaction can only be set by a form of Reaction)
     */
    this.trackingContext = null;
    /**
     * Each time a derivation is tracked, it is assigned a unique run-id
     */
    this.runId = 0;
    /**
     * 'guid' for general purpose. Will be persisted amongst resets.
     */
    this.mobxGuid = 0;
    /**
     * Are we in a batch block? (and how many of them)
     */
    this.inBatch = 0;
    /**
     * Observables that don't have observers anymore, and are about to be
     * suspended, unless somebody else accesses it in the same batch
     *
     * @type {IObservable[]}
     */
    this.pendingUnobservations = [];
    /**
     * List of scheduled, not yet executed, reactions.
     */
    this.pendingReactions = [];
    /**
     * Are we currently processing reactions?
     */
    this.isRunningReactions = false;
    /**
     * Are we currently draining pendingUnobservations in endBatch?
     * An onBecomeUnobserved handler can dispose a Reaction, which calls
     * startBatch/endBatch again; this guards against re-entering the same
     * drain loop recursively (see endBatch in observable.ts).
     */
    this.isRunningUnobservations = false;
    /**
     * Is it allowed to change observables at this point?
     * In general, MobX doesn't allow that when running computations and React.render.
     * To ensure that those functions stay pure.
     */
    this.allowStateChanges = false;
    /**
     * Is it allowed to read observables at this point?
     * Used to hold the state needed for `observableRequiresReaction`
     */
    this.allowStateReads = true;
    /**
     * If strict mode is enabled, state changes are by default not allowed
     */
    this.enforceActions = true;
    /**
     * Spy callbacks
     */
    this.spyListeners = [];
    /**
     * Globally attached error handlers that react specifically to errors in reactions
     */
    this.globalReactionErrorHandlers = [];
    /**
     * Warn if computed values are accessed outside a reactive context
     */
    this.computedRequiresReaction = false;
    /**
     * (Experimental)
     * Warn if you try to create to derivation / reactive context without accessing any observable.
     */
    this.reactionRequiresObservable = false;
    /**
     * (Experimental)
     * Warn if observables are accessed outside a reactive context
     */
    this.observableRequiresReaction = false;
    /*
     * Don't catch and rethrow exceptions. This is useful for inspecting the state of
     * the stack when an exception occurs while debugging.
     */
    this.disableErrorBoundaries = false;
    /*
     * If true, we are already handling an exception in an action. Any errors in reactions should be suppressed, as
     * they are not the cause, see: https://github.com/mobxjs/mobx/issues/1836
     */
    this.suppressReactionErrors = false;
    /**
     * False forces all object's descriptors to
     * writable: true
     * configurable: true
     */
    this.safeDescriptors = true;
  }
}
let canMergeGlobalState = true;
let isolateCalled = false;
let globalState = /*#__PURE__*/function () {
  let global = globalThis;
  if (global.__mobxInstanceCount > 0 && !global.__mobxGlobals) {
    canMergeGlobalState = false;
  }
  if (global.__mobxGlobals && global.__mobxGlobals.version !== MOBX_GLOBALS_VERSION) {
    canMergeGlobalState = false;
  }
  if (!canMergeGlobalState) {
    // Because this is a IIFE we need to let isolateCalled a chance to change
    // so we run it after the event loop completed at least 1 iteration
    setTimeout(() => {
      if (!isolateCalled) {
        die(35);
      }
    }, 1);
    return new MobXGlobals();
  } else if (global.__mobxGlobals) {
    global.__mobxInstanceCount += 1;
    if (!global.__mobxGlobals.UNCHANGED) {
      global.__mobxGlobals.UNCHANGED = {};
    } // make merge backward compatible
    return global.__mobxGlobals;
  } else {
    global.__mobxInstanceCount = 1;
    return global.__mobxGlobals = /*#__PURE__*/new MobXGlobals();
  }
}();
function isolateGlobalState() {
  if (globalState.pendingReactions.length || globalState.inBatch || globalState.isRunningReactions) {
    die(36);
  }
  isolateCalled = true;
  if (canMergeGlobalState) {
    let global = globalThis;
    if (--global.__mobxInstanceCount === 0) {
      global.__mobxGlobals = undefined;
    }
    globalState = new MobXGlobals();
  }
}
function getGlobalState() {
  return globalState;
}
/**
 * For testing purposes only; this will break the internal state of existing observables,
 * but can be used to get back at a stable state after throwing errors
 */
function resetGlobalState() {
  const defaultGlobals = new MobXGlobals();
  for (let key in defaultGlobals) {
    if (persistentKeys.indexOf(key) === -1) {
      globalState[key] = defaultGlobals[key];
    }
  }
  globalState.allowStateChanges = !globalState.enforceActions;
}

function hasObservers(observable) {
  return !!observable.observers_ && observable.observers_.size > 0;
}
function getObservers(observable) {
  var _observable$observers;
  return (_observable$observers = observable.observers_) != null ? _observable$observers : new Set();
}
// function invariantObservers(observable: IObservable) {
//     const list = observable.observers
//     const map = observable.observersIndexes
//     const l = list.length
//     for (let i = 0; i < l; i++) {
//         const id = list[i].__mapid
//         if (i) {
//             invariant(map[id] === i, "INTERNAL ERROR maps derivation.__mapid to index in list") // for performance
//         } else {
//             invariant(!(id in map), "INTERNAL ERROR observer on index 0 shouldn't be held in map.") // for performance
//         }
//     }
//     invariant(
//         list.length === 0 || Object.keys(map).length === list.length - 1,
//         "INTERNAL ERROR there is no junk in map"
//     )
// }
function addObserver(observable, node) {
  var _observable$observers2;
  ((_observable$observers2 = observable.observers_) != null ? _observable$observers2 : observable.observers_ = new Set()).add(node);
  if (observable.lowestObserverState_ > node.dependenciesState_) {
    observable.lowestObserverState_ = node.dependenciesState_;
  }
  // invariantObservers(observable);
  // invariant(observable._observers.indexOf(node) !== -1, "INTERNAL ERROR didn't add node");
}
function removeObserver(observable, node) {
  // invariant(globalState.inBatch > 0, "INTERNAL ERROR, remove should be called only inside batch");
  // invariant(observable._observers.indexOf(node) !== -1, "INTERNAL ERROR remove already removed node");
  // invariantObservers(observable);
  const observers = observable.observers_;
  if (!observers) {
    return;
  }
  observers.delete(node);
  if (observers.size === 0) {
    // deleting last observer
    queueForUnobservation(observable);
  }
  // invariantObservers(observable);
  // invariant(observable._observers.indexOf(node) === -1, "INTERNAL ERROR remove already removed node2");
}
function queueForUnobservation(observable) {
  if (observable.isPendingUnobservation === false) {
    // invariant(observable._observers.length === 0, "INTERNAL ERROR, should only queue for unobservation unobserved observables");
    observable.isPendingUnobservation = true;
    globalState.pendingUnobservations.push(observable);
  }
}
/**
 * Batch starts a transaction, at least for purposes of memoizing ComputedValues when nothing else does.
 * During a batch `onBecomeUnobserved` will be called at most once per observable.
 * Avoids unnecessary recalculations.
 */
function startBatch() {
  globalState.inBatch++;
}
function endBatch() {
  if (--globalState.inBatch === 0) {
    runReactions();
    // the batch is actually about to finish, all unobserving should happen here.
    // Guard against re-entering this loop: an onBUO handler can dispose a Reaction,
    // which calls startBatch/endBatch again while we're still iterating. Bail out of
    // the nested call instead of recursing; the outer loop re-reads list.length on
    // every iteration, so it picks up anything the nested dispose() pushes onto the
    // same pendingUnobservations array.
    if (!globalState.isRunningUnobservations) {
      globalState.isRunningUnobservations = true;
      try {
        const list = globalState.pendingUnobservations;
        for (let i = 0; i < list.length; i++) {
          const observable = list[i];
          observable.isPendingUnobservation = false;
          if (!observable.observers_ || observable.observers_.size === 0) {
            if (observable.isBeingObserved) {
              // if this observable had reactive observers, trigger the hooks
              observable.isBeingObserved = false;
              observable.onBUO();
            }
            if (observable instanceof ComputedValue) {
              // computed values are automatically teared down when the last observer leaves
              // this process happens recursively, this computed might be the last observabe of another, etc..
              observable.suspend_();
            }
          }
        }
        globalState.pendingUnobservations = [];
      } finally {
        // Always release the guard, even if an onBUO handler (user code) threw,
        // otherwise every future endBatch() would see isRunningUnobservations
        // stuck true and silently stop draining pendingUnobservations forever.
        globalState.isRunningUnobservations = false;
      }
    }
  }
}
/**
 * Marks an observable as observed, cascading into the dependencies of a ComputedValue.
 * Unobservation already cascades (`suspend_` -> `clearObserving`), observation normally
 * only does so by accident: a newly observed computed usually recomputes and re-reports
 * its dependencies. When it serves a cached value instead nothing re-reports them, so the
 * transition has to be propagated by hand. See #4547.
 */
function markObserved(observable) {
  var _observable$observing;
  if (observable.isBeingObserved) {
    return;
  }
  observable.isBeingObserved = true;
  observable.onBO();
  // No queueForUnobservation here: the observer links already exist, so the regular
  // suspend_ -> clearObserving -> removeObserver teardown still delivers the onBUO.
  (_observable$observing = observable.observing_) == null || _observable$observing.forEach(markObserved);
}
function reportObserved(observable) {
  checkIfStateReadsAreAllowed(observable);
  const derivation = globalState.trackingDerivation;
  if (derivation !== null) {
    /**
     * Simple optimization, give each derivation run an unique id (runId)
     * Check if last time this observable was accessed the same runId is used
     * if this is the case, the relation is already known
     */
    if (derivation.runId_ !== observable.lastAccessedBy_) {
      observable.lastAccessedBy_ = derivation.runId_;
      // Tried storing newObserving, or observing, or both as Set, but performance didn't come close...
      derivation.newObserving_[derivation.unboundDepsCount_++] = observable;
      if (!observable.isBeingObserved && globalState.trackingContext) {
        observable.isBeingObserved = true;
        observable.onBO();
      }
    }
    return observable.isBeingObserved;
  } else if ((!observable.observers_ || observable.observers_.size === 0) && globalState.inBatch > 0) {
    queueForUnobservation(observable);
  }
  return false;
}
// function invariantLOS(observable: IObservable, msg: string) {
//     // it's expensive so better not run it in produciton. but temporarily helpful for testing
//     const min = getObservers(observable).reduce((a, b) => Math.min(a, b.dependenciesState), 2)
//     if (min >= observable.lowestObserverState) return // <- the only assumption about `lowestObserverState`
//     throw new Error(
//         "lowestObserverState is wrong for " +
//             msg +
//             " because " +
//             min +
//             " < " +
//             observable.lowestObserverState
//     )
// }
/**
 * NOTE: current propagation mechanism will in case of self reruning autoruns behave unexpectedly
 * It will propagate changes to observers from previous run
 * It's hard or maybe impossible (with reasonable perf) to get it right with current approach
 * Hopefully self reruning autoruns aren't a feature people should depend on
 * Also most basic use cases should be ok
 */
// Called by Atom when its value changes
function propagateChanged(observable) {
  var _observable$observers3;
  // invariantLOS(observable, "changed start");
  if (observable.lowestObserverState_ === 2 /* IDerivationState_.STALE_ */) {
    return;
  }
  observable.lowestObserverState_ = 2 /* IDerivationState_.STALE_ */;
  // Ideally we use for..of here, but the downcompiled version is really slow...
  (_observable$observers3 = observable.observers_) == null || _observable$observers3.forEach(d => {
    if (d.dependenciesState_ === 0 /* IDerivationState_.UP_TO_DATE_ */) {
      d.onBecomeStale_();
    }
    d.dependenciesState_ = 2 /* IDerivationState_.STALE_ */;
  });
  // invariantLOS(observable, "changed end");
}
// Called by ComputedValue when it recalculate and its value changed
function propagateChangeConfirmed(observable) {
  var _observable$observers4;
  // invariantLOS(observable, "confirmed start");
  if (observable.lowestObserverState_ === 2 /* IDerivationState_.STALE_ */) {
    return;
  }
  observable.lowestObserverState_ = 2 /* IDerivationState_.STALE_ */;
  (_observable$observers4 = observable.observers_) == null || _observable$observers4.forEach(d => {
    if (d.dependenciesState_ === 1 /* IDerivationState_.POSSIBLY_STALE_ */) {
      d.dependenciesState_ = 2 /* IDerivationState_.STALE_ */;
    } else if (d.dependenciesState_ === 0 /* IDerivationState_.UP_TO_DATE_ */ // this happens during computing of `d`, just keep lowestObserverState up to date.
    ) {
      observable.lowestObserverState_ = 0 /* IDerivationState_.UP_TO_DATE_ */;
    }
  });
  // invariantLOS(observable, "confirmed end");
}
// Used by computed when its dependency changed, but we don't wan't to immediately recompute.
function propagateMaybeChanged(observable) {
  var _observable$observers5;
  // invariantLOS(observable, "maybe start");
  if (observable.lowestObserverState_ !== 0 /* IDerivationState_.UP_TO_DATE_ */) {
    return;
  }
  observable.lowestObserverState_ = 1 /* IDerivationState_.POSSIBLY_STALE_ */;
  (_observable$observers5 = observable.observers_) == null || _observable$observers5.forEach(d => {
    if (d.dependenciesState_ === 0 /* IDerivationState_.UP_TO_DATE_ */) {
      d.dependenciesState_ = 1 /* IDerivationState_.POSSIBLY_STALE_ */;
      d.onBecomeStale_();
    }
  });
  // invariantLOS(observable, "maybe end");
}

class Reaction {
  constructor(name_ = "Reaction@" + getNextId() , onInvalidate_, errorHandler_, requiresObservable_) {
    this.name_ = void 0;
    this.onInvalidate_ = void 0;
    this.errorHandler_ = void 0;
    this.requiresObservable_ = void 0;
    this.observing_ = [];
    // nodes we are looking at. Our value depends on these nodes
    this.newObserving_ = [];
    this.dependenciesState_ = -1 /* IDerivationState_.NOT_TRACKING_ */;
    this.runId_ = 0;
    this.unboundDepsCount_ = 0;
    this.flags_ = 0b00000;
    this.name_ = name_;
    this.onInvalidate_ = onInvalidate_;
    this.errorHandler_ = errorHandler_;
    this.requiresObservable_ = requiresObservable_;
  }
  get isDisposed() {
    return getFlag(this.flags_, 1 /* ReactionFlags.isDisposed */);
  }
  set isDisposed(newValue) {
    this.flags_ = setFlag(this.flags_, 1 /* ReactionFlags.isDisposed */, newValue);
  }
  get isScheduled() {
    return getFlag(this.flags_, 2 /* ReactionFlags.isScheduled */);
  }
  set isScheduled(newValue) {
    this.flags_ = setFlag(this.flags_, 2 /* ReactionFlags.isScheduled */, newValue);
  }
  get isTrackPending() {
    return getFlag(this.flags_, 4 /* ReactionFlags.isTrackPending */);
  }
  set isTrackPending(newValue) {
    this.flags_ = setFlag(this.flags_, 4 /* ReactionFlags.isTrackPending */, newValue);
  }
  get isRunning() {
    return getFlag(this.flags_, 8 /* ReactionFlags.isRunning */);
  }
  set isRunning(newValue) {
    this.flags_ = setFlag(this.flags_, 8 /* ReactionFlags.isRunning */, newValue);
  }
  get diffValue() {
    return getFlag(this.flags_, 16 /* ReactionFlags.diffValue */) ? 1 : 0;
  }
  set diffValue(newValue) {
    this.flags_ = setFlag(this.flags_, 16 /* ReactionFlags.diffValue */, newValue === 1 ? true : false);
  }
  onBecomeStale_() {
    this.schedule_();
  }
  schedule_() {
    if (!this.isScheduled) {
      this.isScheduled = true;
      globalState.pendingReactions.push(this);
      runReactions();
    }
  }
  /**
   * internal, use schedule() if you intend to kick off a reaction
   */
  runReaction_() {
    if (!this.isDisposed) {
      startBatch();
      this.isScheduled = false;
      const prev = globalState.trackingContext;
      globalState.trackingContext = this;
      if (shouldCompute(this)) {
        this.isTrackPending = true;
        try {
          this.onInvalidate_();
          if ("development" !== "production" && this.isTrackPending && isSpyEnabled()) {
            // onInvalidate didn't trigger track right away..
            spyReport({
              name: this.name_,
              type: "scheduled-reaction"
            });
          }
        } catch (e) {
          this.reportExceptionInDerivation_(e);
        }
      }
      globalState.trackingContext = prev;
      endBatch();
    }
  }
  track(fn) {
    if (this.isDisposed) {
      return;
      // console.warn("Reaction already disposed") // Note: Not a warning / error in mobx 4 either
    }
    startBatch();
    const notify = isSpyEnabled();
    let startTime;
    if (notify) {
      startTime = Date.now();
      spyReportStart({
        name: this.name_,
        type: "reaction"
      });
    }
    this.isRunning = true;
    const prevReaction = globalState.trackingContext; // reactions could create reactions...
    globalState.trackingContext = this;
    const result = trackDerivedFunction(this, fn, undefined);
    globalState.trackingContext = prevReaction;
    this.isRunning = false;
    this.isTrackPending = false;
    if (this.isDisposed) {
      // disposed during last run. Clean up everything that was bound after the dispose call.
      clearObserving(this);
    }
    if (isCaughtException(result)) {
      this.reportExceptionInDerivation_(result.cause);
    }
    if (notify) {
      spyReportEnd({
        time: Date.now() - startTime
      });
    }
    endBatch();
  }
  reportExceptionInDerivation_(error) {
    if (this.errorHandler_) {
      this.errorHandler_(error, this);
      return;
    }
    if (globalState.disableErrorBoundaries) {
      throw error;
    }
    const message = `[mobx] Encountered an uncaught exception that was thrown by a reaction or observer component, in: '${this}'` ;
    if (!globalState.suppressReactionErrors) {
      console.error(message, error);
      /** If debugging brought you here, please, read the above message :-). Tnx! */
    } else {
      console.warn(`[mobx] (error in reaction '${this.name_}' suppressed, fix error of causing action below)`);
    } // prettier-ignore
    if (isSpyEnabled()) {
      spyReport({
        type: "error",
        name: this.name_,
        message,
        error: "" + error
      });
    }
    globalState.globalReactionErrorHandlers.forEach(f => f(error, this));
  }
  dispose() {
    if (!this.isDisposed) {
      this.isDisposed = true;
      if (!this.isRunning) {
        // if disposed while running, clean up later. Maybe not optimal, but rare case
        startBatch();
        clearObserving(this);
        endBatch();
      }
    }
  }
  getDisposer_(abortSignal) {
    const dispose = () => {
      this.dispose();
      abortSignal == null || abortSignal.removeEventListener == null || abortSignal.removeEventListener("abort", dispose);
    };
    abortSignal == null || abortSignal.addEventListener == null || abortSignal.addEventListener("abort", dispose);
    dispose[$mobx] = this;
    if ("dispose" in Symbol && typeof Symbol.dispose === "symbol") {
      dispose[Symbol.dispose] = dispose;
    }
    return dispose;
  }
  toString() {
    return `Reaction[${this.name_}]`;
  }
}
function onReactionError(handler) {
  globalState.globalReactionErrorHandlers.push(handler);
  return () => {
    const idx = globalState.globalReactionErrorHandlers.indexOf(handler);
    if (idx >= 0) {
      globalState.globalReactionErrorHandlers.splice(idx, 1);
    }
  };
}
/**
 * Magic number alert!
 * Defines within how many times a reaction is allowed to re-trigger itself
 * until it is assumed that this is gonna be a never ending loop...
 */
const MAX_REACTION_ITERATIONS = 100;
let reactionScheduler = f => f();
function runReactions() {
  // Trampolining, if runReactions are already running, new reactions will be picked up
  if (globalState.inBatch > 0 || globalState.isRunningReactions) {
    return;
  }
  reactionScheduler(runReactionsHelper);
}
function runReactionsHelper() {
  globalState.isRunningReactions = true;
  const allReactions = globalState.pendingReactions;
  let iterations = 0;
  // While running reactions, new reactions might be triggered.
  // Hence we work with two variables and check whether
  // we converge to no remaining reactions after a while.
  while (allReactions.length > 0) {
    if (++iterations === MAX_REACTION_ITERATIONS) {
      console.error(`Reaction doesn't converge to a stable state after ${MAX_REACTION_ITERATIONS} iterations.` + ` Probably there is a cycle in the reactive function: ${allReactions[0]}` );
      allReactions.splice(0); // clear reactions
    }
    let remainingReactions = allReactions.splice(0);
    for (let i = 0, l = remainingReactions.length; i < l; i++) {
      remainingReactions[i].runReaction_();
    }
  }
  globalState.isRunningReactions = false;
}
const isReaction = /*#__PURE__*/createInstanceofPredicate("Reaction", Reaction);
function setReactionScheduler(fn) {
  const baseScheduler = reactionScheduler;
  reactionScheduler = f => fn(() => baseScheduler(f));
}

function isSpyEnabled() {
  return !!globalState.spyListeners.length;
}
function spyReport(event) {
  if (!globalState.spyListeners.length) {
    return;
  }
  const listeners = globalState.spyListeners;
  for (let i = 0, l = listeners.length; i < l; i++) {
    listeners[i](event);
  }
}
function spyReportStart(event) {
  const change = assign({}, event, {
    spyReportStart: true
  });
  spyReport(change);
}
const END_EVENT = {
  type: "report-end",
  spyReportEnd: true
};
function spyReportEnd(change) {
  if (change) {
    spyReport(assign({}, change, {
      type: "report-end",
      spyReportEnd: true
    }));
  } else {
    spyReport(END_EVENT);
  }
}
function spy(listener) {
  {
    globalState.spyListeners.push(listener);
    return once(() => {
      globalState.spyListeners = globalState.spyListeners.filter(l => l !== listener);
    });
  }
}

const ACTION = "action";
const ACTION_BOUND = "action.bound";
const AUTOACTION = "autoAction";
const AUTOACTION_BOUND = "autoAction.bound";
const DEFAULT_ACTION_NAME = "<unnamed action>";
const actionAnnotation = /*#__PURE__*/createActionAnnotation(ACTION);
const actionBoundAnnotation = /*#__PURE__*/createActionAnnotation(ACTION_BOUND, {
  bound: true
});
const autoActionAnnotation = /*#__PURE__*/createActionAnnotation(AUTOACTION, {
  autoAction: true
});
const autoActionBoundAnnotation = /*#__PURE__*/createActionAnnotation(AUTOACTION_BOUND, {
  autoAction: true,
  bound: true
});
function createActionDecoratorAnnotation(annotation) {
  return createDecoratorAnnotation(annotation, decorateAction20223_);
}
function createActionFactory(autoAction) {
  const res = function action(arg1, arg2) {
    if (arg2 && typeof arg2.kind === "string") {
      return decorateAction20223_(autoAction ? autoActionAnnotation : actionAnnotation, arg1, arg2);
    }
    // action(fn() {})
    if (isFunction(arg1)) {
      return createAction(arg1.name || DEFAULT_ACTION_NAME, arg1, autoAction);
    }
    // action("name", fn() {})
    if (isFunction(arg2)) {
      return createAction(arg1, arg2, autoAction);
    }
    // action("name") annotation
    if (isStringish(arg1)) {
      return createActionDecoratorAnnotation(createActionAnnotation(autoAction ? AUTOACTION : ACTION, {
        name: arg1,
        autoAction
      }));
    }
    {
      die("Invalid arguments for `action`");
    }
  };
  return res;
}
const action = /*#__PURE__*/createActionFactory(false);
assign(action, actionAnnotation);
const autoAction = /*#__PURE__*/createActionFactory(true);
assign(autoAction, autoActionAnnotation);
const actionBound = /*#__PURE__*/createActionDecoratorAnnotation(actionBoundAnnotation);
const autoActionBound = /*#__PURE__*/createActionDecoratorAnnotation(autoActionBoundAnnotation);
function runInAction(fn) {
  return executeAction(fn.name || DEFAULT_ACTION_NAME, false, fn, this, undefined);
}
function isAction(thing) {
  return isFunction(thing) && thing.isMobxAction === true;
}

/**
 * Creates a named reactive view and keeps it alive, so that the view is always
 * updated if one of the dependencies changes, even when the view is not further used by something else.
 * @param view The reactive view
 * @returns disposer function, which can be used to stop the view from being updated in the future.
 */
function autorun(view, opts = EMPTY_OBJECT) {
  var _opts$name, _opts$signal;
  {
    if (!isFunction(view)) {
      die("Autorun expects a function as first argument");
    }
    if (isAction(view)) {
      die("Autorun does not accept actions since actions are untrackable");
    }
  }
  const name = (_opts$name = opts == null ? void 0 : opts.name) != null ? _opts$name : view.name || "Autorun@" + getNextId() ;
  const runSync = !opts.scheduler && !opts.delay;
  let reaction;
  if (runSync) {
    // normal autorun
    reaction = new Reaction(name, function () {
      this.track(reactionRunner);
    }, opts.onError, opts.requiresObservable);
  } else {
    const scheduler = createSchedulerFromOptions(opts);
    // debounced autorun
    let isScheduled = false;
    reaction = new Reaction(name, () => {
      if (!isScheduled) {
        isScheduled = true;
        scheduler(() => {
          isScheduled = false;
          if (!reaction.isDisposed) {
            reaction.track(reactionRunner);
          }
        });
      }
    }, opts.onError, opts.requiresObservable);
  }
  function reactionRunner() {
    view(reaction);
  }
  if (!(opts != null && (_opts$signal = opts.signal) != null && _opts$signal.aborted)) {
    reaction.schedule_();
  }
  return reaction.getDisposer_(opts == null ? void 0 : opts.signal);
}
const run = f => f();
function createSchedulerFromOptions(opts) {
  return opts.scheduler ? opts.scheduler : opts.delay ? f => setTimeout(f, opts.delay) : run;
}
function reaction(expression, effect, opts = EMPTY_OBJECT) {
  var _opts$name2, _opts$signal2;
  {
    if (!isFunction(expression) || !isFunction(effect)) {
      die("First and second argument to reaction should be functions");
    }
    if (!isPlainObject(opts)) {
      die("Third argument of reactions should be an object");
    }
  }
  const name = (_opts$name2 = opts.name) != null ? _opts$name2 : "Reaction@" + getNextId() ;
  const effectAction = action(name, opts.onError ? wrapErrorHandler(opts.onError, effect) : effect);
  const runSync = !opts.scheduler && !opts.delay;
  const scheduler = createSchedulerFromOptions(opts);
  let firstTime = true;
  let isScheduled = false;
  let value;
  const equals = opts.equals || compareDefault;
  const r = new Reaction(name, () => {
    if (firstTime || runSync) {
      reactionRunner();
    } else if (!isScheduled) {
      isScheduled = true;
      scheduler(reactionRunner);
    }
  }, opts.onError, opts.requiresObservable);
  function reactionRunner() {
    isScheduled = false;
    if (r.isDisposed) {
      return;
    }
    let changed = false;
    const oldValue = value;
    r.track(() => {
      const nextValue = allowStateChanges(false, () => expression(r));
      changed = firstTime || !equals(value, nextValue);
      value = nextValue;
    });
    if (firstTime && opts.fireImmediately) {
      effectAction(value, oldValue, r);
    } else if (!firstTime && changed) {
      effectAction(value, oldValue, r);
    }
    firstTime = false;
  }
  if (!(opts != null && (_opts$signal2 = opts.signal) != null && _opts$signal2.aborted)) {
    r.schedule_();
  }
  return r.getDisposer_(opts == null ? void 0 : opts.signal);
}
function wrapErrorHandler(errorHandler, baseFn) {
  return function () {
    try {
      return baseFn.apply(this, arguments);
    } catch (e) {
      errorHandler.call(this, e);
    }
  };
}

const ON_BECOME_OBSERVED = "onBO";
const ON_BECOME_UNOBSERVED = "onBUO";
function onBecomeObserved(thing, arg2, arg3) {
  return interceptHook(ON_BECOME_OBSERVED, thing, arg2, arg3);
}
function onBecomeUnobserved(thing, arg2, arg3) {
  return interceptHook(ON_BECOME_UNOBSERVED, thing, arg2, arg3);
}
function interceptHook(hook, thing, arg2, arg3) {
  const atom = typeof arg3 === "function" ? getAtom(thing, arg2) : getAtom(thing);
  const cb = isFunction(arg3) ? arg3 : arg2;
  const listenersKey = `${hook}L`;
  if (atom[listenersKey]) {
    atom[listenersKey].add(cb);
  } else {
    atom[listenersKey] = new Set([cb]);
  }
  return function () {
    const hookListeners = atom[listenersKey];
    if (hookListeners) {
      hookListeners.delete(cb);
      if (hookListeners.size === 0) {
        delete atom[listenersKey];
      }
    }
  };
}

const ALWAYS = "always";
const OBSERVED = "observed";
function configure(options) {
  if (options.isolateGlobalState === true) {
    isolateGlobalState();
  }
  const {
    enforceActions
  } = options;
  if (enforceActions !== undefined) {
    const ea = enforceActions === ALWAYS ? ALWAYS : enforceActions === OBSERVED;
    globalState.enforceActions = ea;
    globalState.allowStateChanges = ea === true || ea === ALWAYS ? false : true;
  }
  ["computedRequiresReaction", "reactionRequiresObservable", "observableRequiresReaction", "disableErrorBoundaries", "safeDescriptors"].forEach(key => {
    if (key in options) {
      globalState[key] = !!options[key];
    }
  });
  globalState.allowStateReads = !globalState.observableRequiresReaction;
  if (globalState.disableErrorBoundaries === true) {
    console.warn("WARNING: Debug feature only. MobX will NOT recover from errors when `disableErrorBoundaries` is enabled.");
  }
  if (options.reactionScheduler) {
    setReactionScheduler(options.reactionScheduler);
  }
}

function extendObservable(target, properties, annotations, options) {
  {
    if (arguments.length > 4) {
      die("'extendObservable' expected 2-4 arguments");
    }
    if (typeof target !== "object") {
      die("'extendObservable' expects an object as first argument");
    }
    if (isObservableMap(target)) {
      die("'extendObservable' should not be used on maps, use map.merge instead");
    }
    if (!isPlainObject(properties)) {
      die(`'extendObservable' only accepts plain objects as second argument`);
    }
    if (isObservable(properties) || isObservable(annotations)) {
      die(`Extending an object with another observable (object) is not supported`);
    }
  }
  // Pull descriptors first, so we don't have to deal with props added by administration ($mobx)
  const descriptors = getOwnPropertyDescriptors(properties);
  initObservable(() => {
    const adm = asObservableObject(target, options)[$mobx];
    ownKeys(descriptors).forEach(key => {
      adm.extend_(key, descriptors[key],
      // must pass "undefined" for { key: undefined }
      !annotations ? true : key in annotations ? annotations[key] : true);
    });
  });
  return target;
}

function getDependencyTree(thing, property) {
  return nodeToDependencyTree(getAtom(thing, property));
}
function nodeToDependencyTree(node) {
  const result = {
    name: node.name_
  };
  if (node.observing_ && node.observing_.length > 0) {
    result.dependencies = unique(node.observing_).map(nodeToDependencyTree);
  }
  return result;
}
function getObserverTree(thing, property) {
  return nodeToObserverTree(getAtom(thing, property));
}
function nodeToObserverTree(node) {
  const result = {
    name: node.name_
  };
  if (hasObservers(node)) {
    result.observers = Array.from(getObservers(node), nodeToObserverTree);
  }
  return result;
}
function unique(list) {
  return Array.from(new Set(list));
}

let generatorId = 0;
class FlowCancellationError extends Error {
  constructor() {
    super("FLOW_CANCELLED");
    Object.setPrototypeOf(this, new.target.prototype);
    this.name = "FlowCancellationError";
  }
  toString() {
    return `Error: ${this.message}`;
  }
}
function isFlowCancellationError(error) {
  return error instanceof FlowCancellationError;
}
function createFlowDecoratorAnnotation(annotation) {
  return createDecoratorAnnotation(annotation, decorateFlow20223_);
}
const flowAnnotation = /*#__PURE__*/createFlowAnnotation("flow");
const flowBoundAnnotation = /*#__PURE__*/createFlowAnnotation("flow.bound", {
  bound: true
});
const flow = /*#__PURE__*/assign(function flow(arg1, arg2) {
  if (arg2 && typeof arg2.kind === "string") {
    return decorateFlow20223_(flowAnnotation, arg1, arg2);
  }
  // flow(fn)
  if (arguments.length !== 1) {
    die(`Flow expects single argument with generator function`);
  }
  const generator = arg1;
  const name = generator.name || ("<unnamed flow>" );
  // Implementation based on https://github.com/tj/co/blob/master/index.js
  const res = function res() {
    const ctx = this;
    const args = arguments;
    const runId = ++generatorId ;
    const gen = action(`${name} - runid: ${runId} - init` , generator).apply(ctx, args);
    let rejector;
    let pendingPromise = undefined;
    const promise = new Promise(function (resolve, reject) {
      let stepId = 0;
      rejector = reject;
      function onFulfilled(res) {
        pendingPromise = undefined;
        let ret;
        try {
          ret = action("development" !== "production" ? `${name} - runid: ${runId} - yield ${stepId++}` : name, gen.next).call(gen, res);
        } catch (e) {
          return reject(e);
        }
        next(ret);
      }
      function onRejected(err) {
        pendingPromise = undefined;
        let ret;
        try {
          ret = action("development" !== "production" ? `${name} - runid: ${runId} - yield ${stepId++}` : name, gen.throw).call(gen, err);
        } catch (e) {
          return reject(e);
        }
        next(ret);
      }
      function next(ret) {
        if (isFunction(ret == null ? void 0 : ret.then)) {
          // an async iterator
          ret.then(next, reject);
          return;
        }
        if (ret.done) {
          return resolve(ret.value);
        }
        pendingPromise = Promise.resolve(ret.value);
        return pendingPromise.then(onFulfilled, onRejected);
      }
      onFulfilled(undefined); // kick off the process
    });
    const cancelActionName = `${name} - runid: ${runId} - cancel` ;
    promise.cancel = action(cancelActionName, function () {
      try {
        if (pendingPromise) {
          cancelPromise(pendingPromise);
        }
        // Finally block can return (or yield) stuff..
        const res = gen.return(undefined);
        // eat anything that promise would do, it's cancelled!
        const yieldedPromise = Promise.resolve(res.value);
        yieldedPromise.then(noop, noop);
        cancelPromise(yieldedPromise); // maybe it can be cancelled :)
        // reject our original promise
        rejector(new FlowCancellationError());
      } catch (e) {
        rejector(e); // there could be a throwing finally block
      }
    });
    return promise;
  };
  res.isMobXFlow = true;
  return res;
}, flowAnnotation);
const flowBound = /*#__PURE__*/createFlowDecoratorAnnotation(flowBoundAnnotation);
function cancelPromise(promise) {
  if (isFunction(promise.cancel)) {
    promise.cancel();
  }
}
function flowResult(result) {
  return result; // just tricking TypeScript :)
}
function isFlow(fn) {
  return (fn == null ? void 0 : fn.isMobXFlow) === true;
}

function interceptReads(thing, propOrHandler, handler) {
  let target;
  if (isObservableMap(thing) || isObservableArray(thing) || isObservableValue(thing)) {
    target = getAdministration(thing);
  } else if (isObservableObject(thing)) {
    if (!isStringish(propOrHandler)) {
      return die(`InterceptReads can only be used with a specific property, not with an object in general`);
    }
    target = getAdministration(thing, propOrHandler);
  } else {
    return die(`Expected observable map, object or array as first array`);
  }
  if (target.dehancer !== undefined) {
    return die(`An intercept reader was already established`);
  }
  target.dehancer = typeof propOrHandler === "function" ? propOrHandler : handler;
  return () => {
    target.dehancer = undefined;
  };
}

function intercept(thing, propOrHandler, handler) {
  if (isFunction(handler)) {
    return interceptProperty(thing, propOrHandler, handler);
  } else {
    return interceptInterceptable(thing, propOrHandler);
  }
}
function interceptInterceptable(thing, handler) {
  return registerInterceptor(getAdministration(thing), handler);
}
function interceptProperty(thing, property, handler) {
  return registerInterceptor(getAdministration(thing, property), handler);
}

function _isComputed(value, property) {
  var _adm$lazyComputedKeys;
  if (property === undefined) {
    return isComputedValue(value);
  }
  if (isObservableObject(value) === false) {
    return false;
  }
  const adm = value[$mobx];
  if ((_adm$lazyComputedKeys = adm.lazyComputedKeys_) != null && _adm$lazyComputedKeys.has(property)) {
    return true;
  }
  if (!adm.values_.has(property)) {
    return false;
  }
  const atom = getAtom(value, property);
  return isComputedValue(atom);
}
function isComputed(value) {
  if (arguments.length > 1) {
    return die(`isComputed expects only 1 argument. Use isComputedProp to inspect the observability of a property`);
  }
  return _isComputed(value);
}
function isComputedProp(value, propName) {
  if (!isStringish(propName)) {
    return die(`isComputed expected a property name as second argument`);
  }
  return _isComputed(value, propName);
}

function _isObservable(value, property) {
  if (!value) {
    return false;
  }
  if (property !== undefined) {
    if ((isObservableMap(value) || isObservableArray(value))) {
      return die("isObservable(object, propertyName) is not supported for arrays and maps. Use map.has or array.length instead.");
    }
    if (isObservableObject(value)) {
      var _adm$lazyComputedKeys, _adm$lazyObservableKe;
      const adm = value[$mobx];
      return adm.values_.has(property) || !!((_adm$lazyComputedKeys = adm.lazyComputedKeys_) != null && _adm$lazyComputedKeys.has(property)) || !!((_adm$lazyObservableKe = adm.lazyObservableKeys_) != null && _adm$lazyObservableKe.has(property));
    }
    return false;
  }
  // For first check, see #701
  return isObservableObject(value) || !!value[$mobx] || isAtom(value) || isReaction(value) || isComputedValue(value);
}
function isObservable(value) {
  if (arguments.length !== 1) {
    die(`isObservable expects only 1 argument. Use isObservableProp to inspect the observability of a property`);
  }
  return _isObservable(value);
}
function isObservableProp(value, propName) {
  if (!isStringish(propName)) {
    return die(`expected a property name as second argument`);
  }
  return _isObservable(value, propName);
}

function keys(obj) {
  if (isObservableObject(obj)) {
    return obj[$mobx].keys_();
  }
  if (isObservableMap(obj) || isObservableSet(obj)) {
    return Array.from(obj.keys());
  }
  if (isObservableArray(obj)) {
    return obj.map((_, index) => index);
  }
  die(5);
}
function values(obj) {
  if (isObservableObject(obj)) {
    return keys(obj).map(key => obj[key]);
  }
  if (isObservableMap(obj)) {
    return keys(obj).map(key => obj.get(key));
  }
  if (isObservableSet(obj)) {
    return Array.from(obj.values());
  }
  if (isObservableArray(obj)) {
    return obj.slice();
  }
  die(6);
}
function entries(obj) {
  if (isObservableObject(obj)) {
    return keys(obj).map(key => [key, obj[key]]);
  }
  if (isObservableMap(obj)) {
    return keys(obj).map(key => [key, obj.get(key)]);
  }
  if (isObservableSet(obj)) {
    return Array.from(obj.entries());
  }
  if (isObservableArray(obj)) {
    return obj.map((key, index) => [index, key]);
  }
  die(7);
}
function set(obj, key, value) {
  if (arguments.length === 2 && !isObservableSet(obj)) {
    startBatch();
    const values = key;
    try {
      for (let _key in values) {
        set(obj, _key, values[_key]);
      }
    } finally {
      endBatch();
    }
    return;
  }
  if (isObservableObject(obj)) {
    obj[$mobx].set_(key, value);
  } else if (isObservableMap(obj)) {
    obj.set(key, value);
  } else if (isObservableSet(obj)) {
    obj.add(key);
  } else if (isObservableArray(obj)) {
    if (typeof key !== "number") {
      key = parseInt(key, 10);
    }
    if (key < 0) {
      die(42, key);
    }
    startBatch();
    if (key >= obj.length) {
      obj.length = key + 1;
    }
    obj[key] = value;
    endBatch();
  } else {
    die(8);
  }
}
function remove(obj, key) {
  if (isObservableObject(obj)) {
    obj[$mobx].delete_(key);
  } else if (isObservableMap(obj)) {
    obj.delete(key);
  } else if (isObservableSet(obj)) {
    obj.delete(key);
  } else if (isObservableArray(obj)) {
    if (typeof key !== "number") {
      key = parseInt(key, 10);
    }
    obj.splice(key, 1);
  } else {
    die(9);
  }
}
function has(obj, key) {
  if (isObservableObject(obj)) {
    return obj[$mobx].has_(key);
  } else if (isObservableMap(obj)) {
    return obj.has(key);
  } else if (isObservableSet(obj)) {
    return obj.has(key);
  } else if (isObservableArray(obj)) {
    return key >= 0 && key < obj.length;
  }
  die(10);
}
function get(obj, key) {
  if (!has(obj, key)) {
    return undefined;
  }
  if (isObservableObject(obj)) {
    return obj[$mobx].get_(key);
  } else if (isObservableMap(obj)) {
    return obj.get(key);
  } else if (isObservableArray(obj)) {
    return obj[key];
  }
  die(11);
}
function apiDefineProperty(obj, key, descriptor) {
  if (isObservableObject(obj)) {
    return obj[$mobx].defineProperty_(key, descriptor);
  }
  die(39);
}
function apiOwnKeys(obj) {
  if (isObservableObject(obj)) {
    return obj[$mobx].ownKeys_();
  }
  die(38);
}

function observe(thing, propOrCb, cbOrFire, fireImmediately) {
  if (isFunction(cbOrFire)) {
    return observeObservableProperty(thing, propOrCb, cbOrFire, fireImmediately);
  } else {
    return observeObservable(thing, propOrCb, cbOrFire);
  }
}
function observeObservable(thing, listener, fireImmediately) {
  const adm = getAdministration(thing);
  if (isObservableArray(thing)) {
    if (fireImmediately) {
      listener({
        observableKind: "array",
        object: adm.proxy_,
        debugObjectName: adm.atom_.name_,
        type: "splice",
        index: 0,
        added: adm.values_.slice(),
        addedCount: adm.values_.length,
        removed: [],
        removedCount: 0
      });
    }
  } else if (isObservableMap(thing)) {
    if (fireImmediately === true) {
      die("`observe` doesn't support fireImmediately=true in combination with maps.");
    }
  } else if (isObservableSet(thing)) {
    if (fireImmediately === true) {
      die("`observe` doesn't support fireImmediately=true in combination with sets.");
    }
  } else if (isObservableObject(thing)) {
    if (fireImmediately === true) {
      die("`observe` doesn't support the fire immediately property for observable objects.");
    }
  } else {
    return observeValue(adm, listener, fireImmediately);
  }
  return registerListener(adm, listener);
}
function observeObservableProperty(thing, property, listener, fireImmediately) {
  return observeValue(getAdministration(thing, property), listener, fireImmediately);
}
function observeValue(adm, listener, fireImmediately) {
  if (isComputedValue(adm)) {
    let firstTime = true;
    let prevValue = undefined;
    return autorun(() => {
      const newValue = adm.get();
      if (!firstTime || fireImmediately) {
        const prevU = untrackedStart();
        listener({
          observableKind: "computed",
          debugObjectName: adm.name_,
          type: UPDATE,
          object: adm,
          newValue,
          oldValue: prevValue
        });
        untrackedEnd(prevU);
      }
      firstTime = false;
      prevValue = newValue;
    });
  }
  if (fireImmediately) {
    listener({
      observableKind: "value",
      debugObjectName: adm.name_,
      object: adm,
      type: UPDATE,
      newValue: adm.value_,
      oldValue: undefined
    });
  }
  return registerListener(adm, listener);
}

function cache(map, key, value) {
  map.set(key, value);
  return value;
}
function toJSHelper(source, __alreadySeen) {
  if (source == null || typeof source !== "object" || source instanceof Date || !isObservable(source)) {
    return source;
  }
  if (isObservableValue(source) || isComputedValue(source)) {
    return toJSHelper(source.get(), __alreadySeen);
  }
  if (__alreadySeen.has(source)) {
    return __alreadySeen.get(source);
  }
  if (isObservableArray(source)) {
    const res = cache(__alreadySeen, source, new Array(source.length));
    source.forEach((value, idx) => {
      res[idx] = toJSHelper(value, __alreadySeen);
    });
    return res;
  }
  if (isObservableSet(source)) {
    const res = cache(__alreadySeen, source, new Set());
    source.forEach(value => {
      res.add(toJSHelper(value, __alreadySeen));
    });
    return res;
  }
  if (isObservableMap(source)) {
    const res = cache(__alreadySeen, source, new Map());
    source.forEach((value, key) => {
      res.set(key, toJSHelper(value, __alreadySeen));
    });
    return res;
  } else {
    // must be observable object
    const res = cache(__alreadySeen, source, {});
    apiOwnKeys(source).forEach(key => {
      if (objectPrototype.propertyIsEnumerable.call(source, key)) {
        res[key] = toJSHelper(source[key], __alreadySeen);
      }
    });
    return res;
  }
}
/**
 * Recursively converts an observable to it's non-observable native counterpart.
 * It does NOT recurse into non-observables, these are left as they are, even if they contain observables.
 * Computed and other non-enumerable properties are completely ignored.
 * Complex scenarios require custom solution, eg implementing `toJSON` or using `serializr` lib.
 */
function toJS(source, options) {
  if (options) {
    die("toJS no longer supports options");
  }
  return toJSHelper(source, new Map());
}

/**
 * During a transaction no views are updated until the end of the transaction.
 * The transaction will be run synchronously nonetheless.
 *
 * @param action a function that updates some reactive state
 * @returns any value that was returned by the 'action' parameter.
 */
function transaction(action, thisArg = undefined) {
  startBatch();
  try {
    return action.apply(thisArg);
  } finally {
    endBatch();
  }
}

function when(predicate, arg1, arg2) {
  if (arguments.length === 1 || arg1 && typeof arg1 === "object") {
    return whenPromise(predicate, arg1);
  }
  return _when(predicate, arg1, arg2 || {});
}
function _when(predicate, effect, opts) {
  let timeoutHandle;
  if (typeof opts.timeout === "number") {
    const error = new Error("WHEN_TIMEOUT");
    timeoutHandle = setTimeout(() => {
      if (!disposer[$mobx].isDisposed) {
        disposer();
        if (opts.onError) {
          opts.onError(error);
        } else {
          throw error;
        }
      }
    }, opts.timeout);
  }
  opts.name = opts.name || "When@" + getNextId() ;
  const effectAction = createAction(opts.name + "-effect" , effect);
  // eslint-disable-next-line
  var disposer = autorun(r => {
    // predicate should not change state
    let cond = allowStateChanges(false, predicate);
    if (cond) {
      r.dispose();
      if (timeoutHandle) {
        clearTimeout(timeoutHandle);
      }
      effectAction();
    }
  }, opts);
  return disposer;
}
function whenPromise(predicate, opts) {
  var _opts$signal;
  if (opts && opts.onError) {
    return die(`the options 'onError' and 'promise' cannot be combined`);
  }
  if (opts != null && (_opts$signal = opts.signal) != null && _opts$signal.aborted) {
    return assign(Promise.reject(new Error("WHEN_ABORTED")), {
      cancel: () => null
    });
  }
  let cancel;
  let abort;
  const res = new Promise((resolve, reject) => {
    var _opts$signal2;
    let disposer = _when(predicate, resolve, assign({}, opts, {
      onError: reject
    }));
    cancel = () => {
      disposer();
      reject(new Error("WHEN_CANCELLED"));
    };
    abort = () => {
      disposer();
      reject(new Error("WHEN_ABORTED"));
    };
    opts == null || (_opts$signal2 = opts.signal) == null || _opts$signal2.addEventListener == null || _opts$signal2.addEventListener("abort", abort);
  }).finally(() => {
    var _opts$signal3;
    return opts == null || (_opts$signal3 = opts.signal) == null || _opts$signal3.removeEventListener == null ? void 0 : _opts$signal3.removeEventListener("abort", abort);
  });
  res.cancel = cancel;
  return res;
}

function getAdm(target) {
  return target[$mobx];
}
// Optimization: we don't need the intermediate objects and could have a completely custom administration for DynamicObjects,
// and skip either the internal values map, or the base object with its property descriptors!
const objectProxyTraps = {
  has(target, name) {
    return getAdm(target).has_(name);
  },
  get(target, name) {
    return getAdm(target).get_(name);
  },
  set(target, name, value) {
    var _getAdm$set_;
    if (!isStringish(name)) {
      return false;
    }
    // null (intercepted) -> true (success)
    return (_getAdm$set_ = getAdm(target).set_(name, value, true)) != null ? _getAdm$set_ : true;
  },
  deleteProperty(target, name) {
    var _getAdm$delete_;
    if (!isStringish(name)) {
      return false;
    }
    // null (intercepted) -> true (success)
    return (_getAdm$delete_ = getAdm(target).delete_(name, true)) != null ? _getAdm$delete_ : true;
  },
  defineProperty(target, name, descriptor) {
    var _getAdm$definePropert;
    // null (intercepted) -> true (success)
    return (_getAdm$definePropert = getAdm(target).defineProperty_(name, descriptor)) != null ? _getAdm$definePropert : true;
  },
  ownKeys(target) {
    return getAdm(target).ownKeys_();
  },
  preventExtensions(target) {
    die(13);
  }
};
function asDynamicObservableObject(target, options) {
  var _target$$mobx, _target$$mobx$proxy_;
  target = asObservableObject(target, options);
  return (_target$$mobx$proxy_ = (_target$$mobx = target[$mobx]).proxy_) != null ? _target$$mobx$proxy_ : _target$$mobx.proxy_ = new Proxy(target, objectProxyTraps);
}

function hasInterceptors(interceptable) {
  return interceptable.interceptors_ !== undefined && interceptable.interceptors_.length > 0;
}
function registerInterceptor(interceptable, handler) {
  const interceptors = interceptable.interceptors_ || (interceptable.interceptors_ = []);
  interceptors.push(handler);
  return once(() => {
    const idx = interceptors.indexOf(handler);
    if (idx !== -1) {
      interceptors.splice(idx, 1);
    }
  });
}
function interceptChange(interceptable, change) {
  const prevU = untrackedStart();
  try {
    // Interceptor can modify the array, copy it to avoid concurrent modification, see #1950
    const interceptors = [...(interceptable.interceptors_ || [])];
    for (let i = 0, l = interceptors.length; i < l; i++) {
      change = interceptors[i](change);
      if (change && !change.type) {
        die(14);
      }
      if (!change) {
        break;
      }
    }
    return change;
  } finally {
    untrackedEnd(prevU);
  }
}

function hasListeners(listenable) {
  return listenable.changeListeners_ !== undefined && listenable.changeListeners_.length > 0;
}
function registerListener(listenable, handler) {
  const listeners = listenable.changeListeners_ || (listenable.changeListeners_ = []);
  listeners.push(handler);
  return once(() => {
    const idx = listeners.indexOf(handler);
    if (idx !== -1) {
      listeners.splice(idx, 1);
    }
  });
}
function notifyListeners(listenable, change) {
  const prevU = untrackedStart();
  let listeners = listenable.changeListeners_;
  if (!listeners) {
    return;
  }
  listeners = listeners.slice();
  for (let i = 0, l = listeners.length; i < l; i++) {
    listeners[i](change);
  }
  untrackedEnd(prevU);
}

function makeObservable(target, annotations, options) {
  initObservable(() => {
    const adm = asObservableObject(target, options)[$mobx];
    // Annotate
    ownKeys(annotations).forEach(key => make_(adm, key, annotations[key]));
  });
  return target;
}
// proto[keysSymbol] = new Set<PropertyKey>()
const keysSymbol = /*#__PURE__*/Symbol("mobx-keys");
function makeAutoObservable(target, overrides, options) {
  {
    if (!isPlainObject(target) && !isPlainObject(Object.getPrototypeOf(target))) {
      die(`'makeAutoObservable' can only be used for classes that don't have a superclass`);
    }
    if (isObservableObject(target)) {
      die(`makeAutoObservable can only be used on objects not already made observable`);
    }
  }
  // Optimization: avoid visiting protos
  // Assumes that annotation.make_/.extend_ works the same for plain objects
  if (isPlainObject(target)) {
    return extendObservable(target, target, overrides, options);
  }
  initObservable(() => {
    const adm = asObservableObject(target, options)[$mobx];
    // Optimization: cache keys on proto
    // Assumes makeAutoObservable can be called only once per object and can't be used in subclass
    if (!target[keysSymbol]) {
      const proto = Object.getPrototypeOf(target);
      const keys = new Set([...ownKeys(target), ...ownKeys(proto)]);
      keys.delete("constructor");
      keys.delete($mobx);
      addHiddenProp(proto, keysSymbol, keys);
    }
    target[keysSymbol].forEach(key => make_(adm, key,
    // must pass "undefined" for { key: undefined }
    !overrides ? true : key in overrides ? overrides[key] : true));
  });
  return target;
}
function make_(adm, key, annotation) {
  if (annotation === true) {
    annotation = adm.defaultAnnotation_;
  }
  if (annotation === false) {
    return;
  }
  assertAnnotable(adm, annotation, key);
  if (!(key in adm.target_)) {
    die(1, annotation.annotationType_, `${adm.name_}.${key.toString()}`);
  }
  let source = adm.target_;
  while (source && source !== objectPrototype) {
    const descriptor = getDescriptor(source, key);
    if (descriptor) {
      const outcome = annotation.make_(adm, key, descriptor, source);
      if (outcome === 0 /* MakeResult.Cancel */) {
        return;
      }
      if (outcome === 1 /* MakeResult.Break */) {
        break;
      }
    }
    source = Object.getPrototypeOf(source);
  }
  recordAnnotationApplied(adm, annotation, key);
}

const SPLICE = "splice";
const UPDATE = "update";
const MAX_SPLICE_SIZE = 10000; // See e.g. https://github.com/mobxjs/mobx/issues/859
const arrayTraps = {
  get(target, name) {
    const adm = target[$mobx];
    if (name === $mobx) {
      return adm;
    }
    if (name === "length") {
      return adm.getArrayLength_();
    }
    if (typeof name === "string" && !isNaN(name)) {
      return adm.get_(parseInt(name));
    }
    if (hasProp(arrayExtensions, name)) {
      return arrayExtensions[name];
    }
    return target[name];
  },
  set(target, name, value) {
    const adm = target[$mobx];
    if (name === "length") {
      adm.setArrayLength_(value);
    }
    if (typeof name === "symbol" || isNaN(name)) {
      target[name] = value;
    } else {
      // numeric string
      adm.set_(parseInt(name), value);
    }
    return true;
  },
  preventExtensions() {
    die(15);
  }
};
class ObservableArrayAdministration {
  constructor(name = "ObservableArray@" + getNextId() , enhancer, owned_) {
    this.owned_ = void 0;
    this.atom_ = void 0;
    this.values_ = [];
    // this is the prop that gets proxied, so can't replace it!
    this.interceptors_ = void 0;
    this.changeListeners_ = void 0;
    this.enhancer_ = void 0;
    this.dehancer = void 0;
    this.proxy_ = void 0;
    this.lastKnownLength_ = 0;
    this.owned_ = owned_;
    this.atom_ = new Atom(name);
    this.enhancer_ = (newV, oldV) => enhancer(newV, oldV, name + "[..]" );
  }
  dehanceValue_(value) {
    if (this.dehancer !== undefined) {
      return this.dehancer(value);
    }
    return value;
  }
  dehanceValues_(values) {
    if (this.dehancer !== undefined && values.length > 0) {
      return values.map(this.dehancer);
    }
    return values;
  }
  getArrayLength_() {
    this.atom_.reportObserved();
    return this.values_.length;
  }
  setArrayLength_(newLength) {
    if (typeof newLength !== "number" || isNaN(newLength) || newLength < 0) {
      die(40, newLength);
    }
    let currentLength = this.values_.length;
    if (newLength === currentLength) {
      return;
    } else if (newLength > currentLength) {
      const newItems = Array.from({
        length: newLength - currentLength
      });
      this.spliceWithArray_(currentLength, 0, newItems);
    } else {
      this.spliceWithArray_(newLength, currentLength - newLength);
    }
  }
  updateArrayLength_(oldLength, delta) {
    if (oldLength !== this.lastKnownLength_) {
      die(16);
    }
    this.lastKnownLength_ += delta;
  }
  spliceWithArray_(index, deleteCount, newItems) {
    checkIfStateModificationsAreAllowed(this.atom_);
    const length = this.values_.length;
    if (index === undefined) {
      index = 0;
    } else if (index > length) {
      index = length;
    } else if (index < 0) {
      index = Math.max(0, length + index);
    }
    if (arguments.length === 1) {
      deleteCount = length - index;
    } else if (deleteCount === undefined || deleteCount === null) {
      deleteCount = 0;
    } else {
      deleteCount = Math.max(0, Math.min(deleteCount, length - index));
    }
    if (newItems === undefined) {
      newItems = EMPTY_ARRAY;
    }
    if (hasInterceptors(this)) {
      const change = interceptChange(this, {
        object: this.proxy_,
        type: SPLICE,
        index,
        removedCount: deleteCount,
        added: newItems
      });
      if (!change) {
        return EMPTY_ARRAY;
      }
      deleteCount = change.removedCount;
      newItems = change.added;
    }
    newItems = newItems.length === 0 ? newItems : newItems.map(v => this.enhancer_(v, undefined));
    {
      const lengthDelta = newItems.length - deleteCount;
      this.updateArrayLength_(length, lengthDelta); // checks if internal array wasn't modified
    }
    const res = this.spliceItemsIntoValues_(index, deleteCount, newItems);
    if (deleteCount !== 0 || newItems.length !== 0) {
      this.notifyArraySplice_(index, newItems, res);
    }
    return this.dehanceValues_(res);
  }
  spliceItemsIntoValues_(index, deleteCount, newItems) {
    if (newItems.length < MAX_SPLICE_SIZE) {
      return this.values_.splice(index, deleteCount, ...newItems);
    } else {
      // The items removed by the splice
      const res = this.values_.slice(index, index + deleteCount);
      // The items that that should remain at the end of the array
      let oldItems = this.values_.slice(index + deleteCount);
      // New length is the previous length + addition count - deletion count
      this.values_.length += newItems.length - deleteCount;
      for (let i = 0; i < newItems.length; i++) {
        this.values_[index + i] = newItems[i];
      }
      for (let i = 0; i < oldItems.length; i++) {
        this.values_[index + newItems.length + i] = oldItems[i];
      }
      return res;
    }
  }
  notifyArrayChildUpdate_(index, newValue, oldValue) {
    const notifySpy = !this.owned_ && isSpyEnabled();
    const notify = hasListeners(this);
    const change = notify || notifySpy ? {
      observableKind: "array",
      object: this.proxy_,
      type: UPDATE,
      debugObjectName: this.atom_.name_,
      index,
      newValue,
      oldValue
    } : null;
    // The reason why this is on right hand side here (and not above), is this way the uglifier will drop it, but it won't
    // cause any runtime overhead in development mode without NODE_ENV set, unless spying is enabled
    if (notifySpy) {
      spyReportStart(change);
    }
    this.atom_.reportChanged();
    if (notify) {
      notifyListeners(this, change);
    }
    if (notifySpy) {
      spyReportEnd();
    }
  }
  notifyArraySplice_(index, added, removed) {
    const notifySpy = !this.owned_ && isSpyEnabled();
    const notify = hasListeners(this);
    const change = notify || notifySpy ? {
      observableKind: "array",
      object: this.proxy_,
      debugObjectName: this.atom_.name_,
      type: SPLICE,
      index,
      removed,
      added,
      removedCount: removed.length,
      addedCount: added.length
    } : null;
    if (notifySpy) {
      spyReportStart(change);
    }
    this.atom_.reportChanged();
    // conform: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/observe
    if (notify) {
      notifyListeners(this, change);
    }
    if (notifySpy) {
      spyReportEnd();
    }
  }
  get_(index) {
    this.atom_.reportObserved();
    return this.dehanceValue_(this.values_[index]);
  }
  set_(index, newValue) {
    const values = this.values_;
    if (index < values.length) {
      // update at index in range
      checkIfStateModificationsAreAllowed(this.atom_);
      const oldValue = values[index];
      if (hasInterceptors(this)) {
        const change = interceptChange(this, {
          type: UPDATE,
          object: this.proxy_,
          // since "this" is the real array we need to pass its proxy
          index,
          newValue
        });
        if (!change) {
          return;
        }
        newValue = change.newValue;
      }
      newValue = this.enhancer_(newValue, oldValue);
      const changed = newValue !== oldValue;
      if (changed) {
        values[index] = newValue;
        this.notifyArrayChildUpdate_(index, newValue, oldValue);
      }
    } else {
      // For out of bound index, we don't create an actual sparse array,
      // but rather fill the holes with undefined (same as setArrayLength_).
      // This could be considered a bug.
      const newItems = Array.from({
        length: index + 1 - values.length
      });
      newItems[newItems.length - 1] = newValue;
      this.spliceWithArray_(values.length, 0, newItems);
    }
  }
}
function createObservableArray(initialValues, enhancer, name = "ObservableArray@" + getNextId() , owned = false) {
  return initObservable(() => {
    const adm = new ObservableArrayAdministration(name, enhancer, owned);
    addHiddenFinalProp(adm.values_, $mobx, adm);
    const proxy = new Proxy(adm.values_, arrayTraps);
    adm.proxy_ = proxy;
    if (initialValues && initialValues.length) {
      adm.spliceWithArray_(0, 0, initialValues);
    }
    return proxy;
  });
}
// eslint-disable-next-line
var arrayExtensions = {
  clear() {
    return this.splice(0);
  },
  replace(newItems) {
    const adm = this[$mobx];
    return adm.spliceWithArray_(0, adm.values_.length, newItems);
  },
  // Used by JSON.stringify
  toJSON() {
    return this.slice();
  },
  /*
   * functions that do alter the internal structure of the array, (based on lib.es6.d.ts)
   * since these functions alter the inner structure of the array, the have side effects.
   * Because the have side effects, they should not be used in computed function,
   * and for that reason the do not call dependencyState.notifyObserved
   */
  splice(index, deleteCount, ...newItems) {
    const adm = this[$mobx];
    switch (arguments.length) {
      case 0:
        return [];
      case 1:
        return adm.spliceWithArray_(index);
      case 2:
        return adm.spliceWithArray_(index, deleteCount);
    }
    return adm.spliceWithArray_(index, deleteCount, newItems);
  },
  spliceWithArray(index, deleteCount, newItems) {
    return this[$mobx].spliceWithArray_(index, deleteCount, newItems);
  },
  push(...items) {
    const adm = this[$mobx];
    adm.spliceWithArray_(adm.values_.length, 0, items);
    return adm.values_.length;
  },
  pop() {
    return this.splice(Math.max(this[$mobx].values_.length - 1, 0), 1)[0];
  },
  shift() {
    return this.splice(0, 1)[0];
  },
  unshift(...items) {
    const adm = this[$mobx];
    adm.spliceWithArray_(0, 0, items);
    return adm.values_.length;
  },
  reverse() {
    // reverse by default mutates in place before returning the result
    // which makes it both a 'derivation' and a 'mutation'.
    if (globalState.trackingDerivation) {
      die(37, "reverse");
    }
    this.replace(this.slice().reverse());
    return this;
  },
  sort() {
    // sort by default mutates in place before returning the result
    // which goes against all good practices. Let's not change the array in place!
    if (globalState.trackingDerivation) {
      die(37, "sort");
    }
    const copy = this.slice();
    copy.sort.apply(copy, arguments);
    this.replace(copy);
    return this;
  },
  remove(value) {
    const adm = this[$mobx];
    const idx = adm.dehanceValues_(adm.values_).indexOf(value);
    if (idx > -1) {
      this.splice(idx, 1);
      return true;
    }
    return false;
  }
};
/**
 * Wrap function from prototype
 * Without this, everything works as well, but this works
 * faster as everything works on unproxied values
 */
addArrayExtension("at", simpleFunc);
addArrayExtension("concat", simpleFunc);
addArrayExtension("flat", simpleFunc);
addArrayExtension("includes", simpleFunc);
addArrayExtension("indexOf", simpleFunc);
addArrayExtension("join", simpleFunc);
addArrayExtension("lastIndexOf", simpleFunc);
addArrayExtension("slice", simpleFunc);
addArrayExtension("toString", simpleFunc);
addArrayExtension("toLocaleString", simpleFunc);
addArrayExtension("toSorted", simpleFunc);
addArrayExtension("toSpliced", simpleFunc);
addArrayExtension("with", simpleFunc);
// map
addArrayExtension("every", mapLikeFunc);
addArrayExtension("filter", mapLikeFunc);
addArrayExtension("find", mapLikeFunc);
addArrayExtension("findIndex", mapLikeFunc);
addArrayExtension("findLast", mapLikeFunc);
addArrayExtension("findLastIndex", mapLikeFunc);
addArrayExtension("flatMap", mapLikeFunc);
addArrayExtension("forEach", mapLikeFunc);
addArrayExtension("map", mapLikeFunc);
addArrayExtension("some", mapLikeFunc);
addArrayExtension("toReversed", mapLikeFunc);
// reduce
addArrayExtension("reduce", reduceLikeFunc);
addArrayExtension("reduceRight", reduceLikeFunc);
function addArrayExtension(funcName, funcFactory) {
  if (typeof Array.prototype[funcName] === "function") {
    arrayExtensions[funcName] = funcFactory(funcName);
  }
}
// Report and delegate to dehanced array
function simpleFunc(funcName) {
  return function () {
    const adm = this[$mobx];
    adm.atom_.reportObserved();
    const dehancedValues = adm.dehanceValues_(adm.values_);
    return dehancedValues[funcName].apply(dehancedValues, arguments);
  };
}
// Make sure callbacks receive correct array arg #2326
function mapLikeFunc(funcName) {
  return function (callback, thisArg) {
    const adm = this[$mobx];
    adm.atom_.reportObserved();
    const dehancedValues = adm.dehanceValues_(adm.values_);
    return dehancedValues[funcName]((element, index) => {
      return callback.call(thisArg, element, index, this);
    });
  };
}
// Make sure callbacks receive correct array arg #2326
function reduceLikeFunc(funcName) {
  return function () {
    const adm = this[$mobx];
    adm.atom_.reportObserved();
    const dehancedValues = adm.dehanceValues_(adm.values_);
    // #2432 - reduce behavior depends on arguments.length
    const callback = arguments[0];
    arguments[0] = (accumulator, currentValue, index) => {
      return callback(accumulator, currentValue, index, this);
    };
    return dehancedValues[funcName].apply(dehancedValues, arguments);
  };
}
const isObservableArrayAdministration = /*#__PURE__*/createInstanceofPredicate("ObservableArrayAdministration", ObservableArrayAdministration);
function isObservableArray(thing) {
  return isObject(thing) && isObservableArrayAdministration(thing[$mobx]);
}

const ObservableMapMarker = {};
const ADD = "add";
const DELETE = "delete";
// just extend Map? See also https://gist.github.com/nestharus/13b4d74f2ef4a2f4357dbd3fc23c1e54
// But: https://github.com/mobxjs/mobx/issues/1556
class ObservableMap {
  constructor(initialData, enhancer_ = deepEnhancer, name_ = "ObservableMap@" + getNextId() ) {
    this.enhancer_ = void 0;
    this.name_ = void 0;
    this[$mobx] = ObservableMapMarker;
    this.data_ = void 0;
    this.hasMap_ = void 0;
    // hasMap, not hashMap >-).
    this.keysAtom_ = void 0;
    this.interceptors_ = void 0;
    this.changeListeners_ = void 0;
    this.dehancer = void 0;
    this.enhancer_ = enhancer_;
    this.name_ = name_;
    initObservable(() => {
      this.keysAtom_ = createAtom("development" !== "production" ? `${this.name_}.keys()` : "ObservableMap.keys()");
      this.data_ = new Map();
      this.hasMap_ = new Map();
      if (initialData) {
        this.merge(initialData);
      }
    });
  }
  has_(key) {
    return this.data_.has(key);
  }
  has(key) {
    if (!globalState.trackingDerivation) {
      return this.has_(key);
    }
    let entry = this.hasMap_.get(key);
    if (!entry) {
      const newEntry = entry = new ObservableValue(this.has_(key), referenceEnhancer, `${this.name_}.${stringifyKey(key)}?` , false);
      this.hasMap_.set(key, newEntry);
      newEntry.onBUOL = new Set([() => this.hasMap_.delete(key)]);
    }
    return entry.get();
  }
  set(key, value) {
    const hasKey = this.has_(key);
    if (hasInterceptors(this)) {
      const change = interceptChange(this, {
        type: hasKey ? UPDATE : ADD,
        object: this,
        newValue: value,
        name: key
      });
      if (!change) {
        return this;
      }
      value = change.newValue;
    }
    if (hasKey) {
      this.updateValue_(key, value);
    } else {
      this.addValue_(key, value);
    }
    return this;
  }
  delete(key) {
    checkIfStateModificationsAreAllowed(this.keysAtom_);
    if (hasInterceptors(this)) {
      const change = interceptChange(this, {
        type: DELETE,
        object: this,
        name: key
      });
      if (!change) {
        return false;
      }
    }
    if (this.has_(key)) {
      const notifySpy = isSpyEnabled();
      const notify = hasListeners(this);
      const change = notify || notifySpy ? {
        observableKind: "map",
        debugObjectName: this.name_,
        type: DELETE,
        object: this,
        oldValue: this.data_.get(key).value_,
        name: key
      } : null;
      if (notifySpy) {
        spyReportStart(change);
      } // TODO fix type
      transaction(() => {
        var _this$hasMap_$get;
        this.keysAtom_.reportChanged();
        (_this$hasMap_$get = this.hasMap_.get(key)) == null || _this$hasMap_$get.setNewValue_(false);
        const observable = this.data_.get(key);
        observable.setNewValue_(undefined);
        this.data_.delete(key);
      });
      if (notify) {
        notifyListeners(this, change);
      }
      if (notifySpy) {
        spyReportEnd();
      }
      return true;
    }
    return false;
  }
  updateValue_(key, newValue) {
    const observable = this.data_.get(key);
    newValue = observable.prepareNewValue_(newValue);
    if (newValue !== globalState.UNCHANGED) {
      const notifySpy = isSpyEnabled();
      const notify = hasListeners(this);
      const change = notify || notifySpy ? {
        observableKind: "map",
        debugObjectName: this.name_,
        type: UPDATE,
        object: this,
        oldValue: observable.value_,
        name: key,
        newValue
      } : null;
      if (notifySpy) {
        spyReportStart(change);
      } // TODO fix type
      observable.setNewValue_(newValue);
      if (notify) {
        notifyListeners(this, change);
      }
      if (notifySpy) {
        spyReportEnd();
      }
    }
  }
  addValue_(key, newValue) {
    checkIfStateModificationsAreAllowed(this.keysAtom_);
    transaction(() => {
      var _this$hasMap_$get2;
      const observable = new ObservableValue(newValue, this.enhancer_, `${this.name_}.${stringifyKey(key)}` , false);
      this.data_.set(key, observable);
      newValue = observable.value_; // value might have been changed
      (_this$hasMap_$get2 = this.hasMap_.get(key)) == null || _this$hasMap_$get2.setNewValue_(true);
      this.keysAtom_.reportChanged();
    });
    const notifySpy = isSpyEnabled();
    const notify = hasListeners(this);
    const change = notify || notifySpy ? {
      observableKind: "map",
      debugObjectName: this.name_,
      type: ADD,
      object: this,
      name: key,
      newValue
    } : null;
    if (notifySpy) {
      spyReportStart(change);
    } // TODO fix type
    if (notify) {
      notifyListeners(this, change);
    }
    if (notifySpy) {
      spyReportEnd();
    }
  }
  get(key) {
    if (this.has(key)) {
      return this.dehanceValue_(this.data_.get(key).get());
    }
    return this.dehanceValue_(undefined);
  }
  getOrInsert(key, value) {
    if (!this.has(key)) {
      this.set(key, value);
    }
    return this.get(key);
  }
  getOrInsertComputed(key, callback) {
    if (!this.has(key)) {
      this.set(key, callback(key));
    }
    return this.get(key);
  }
  dehanceValue_(value) {
    if (this.dehancer !== undefined) {
      return this.dehancer(value);
    }
    return value;
  }
  keys() {
    this.keysAtom_.reportObserved();
    return this.data_.keys();
  }
  values() {
    const self = this;
    const keys = this.keys();
    return makeIterableForMap({
      next() {
        const {
          done,
          value
        } = keys.next();
        return {
          done,
          value: done ? undefined : self.get(value)
        };
      }
    });
  }
  entries() {
    const self = this;
    const keys = this.keys();
    return makeIterableForMap({
      next() {
        const {
          done,
          value
        } = keys.next();
        return {
          done,
          value: done ? undefined : [value, self.get(value)]
        };
      }
    });
  }
  [Symbol.iterator]() {
    return this.entries();
  }
  forEach(callback, thisArg) {
    for (const [key, value] of this) {
      callback.call(thisArg, value, key, this);
    }
  }
  /** Merge another object into this object, returns this. */
  merge(other) {
    if (isObservableMap(other)) {
      other = new Map(other);
    }
    transaction(() => {
      if (isPlainObject(other)) {
        getPlainObjectKeys(other).forEach(key => this.set(key, other[key]));
      } else if (Array.isArray(other)) {
        other.forEach(([key, value]) => this.set(key, value));
      } else if (isES6Map(other)) {
        if (!isPlainES6Map(other)) {
          die(19, other);
        }
        other.forEach((value, key) => this.set(key, value));
      } else if (other !== null && other !== undefined) {
        die(20, other);
      }
    });
    return this;
  }
  clear() {
    transaction(() => {
      untracked(() => {
        for (const key of this.keys()) {
          this.delete(key);
        }
      });
    });
  }
  replace(values) {
    // Implementation requirements:
    // - respect ordering of replacement map
    // - allow interceptors to run and potentially prevent individual operations
    // - don't recreate observables that already exist in original map (so we don't destroy existing subscriptions)
    // - don't _keysAtom.reportChanged if the keys of resulting map are indentical (order matters!)
    // - note that result map may differ from replacement map due to the interceptors
    transaction(() => {
      // Convert to map so we can do quick key lookups
      const replacementMap = convertToMap(values);
      const orderedData = new Map();
      // Used for optimization
      let keysReportChangedCalled = false;
      // Delete keys that don't exist in replacement map
      // if the key deletion is prevented by interceptor
      // add entry at the beginning of the result map
      for (const key of this.data_.keys()) {
        // Concurrently iterating/deleting keys
        // iterator should handle this correctly
        if (!replacementMap.has(key)) {
          const deleted = this.delete(key);
          // Was the key removed?
          if (deleted) {
            // _keysAtom.reportChanged() was already called
            keysReportChangedCalled = true;
          } else {
            // Delete prevented by interceptor
            const value = this.data_.get(key);
            orderedData.set(key, value);
          }
        }
      }
      // Merge entries
      for (const [key, value] of replacementMap.entries()) {
        // We will want to know whether a new key is added
        const keyExisted = this.data_.has(key);
        // Add or update value
        this.set(key, value);
        // The addition could have been prevent by interceptor
        if (this.data_.has(key)) {
          // The update could have been prevented by interceptor
          // and also we want to preserve existing values
          // so use value from _data map (instead of replacement map)
          const _value = this.data_.get(key);
          orderedData.set(key, _value);
          // Was a new key added?
          if (!keyExisted) {
            // _keysAtom.reportChanged() was already called
            keysReportChangedCalled = true;
          }
        }
      }
      // Check for possible key order change
      if (!keysReportChangedCalled) {
        if (this.data_.size !== orderedData.size) {
          // If size differs, keys are definitely modified
          this.keysAtom_.reportChanged();
        } else {
          const iter1 = this.data_.keys();
          const iter2 = orderedData.keys();
          let next1 = iter1.next();
          let next2 = iter2.next();
          while (!next1.done) {
            if (next1.value !== next2.value) {
              this.keysAtom_.reportChanged();
              break;
            }
            next1 = iter1.next();
            next2 = iter2.next();
          }
        }
      }
      // Use correctly ordered map
      this.data_ = orderedData;
    });
    return this;
  }
  get size() {
    this.keysAtom_.reportObserved();
    return this.data_.size;
  }
  toString() {
    return "[object ObservableMap]";
  }
  toJSON() {
    return Array.from(this);
  }
  get [Symbol.toStringTag]() {
    return "Map";
  }
}
// eslint-disable-next-line
var isObservableMap = /*#__PURE__*/createInstanceofPredicate("ObservableMap", ObservableMap);
function makeIterableForMap(iterator) {
  iterator[Symbol.toStringTag] = "MapIterator";
  return makeIterable(iterator);
}
function convertToMap(dataStructure) {
  if (isES6Map(dataStructure) || isObservableMap(dataStructure)) {
    return dataStructure;
  } else if (Array.isArray(dataStructure)) {
    return new Map(dataStructure);
  } else if (isPlainObject(dataStructure)) {
    const map = new Map();
    for (const key in dataStructure) {
      map.set(key, dataStructure[key]);
    }
    return map;
  } else {
    return die(21, dataStructure);
  }
}

const ObservableSetMarker = {};
class ObservableSet {
  constructor(initialData, enhancer = deepEnhancer, name_ = "ObservableSet@" + getNextId() ) {
    this.name_ = void 0;
    this[$mobx] = ObservableSetMarker;
    this.data_ = new Set();
    this.atom_ = void 0;
    this.changeListeners_ = void 0;
    this.interceptors_ = void 0;
    this.dehancer = void 0;
    this.enhancer_ = void 0;
    this.name_ = name_;
    this.enhancer_ = (newV, oldV) => enhancer(newV, oldV, name_);
    initObservable(() => {
      this.atom_ = createAtom(this.name_);
      if (initialData) {
        this.replace(initialData);
      }
    });
  }
  dehanceValue_(value) {
    if (this.dehancer !== undefined) {
      return this.dehancer(value);
    }
    return value;
  }
  clear() {
    transaction(() => {
      untracked(() => {
        for (const value of this.data_.values()) {
          this.delete(value);
        }
      });
    });
  }
  forEach(callbackFn, thisArg) {
    for (const value of this) {
      callbackFn.call(thisArg, value, value, this);
    }
  }
  get size() {
    this.atom_.reportObserved();
    return this.data_.size;
  }
  add(value) {
    checkIfStateModificationsAreAllowed(this.atom_);
    if (hasInterceptors(this)) {
      const change = interceptChange(this, {
        type: ADD,
        object: this,
        newValue: value
      });
      if (!change) {
        return this;
      }
      // implemented reassignment same as it's done for ObservableMap
      value = change.newValue;
    }
    if (!this.has(value)) {
      transaction(() => {
        this.data_.add(this.enhancer_(value, undefined));
        this.atom_.reportChanged();
      });
      const notifySpy = isSpyEnabled();
      const notify = hasListeners(this);
      const change = notify || notifySpy ? {
        observableKind: "set",
        debugObjectName: this.name_,
        type: ADD,
        object: this,
        newValue: value
      } : null;
      if (notifySpy && "development" !== "production") {
        spyReportStart(change);
      }
      if (notify) {
        notifyListeners(this, change);
      }
      if (notifySpy && "development" !== "production") {
        spyReportEnd();
      }
    }
    return this;
  }
  delete(value) {
    if (hasInterceptors(this)) {
      const change = interceptChange(this, {
        type: DELETE,
        object: this,
        oldValue: value
      });
      if (!change) {
        return false;
      }
    }
    if (this.has(value)) {
      const notifySpy = isSpyEnabled();
      const notify = hasListeners(this);
      const change = notify || notifySpy ? {
        observableKind: "set",
        debugObjectName: this.name_,
        type: DELETE,
        object: this,
        oldValue: value
      } : null;
      if (notifySpy && "development" !== "production") {
        spyReportStart(change);
      }
      transaction(() => {
        this.atom_.reportChanged();
        this.data_.delete(value);
      });
      if (notify) {
        notifyListeners(this, change);
      }
      if (notifySpy && "development" !== "production") {
        spyReportEnd();
      }
      return true;
    }
    return false;
  }
  has(value) {
    this.atom_.reportObserved();
    return this.data_.has(this.dehanceValue_(value));
  }
  entries() {
    const values = this.values();
    return makeIterableForSet({
      next() {
        const {
          value,
          done
        } = values.next();
        return !done ? {
          value: [value, value],
          done
        } : {
          value: undefined,
          done
        };
      }
    });
  }
  keys() {
    return this.values();
  }
  values() {
    this.atom_.reportObserved();
    const self = this;
    const values = this.data_.values();
    return makeIterableForSet({
      next() {
        const {
          value,
          done
        } = values.next();
        return !done ? {
          value: self.dehanceValue_(value),
          done
        } : {
          value: undefined,
          done
        };
      }
    });
  }
  intersection(otherSet) {
    return new Set(this).intersection(otherSet);
  }
  union(otherSet) {
    return new Set(this).union(otherSet);
  }
  difference(otherSet) {
    return new Set(this).difference(otherSet);
  }
  symmetricDifference(otherSet) {
    return new Set(this).symmetricDifference(otherSet);
  }
  isSubsetOf(otherSet) {
    return new Set(this).isSubsetOf(otherSet);
  }
  isSupersetOf(otherSet) {
    return new Set(this).isSupersetOf(otherSet);
  }
  isDisjointFrom(otherSet) {
    return new Set(this).isDisjointFrom(otherSet);
  }
  replace(other) {
    if (isObservableSet(other)) {
      other = new Set(other);
    }
    if (Array.isArray(other) || isES6Set(other)) {
      // Only emit `delete`/`add` events (and `reportChanged`) for values that
      // actually change, instead of clearing and re-adding everything. `add` and
      // `delete` are already no-ops for values that are respectively already
      // present or already absent, so we just need to avoid deleting values that
      // are part of the replacement. See #3761.
      transaction(() => {
        // Collect the desired values for quick lookup. `other` is already a Set
        // here when it was passed (or snapshotted from an observable set) as one,
        // so reuse it rather than allocating another; arrays are wrapped (which
        // also dedupes them).
        const replacementValues = isES6Set(other) ? other : new Set(other);
        // Short-circuit the trivial cases: an empty replacement is just a clear,
        // and replacing into an empty set only needs the adds.
        if (replacementValues.size === 0) {
          this.clear();
          return;
        }
        if (this.data_.size === 0) {
          replacementValues.forEach(value => this.add(value));
          return;
        }
        // Delete values that are not part of the replacement.
        for (const value of this.data_.values()) {
          if (!replacementValues.has(this.dehanceValue_(value))) {
            this.delete(value);
          }
        }
        // Add new values; values that are already present are a no-op.
        replacementValues.forEach(value => this.add(value));
      });
    } else if (other !== null && other !== undefined) {
      die(41, other);
    }
    return this;
  }
  toJSON() {
    return Array.from(this);
  }
  toString() {
    return "[object ObservableSet]";
  }
  [Symbol.iterator]() {
    return this.values();
  }
  get [Symbol.toStringTag]() {
    return "Set";
  }
}
// eslint-disable-next-line
var isObservableSet = /*#__PURE__*/createInstanceofPredicate("ObservableSet", ObservableSet);
function makeIterableForSet(iterator) {
  iterator[Symbol.toStringTag] = "SetIterator";
  return makeIterable(iterator);
}

const descriptorCache = /*#__PURE__*/Object.create(null);
const REMOVE = "remove";
class ObservableObjectAdministration {
  constructor(target_, values_ = new Map(), name_,
  // Used anytime annotation is not explicitely provided
  defaultAnnotation_ = autoAnnotation) {
    this.target_ = void 0;
    this.values_ = void 0;
    this.name_ = void 0;
    this.defaultAnnotation_ = void 0;
    this.keysAtom_ = void 0;
    this.changeListeners_ = void 0;
    this.interceptors_ = void 0;
    this.proxy_ = void 0;
    this.isPlainObject_ = void 0;
    this.appliedAnnotations_ = void 0;
    this.pendingKeys_ = void 0;
    this.lazyComputedKeys_ = void 0;
    this.lazyObservableKeys_ = void 0;
    this.target_ = target_;
    this.values_ = values_;
    this.name_ = name_;
    this.defaultAnnotation_ = defaultAnnotation_;
    this.keysAtom_ = new Atom(`${this.name_}.keys` );
    // Optimization: we use this frequently
    this.isPlainObject_ = isPlainObject(this.target_);
    if (!isAnnotation(this.defaultAnnotation_)) {
      die(`defaultAnnotation must be valid annotation`);
    }
    {
      // Prepare structure for tracking which fields were already annotated
      this.appliedAnnotations_ = {};
    }
  }
  getObservablePropValue_(key) {
    var _ref, _this$values_$get;
    // Hot path: single map lookup. Lazy entries (rare) take the materialise branch.
    const observable = (_ref = (_this$values_$get = this.values_.get(key)) != null ? _this$values_$get : this.materializeLazyComputed_(key)) != null ? _ref : this.materializeLazyObservable_(key);
    return observable.get();
  }
  materializeLazyComputed_(key) {
    var _this$lazyComputedKey;
    const factory = (_this$lazyComputedKey = this.lazyComputedKeys_) == null ? void 0 : _this$lazyComputedKey.get(key);
    if (!factory) {
      return undefined;
    }
    this.lazyComputedKeys_.delete(key);
    if (this.lazyComputedKeys_.size === 0) {
      this.lazyComputedKeys_ = undefined;
    }
    const computed = factory();
    this.values_.set(key, computed);
    return computed;
  }
  materializeLazyObservable_(key) {
    var _this$lazyObservableK;
    const factory = (_this$lazyObservableK = this.lazyObservableKeys_) == null ? void 0 : _this$lazyObservableK.get(key);
    if (!factory) {
      return undefined;
    }
    this.lazyObservableKeys_.delete(key);
    if (this.lazyObservableKeys_.size === 0) {
      this.lazyObservableKeys_ = undefined;
    }
    const observable = factory();
    this.values_.set(key, observable);
    return observable;
  }
  setObservablePropValue_(key, newValue) {
    var _ref2, _this$values_$get2;
    const observable = (_ref2 = (_this$values_$get2 = this.values_.get(key)) != null ? _this$values_$get2 : this.materializeLazyComputed_(key)) != null ? _ref2 : this.materializeLazyObservable_(key);
    if (observable instanceof ComputedValue) {
      observable.set(newValue);
      return true;
    }
    // intercept
    if (hasInterceptors(this)) {
      const change = interceptChange(this, {
        type: UPDATE,
        object: this.proxy_ || this.target_,
        name: key,
        newValue
      });
      if (!change) {
        return null;
      }
      newValue = change.newValue;
    }
    newValue = observable.prepareNewValue_(newValue);
    // notify spy & observers
    if (newValue !== globalState.UNCHANGED) {
      const notify = hasListeners(this);
      const notifySpy = isSpyEnabled();
      const change = notify || notifySpy ? {
        type: UPDATE,
        observableKind: "object",
        debugObjectName: this.name_,
        object: this.proxy_ || this.target_,
        oldValue: observable.value_,
        name: key,
        newValue
      } : null;
      if (notifySpy) {
        spyReportStart(change);
      }
      observable.setNewValue_(newValue);
      if (notify) {
        notifyListeners(this, change);
      }
      if (notifySpy) {
        spyReportEnd();
      }
    }
    return true;
  }
  get_(key) {
    if (globalState.trackingDerivation && !hasProp(this.target_, key)) {
      // Key doesn't exist yet, subscribe for it in case it's added later
      this.has_(key);
    }
    return this.target_[key];
  }
  /**
   * @param {PropertyKey} key
   * @param {any} value
   * @param {Annotation|boolean} annotation true - use default annotation, false - copy as is
   * @param {boolean} proxyTrap whether it's called from proxy trap
   * @returns {boolean|null} true on success, false on failure (proxyTrap + non-configurable), null when cancelled by interceptor
   */
  set_(key, value, proxyTrap = false) {
    // Don't use .has(key) - we care about own
    if (hasProp(this.target_, key)) {
      // Existing prop
      if (this.values_.has(key)) {
        // Observable (can be intercepted)
        return this.setObservablePropValue_(key, value);
      } else if (proxyTrap) {
        // Non-observable - proxy
        return Reflect.set(this.target_, key, value);
      } else {
        // Non-observable
        this.target_[key] = value;
        return true;
      }
    } else {
      // New prop
      return this.extend_(key, {
        value,
        enumerable: true,
        writable: true,
        configurable: true
      }, this.defaultAnnotation_, proxyTrap);
    }
  }
  // Trap for "in"
  has_(key) {
    if (!globalState.trackingDerivation) {
      // Skip key subscription outside derivation
      return key in this.target_;
    }
    this.pendingKeys_ || (this.pendingKeys_ = new Map());
    let entry = this.pendingKeys_.get(key);
    if (!entry) {
      entry = new ObservableValue(key in this.target_, referenceEnhancer, `${this.name_}.${stringifyKey(key)}?` , false);
      this.pendingKeys_.set(key, entry);
    }
    return entry.get();
  }
  /**
   * @param {PropertyKey} key
   * @param {PropertyDescriptor} descriptor
   * @param {Annotation|boolean} annotation true - use default annotation, false - copy as is
   * @param {boolean} proxyTrap whether it's called from proxy trap
   * @returns {boolean|null} true on success, false on failure (proxyTrap + non-configurable), null when cancelled by interceptor
   */
  extend_(key, descriptor, annotation, proxyTrap = false) {
    if (annotation === true) {
      annotation = this.defaultAnnotation_;
    }
    if (annotation === false) {
      return this.defineProperty_(key, descriptor, proxyTrap);
    }
    assertAnnotable(this, annotation, key);
    const outcome = annotation.extend_(this, key, descriptor, proxyTrap);
    if (outcome) {
      recordAnnotationApplied(this, annotation, key);
    }
    return outcome;
  }
  /**
   * @param {PropertyKey} key
   * @param {PropertyDescriptor} descriptor
   * @param {boolean} proxyTrap whether it's called from proxy trap
   * @returns {boolean|null} true on success, false on failure (proxyTrap + non-configurable), null when cancelled by interceptor
   */
  defineProperty_(key, descriptor, proxyTrap = false) {
    checkIfStateModificationsAreAllowed(this.keysAtom_);
    try {
      startBatch();
      // Delete
      const deleteOutcome = this.delete_(key);
      if (!deleteOutcome) {
        // Failure or intercepted
        return deleteOutcome;
      }
      // ADD interceptor
      if (hasInterceptors(this)) {
        const change = interceptChange(this, {
          object: this.proxy_ || this.target_,
          name: key,
          type: ADD,
          newValue: descriptor.value
        });
        if (!change) {
          return null;
        }
        const {
          newValue
        } = change;
        if (descriptor.value !== newValue) {
          descriptor = assign({}, descriptor, {
            value: newValue
          });
        }
      }
      // Define
      if (proxyTrap) {
        if (!Reflect.defineProperty(this.target_, key, descriptor)) {
          return false;
        }
      } else {
        defineProperty(this.target_, key, descriptor);
      }
      // Notify
      this.notifyPropertyAddition_(key, descriptor.value);
    } finally {
      endBatch();
    }
    return true;
  }
  // If original descriptor becomes relevant, move this to annotation directly
  defineObservableProperty_(key, value, enhancer, proxyTrap = false) {
    checkIfStateModificationsAreAllowed(this.keysAtom_);
    try {
      startBatch();
      // Delete
      const deleteOutcome = this.delete_(key);
      if (!deleteOutcome) {
        // Failure or intercepted
        return deleteOutcome;
      }
      // ADD interceptor
      if (hasInterceptors(this)) {
        const change = interceptChange(this, {
          object: this.proxy_ || this.target_,
          name: key,
          type: ADD,
          newValue: value
        });
        if (!change) {
          return null;
        }
        value = change.newValue;
      }
      const cachedDescriptor = getCachedObservablePropDescriptor(key);
      const descriptor = {
        configurable: globalState.safeDescriptors ? this.isPlainObject_ : true,
        enumerable: true,
        get: cachedDescriptor.get,
        set: cachedDescriptor.set
      };
      // Define
      if (proxyTrap) {
        if (!Reflect.defineProperty(this.target_, key, descriptor)) {
          return false;
        }
      } else {
        defineProperty(this.target_, key, descriptor);
      }
      const observable = new ObservableValue(value, enhancer, "development" !== "production" ? `${this.name_}.${key.toString()}` : "ObservableObject.key", false);
      this.values_.set(key, observable);
      // Notify (value possibly changed by ObservableValue)
      this.notifyPropertyAddition_(key, observable.value_);
    } finally {
      endBatch();
    }
    return true;
  }
  // If original descriptor becomes relevant, move this to annotation directly
  defineComputedProperty_(key, options, proxyTrap = false) {
    checkIfStateModificationsAreAllowed(this.keysAtom_);
    try {
      startBatch();
      // Delete
      const deleteOutcome = this.delete_(key);
      if (!deleteOutcome) {
        // Failure or intercepted
        return deleteOutcome;
      }
      // ADD interceptor
      if (hasInterceptors(this)) {
        const change = interceptChange(this, {
          object: this.proxy_ || this.target_,
          name: key,
          type: ADD,
          newValue: undefined
        });
        if (!change) {
          return null;
        }
      }
      options.name || (options.name = "development" !== "production" ? `${this.name_}.${key.toString()}` : "ObservableObject.key");
      options.context = this.proxy_ || this.target_;
      const cachedDescriptor = getCachedObservablePropDescriptor(key);
      const descriptor = {
        configurable: globalState.safeDescriptors ? this.isPlainObject_ : true,
        enumerable: false,
        get: cachedDescriptor.get,
        set: cachedDescriptor.set
      };
      // Define
      if (proxyTrap) {
        if (!Reflect.defineProperty(this.target_, key, descriptor)) {
          return false;
        }
      } else {
        defineProperty(this.target_, key, descriptor);
      }
      this.values_.set(key, new ComputedValue(options));
      // Notify
      this.notifyPropertyAddition_(key, undefined);
    } finally {
      endBatch();
    }
    return true;
  }
  /**
   * @param {PropertyKey} key
   * @param {PropertyDescriptor} descriptor
   * @param {boolean} proxyTrap whether it's called from proxy trap
   * @returns {boolean|null} true on success, false on failure (proxyTrap + non-configurable), null when cancelled by interceptor
   */
  delete_(key, proxyTrap = false) {
    checkIfStateModificationsAreAllowed(this.keysAtom_);
    // No such prop
    if (!hasProp(this.target_, key)) {
      return true;
    }
    // Intercept
    if (hasInterceptors(this)) {
      const change = interceptChange(this, {
        object: this.proxy_ || this.target_,
        name: key,
        type: REMOVE
      });
      // Cancelled
      if (!change) {
        return null;
      }
    }
    // Delete
    try {
      var _this$pendingKeys_;
      startBatch();
      const notify = hasListeners(this);
      const notifySpy = "development" !== "production" && isSpyEnabled();
      const observable = this.values_.get(key);
      // Value needed for spies/listeners
      let value = undefined;
      // Optimization: don't pull the value unless we will need it
      if (!observable && (notify || notifySpy)) {
        var _getDescriptor;
        value = (_getDescriptor = getDescriptor(this.target_, key)) == null ? void 0 : _getDescriptor.value;
      }
      // delete prop (do first, may fail)
      if (proxyTrap) {
        if (!Reflect.deleteProperty(this.target_, key)) {
          return false;
        }
      } else {
        delete this.target_[key];
      }
      // Allow re-annotating this field
      if ("development" !== "production") {
        delete this.appliedAnnotations_[key];
      }
      // Clear observable
      if (observable) {
        this.values_.delete(key);
        // for computed, value is undefined
        if (observable instanceof ObservableValue) {
          value = observable.value_;
        }
        // Notify: autorun(() => obj[key]), see #1796
        propagateChanged(observable);
      }
      // Notify "keys/entries/values" observers
      this.keysAtom_.reportChanged();
      // Notify "has" observers
      // "in" as it may still exist in proto
      (_this$pendingKeys_ = this.pendingKeys_) == null || (_this$pendingKeys_ = _this$pendingKeys_.get(key)) == null || _this$pendingKeys_.set(key in this.target_);
      // Notify spies/listeners
      if (notify || notifySpy) {
        const change = {
          type: REMOVE,
          observableKind: "object",
          object: this.proxy_ || this.target_,
          debugObjectName: this.name_,
          oldValue: value,
          name: key
        };
        if ("development" !== "production" && notifySpy) {
          spyReportStart(change);
        }
        if (notify) {
          notifyListeners(this, change);
        }
        if ("development" !== "production" && notifySpy) {
          spyReportEnd();
        }
      }
    } finally {
      endBatch();
    }
    return true;
  }
  notifyPropertyAddition_(key, value) {
    var _this$pendingKeys_2;
    const notify = hasListeners(this);
    const notifySpy = isSpyEnabled();
    if (notify || notifySpy) {
      const change = notify || notifySpy ? {
        type: ADD,
        observableKind: "object",
        debugObjectName: this.name_,
        object: this.proxy_ || this.target_,
        name: key,
        newValue: value
      } : null;
      if (notifySpy) {
        spyReportStart(change);
      }
      if (notify) {
        notifyListeners(this, change);
      }
      if (notifySpy) {
        spyReportEnd();
      }
    }
    (_this$pendingKeys_2 = this.pendingKeys_) == null || (_this$pendingKeys_2 = _this$pendingKeys_2.get(key)) == null || _this$pendingKeys_2.set(true);
    // Notify "keys/entries/values" observers
    this.keysAtom_.reportChanged();
  }
  ownKeys_() {
    this.keysAtom_.reportObserved();
    return ownKeys(this.target_);
  }
  keys_() {
    // Returns enumerable && own, but unfortunately keysAtom will report on ANY key change.
    // There is no way to distinguish between Object.keys(object) and Reflect.ownKeys(object) - both are handled by ownKeys trap.
    // We can either over-report in Object.keys(object) or under-report in Reflect.ownKeys(object)
    // We choose to over-report in Object.keys(object), because:
    // - typically it's used with simple data objects
    // - when symbolic/non-enumerable keys are relevant Reflect.ownKeys works as expected
    this.keysAtom_.reportObserved();
    return Object.keys(this.target_);
  }
}
function asObservableObject(target, options) {
  var _options$name;
  if (options && isObservableObject(target)) {
    die(`Options can't be provided for already observable objects.`);
  }
  if (hasProp(target, $mobx)) {
    if (!(getAdministration(target) instanceof ObservableObjectAdministration)) {
      die(`Cannot convert '${getDebugName(target)}' into observable object:` + `\nThe target is already observable of different type.` + `\nExtending builtins is not supported.`);
    }
    return target;
  }
  if (!Object.isExtensible(target)) {
    die("Cannot make the designated object observable; it is not extensible");
  }
  const name = (_options$name = options == null ? void 0 : options.name) != null ? _options$name : `${isPlainObject(target) ? "ObservableObject" : target.constructor.name}@${getNextId()}` ;
  const adm = new ObservableObjectAdministration(target, new Map(), String(name), getAnnotationFromOptions(options));
  addHiddenProp(target, $mobx, adm);
  return target;
}
const isObservableObjectAdministration = /*#__PURE__*/createInstanceofPredicate("ObservableObjectAdministration", ObservableObjectAdministration);
function getCachedObservablePropDescriptor(key) {
  return descriptorCache[key] || (descriptorCache[key] = {
    get() {
      return this[$mobx].getObservablePropValue_(key);
    },
    set(value) {
      return this[$mobx].setObservablePropValue_(key, value);
    }
  });
}
function isObservableObject(thing) {
  if (isObject(thing)) {
    return isObservableObjectAdministration(thing[$mobx]);
  }
  return false;
}
function recordAnnotationApplied(adm, annotation, key) {
  {
    adm.appliedAnnotations_[key] = annotation;
  }
}
function assertAnnotable(adm, annotation, key) {
  // Valid annotation
  if (!isAnnotation(annotation)) {
    die(`Cannot annotate '${adm.name_}.${key.toString()}': Invalid annotation.`);
  }
  /*
  // Configurable, not sealed, not frozen
  // Possibly not needed, just a little better error then the one thrown by engine.
  // Cases where this would be useful the most (subclass field initializer) are not interceptable by this.
  if (__DEV__) {
      const configurable = getDescriptor(adm.target_, key)?.configurable
      const frozen = Object.isFrozen(adm.target_)
      const sealed = Object.isSealed(adm.target_)
      if (!configurable || frozen || sealed) {
          const fieldName = `${adm.name_}.${key.toString()}`
          const requestedAnnotationType = annotation.annotationType_
          let error = `Cannot apply '${requestedAnnotationType}' to '${fieldName}':`
          if (frozen) {
              error += `\nObject is frozen.`
          }
          if (sealed) {
              error += `\nObject is sealed.`
          }
          if (!configurable) {
              error += `\nproperty is not configurable.`
              // Mention only if caused by us to avoid confusion
              if (hasProp(adm.appliedAnnotations!, key)) {
                  error += `\nTo prevent accidental re-definition of a field by a subclass, `
                  error += `all annotated fields of non-plain objects (classes) are not configurable.`
              }
          }
          die(error)
      }
  }
  */
  // Not annotated
  if (!isOverride(annotation) && hasProp(adm.appliedAnnotations_, key)) {
    const fieldName = `${adm.name_}.${key.toString()}`;
    const currentAnnotationType = adm.appliedAnnotations_[key].annotationType_;
    const requestedAnnotationType = annotation.annotationType_;
    die(`Cannot apply '${requestedAnnotationType}' to '${fieldName}':` + `\nThe field is already annotated with '${currentAnnotationType}'.` + `\nRe-annotating fields is not allowed.` + `\nUse 'override' annotation for methods overridden by subclass.`);
  }
}

function getAtom(thing, property) {
  if (typeof thing === "object" && thing !== null) {
    if (isObservableArray(thing)) {
      if (property !== undefined) {
        die(23);
      }
      return thing[$mobx].atom_;
    }
    if (isObservableSet(thing)) {
      return thing.atom_;
    }
    if (isObservableMap(thing)) {
      if (property === undefined) {
        return thing.keysAtom_;
      }
      const observable = thing.data_.get(property) || thing.hasMap_.get(property);
      if (!observable) {
        die(25, property, getDebugName(thing));
      }
      return observable;
    }
    if (isObservableObject(thing)) {
      var _ref, _adm$values_$get;
      if (!property) {
        return die(26);
      }
      const adm = thing[$mobx];
      const observable = (_ref = (_adm$values_$get = adm.values_.get(property)) != null ? _adm$values_$get : adm.materializeLazyComputed_(property)) != null ? _ref : adm.materializeLazyObservable_(property);
      if (!observable) {
        die(27, property, getDebugName(thing));
      }
      return observable;
    }
    if (isAtom(thing) || isComputedValue(thing) || isReaction(thing)) {
      return thing;
    }
  } else if (isFunction(thing)) {
    if (isReaction(thing[$mobx])) {
      // disposer function
      return thing[$mobx];
    }
  }
  die(28);
}
function getAdministration(thing, property) {
  if (!thing) {
    die(29);
  }
  if (property !== undefined) {
    return getAdministration(getAtom(thing, property));
  }
  if (isAtom(thing) || isComputedValue(thing) || isReaction(thing)) {
    return thing;
  }
  if (isObservableMap(thing) || isObservableSet(thing)) {
    return thing;
  }
  if (thing[$mobx]) {
    return thing[$mobx];
  }
  die(24, thing);
}
function getDebugName(thing, property) {
  let named;
  if (property !== undefined) {
    named = getAtom(thing, property);
  } else if (isAction(thing)) {
    return thing.name;
  } else if (isObservableObject(thing) || isObservableMap(thing) || isObservableSet(thing)) {
    named = getAdministration(thing);
  } else {
    // valid for arrays as well
    named = getAtom(thing);
  }
  return named.name_;
}
/**
 * Helper function for initializing observable structures, it applies:
 * 1. allowStateChanges so we don't violate enforceActions.
 * 2. untracked so we don't accidentaly subscribe to anything observable accessed during init in case the observable is created inside derivation.
 * 3. batch to avoid state version updates
 */
function initObservable(cb) {
  const derivation = untrackedStart();
  const allowStateChanges = allowStateChangesStart(true) ;
  startBatch();
  try {
    return cb();
  } finally {
    endBatch();
    {
      allowStateChangesEnd(allowStateChanges);
    }
    untrackedEnd(derivation);
  }
}

const toString = objectPrototype.toString;
function deepEqual(a, b, depth = -1) {
  return eq(a, b, depth);
}
// Copied from https://github.com/jashkenas/underscore/blob/5c237a7c682fb68fd5378203f0bf22dce1624854/underscore.js#L1186-L1289
// Modified: "Deep compare objects" part to iterate over keys in forward order instead of reverse order.
//
// Internal recursive comparison function for `isEqual`.
function eq(a, b, depth, aStack, bStack) {
  // Identical objects are equal. `0 === -0`, but they aren't identical.
  // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
  if (a === b) {
    return a !== 0 || 1 / a === 1 / b;
  }
  // `null` or `undefined` only equal to itself (strict comparison).
  if (a == null || b == null) {
    return false;
  }
  // `NaN`s are equivalent, but non-reflexive.
  if (a !== a) {
    return b !== b;
  }
  // Exhaust primitive checks
  const type = typeof a;
  if (type !== "function" && type !== "object" && typeof b != "object") {
    return false;
  }
  // Compare `[[Class]]` names.
  const className = toString.call(a);
  if (className !== toString.call(b)) {
    return false;
  }
  switch (className) {
    // Strings, numbers, regular expressions, dates, and booleans are compared by value.
    case "[object RegExp]":
    // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
    case "[object String]":
      // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
      // equivalent to `new String("5")`.
      return "" + a === "" + b;
    case "[object Number]":
      // `NaN`s are equivalent, but non-reflexive.
      // Object(NaN) is equivalent to NaN.
      if (+a !== +a) {
        return +b !== +b;
      }
      // An `egal` comparison is performed for other numeric values.
      return +a === 0 ? 1 / +a === 1 / b : +a === +b;
    case "[object Date]":
    case "[object Boolean]":
      // Coerce dates and booleans to numeric primitive values. Dates are compared by their
      // millisecond representations. Note that invalid dates with millisecond representations
      // of `NaN` are not equivalent.
      return +a === +b;
    case "[object Symbol]":
      return typeof Symbol !== "undefined" && Symbol.valueOf.call(a) === Symbol.valueOf.call(b);
    case "[object Map]":
    case "[object Set]":
      // Maps and Sets are unwrapped to arrays of entry-pairs, adding an incidental level.
      // Hide this extra level by increasing the depth.
      if (depth >= 0) {
        depth++;
      }
      break;
  }
  // Unwrap any wrapped objects.
  a = unwrap(a);
  b = unwrap(b);
  const areArrays = className === "[object Array]";
  if (!areArrays) {
    if (typeof a != "object" || typeof b != "object") {
      return false;
    }
    // Objects with different constructors are not equivalent, but `Object`s or `Array`s
    // from different frames are.
    const aCtor = a.constructor,
      bCtor = b.constructor;
    if (aCtor !== bCtor && !(isFunction(aCtor) && aCtor instanceof aCtor && isFunction(bCtor) && bCtor instanceof bCtor) && "constructor" in a && "constructor" in b) {
      return false;
    }
  }
  if (depth === 0) {
    return false;
  } else if (depth < 0) {
    depth = -1;
  }
  // Assume equality for cyclic structures. The algorithm for detecting cyclic
  // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
  // Initializing stack of traversed objects.
  // It's done here since we only need them for objects and arrays comparison.
  aStack = aStack || [];
  bStack = bStack || [];
  let length = aStack.length;
  while (length--) {
    // Linear search. Performance is inversely proportional to the number of
    // unique nested structures.
    if (aStack[length] === a) {
      return bStack[length] === b;
    }
  }
  // Add the first object to the stack of traversed objects.
  aStack.push(a);
  bStack.push(b);
  // Recursively compare objects and arrays.
  if (areArrays) {
    // Compare array lengths to determine if a deep comparison is necessary.
    length = a.length;
    if (length !== b.length) {
      return false;
    }
    // Deep compare the contents, ignoring non-numeric properties.
    while (length--) {
      if (!eq(a[length], b[length], depth - 1, aStack, bStack)) {
        return false;
      }
    }
  } else {
    // Deep compare objects.
    const keys = Object.keys(a);
    const _length = keys.length;
    // Ensure that both objects contain the same number of properties before comparing deep equality.
    if (Object.keys(b).length !== _length) {
      return false;
    }
    for (let i = 0; i < _length; i++) {
      // Deep compare each member
      const key = keys[i];
      if (!(hasProp(b, key) && eq(a[key], b[key], depth - 1, aStack, bStack))) {
        return false;
      }
    }
  }
  // Remove the first object from the stack of traversed objects.
  aStack.pop();
  bStack.pop();
  return true;
}
function unwrap(a) {
  if (isObservableArray(a)) {
    return a.slice();
  }
  if (isES6Map(a) || isObservableMap(a)) {
    return Array.from(a.entries());
  }
  if (isES6Set(a) || isObservableSet(a)) {
    return Array.from(a.entries());
  }
  return a;
}

var _globalThis$Iterator;
// safely get iterator prototype if available
const maybeIteratorPrototype = ((_globalThis$Iterator = globalThis.Iterator) == null ? void 0 : _globalThis$Iterator.prototype) || {};
function makeIterable(iterator) {
  iterator[Symbol.iterator] = getSelf;
  return assign(Object.create(maybeIteratorPrototype), iterator);
}
function getSelf() {
  return this;
}

function isAnnotation(thing) {
  return (
    // Can be function
    thing instanceof Object && typeof thing.annotationType_ === "string" && isFunction(thing.make_) && isFunction(thing.extend_)
  );
}

/**
 * (c) Michel Weststrate 2015 - 2020
 * MIT Licensed
 *
 * Welcome to the mobx sources! To get a global overview of how MobX internally works,
 * this is a good place to start:
 * https://medium.com/@mweststrate/becoming-fully-reactive-an-in-depth-explanation-of-mobservable-55995262a254#.xvbh6qd74
 *
 * Source folders:
 * ===============
 *
 * - api/     Most of the public static methods exposed by the module can be found here.
 * - core/    Implementation of the MobX algorithm; atoms, derivations, reactions, dependency trees, optimizations. Cool stuff can be found here.
 * - types/   All the magic that is need to have observable objects, arrays and values is in this folder. Including the modifiers like `asFlat`.
 * - utils/   Utility stuff.
 *
 */
{
  const g = globalThis;
  ["Symbol", "Map", "Set", "Proxy"].forEach(m => {
    if (typeof g[m] === "undefined") {
      die(`MobX requires global '${m}' to be available or polyfilled`);
    }
  });
}
if (typeof __MOBX_DEVTOOLS_GLOBAL_HOOK__ === "object") {
  // See: https://github.com/andykog/mobx-devtools/
  __MOBX_DEVTOOLS_GLOBAL_HOOK__.injectMobx({
    spy,
    extras: {
      getDebugName
    },
    $mobx
  });
}

exports.$mobx = $mobx;
exports.FlowCancellationError = FlowCancellationError;
exports.ObservableMap = ObservableMap;
exports.ObservableSet = ObservableSet;
exports.Reaction = Reaction;
exports._allowStateChanges = allowStateChanges;
exports._allowStateChangesInsideComputed = runInAction;
exports._allowStateReadsEnd = allowStateReadsEnd;
exports._allowStateReadsStart = allowStateReadsStart;
exports._autoAction = autoAction;
exports._autoActionBound = autoActionBound;
exports._endAction = _endAction;
exports._getAdministration = getAdministration;
exports._getGlobalState = getGlobalState;
exports._interceptReads = interceptReads;
exports._isComputingDerivation = isComputingDerivation;
exports._resetGlobalState = resetGlobalState;
exports._startAction = _startAction;
exports.action = action;
exports.actionBound = actionBound;
exports.autorun = autorun;
exports.compareDefault = compareDefault;
exports.compareIdentity = compareIdentity;
exports.compareShallow = compareShallow;
exports.compareStructural = compareStructural;
exports.computed = computed;
exports.computedStruct = computedStruct;
exports.configure = configure;
exports.createAtom = createAtom;
exports.defineProperty = apiDefineProperty;
exports.entries = entries;
exports.extendObservable = extendObservable;
exports.flow = flow;
exports.flowBound = flowBound;
exports.flowResult = flowResult;
exports.get = get;
exports.getAtom = getAtom;
exports.getDebugName = getDebugName;
exports.getDependencyTree = getDependencyTree;
exports.getObserverTree = getObserverTree;
exports.has = has;
exports.intercept = intercept;
exports.isAction = isAction;
exports.isBoxedObservable = isObservableValue;
exports.isComputed = isComputed;
exports.isComputedProp = isComputedProp;
exports.isFlow = isFlow;
exports.isFlowCancellationError = isFlowCancellationError;
exports.isObservable = isObservable;
exports.isObservableArray = isObservableArray;
exports.isObservableMap = isObservableMap;
exports.isObservableObject = isObservableObject;
exports.isObservableProp = isObservableProp;
exports.isObservableSet = isObservableSet;
exports.keys = keys;
exports.makeAutoObservable = makeAutoObservable;
exports.makeObservable = makeObservable;
exports.observable = observable;
exports.observableDeep = observableDeep;
exports.observableRef = observableRef;
exports.observableShallow = observableShallow;
exports.observableStruct = observableStruct;
exports.observe = observe;
exports.onBecomeObserved = onBecomeObserved;
exports.onBecomeUnobserved = onBecomeUnobserved;
exports.onReactionError = onReactionError;
exports.override = override;
exports.ownKeys = apiOwnKeys;
exports.reaction = reaction;
exports.remove = remove;
exports.runInAction = runInAction;
exports.set = set;
exports.spy = spy;
exports.toJS = toJS;
exports.transaction = transaction;
exports.untracked = untracked;
exports.values = values;
exports.when = when;
//# sourceMappingURL=mobx.cjs.development.js.map