function defineKey(prop, subprops, prototype, prefix, keys, options) {
  var path = (prefix ? prefix + '.' : '') + prop;
  prefix = prefix || '';

  if (subprops) {
    Object.defineProperty(prototype, prop, {
      enumerable: true,
      configurable: true,
      get: function() {
        var _this = this;
        if (!this.$__.getters) {
          this.$__.getters = {};
        }

        if (!this.$__.getters[path]) {
          var nested = Object.create(Object.getPrototypeOf(this), getOwnPropertyDescriptors(this));

          // save scope for nested getters/setters
          if (!prefix) {
            nested.$__.scope = this;
          }

          // shadow inherited getters from sub-objects so
          // thing.nested.nested.nested... doesn't occur (gh-366)
          var i = 0,
              len = keys.length;

          for (; i < len; ++i) {
            // over-write the parents getter without triggering it
            Object.defineProperty(nested, keys[i], {
              enumerable: false,    // It doesn't show up.
              writable: true,       // We can set it later.
              configurable: true,   // We can Object.defineProperty again.
              value: undefined      // It shadows its parent.
            });
          }

          Object.defineProperty(nested, 'toObject', {
            enumerable: true,
            configurable: true,
            writable: false,
            value: function() {
              return clone(_this.get(path), { retainKeyOrder: true });
            }
          });

          Object.defineProperty(nested, 'toJSON', {
            enumerable: true,
            configurable: true,
            writable: false,
            value: function() {
              return _this.get(path);
            }
          });

          Object.defineProperty(nested, '$__isNested', {
            enumerable: true,
            configurable: true,
            writable: false,
            value: true
          });

          compile(subprops, nested, path, options);
          this.$__.getters[path] = nested;
        }

        return this.$__.getters[path];
      },
      set: function(v) {
        if (v instanceof Document) {
          v = v.toObject({ transform: false });
        }
        return (this.$__.scope || this).set(path, v);
      }
    });
  } else {
    Object.defineProperty(prototype, prop, {
      enumerable: true,
      configurable: true,
      get: function() {
        return this.get.call(this.$__.scope || this, path);
      },
      set: function(v) {
        return this.set.call(this.$__.scope || this, path, v);
      }
    });
  }
}
/*!
 * Defines the accessor named prop on the incoming prototype.
 */
Defines the accessor named prop on the incoming prototype.
Defines the accessor named prop on the incoming prototype .
function defineKey(prop, subprops, prototype, prefix, keys, options) {
  var path = (prefix ? prefix + '.' : '') + prop;
  prefix = prefix || '';
  if (subprops) {
    Object.defineProperty(prototype, prop, {
      enumerable: true,
      configurable: true,
      get: function() {
        var _this = this;
        if (!this.$__.getters) {
          this.$__.getters = {};
        }
        if (!this.$__.getters[path]) {
          var nested = Object.create(Object.getPrototypeOf(this), getOwnPropertyDescriptors(this));
          if (!prefix) {
            nested.$__.scope = this;
          }
          var i = 0,
              len = keys.length;
          for (; i < len; ++i) {
            Object.defineProperty(nested, keys[i], {
              enumerable: false,    
              writable: true,       
              configurable: true,   
              value: undefined      
            });
          }
          Object.defineProperty(nested, 'toObject', {
            enumerable: true,
            configurable: true,
            writable: false,
            value: function() {
              return clone(_this.get(path), { retainKeyOrder: true });
            }
          });
          Object.defineProperty(nested, 'toJSON', {
            enumerable: true,
            configurable: true,
            writable: false,
            value: function() {
              return _this.get(path);
            }
          });
          Object.defineProperty(nested, '$__isNested', {
            enumerable: true,
            configurable: true,
            writable: false,
            value: true
          });
          compile(subprops, nested, path, options);
          this.$__.getters[path] = nested;
        }
        return this.$__.getters[path];
      },
      set: function(v) {
        if (v instanceof Document) {
          v = v.toObject({ transform: false });
        }
        return (this.$__.scope || this).set(path, v);
      }
    });
  } else {
    Object.defineProperty(prototype, prop, {
      enumerable: true,
      configurable: true,
      get: function() {
        return this.get.call(this.$__.scope || this, path);
      },
      set: function(v) {
        return this.set.call(this.$__.scope || this, path, v);
      }
    });
  }
}
function defineKey ( prop , subprops , prototype , prefix , keys , options ) { var path = ( prefix ? prefix + '.' : '' ) + prop ; prefix = prefix || '' ; if ( subprops ) { Object . defineProperty ( prototype , prop , { enumerable : true , configurable : true , get : function ( ) { var _this = this ; if ( ! this . $__ . getters ) { this . $__ . getters = { } ; } if ( ! this . $__ . getters [ path ] ) { var nested = Object . create ( Object . getPrototypeOf ( this ) , getOwnPropertyDescriptors ( this ) ) ; if ( ! prefix ) { nested . $__ . scope = this ; } var i = 0 , len = keys . length ; for ( ; i < len ; ++ i ) { Object . defineProperty ( nested , keys [ i ] , { enumerable : false , writable : true , configurable : true , value : undefined } ) ; } Object . defineProperty ( nested , 'toObject' , { enumerable : true , configurable : true , writable : false , value : function ( ) { return clone ( _this . get ( path ) , { retainKeyOrder : true } ) ; } } ) ; Object . defineProperty ( nested , 'toJSON' , { enumerable : true , configurable : true , writable : false , value : function ( ) { return _this . get ( path ) ; } } ) ; Object . defineProperty ( nested , '$__isNested' , { enumerable : true , configurable : true , writable : false , value : true } ) ; compile ( subprops , nested , path , options ) ; this . $__ . getters [ path ] = nested ; } return this . $__ . getters [ path ] ; } , set : function ( v ) { if ( v instanceof Document ) { v = v . toObject ( { transform : false } ) ; } return ( this . $__ . scope || this ) . set ( path , v ) ; } } ) ; } else { Object . defineProperty ( prototype , prop , { enumerable : true , configurable : true , get : function ( ) { return this . get . call ( this . $__ . scope || this , path ) ; } , set : function ( v ) { return this . set . call ( this . $__ . scope || this , path , v ) ; } } ) ; } }
Defines the accessor named prop on the incoming prototype.
Defines the accessor named prop on the incoming prototype .
// save scope for nested getters/setters // shadow inherited getters from sub-objects so // thing.nested.nested.nested... doesn't occur (gh-366) // over-write the parents getter without triggering it // It doesn't show up. // We can set it later. // We can Object.defineProperty again. // It shadows its parent.