(function() {

  this.def_class('DObject',DObject,function(__scope,__class){

    if(!this.__ctor__){this.__ctor__= function DObject(){}; this.__ctor__.prototype = this.prototype; }

    this.method_added = function(name) {
      var len, p, primitives;
      if (this === DObject) {
        primitives = [Array, String, Number, Date];
        len = primitives.length;
        while (len--) {
          p = primitives[len].prototype;
          if (!p[name]) p[name] = this.prototype[name];
        }
      }
      return this;
    };__singleton_method_added(this,"method_added");

    this.attr_reader = function(name, options) {
      var _methname;
      this.prototype[_methname = name] = function() {
        return this["@" + name];
      }; __method_added(this,_methname);
      return this;
    };__singleton_method_added(this,"attr_reader");

    this.attr_writer = function(name, options) {
      var ivar, observes, _methname;
      ivar = "@" + name;
      observes = options && !!options.observe();
      this.prototype[_methname = name + "="] = function(value) {
        var prev;
        prev = this[ivar];
        if (prev !== value) {
          this[ivar] = value;
          if (observes) {
            this.forget(prev);
            this.observe(value, {
              as: name
            });
          }
          this.emit("change:" + name, value, prev);
        }
        return value;
      }; __method_added(this,_methname);
      return this;
    };__singleton_method_added(this,"attr_writer");

    this.attr = function(name, options) {
      this.attr_reader(name, options);
      this.attr_writer(name, options);
      return this;
    };__singleton_method_added(this,"attr");

    this.prototype.uid = function() {
      return this["@uid"] || (this["@uid"] = $uid());
    }; __method_added(this,"uid");

    this.prototype.on = function(event, callback) {
      var cbs, list, tail;
      cbs = this['__callbacks__'] || (this['__callbacks__'] = {});
      list = cbs[event] || (cbs[event] = {});
      tail = list.tail || (list.tail = (list.next = {}));
      tail.callback = callback;
      list.tail = tail.next = {};
      return tail;
    }; __method_added(this,"on");

    this.prototype.once = function(event, callback) {
      var tail;
      tail = this.on(event, callback);
      tail.times = 1;
      return tail;
    }; __method_added(this,"once");

    this.prototype.un = function(event, callback, scope) {
      var cbs, node, prev;
      if (!event) {
        this['__callbacks__'] = null;
      } else if (cbs = this['__callbacks__']) {
        if (!callback) {
          cbs[event] = null;
        } else if (node = cbs[event]) {
          while ((prev = node) && (node = node.next)) {
            if (node === callback || node.callback === callback) {
              prev.next = node.next;
              node.callback = null;
              break;
            }
          }
        }
      }
      return this;
    }; __method_added(this,"un");

    this.prototype.emit = function(event) {
      var args, cb, cbs, node, target;
      args = [];
      args.push.apply(args, arguments);
      args.shift();
      if (cb = this["on" + event.replace(":", "")]) cb.apply(this, args);
      cbs = this['__callbacks__'];
      this.__emit(event, args, cbs);
      args.unshift(event);
      this.__emit('*', args, cbs);
      if (node = this['__observers__']) {
        while (node = node.next) {
          if (target = node.observer) {
            args['[]='](0,node.prefix ? node.prefix + ':' + event : event);
            target.emit.apply(target, args);
          }
        }
      }
      return this;
    }; __method_added(this,"emit");

    this.prototype.__emit = function(event, args, cbs) {
      var cb, node, prev;
      if (cbs && (node = cbs[event])) {
        while ((prev = node) && (node = node.next)) {
          if (cb = node.callback) cb.apply(node, args);
          if (node.times && (--node.times <= 0)) {
            prev.next = node.next;
            node.callback = null;
          }
        }
      }
      return this;
    }; __method_added(this,"__emit");

    this.prototype.deferred = function(method, callback) {
      var cbs, defers, fn;
      var _this = this;
      defers = this['__deferred__'] || (this['__deferred__'] = {});
      fn = defers[method] || (defers[method] = function() {
        var cbs;
        if (--fn.queued === 0) {
          _this[method]();
          if (cbs = fn.callbacks) {
            return cbs.each(function(cb) {
              return cb();
            });
          }
        }
      });
      fn.queued = (fn.queued || 0) + 1;
      if (callback) {
        cbs = fn.callbacks || (fn.callbacks = []);
        cbs.push(callback);
      }
      return fn;
    }; __method_added(this,"deferred");

    this.prototype.observe = function(target, options) {
      var obs, tail;
      if (!target) return nil;
      obs = target['__observers__'] || (target['__observers__'] = {});
      tail = obs.tail || (obs.tail = (obs.next = {}));
      tail.observer = this;
      tail.prefix = options && options.as;
      obs.tail = tail.next = {};
      return tail;
    }; __method_added(this,"observe");

    this.prototype.forget = function(target) {
      var node, prev;
      if (target && (node = target['__observers__'])) {
        while ((prev = node) && (node = node.next)) {
          if (node.observer !== this) continue;
          prev.next = node.next;
          node.callback = null;
          node.observer = null;
          break;
        }
      }
      return this;
    }; __method_added(this,"forget");

  });

}).call($$base);

