UNPKG

mobx

Version:

Simple, scalable state management.

5,397 lines 201 kB
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define(['exports'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.mobx = {}));
})(this, (function (exports) { 'use strict';

    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;

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

}));
//# sourceMappingURL=mobx.umd.development.js.map