function(obj, callback, thisArg) {
    return obj.map ? obj.map.call(obj, callback, thisArg) : map.call(obj, callback, thisArg);
  }

function ( obj , callback , thisArg ) { return obj . map ? obj . map . call ( obj , callback , thisArg ) : map . call ( obj , callback , thisArg ) ; }

Calls the map function on the passed object with a specified callback. This
uses `Ember.ArrayPolyfill`'s-map method when necessary.

@method map
@param {Object} obj The object that should be mapped
@param {Function} callback The callback to execute
@param {Object} thisArg Value to use as this when executing *callback*

@return {Array} An array of mapped values.

Calls the map function on the passed object with a specified callback . This uses Ember . ArrayPolyfill s - map method when necessary .


function(obj, callback, thisArg) {
    return obj.filter ? obj.filter.call(obj, callback, thisArg) : filter.call(obj, callback, thisArg);
  }

function ( obj , callback , thisArg ) { return obj . filter ? obj . filter . call ( obj , callback , thisArg ) : filter . call ( obj , callback , thisArg ) ; }

Calls the filter function on the passed object with a specified callback. This
uses `Ember.ArrayPolyfill`'s-filter method when necessary.

@method filter
@param {Object} obj The object to call filter on
@param {Function} callback The callback to execute
@param {Object} thisArg Value to use as this when executing *callback*

@return {Array} An array containing the filtered values

Calls the filter function on the passed object with a specified callback . This uses Ember . ArrayPolyfill s - filter method when necessary .


function(obj, elements) {
    return elements === undefined ? [] : utils.map(elements, function(item) {
      return utils.indexOf(obj, item);
    });
  }

function ( obj , elements ) { return elements === undefined ? [ ] : utils . map ( elements , function ( item ) { return utils . indexOf ( obj , item ) ; } ) ; }

Returns an array of indexes of the first occurrences of the passed elements
on the passed object.

```javascript
var array = [1, 2, 3, 4, 5];
Ember.EnumerableUtils.indexesOf(array, [2, 5]); // [1, 4]

var fubar = "Fubarr";
Ember.EnumerableUtils.indexesOf(fubar, ['b', 'r']); // [2, 4]
```

@method indexesOf
@param {Object} obj The object to check for element indexes
@param {Array} elements The elements to search for on *obj*

@return {Array} An array of indexes.

Returns an array of indexes of the first occurrences of the passed elements on the passed object .


function(array, item) {
    var index = utils.indexOf(array, item);
    if (index === -1) { array.push(item); }
  }

function ( array , item ) { var index = utils . indexOf ( array , item ) ; if ( index === - 1 ) { array . push ( item ) ; } }

Adds an object to an array. If the array already includes the object this
method has no effect.

@method addObject
@param {Array} array The array the passed item should be added to
@param {Object} item The item to add to the passed array

@return 'undefined'

Adds an object to an array . If the array already includes the object this method has no effect .


function(array, idx, amt, objects) {
    if (array.replace) {
      return array.replace(idx, amt, objects);
    } else {
      return utils._replace(array, idx, amt, objects);
    }
  }

function ( array , idx , amt , objects ) { if ( array . replace ) { return array . replace ( idx , amt , objects ) ; } else { return utils . _replace ( array , idx , amt , objects ) ; } }

Replaces objects in an array with the passed objects.

```javascript
var array = [1,2,3];
Ember.EnumerableUtils.replace(array, 1, 2, [4, 5]); // [1, 4, 5]

var array = [1,2,3];
Ember.EnumerableUtils.replace(array, 1, 1, [4, 5]); // [1, 4, 5, 3]

var array = [1,2,3];
Ember.EnumerableUtils.replace(array, 10, 1, [4, 5]); // [1, 2, 3, 4, 5]
```

@method replace
@param {Array} array The array the objects should be inserted into.
@param {Number} idx Starting index in the array to replace. If *idx* >=
length, then append to the end of the array.
@param {Number} amt Number of elements that should be removed from the array,
starting at *idx*
@param {Array} objects An array of zero or more objects that should be
inserted into the array at *idx*

@return {Array} The modified array.

Replaces objects in an array with the passed objects .


function(array1, array2) {
    var intersection = [];

    utils.forEach(array1, function(element) {
      if (utils.indexOf(array2, element) >= 0) {
        intersection.push(element);
      }
    });

    return intersection;
  }

function ( array1 , array2 ) { var intersection = [ ] ; utils . forEach ( array1 , function ( element ) { if ( utils . indexOf ( array2 , element ) >= 0 ) { intersection . push ( element ) ; } } ) ; return intersection ; }

Calculates the intersection of two arrays. This method returns a new array
filled with the records that the two passed arrays share with each other.
If there is no intersection, an empty array will be returned.

```javascript
var array1 = [1, 2, 3, 4, 5];
var array2 = [1, 3, 5, 6, 7];

Ember.EnumerableUtils.intersection(array1, array2); // [1, 3, 5]

var array1 = [1, 2, 3];
var array2 = [4, 5, 6];

Ember.EnumerableUtils.intersection(array1, array2); // []
```

@method intersection
@param {Array} array1 The first array
@param {Array} array2 The second array

@return {Array} The intersection of the two passed arrays.

Calculates the intersection of two arrays . This method returns a new array filled with the records that the two passed arrays share with each other . If there is no intersection an empty array will be returned .


function removeListener(obj, eventName, target, method) {
  Ember.assert("You must pass at least an object and event name to Ember.removeListener", !!obj && !!eventName);

  if (!method && 'function' === typeof target) {
    method = target;
    target = null;
  }

  function _removeListener(target, method) {
    var actions = actionsFor(obj, eventName),
        actionIndex = indexOf(actions, target, method);

    // action doesn't exist, give up silently
    if (actionIndex === -1) { return; }

    actions.splice(actionIndex, 3);

    if ('function' === typeof obj.didRemoveListener) {
      obj.didRemoveListener(eventName, target, method);
    }
  }

  if (method) {
    _removeListener(target, method);
  } else {
    var meta = obj[META_KEY],
        actions = meta && meta.listeners && meta.listeners[eventName];

    if (!actions) { return; }
    for (var i = actions.length - 3; i >= 0; i -= 3) {
      _removeListener(actions[i], actions[i+1]);
    }
  }
}

Remove an event listener

Arguments should match those passed to `Ember.addListener`.

@method removeListener
@for Ember
@param obj
@param {String} eventName
@param {Object|Function} targetOrMethod A target object or a function
@param {Function|String} method A function or the name of a function to be called on `target`


function suspendListener(obj, eventName, target, method, callback) {
  if (!method && 'function' === typeof target) {
    method = target;
    target = null;
  }

  var actions = actionsFor(obj, eventName),
      actionIndex = indexOf(actions, target, method);

  if (actionIndex !== -1) {
    actions[actionIndex+2] |= SUSPENDED; // mark the action as suspended
  }

  function tryable()   { return callback.call(target); }
  function finalizer() { if (actionIndex !== -1) { actions[actionIndex+2] &= ~SUSPENDED; } }

  return Ember.tryFinally(tryable, finalizer);
}

function
suspendListener
(
obj
,
eventName
,
target
,
method
,
callback
)
{
if
(
!
method
&&
'function'
===
typeof
target
)
{
method
=
target
;
target
=
;
}
var
actions
=
actionsFor
(
obj
,
eventName
)
,
actionIndex
=
indexOf
(
actions
,
target
,
method
)
;
if
(
actionIndex
!==
1
)
{
actions
[
actionIndex
+
2
]
|=
SUSPENDED
;
// mark the action as suspended
}
function
tryable
(
)
{
return
callback
.
call
(
target
)
;
}
function
finalizer
(
)
{
if
(
actionIndex
!==
1
)
{
actions
[
actionIndex
+
2
]
&=
~
SUSPENDED
;
}
}
return
Ember
.
tryFinally
(
tryable
,
finalizer
)
;
}

Suspend listener during callback.

This should only be used by the target of the event listener
when it is taking an action that would cause the event, e.g.
an object might suspend its property change listener while it is
setting that property.

@method suspendListener
@for Ember

@private
@param obj
@param {String} eventName
@param {Object|Function} targetOrMethod A target object or a function
@param {Function|String} method A function or the name of a function to be called on `target`
@param {Function} callback


function dependentKeysDidChange(obj, depKey, meta) {
  if (obj.isDestroying) { return; }

  var seen = DID_SEEN, top = !seen;
  if (top) { seen = DID_SEEN = {}; }
  iterDeps(propertyDidChange, obj, depKey, seen, meta);
  if (top) { DID_SEEN = null; }
}

function dependentKeysDidChange ( obj , depKey , meta ) { if ( obj . isDestroying ) { return ; } var seen = DID_SEEN , top = ! seen ; if ( top ) { seen = DID_SEEN = { } ; } iterDeps ( propertyDidChange , obj , depKey , seen , meta ) ; if ( top ) { DID_SEEN = null ; } }

called whenever a property has just changed to update dependent keys


function set(obj, keyName, value, tolerant) {
  if (typeof obj === 'string') {
    Ember.assert("Path '" + obj + "' must be global if no obj is given.", IS_GLOBAL.test(obj));
    value = keyName;
    keyName = obj;
    obj = null;
  }

  Ember.assert("Cannot call set with "+ keyName +" key.", !!keyName);

  if (!obj || keyName.indexOf('.') !== -1) {
    return setPath(obj, keyName, value, tolerant);
  }

  Ember.assert("You need to provide an object and key to `set`.", !!obj && keyName !== undefined);
  Ember.assert('calling set on destroyed object', !obj.isDestroyed);

  var meta = obj[META_KEY], desc = meta && meta.descs[keyName],
      isUnknown, currentValue;
  if (desc) {
    desc.set(obj, keyName, value);
  } else {
    isUnknown = 'object' === typeof obj && !(keyName in obj);

    // setUnknownProperty is called if `obj` is an object,
    // the property does not already exist, and the
    // `setUnknownProperty` method exists on the object
    if (isUnknown && 'function' === typeof obj.setUnknownProperty) {
      obj.setUnknownProperty(keyName, value);
    } else if (meta && meta.watching[keyName] > 0) {
      if (MANDATORY_SETTER) {
        currentValue = meta.values[keyName];
      } else {
        currentValue = obj[keyName];
      }
      // only trigger a change if the value has changed
      if (value !== currentValue) {
        Ember.propertyWillChange(obj, keyName);
        if (MANDATORY_SETTER) {
          if ((currentValue === undefined && !(keyName in obj)) || !obj.propertyIsEnumerable(keyName)) {
            Ember.defineProperty(obj, keyName, null, value); // setup mandatory setter
          } else {
            meta.values[keyName] = value;
          }
        } else {
          obj[keyName] = value;
        }
        Ember.propertyDidChange(obj, keyName);
      }
    } else {
      obj[keyName] = value;
    }
  }
  return value;
}

Sets the value of a property on an object, respecting computed properties
and notifying observers and other listeners of the change. If the
property is not defined but the object implements the `setUnknownProperty`
method then that will be invoked as well.

@method set
@for Ember
@param {Object} obj The object to modify.
@param {String} keyName The property key to set
@param {Object} value The value to set
@return {Object} the passed value.

Sets the value of a property on an object respecting computed properties and notifying observers and other listeners of the change . If the property is not defined but the object implements the setUnknownProperty method then that will be invoked as well .


function(key, value) {
    var keys = this.keys,
        values = this.values,
        guid = guidFor(key);

    keys.add(key);
    values[guid] = value;
    set(this, 'length', keys.list.length);
  }

function ( key , value ) { var keys = this . keys , values = this . values , guid = guidFor ( key ) ; keys . add ( key ) ; values [ guid ] = value ; set ( this , 'length' , keys . list . length ) ; }

Adds a value to the map. If a value for the given key has already been
provided, the new value will replace the old value.

@method set
@param {*} key
@param {*} value

Adds a value to the map . If a value for the given key has already been provided the new value will replace the old value .


function(key) {
    // don't use ES6 "delete" because it will be annoying
    // to use in browsers that are not ES6 friendly;
    var keys = this.keys,
        values = this.values,
        guid = guidFor(key);

    if (values.hasOwnProperty(guid)) {
      keys.remove(key);
      delete values[guid];
      set(this, 'length', keys.list.length);
      return true;
    } else {
      return false;
    }
  }

Removes a value from the map for an associated key.

@method remove
@param {*} key
@return {Boolean} true if an item was removed, false otherwise

Removes a value from the map for an associated key .


function(callback, self) {
    var keys = this.keys,
        values = this.values;

    keys.forEach(function(key) {
      var guid = guidFor(key);
      callback.call(self, key, values[guid]);
    });
  }

function ( callback , self ) { var keys = this . keys , values = this . values ; keys . forEach ( function ( key ) { var guid = guidFor ( key ) ; callback . call ( self , key , values [ guid ] ) ; } ) ; }

Iterate over all the keys and values. Calls the function once
for each key, passing in the key and value, in that order.

The keys are guaranteed to be iterated over in insertion order.

@method forEach
@param {Function} callback
@param {*} self if passed, the `this` value inside the
callback. By default, `this` is the map.

Iterate over all the keys and values . Calls the function once for each key passing in the key and value in that order .


function(obj) {
    Ember.assert('Must pass a valid object to Ember.Binding.disconnect()', !!obj);

    var twoWay = !this._oneWay;

    // remove an observer on the object so we're no longer notified of
    // changes that should update bindings.
    Ember.removeObserver(obj, this._from, this, this.fromDidChange);

    // if the binding is two-way, remove the observer from the target as well
    if (twoWay) { Ember.removeObserver(obj, this._to, this, this.toDidChange); }

    this._readyToSync = false; // disable scheduled syncs...
    return this;
  }

Disconnects the binding instance. Changes will no longer be relayed. You
will not usually need to call this method.

@method disconnect
@param {Object} obj The root object you passed when connecting the binding.
@return {Ember.Binding} `this`

Disconnects the binding instance . Changes will no longer be relayed . You will not usually need to call this method .


function filter(promises, filterFn, label) {
      return all(promises, label).then(function(values){
        if (!isArray(promises)) {
          throw new TypeError('You must pass an array to filter.');
        }

        if (!isFunction(filterFn)){
          throw new TypeError("You must pass a function to filter's second argument.");
        }

        return map(promises, filterFn, label).then(function(filterResults){
           var i,
               valuesLen = values.length,
               filtered = [];

           for (i = 0; i < valuesLen; i++){
             if(filterResults[i]) filtered.push(values[i]);
           }
           return filtered;
        });
      });
    }

`RSVP.filter` is similar to JavaScript's native `filter` method, except that it
waits for all promises to become fulfilled before running the `filterFn` on
each item in given to `promises`. `RSVP.filter` returns a promise that will
become fulfilled with the result of running `filterFn` on the values the
promises become fulfilled with.

For example:

```javascript

var promise1 = RSVP.resolve(1);
var promise2 = RSVP.resolve(2);
var promise3 = RSVP.resolve(3);

var filterFn = function(item){
return item > 1;
};

RSVP.filter(promises, filterFn).then(function(result){
result is [ 2, 3 ]
});
```

If any of the `promises` given to `RSVP.filter` are rejected, the first promise
that is rejected will be given as an argument to the returned promise's
rejection handler. For example:

```javascript
var promise1 = RSVP.resolve(1);
var promise2 = RSVP.reject(new Error("2"));
var promise3 = RSVP.reject(new Error("3"));
var promises = [ promise1, promise2, promise3 ];

var filterFn = function(item){
return item > 1;
};

RSVP.filter(promises, filterFn).then(function(array){
Code here never runs because there are rejected promises!
}, function(reason) {
reason.message === "2"
});
```

`RSVP.filter` will also wait for any promises returned from `filterFn`.
For instance, you may want to fetch a list of users then return a subset
of those users based on some asynchronous operation:

```javascript

var alice = { name: 'alice' };
var bob   = { name: 'bob' };
var users = [ alice, bob ];

var promises = users.map(function(user){
return RSVP.resolve(user);
});

var filterFn = function(user){
Here, Alice has permissions to create a blog post, but Bob does not.
return getPrivilegesForUser(user).then(function(privs){
return privs.can_create_blog_post === true;
});
};
RSVP.filter(promises, filterFn).then(function(users){
true, because the server told us only Alice can create a blog post.
users.length === 1;
false, because Alice is the only user present in `users`
users[0] === bob;
});
```

@method filter
@for RSVP
@param {Array} promises
@param {Function} filterFn - function to be called on each resolved value to
filter the final results.
@param {String} label optional string describing the promise. Useful for
tooling.
@return {Promise}

RSVP . filter is similar to JavaScript s native filter method except that it waits for all promises to become fulfilled before running the filterFn on each item in given to promises . RSVP . filter returns a promise that will become fulfilled with the result of running filterFn on the values the promises become fulfilled with .


function Container(parent) {
      this.parent = parent;
      this.children = [];

      this.resolver = parent && parent.resolver || function() {};

      this.registry = new InheritingDict(parent && parent.registry);
      this.cache = new InheritingDict(parent && parent.cache);
      this.factoryCache = new InheritingDict(parent && parent.factoryCache);
      this.resolveCache = new InheritingDict(parent && parent.resolveCache);
      this.typeInjections = new InheritingDict(parent && parent.typeInjections);
      this.injections = {};

      this.factoryTypeInjections = new InheritingDict(parent && parent.factoryTypeInjections);
      this.factoryInjections = {};

      this._options = new InheritingDict(parent && parent._options);
      this._typeOptions = new InheritingDict(parent && parent._typeOptions);
    }

function Container ( parent ) { this . parent = parent ; this . children = [ ] ; this . resolver = parent && parent . resolver || function ( ) { } ; this . registry = new InheritingDict ( parent && parent . registry ) ; this . cache = new InheritingDict ( parent && parent . cache ) ; this . factoryCache = new InheritingDict ( parent && parent . factoryCache ) ; this . resolveCache = new InheritingDict ( parent && parent . resolveCache ) ; this . typeInjections = new InheritingDict ( parent && parent . typeInjections ) ; this . injections = { } ; this . factoryTypeInjections = new InheritingDict ( parent && parent . factoryTypeInjections ) ; this . factoryInjections = { } ; this . _options = new InheritingDict ( parent && parent . _options ) ; this . _typeOptions = new InheritingDict ( parent && parent . _typeOptions ) ; }

A lightweight container that helps to assemble and decouple components. Public api for the container is still in flux. The public api, specified on the application namespace should be considered the stable api.

A lightweight container that helps to assemble and decouple components . Public api for the container is still in flux . The public api specified on the application namespace should be considered the stable api .


function(fullName, factory, options) {
        validateFullName(fullName);

        if (factory === undefined) {
          throw new TypeError('Attempting to register an unknown factory: `' + fullName + '`');
        }

        var normalizedName = this.normalize(fullName);

        if (this.cache.has(normalizedName)) {
          throw new Error('Cannot re-register: `' + fullName +'`, as it has already been looked up.');
        }

        this.registry.set(normalizedName, factory);
        this._options.set(normalizedName, options || {});
      }

Registers a factory for later injection.

Example:

```javascript
var container = new Container();

container.register('model:user', Person, {singleton: false });
container.register('fruit:favorite', Orange);
container.register('communication:main', Email, {singleton: false});
```

@method register
@param {String} fullName
@param {Function} factory
@param {Object} options

Registers a factory for later injection .


function(fullName) {
        validateFullName(fullName);

        var normalizedName = this.normalize(fullName);

        this.registry.remove(normalizedName);
        this.cache.remove(normalizedName);
        this.factoryCache.remove(normalizedName);
        this.resolveCache.remove(normalizedName);
        this._options.remove(normalizedName);
      }

function ( fullName ) { validateFullName ( fullName ) ; var normalizedName = this . normalize ( fullName ) ; this . registry . remove ( normalizedName ) ; this . cache . remove ( normalizedName ) ; this . factoryCache . remove ( normalizedName ) ; this . resolveCache . remove ( normalizedName ) ; this . _options . remove ( normalizedName ) ; }

Unregister a fullName

```javascript
var container = new Container();
container.register('model:user', User);

container.lookup('model:user') instanceof User //=> true

container.unregister('model:user')
container.lookup('model:user') === undefined //=> true
```

@method unregister
@param {String} fullName


function(fullName) {
        validateFullName(fullName);

        var normalizedName = this.normalize(fullName);
        var cached = this.resolveCache.get(normalizedName);

        if (cached) { return cached; }

        var resolved = this.resolver(normalizedName) || this.registry.get(normalizedName);

        this.resolveCache.set(normalizedName, resolved);

        return resolved;
      }

function ( fullName ) { validateFullName ( fullName ) ; var normalizedName = this . normalize ( fullName ) ; var cached = this . resolveCache . get ( normalizedName ) ; if ( cached ) { return cached ; } var resolved = this . resolver ( normalizedName ) || this . registry . get ( normalizedName ) ; this . resolveCache . set ( normalizedName , resolved ) ; return resolved ; }

Given a fullName return the corresponding factory.

By default `resolve` will retrieve the factory from
its container's registry.

```javascript
var container = new Container();
container.register('api:twitter', Twitter);

container.resolve('api:twitter') // => Twitter
```

Optionally the container can be provided with a custom resolver.
If provided, `resolve` will first provide the custom resolver
the oppertunity to resolve the fullName, otherwise it will fallback
to the registry.

```javascript
var container = new Container();
container.resolver = function(fullName) {
lookup via the module system of choice
};

the twitter factory is added to the module system
container.resolve('api:twitter') // => Twitter
```

@method resolve
@param {String} fullName
@return {Function} fullName's factory

Given a fullName return the corresponding factory .


function(type, property, fullName) {
        validateFullName(fullName);
        if (this.parent) { illegalChildOperation('typeInjection'); }

        addTypeInjection(this.typeInjections, type, property, fullName);
      }

function ( type , property , fullName ) { validateFullName ( fullName ) ; if ( this . parent ) { illegalChildOperation ( 'typeInjection' ) ; } addTypeInjection ( this . typeInjections , type , property , fullName ) ; }

Used only via `injection`.

Provides a specialized form of injection, specifically enabling
all objects of one type to be injected with a reference to another
object.

For example, provided each object of type `controller` needed a `router`.
one would do the following:

```javascript
var container = new Container();

container.register('router:main', Router);
container.register('controller:user', UserController);
container.register('controller:post', PostController);

container.typeInjection('controller', 'router', 'router:main');

var user = container.lookup('controller:user');
var post = container.lookup('controller:post');

user.router instanceof Router; //=> true
post.router instanceof Router; //=> true

both controllers share the same router
user.router === post.router; //=> true
```

@private
@method typeInjection
@param {String} type
@param {String} property
@param {String} fullName


function(fullName, property, injectionName) {
        if (this.parent) { illegalChildOperation('injection'); }

        validateFullName(injectionName);
        var normalizedInjectionName = this.normalize(injectionName);

        if (fullName.indexOf(':') === -1) {
          return this.typeInjection(fullName, property, normalizedInjectionName);
        }

        validateFullName(fullName);
        var normalizedName = this.normalize(fullName);

        addInjection(this.injections, normalizedName, property, normalizedInjectionName);
      }

function ( fullName , property , injectionName ) { if ( this . parent ) { illegalChildOperation ( 'injection' ) ; } validateFullName ( injectionName ) ; var normalizedInjectionName = this . normalize ( injectionName ) ; if ( fullName . indexOf ( ':' ) === - 1 ) { return this . typeInjection ( fullName , property , normalizedInjectionName ) ; } validateFullName ( fullName ) ; var normalizedName = this . normalize ( fullName ) ; addInjection ( this . injections , normalizedName , property , normalizedInjectionName ) ; }

Defines injection rules.

These rules are used to inject dependencies onto objects when they
are instantiated.

Two forms of injections are possible:

Injecting one fullName on another fullName
Injecting one fullName on a type

Example:

```javascript
var container = new Container();

container.register('source:main', Source);
container.register('model:user', User);
container.register('model:post', Post);

injecting one fullName on another fullName
eg. each user model gets a post model
container.injection('model:user', 'post', 'model:post');

injecting one fullName on another type
container.injection('model', 'source', 'source:main');

var user = container.lookup('model:user');
var post = container.lookup('model:post');

user.source instanceof Source; //=> true
post.source instanceof Source; //=> true

user.post instanceof Post; //=> true

and both models share the same source
user.source === post.source; //=> true
```

@method injection
@param {String} factoryName
@param {String} property
@param {String} injectionName


function(type, property, fullName) {
        if (this.parent) { illegalChildOperation('factoryTypeInjection'); }

        addTypeInjection(this.factoryTypeInjections, type, property, this.normalize(fullName));
      }

function ( type , property , fullName ) { if ( this . parent ) { illegalChildOperation ( 'factoryTypeInjection' ) ; } addTypeInjection ( this . factoryTypeInjections , type , property , this . normalize ( fullName ) ) ; }

Used only via `factoryInjection`.

Provides a specialized form of injection, specifically enabling
all factory of one type to be injected with a reference to another
object.

For example, provided each factory of type `model` needed a `store`.
one would do the following:

```javascript
var container = new Container();

container.register('store:main', SomeStore);

container.factoryTypeInjection('model', 'store', 'store:main');

var store = container.lookup('store:main');
var UserFactory = container.lookupFactory('model:user');

UserFactory.store instanceof SomeStore; //=> true
```

@private
@method factoryTypeInjection
@param {String} type
@param {String} property
@param {String} fullName


function(key) {
        var dict = this.dict;

        if (dict.hasOwnProperty(key)) {
          return dict[key];
        }

        if (this.parent) {
          return this.parent.get(key);
        }
      }

function ( key ) { var dict = this . dict ; if ( dict . hasOwnProperty ( key ) ) { return dict [ key ] ; } if ( this . parent ) { return this . parent . get ( key ) ; } }

Retrieve the value given a key, if the value is present at the current
level use it, otherwise walk up the parent hierarchy and try again. If
no matching key is found, return undefined.

@method get
@param {String} key
@return {any}

Retrieve the value given a key if the value is present at the current level use it otherwise walk up the parent hierarchy and try again . If no matching key is found return undefined .


function(key) {
        var dict = this.dict;

        if (dict.hasOwnProperty(key)) {
          return true;
        }

        if (this.parent) {
          return this.parent.has(key);
        }

        return false;
      }

function ( key ) { var dict = this . dict ; if ( dict . hasOwnProperty ( key ) ) { return true ; } if ( this . parent ) { return this . parent . has ( key ) ; } return false ; }

Check for the existence of given a key, if the key is present at the current
level return true, otherwise walk up the parent hierarchy and try again. If
no matching key is found, return false.

@method has
@param {String} key
@return {Boolean}

Check for the existence of given a key if the key is present at the current level return true otherwise walk up the parent hierarchy and try again . If no matching key is found return false .


function(callback, binding) {
        var dict = this.dict;

        for (var prop in dict) {
          if (dict.hasOwnProperty(prop)) {
            callback.call(binding, prop, dict[prop]);
          }
        }
      }

function ( callback , binding ) { var dict = this . dict ; for ( var prop in dict ) { if ( dict . hasOwnProperty ( prop ) ) { callback . call ( binding , prop , dict [ prop ] ) ; } } }

Iterate and invoke a callback for each local key-value pair.

@method eachLocal
@param {Function} callback
@param {Object} binding

Iterate and invoke a callback for each local key - value pair .


function(str) {
    var cache = STRING_DASHERIZE_CACHE,
        hit   = cache.hasOwnProperty(str),
        ret;

    if (hit) {
      return cache[str];
    } else {
      ret = Ember.String.decamelize(str).replace(STRING_DASHERIZE_REGEXP,'-');
      cache[str] = ret;
    }

    return ret;
  }

function ( str ) { var cache = STRING_DASHERIZE_CACHE , hit = cache . hasOwnProperty ( str ) , ret ; if ( hit ) { return cache [ str ] ; } else { ret = Ember . String . decamelize ( str ) . replace ( STRING_DASHERIZE_REGEXP , '-' ) ; cache [ str ] = ret ; } return ret ; }

Replaces underscores, spaces, or camelCase with dashes.

```javascript
'innerHTML'.dasherize();          // 'inner-html'
'action_name'.dasherize();        // 'action-name'
'css-class-name'.dasherize();     // 'css-class-name'
'my favorite items'.dasherize();  // 'my-favorite-items'
```

@method dasherize
@param {String} str The string to dasherize.
@return {String} the dasherized string.

Replaces underscores spaces or camelCase with dashes .


function(keyName, increment) {
    if (Ember.isNone(increment)) { increment = 1; }
    Ember.assert("Must pass a numeric value to incrementProperty", (!isNaN(parseFloat(increment)) && isFinite(increment)));
    set(this, keyName, (get(this, keyName) || 0) + increment);
    return get(this, keyName);
  }

Set the value of a property to the current value plus some amount.

```javascript
person.incrementProperty('age');
team.incrementProperty('score', 2);
```

@method incrementProperty
@param {String} keyName The name of the property to increment
@param {Number} increment The amount to increment by. Defaults to 1
@return {Number} The new property value

Set the value of a property to the current value plus some amount .


function(keyName, decrement) {
    if (Ember.isNone(decrement)) { decrement = 1; }
    Ember.assert("Must pass a numeric value to decrementProperty", (!isNaN(parseFloat(decrement)) && isFinite(decrement)));
    set(this, keyName, (get(this, keyName) || 0) - decrement);
    return get(this, keyName);
  }

Set the value of a property to the current value minus some amount.

```javascript
player.decrementProperty('lives');
orc.decrementProperty('health', 5);
```

@method decrementProperty
@param {String} keyName The name of the property to decrement
@param {Number} decrement The amount to decrement by. Defaults to 1
@return {Number} The new property value

Set the value of a property to the current value minus some amount .


function() {
    var Class = makeCtor(), proto;
    Class.ClassMixin = Mixin.create(this.ClassMixin);
    Class.PrototypeMixin = Mixin.create(this.PrototypeMixin);

    Class.ClassMixin.ownerConstructor = Class;
    Class.PrototypeMixin.ownerConstructor = Class;

    reopen.apply(Class.PrototypeMixin, arguments);

    Class.superclass = this;
    Class.__super__  = this.prototype;

    proto = Class.prototype = o_create(this.prototype);
    proto.constructor = Class;
    generateGuid(proto);
    meta(proto).proto = proto; // this will disable observers on prototype

    Class.ClassMixin.apply(Class);
    return Class;
  }

Creates a new subclass.

```javascript
App.Person = Ember.Object.extend({
say: function(thing) {
alert(thing);
}
});
```

This defines a new subclass of Ember.Object: `App.Person`. It contains one method: `say()`.

You can also create a subclass from any existing class by calling its `extend()`  method. For example, you might want to create a subclass of Ember's built-in `Ember.View` class:

```javascript
App.PersonView = Ember.View.extend({
tagName: 'li',
classNameBindings: ['isAdministrator']
});
```

When defining a subclass, you can override methods but still access the implementation of your parent class by calling the special `_super()` method:

```javascript
App.Person = Ember.Object.extend({
say: function(thing) {
var name = this.get('name');
alert(name + ' says: ' + thing);
}
});

App.Soldier = App.Person.extend({
say: function(thing) {
this._super(thing + ", sir!");
},
march: function(numberOfHours) {
alert(this.get('name') + ' marches for ' + numberOfHours + ' hours.')
}
});

var yehuda = App.Soldier.create({
name: "Yehuda Katz"
});

yehuda.say("Yes");  // alerts "Yehuda Katz says: Yes, sir!"
```

The `create()` on line #17 creates an *instance* of the `App.Soldier` class. The `extend()` on line #8 creates a *subclass* of `App.Person`. Any instance of the `App.Person` class will *not* have the `march()` method.

You can also pass `Ember.Mixin` classes to add additional properties to the subclass.

```javascript
App.Person = Ember.Object.extend({
say: function(thing) {
alert(this.get('name') + ' says: ' + thing);
}
});

App.SingingMixin = Ember.Mixin.create({
sing: function(thing){
alert(this.get('name') + ' sings: la la la ' + thing);
}
});

App.BroadwayStar = App.Person.extend(App.SingingMixin, {
dance: function() {
alert(this.get('name') + ' dances: tap tap tap tap ');
}
});
```

The `App.BroadwayStar` class contains three methods: `say()`, `sing()`, and `dance()`.

@method extend
@static

@param {Ember.Mixin} [mixins]* One or more Ember.Mixin classes
@param {Object} [arguments]* Object containing values to use within the new class


function(key) {
    var meta = this.proto()[META_KEY],
        desc = meta && meta.descs[key];

    Ember.assert("metaForProperty() could not find a computed property with key '"+key+"'.", !!desc && desc instanceof Ember.ComputedProperty);
    return desc._meta || {};
  }

In some cases, you may want to annotate computed properties with additional
metadata about how they function or what values they operate on. For
example, computed property functions may close over variables that are then
no longer available for introspection.

You can pass a hash of these values to a computed property like this:

```javascript
person: function() {
var personId = this.get('personId');
return App.Person.create({ id: personId });
}.property().meta({ type: App.Person })
```

Once you've done this, you can retrieve the values saved to the computed
property from your class like this:

```javascript
MyClass.metaForProperty('person');
```

This will return the original hash that was passed to `meta()`.

@method metaForProperty
@param key {String} property name

In some cases you may want to annotate computed properties with additional metadata about how they function or what values they operate on . For example computed property functions may close over variables that are then no longer available for introspection .


function(key, value) {
    var exactValue = function(item) { return get(item, key) === value; },
        hasValue = function(item) { return !!get(item, key); },
        use = (arguments.length === 2 ? exactValue : hasValue);

    return this.reject(use);
  }

function ( key , value ) { var exactValue = function ( item ) { return get ( item , key ) === value ; } , hasValue = function ( item ) { return ! ! get ( item , key ) ; } , use = ( arguments . length === 2 ? exactValue : hasValue ) ; return this . reject ( use ) ; }

Returns an array with the items that do not have truthy values for
key.  You can pass an optional second argument with the target value.  Otherwise
this will match any property that evaluates to false.

@method rejectBy
@param {String} key the property to test
@param {String} [value] optional value to test against.
@return {Array} rejected array

Returns an array with the items that do not have truthy values for key . You can pass an optional second argument with the target value . Otherwise this will match any property that evaluates to false .


function(value) {
    if (!this.contains(value)) return this; // nothing to do
    var ret = Ember.A();
    this.forEach(function(k) {
      if (k !== value) ret[ret.length] = k;
    }) ;
    return ret ;
  }

function
(
value
)
{
if
(
!
this
.
contains
(
value
)
)
return
this
;
// nothing to do
var
ret
=
Ember
.
A
(
)
;
this
.
forEach
(
function
(
k
)
{
if
(
k
!==
value
)
ret
[
ret
.
length
]
=
k
;
}
)
;
return
ret
;
}

Returns a new enumerable that excludes the passed value. The default
implementation returns an array regardless of the receiver type unless
the receiver does not contain the value.

```javascript
var arr = ["a", "b", "a", "c"];
arr.without("a");  // ["b", "c"]
```

@method without
@param {Object} value
@return {Ember.Enumerable}

Returns a new enumerable that excludes the passed value . The default implementation returns an array regardless of the receiver type unless the receiver does not contain the value .


function() {
    var ret = Ember.A();
    this.forEach(function(k) {
      if (a_indexOf(ret, k)<0) ret.push(k);
    });
    return ret;
  }

function ( ) { var ret = Ember . A ( ) ; this . forEach ( function ( k ) { if ( a_indexOf ( ret , k ) < 0 ) ret . push ( k ) ; } ) ; return ret ; }

Returns a new enumerable that contains only unique values. The default
implementation returns an array regardless of the receiver type.

```javascript
var arr = ["a", "a", "b", "b"];
arr.uniq();  // ["a", "b"]
```

@method uniq
@return {Ember.Enumerable}

Returns a new enumerable that contains only unique values . The default implementation returns an array regardless of the receiver type .


function(startIdx, removeAmt, addAmt) {

    // if no args are passed assume everything changes
    if (startIdx===undefined) {
      startIdx = 0;
      removeAmt = addAmt = -1;
    } else {
      if (removeAmt === undefined) removeAmt=-1;
      if (addAmt    === undefined) addAmt=-1;
    }

    // Make sure the @each proxy is set up if anyone is observing @each
    if (Ember.isWatching(this, '@each')) { get(this, '@each'); }

    Ember.sendEvent(this, '@array:before', [this, startIdx, removeAmt, addAmt]);

    var removing, lim;
    if (startIdx>=0 && removeAmt>=0 && get(this, 'hasEnumerableObservers')) {
      removing = [];
      lim = startIdx+removeAmt;
      for(var idx=startIdx;idx<lim;idx++) removing.push(this.objectAt(idx));
    } else {
      removing = removeAmt;
    }

    this.enumerableContentWillChange(removing, addAmt);

    return this;
  }

If you are implementing an object that supports `Ember.Array`, call this
method just before the array content changes to notify any observers and
invalidate any related properties. Pass the starting index of the change
as well as a delta of the amounts to change.

@method arrayContentWillChange
@param {Number} startIdx The starting index in the array that will change.
@param {Number} removeAmt The number of items that will be removed. If you
pass `null` assumes 0
@param {Number} addAmt The number of items that will be added. If you
pass `null` assumes 0.
@return {Ember.Array} receiver

If you are implementing an object that supports Ember . Array call this method just before the array content changes to notify any observers and invalidate any related properties . Pass the starting index of the change as well as a delta of the amounts to change .


function(startIdx, removeAmt, addAmt) {

    // if no args are passed assume everything changes
    if (startIdx===undefined) {
      startIdx = 0;
      removeAmt = addAmt = -1;
    } else {
      if (removeAmt === undefined) removeAmt=-1;
      if (addAmt    === undefined) addAmt=-1;
    }

    var adding, lim;
    if (startIdx>=0 && addAmt>=0 && get(this, 'hasEnumerableObservers')) {
      adding = [];
      lim = startIdx+addAmt;
      for(var idx=startIdx;idx<lim;idx++) adding.push(this.objectAt(idx));
    } else {
      adding = addAmt;
    }

    this.enumerableContentDidChange(removeAmt, adding);
    Ember.sendEvent(this, '@array:change', [this, startIdx, removeAmt, addAmt]);

    var length      = get(this, 'length'),
        cachedFirst = cacheFor(this, 'firstObject'),
        cachedLast  = cacheFor(this, 'lastObject');
    if (this.objectAt(0) !== cachedFirst) {
      Ember.propertyWillChange(this, 'firstObject');
      Ember.propertyDidChange(this, 'firstObject');
    }
    if (this.objectAt(length-1) !== cachedLast) {
      Ember.propertyWillChange(this, 'lastObject');
      Ember.propertyDidChange(this, 'lastObject');
    }

    return this;
  }

If you are implementing an object that supports `Ember.Array`, call this
method just after the array content changes to notify any observers and
invalidate any related properties. Pass the starting index of the change
as well as a delta of the amounts to change.

@method arrayContentDidChange
@param {Number} startIdx The starting index in the array that did change.
@param {Number} removeAmt The number of items that were removed. If you
pass `null` assumes 0
@param {Number} addAmt The number of items that were added. If you
pass `null` assumes 0.
@return {Ember.Array} receiver

If you are implementing an object that supports Ember . Array call this method just after the array content changes to notify any observers and invalidate any related properties . Pass the starting index of the change as well as a delta of the amounts to change .


function ReduceComputedProperty(options) {
  var cp = this;

  this.options = options;

  this._dependentKeys = null;
  // A map of dependentKey -> [itemProperty, ...] that tracks what properties of
  // items in the array we must track to update this property.
  this._itemPropertyKeys = {};
  this._previousItemPropertyKeys = {};

  this.readOnly();
  this.cacheable();

  this.recomputeOnce = function(propertyName) {
    // What we really want to do is coalesce by <cp, propertyName>.
    // We need a form of `scheduleOnce` that accepts an arbitrary token to
    // coalesce by, in addition to the target and method.
    Ember.run.once(this, recompute, propertyName);
  };
  var recompute = function(propertyName) {
    var dependentKeys = cp._dependentKeys,
        meta = cp._instanceMeta(this, propertyName),
        callbacks = cp._callbacks();

    reset.call(this, cp, propertyName);

    meta.dependentArraysObserver.suspendArrayObservers(function () {
      forEach(cp._dependentKeys, function (dependentKey) {
        Ember.assert(
          "dependent array " + dependentKey + " must be an `Ember.Array`.  " +
          "If you are not extending arrays, you will need to wrap native arrays with `Ember.A`",
          !(Ember.isArray(get(this, dependentKey)) && !Ember.Array.detect(get(this, dependentKey))));

        if (!partiallyRecomputeFor(this, dependentKey)) { return; }

        var dependentArray = get(this, dependentKey),
            previousDependentArray = meta.dependentArrays[dependentKey];

        if (dependentArray === previousDependentArray) {
          // The array may be the same, but our item property keys may have
          // changed, so we set them up again.  We can't easily tell if they've
          // changed: the array may be the same object, but with different
          // contents.
          if (cp._previousItemPropertyKeys[dependentKey]) {
            delete cp._previousItemPropertyKeys[dependentKey];
            meta.dependentArraysObserver.setupPropertyObservers(dependentKey, cp._itemPropertyKeys[dependentKey]);
          }
        } else {
          meta.dependentArrays[dependentKey] = dependentArray;

          if (previousDependentArray) {
            meta.dependentArraysObserver.teardownObservers(previousDependentArray, dependentKey);
          }

          if (dependentArray) {
            meta.dependentArraysObserver.setupObservers(dependentArray, dependentKey);
          }
        }
      }, this);
    }, this);

    forEach(cp._dependentKeys, function(dependentKey) {
      if (!partiallyRecomputeFor(this, dependentKey)) { return; }

      var dependentArray = get(this, dependentKey);
      if (dependentArray) {
        addItems.call(this, dependentArray, callbacks, cp, propertyName, meta);
      }
    }, this);
  };

  this.func = function (propertyName) {
    Ember.assert("Computed reduce values require at least one dependent key", cp._dependentKeys);

    recompute.call(this, propertyName);

    return cp._instanceMeta(this, propertyName).getValue();
  };
}

A computed property whose dependent keys are arrays and which is updated with
"one at a time" semantics.

@class ReduceComputedProperty
@namespace Ember
@extends Ember.ComputedProperty
@constructor

A computed property whose dependent keys are arrays and which is updated with one at a time semantics .


function(objects) {
    Ember.beginPropertyChanges(this);
    forEach(objects, function(obj) { this.addObject(obj); }, this);
    Ember.endPropertyChanges(this);
    return this;
  }

function ( objects ) { Ember . beginPropertyChanges ( this ) ; forEach ( objects , function ( obj ) { this . addObject ( obj ) ; } , this ) ; Ember . endPropertyChanges ( this ) ; return this ; }

Adds each object in the passed enumerable to the receiver.

@method addObjects
@param {Ember.Enumerable} objects the objects to add.
@return {Object} receiver

Adds each object in the passed enumerable to the receiver .


function(objects) {
    Ember.beginPropertyChanges(this);
    forEach(objects, function(obj) { this.removeObject(obj); }, this);
    Ember.endPropertyChanges(this);
    return this;
  }

function ( objects ) { Ember . beginPropertyChanges ( this ) ; forEach ( objects , function ( obj ) { this . removeObject ( obj ) ; } , this ) ; Ember . endPropertyChanges ( this ) ; return this ; }

Removes each object in the passed enumerable from the receiver.

@method removeObjects
@param {Ember.Enumerable} objects the objects to remove
@return {Object} receiver

Removes each object in the passed enumerable from the receiver .


function(name) {
    var args = [], i, l;
    for (i = 1, l = arguments.length; i < l; i++) {
      args.push(arguments[i]);
    }
    Ember.sendEvent(this, name, args);
  }

function ( name ) { var args = [ ] , i , l ; for ( i = 1 , l = arguments . length ; i < l ; i ++ ) { args . push ( arguments [ i ] ) ; } Ember . sendEvent ( this , name , args ) ; }

Triggers a named event for the object. Any additional arguments
will be passed as parameters to the functions that are subscribed to the
event.

```javascript
person.on('didEat', function(food) {
console.log('person ate some ' + food);
});

person.trigger('didEat', 'broccoli');

outputs: person ate some broccoli
```
@method trigger
@param {String} name The name of the event
@param {Object...} args Optional arguments to pass on

Triggers a named event for the object . Any additional arguments will be passed as parameters to the functions that are subscribed to the event .


function(resolve, reject, label) {
    var deferred, promise, entity;

    entity = this;
    deferred = get(this, '_deferred');
    promise = deferred.promise;

    function fulfillmentHandler(fulfillment) {
      if (fulfillment === promise) {
        return resolve(entity);
      } else {
        return resolve(fulfillment);
      }
    }

    return promise.then(resolve && fulfillmentHandler, reject, label);
  }

function ( resolve , reject , label ) { var deferred , promise , entity ; entity = this ; deferred = get ( this , '_deferred' ) ; promise = deferred . promise ; function fulfillmentHandler ( fulfillment ) { if ( fulfillment === promise ) { return resolve ( entity ) ; } else { return resolve ( fulfillment ) ; } } return promise . then ( resolve && fulfillmentHandler , reject , label ) ; }

Add handlers to be called when the Deferred object is resolved or rejected.

@method then
@param {Function} resolve a callback function to be called when done
@param {Function} reject  a callback function to be called when failed

Add handlers to be called when the Deferred object is resolved or rejected .


function(value) {
    var deferred, promise;

    deferred = get(this, '_deferred');
    promise = deferred.promise;

    if (value === this) {
      deferred.resolve(promise);
    } else {
      deferred.resolve(value);
    }
  }

function ( value ) { var deferred , promise ; deferred = get ( this , '_deferred' ) ; promise = deferred . promise ; if ( value === this ) { deferred . resolve ( promise ) ; } else { deferred . resolve ( value ) ; } }

Resolve a Deferred object and call any `doneCallbacks` with the given args.

@method resolve

Resolve a Deferred object and call any doneCallbacks with the given args .


function(props) {
    var hashName;

    if (!props._actions) {
      Ember.assert("'actions' should not be a function", typeof(props.actions) !== 'function');

      if (typeOf(props.actions) === 'object') {
        hashName = 'actions';
      } else if (typeOf(props.events) === 'object') {
        Ember.deprecate('Action handlers contained in an `events` object are deprecated in favor of putting them in an `actions` object', false);
        hashName = 'events';
      }

      if (hashName) {
        props._actions = Ember.merge(props._actions || {}, props[hashName]);
      }

      delete props[hashName];
    }
  }

The collection of functions, keyed by name, available on this
`ActionHandler` as action targets.

These functions will be invoked when a matching `{{action}}` is triggered
from within a template and the application's current route is this route.

Actions can also be invoked from other parts of your application
via `ActionHandler#send`.

The `actions` hash will inherit action handlers from
the `actions` hash defined on extended parent classes
or mixins rather than just replace the entire hash, e.g.:

```js
App.CanDisplayBanner = Ember.Mixin.create({
actions: {
displayBanner: function(msg) {
...
}
}
});

App.WelcomeRoute = Ember.Route.extend(App.CanDisplayBanner, {
actions: {
playMusic: function() {
...
}
}
});

`WelcomeRoute`, when active, will be able to respond
to both actions, since the actions hash is merged rather
then replaced when extending mixins / parent classes.
this.send('displayBanner');
this.send('playMusic');
```

Within a Controller, Route, View or Component's action handler,
the value of the `this` context is the Controller, Route, View or
Component object:

```js
App.SongRoute = Ember.Route.extend({
actions: {
myAction: function() {
this.controllerFor("song");
this.transitionTo("other.route");
...
}
}
});
```

It is also possible to call `this._super()` from within an
action handler if it overrides a handler defined on a parent
class or mixin:

Take for example the following routes:

```js
App.DebugRoute = Ember.Mixin.create({
actions: {
debugRouteInformation: function() {
console.debug("trololo");
}
}
});

App.AnnoyingDebugRoute = Ember.Route.extend(App.DebugRoute, {
actions: {
debugRouteInformation: function() {
also call the debugRouteInformation of mixed in App.DebugRoute
this._super();

show additional annoyance
window.alert(...);
}
}
});
```

## Bubbling

By default, an action will stop bubbling once a handler defined
on the `actions` hash handles it. To continue bubbling the action,
you must return `true` from the handler:

```js
App.Router.map(function() {
this.resource("album", function() {
this.route("song");
});
});

App.AlbumRoute = Ember.Route.extend({
actions: {
startPlaying: function() {
}
}
});

App.AlbumSongRoute = Ember.Route.extend({
actions: {
startPlaying: function() {
...

if (actionShouldAlsoBeTriggeredOnParentRoute) {
return true;
}
}
}
});
```

@property actions
@type Hash
@default null

Moves `actions` to `_actions` at extend time. Note that this currently
modifies the mixin themselves, which is technically dubious but
is practically of little consequence. This may change in the future.

@private
@method willMergeMixin

The collection of functions keyed by name available on this ActionHandler as action targets .


function(actionName) {
    var args = [].slice.call(arguments, 1), target;

    if (this._actions && this._actions[actionName]) {
      if (this._actions[actionName].apply(this, args) === true) {
        // handler returned true, so this action will bubble
      } else {
        return;
      }
    } else if (!Ember.FEATURES.isEnabled('ember-routing-drop-deprecated-action-style') && this.deprecatedSend && this.deprecatedSendHandles && this.deprecatedSendHandles(actionName)) {
      Ember.warn("The current default is deprecated but will prefer to handle actions directly on the controller instead of a similarly named action in the actions hash. To turn off this deprecated feature set: Ember.FEATURES['ember-routing-drop-deprecated-action-style'] = true");
      if (this.deprecatedSend.apply(this, [].slice.call(arguments)) === true) {
        // handler return true, so this action will bubble
      } else {
        return;
      }
    }

    if (target = get(this, 'target')) {
      Ember.assert("The `target` for " + this + " (" + target + ") does not have a `send` method", typeof target.send === 'function');
      target.send.apply(target, arguments);
    }
  }

Triggers a named action on the `ActionHandler`. Any parameters
supplied after the `actionName` string will be passed as arguments
to the action target function.

If the `ActionHandler` has its `target` property set, actions may
bubble to the `target`. Bubbling happens when an `actionName` can
not be found in the `ActionHandler`'s `actions` hash or if the
action target function returns `true`.

Example

```js
App.WelcomeRoute = Ember.Route.extend({
actions: {
playTheme: function() {
this.send('playMusic', 'theme.mp3');
},
playMusic: function(track) {
...
}
}
});
```

@method send
@param {String} actionName The action to trigger
@param {*} context a context to send with the action

Triggers a named action on the ActionHandler . Any parameters supplied after the actionName string will be passed as arguments to the action target function .


function (index, newItems) {
    var count = get(newItems, 'length');
    if (count < 1) { return; }

    var match = this._findArrayOperation(index),
        arrayOperation = match.operation,
        arrayOperationIndex = match.index,
        arrayOperationRangeStart = match.rangeStart,
        composeIndex,
        splitIndex,
        splitItems,
        splitArrayOperation,
        newArrayOperation;

    newArrayOperation = new ArrayOperation(INSERT, count, newItems);

    if (arrayOperation) {
      if (!match.split) {
        // insert left of arrayOperation
        this._operations.splice(arrayOperationIndex, 0, newArrayOperation);
        composeIndex = arrayOperationIndex;
      } else {
        this._split(arrayOperationIndex, index - arrayOperationRangeStart, newArrayOperation);
        composeIndex = arrayOperationIndex + 1;
      }
    } else {
      // insert at end
      this._operations.push(newArrayOperation);
      composeIndex = arrayOperationIndex;
    }

    this._composeInsert(composeIndex);
  }

function
(
index
,
newItems
)
{
var
count
=
get
(
newItems
,
'length'
)
;
if
(
count
<
1
)
{
return
;
}
var
match
=
this
.
_findArrayOperation
(
index
)
,
arrayOperation
=
match
.
operation
,
arrayOperationIndex
=
match
.
index
,
arrayOperationRangeStart
=
match
.
rangeStart
,
composeIndex
,
splitIndex
,
splitItems
,
splitArrayOperation
,
newArrayOperation
;
newArrayOperation
=
new
ArrayOperation
(
INSERT
,
count
,
newItems
)
;
if
(
arrayOperation
)
{
if
(
!
match
.
split
)
{
// insert left of arrayOperation
this
.
_operations
.
splice
(
arrayOperationIndex
,
0
,
newArrayOperation
)
;
composeIndex
=
arrayOperationIndex
;
}
else
{
this
.
_split
(
arrayOperationIndex
,
index
arrayOperationRangeStart
,
newArrayOperation
)
;
composeIndex
=
arrayOperationIndex
+
1
;
}
}
else
{
// insert at end
this
.
_operations
.
push
(
newArrayOperation
)
;
composeIndex
=
arrayOperationIndex
;
}
this
.
_composeInsert
(
composeIndex
)
;
}

Track that `newItems` were added to the tracked array at `index`.

@method addItems
@param index
@param newItems

Track that newItems were added to the tracked array at index .


function (index, count) {
    if (count < 1) { return; }

    var match = this._findArrayOperation(index),
        arrayOperation = match.operation,
        arrayOperationIndex = match.index,
        arrayOperationRangeStart = match.rangeStart,
        newArrayOperation,
        composeIndex;

    newArrayOperation = new ArrayOperation(DELETE, count);
    if (!match.split) {
      // insert left of arrayOperation
      this._operations.splice(arrayOperationIndex, 0, newArrayOperation);
      composeIndex = arrayOperationIndex;
    } else {
      this._split(arrayOperationIndex, index - arrayOperationRangeStart, newArrayOperation);
      composeIndex = arrayOperationIndex + 1;
    }

    return this._composeDelete(composeIndex);
  }

function
(
index
,
count
)
{
if
(
count
<
1
)
{
return
;
}
var
match
=
this
.
_findArrayOperation
(
index
)
,
arrayOperation
=
match
.
operation
,
arrayOperationIndex
=
match
.
index
,
arrayOperationRangeStart
=
match
.
rangeStart
,
newArrayOperation
,
composeIndex
;
newArrayOperation
=
new
ArrayOperation
(
DELETE
,
count
)
;
if
(
!
match
.
split
)
{
// insert left of arrayOperation
this
.
_operations
.
splice
(
arrayOperationIndex
,
0
,
newArrayOperation
)
;
composeIndex
=
arrayOperationIndex
;
}
else
{
this
.
_split
(
arrayOperationIndex
,
index
arrayOperationRangeStart
,
newArrayOperation
)
;
composeIndex
=
arrayOperationIndex
+
1
;
}
return
this
.
_composeDelete
(
composeIndex
)
;
}

Track that `count` items were removed at `index`.

@method removeItems
@param index
@param count

Track that count items were removed at index .


function (index) {
    var newArrayOperation = this._operations[index],
        leftArrayOperation = this._operations[index-1], // may be undefined
        rightArrayOperation = this._operations[index+1], // may be undefined
        leftOp = leftArrayOperation && leftArrayOperation.type,
        rightOp = rightArrayOperation && rightArrayOperation.type;

    if (leftOp === INSERT) {
        // merge left
        leftArrayOperation.count += newArrayOperation.count;
        leftArrayOperation.items = leftArrayOperation.items.concat(newArrayOperation.items);

      if (rightOp === INSERT) {
        // also merge right (we have split an insert with an insert)
        leftArrayOperation.count += rightArrayOperation.count;
        leftArrayOperation.items = leftArrayOperation.items.concat(rightArrayOperation.items);
        this._operations.splice(index, 2);
      } else {
        // only merge left
        this._operations.splice(index, 1);
      }
    } else if (rightOp === INSERT) {
      // merge right
      newArrayOperation.count += rightArrayOperation.count;
      newArrayOperation.items = newArrayOperation.items.concat(rightArrayOperation.items);
      this._operations.splice(index + 1, 1);
    }
  }

see SubArray for a better implementation.

see SubArray for a better implementation .


function ArrayOperation (operation, count, items) {
  this.type = operation; // RETAIN | INSERT | DELETE
  this.count = count;
  this.items = items;
}

function
ArrayOperation
(
operation
,
count
,
items
)
{
this
.
type
=
operation
;
// RETAIN | INSERT | DELETE
this
.
count
=
count
;
this
.
items
=
items
;
}

Internal data structure to represent an array operation.

@method ArrayOperation
@private
@param {string} type The type of the operation.  One of
`Ember.TrackedArray.{RETAIN, INSERT, DELETE}`
@param {number} count The number of items in this operation.
@param {array} items The items of the operation, if included.  RETAIN and
INSERT include their items, DELETE does not.

Internal data structure to represent an array operation .


function ArrayOperationMatch(operation, index, split, rangeStart) {
  this.operation = operation;
  this.index = index;
  this.split = split;
  this.rangeStart = rangeStart;
}

function ArrayOperationMatch ( operation , index , split , rangeStart ) { this . operation = operation ; this . index = index ; this . split = split ; this . rangeStart = rangeStart ; }

Internal data structure used to include information when looking up operations
by item index.

@method ArrayOperationMatch
@private
@param {ArrayOperation} operation
@param {number} index The index of `operation` in the array of operations.
@param {boolean} split Whether or not the item index searched for would
require a split for a new operation type.
@param {number} rangeStart The index of the first item in the operation,
with respect to the tracked array.  The index of the last item can be computed
from `rangeStart` and `operation.count`.

Internal data structure used to include information when looking up operations by item index .


function(index, match) {
    var returnValue = -1,
        itemType = match ? RETAIN : FILTER,
        self = this;

    this._findOperation(index, function(operation, operationIndex, rangeStart, rangeEnd, seenInSubArray) {
      var newOperation, splitOperation;

      if (itemType === operation.type) {
        ++operation.count;
      } else if (index === rangeStart) {
        // insert to the left of `operation`
        self._operations.splice(operationIndex, 0, new Operation(itemType, 1));
      } else {
        newOperation = new Operation(itemType, 1);
        splitOperation = new Operation(operation.type, rangeEnd - index + 1);
        operation.count = index - rangeStart;

        self._operations.splice(operationIndex + 1, 0, newOperation, splitOperation);
      }

      if (match) {
        if (operation.type === RETAIN) {
          returnValue = seenInSubArray + (index - rangeStart);
        } else {
          returnValue = seenInSubArray;
        }
      }

      self._composeAt(operationIndex);
    }, function(seenInSubArray) {
      self._operations.push(new Operation(itemType, 1));

      if (match) {
        returnValue = seenInSubArray;
      }

      self._composeAt(self._operations.length-1);
    });

    return returnValue;
  }

function
(
index
,
match
)
{
var
returnValue
=
1
,
itemType
=
match
RETAIN
:
FILTER
,
self
=
this
;
this
.
_findOperation
(
index
,
function
(
operation
,
operationIndex
,
rangeStart
,
rangeEnd
,
seenInSubArray
)
{
var
newOperation
,
splitOperation
;
if
(
itemType
===
operation
.
type
)
{
++
operation
.
count
;
}
else
if
(
index
===
rangeStart
)
{
// insert to the left of `operation`
self
.
_operations
.
splice
(
operationIndex
,
0
,
new
Operation
(
itemType
,
1
)
)
;
}
else
{
newOperation
=
new
Operation
(
itemType
,
1
)
;
splitOperation
=
new
Operation
(
operation
.
type
,
rangeEnd
index
+
1
)
;
operation
.
count
=
index
rangeStart
;
self
.
_operations
.
splice
(
operationIndex
+
1
,
0
,
newOperation
,
splitOperation
)
;
}
if
(
match
)
{
if
(
operation
.
type
===
RETAIN
)
{
returnValue
=
seenInSubArray
+
(
index
rangeStart
)
;
}
else
{
returnValue
=
seenInSubArray
;
}
}
self
.
_composeAt
(
operationIndex
)
;
}
,
function
(
seenInSubArray
)
{
self
.
_operations
.
push
(
new
Operation
(
itemType
,
1
)
)
;
if
(
match
)
{
returnValue
=
seenInSubArray
;
}
self
.
_composeAt
(
self
.
_operations
.
length
1
)
;
}
)
;
return
returnValue
;
}

Track that an item was added to the tracked array.

@method addItem

@param {number} index The index of the item in the tracked array.
@param {boolean} match `true` iff the item is included in the subarray.

@return {number} The index of the item in the subarray.

Track that an item was added to the tracked array .


function(index) {
    var returnValue = -1,
        self = this;

    this._findOperation(index, function (operation, operationIndex, rangeStart, rangeEnd, seenInSubArray) {
      if (operation.type === RETAIN) {
        returnValue = seenInSubArray + (index - rangeStart);
      }

      if (operation.count > 1) {
        --operation.count;
      } else {
        self._operations.splice(operationIndex, 1);
        self._composeAt(operationIndex);
      }
    }, function() {
      throw new Ember.Error("Can't remove an item that has never been added.");
    });

    return returnValue;
  }

Track that an item was removed from the tracked array.

@method removeItem

@param {number} index The index of the item in the tracked array.

@return {number} The index of the item in the subarray, or `-1` if the item
was not in the subarray.

Track that an item was removed from the tracked array .


function(keyName, value) {
    var ret;
    ret = new EachArray(this._content, keyName, this);
    Ember.defineProperty(this, keyName, null, ret);
    this.beginObservingContentKey(keyName);
    return ret;
  }

function ( keyName , value ) { var ret ; ret = new EachArray ( this . _content , keyName , this ) ; Ember . defineProperty ( this , keyName , null , ret ) ; this . beginObservingContentKey ( keyName ) ; return ret ; }

You can directly access mapped properties by simply requesting them.
The `unknownProperty` handler will generate an EachArray of each item.

@method unknownProperty
@param keyName {String}
@param value {*}

You can directly access mapped properties by simply requesting them . The unknownProperty handler will generate an EachArray of each item .


function(idx, amt, objects) {

    if (this.isFrozen) throw Ember.FROZEN_ERROR;

    // if we replaced exactly the same number of items, then pass only the
    // replaced range. Otherwise, pass the full remaining array length
    // since everything has shifted
    var len = objects ? get(objects, 'length') : 0;
    this.arrayContentWillChange(idx, amt, len);

    if (len === 0) {
      this.splice(idx, amt);
    } else {
      replace(this, idx, amt, objects);
    }

    this.arrayContentDidChange(idx, amt, len);
    return this;
  }


function() {
    if (this.isFrozen) { throw new Ember.Error(Ember.FROZEN_ERROR); }

    var len = get(this, 'length');
    if (len === 0) { return this; }

    var guid;

    this.enumerableContentWillChange(len, 0);
    Ember.propertyWillChange(this, 'firstObject');
    Ember.propertyWillChange(this, 'lastObject');

    for (var i=0; i < len; i++) {
      guid = guidFor(this[i]);
      delete this[guid];
      delete this[i];
    }

    set(this, 'length', 0);

    Ember.propertyDidChange(this, 'firstObject');
    Ember.propertyDidChange(this, 'lastObject');
    this.enumerableContentDidChange(len, 0);

    return this;
  }

function ( ) { if ( this . isFrozen ) { throw new Ember . Error ( Ember . FROZEN_ERROR ) ; } var len = get ( this , 'length' ) ; if ( len === 0 ) { return this ; } var guid ; this . enumerableContentWillChange ( len , 0 ) ; Ember . propertyWillChange ( this , 'firstObject' ) ; Ember . propertyWillChange ( this , 'lastObject' ) ; for ( var i = 0 ; i < len ; i ++ ) { guid = guidFor ( this [ i ] ) ; delete this [ guid ] ; delete this [ i ] ; } set ( this , 'length' , 0 ) ; Ember . propertyDidChange ( this , 'firstObject' ) ; Ember . propertyDidChange ( this , 'lastObject' ) ; this . enumerableContentDidChange ( len , 0 ) ; return this ; }

Clears the set. This is useful if you want to reuse an existing set
without having to recreate it.

```javascript
var colors = new Ember.Set(["red", "green", "blue"]);
colors.length;  // 3
colors.clear();
colors.length;  // 0
```

@method clear
@return {Ember.Set} An empty Set

Clears the set . This is useful if you want to reuse an existing set without having to recreate it .


function() {
    if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
    var obj = this.length > 0 ? this[this.length-1] : null;
    this.remove(obj);
    return obj;
  }

function ( ) { if ( get ( this , 'isFrozen' ) ) throw new Ember . Error ( Ember . FROZEN_ERROR ) ; var obj = this . length > 0 ? this [ this . length - 1 ] : null ; this . remove ( obj ) ; return obj ; }

Removes the last element from the set and returns it, or `null` if it's empty.

```javascript
var colors = new Ember.Set(["green", "blue"]);
colors.pop();  // "blue"
colors.pop();  // "green"
colors.pop();  // null
```

@method pop
@return {Object} The removed object from the set or null.

Removes the last element from the set and returns it or null if it s empty .


function(element, id) {
  if (element.getAttribute('id') === id) { return element; }

  var len = element.childNodes.length, idx, node, found;
  for (idx=0; idx<len; idx++) {
    node = element.childNodes[idx];
    found = node.nodeType === 1 && findChildById(node, id);
    if (found) { return found; }
  }
}

function ( element , id ) { if ( element . getAttribute ( 'id' ) === id ) { return element ; } var len = element . childNodes . length , idx , node , found ; for ( idx = 0 ; idx < len ; idx ++ ) { node = element . childNodes [ idx ] ; found = node . nodeType === 1 && findChildById ( node , id ) ; if ( found ) { return found ; } } }

Use this to find children by ID instead of using jQuery


function(className) {
    // lazily create elementClasses
    this.elementClasses = (this.elementClasses || new ClassSet());
    this.elementClasses.add(className);
    this.classes = this.elementClasses.list;

    return this;
  }

function
(
className
)
{
// lazily create elementClasses
this
.
elementClasses
=
(
this
.
elementClasses
||
new
ClassSet
(
)
)
;
this
.
elementClasses
.
add
(
className
)
;
this
.
classes
=
this
.
elementClasses
.
list
;
return
this
;
}

Adds a class to the buffer, which will be rendered to the class attribute.

@method addClass
@param {String} className Class name to add to the buffer
@chainable

Adds a class to the buffer which will be rendered to the class attribute .


function(name, value) {
    var attributes = this.elementAttributes = (this.elementAttributes || {});

    if (arguments.length === 1) {
      return attributes[name];
    } else {
      attributes[name] = value;
    }

    return this;
  }

function ( name , value ) { var attributes = this . elementAttributes = ( this . elementAttributes || { } ) ; if ( arguments . length === 1 ) { return attributes [ name ] ; } else { attributes [ name ] = value ; } return this ; }

duck type attribute functionality like jQuery so a render buffer can be used like a jQuery object in attribute binding scenarios.
Adds an attribute which will be rendered to the element.

@method attr
@param {String} name The name of the attribute
@param {String} value The value to add to the attribute
@chainable
@return {Ember.RenderBuffer|String} this or the current attribute value

duck type attribute functionality like jQuery so a render buffer can be used like a jQuery object in attribute binding scenarios . Adds an attribute which will be rendered to the element .


function(name, value) {
    var properties = this.elementProperties = (this.elementProperties || {});

    if (arguments.length === 1) {
      return properties[name];
    } else {
      properties[name] = value;
    }

    return this;
  }

function ( name , value ) { var properties = this . elementProperties = ( this . elementProperties || { } ) ; if ( arguments . length === 1 ) { return properties [ name ] ; } else { properties [ name ] = value ; } return this ; }

Adds a property which will be rendered to the element.

@method prop
@param {String} name The name of the property
@param {String} value The value to add to the property
@chainable
@return {Ember.RenderBuffer|String} this or the current property value

Adds a property which will be rendered to the element .


function() {
    if (this._hasElement && this._element) {
      // Firefox versions < 11 do not have support for element.outerHTML.
      var thisElement = this.element(), outerHTML = thisElement.outerHTML;
      if (typeof outerHTML === 'undefined') {
        return Ember.$('<div/>').append(thisElement).html();
      }
      return outerHTML;
    } else {
      return this.innerString();
    }
  }

Generates the HTML content for this buffer.

@method string
@return {String} The generated HTML

Generates the HTML content for this buffer .


function(addedEvents, rootElement) {
    var event, events = get(this, 'events');

    Ember.$.extend(events, addedEvents || {});

    if (!Ember.isNone(rootElement)) {
      set(this, 'rootElement', rootElement);
    }

    rootElement = Ember.$(get(this, 'rootElement'));

    Ember.assert(fmt('You cannot use the same root element (%@) multiple times in an Ember.Application', [rootElement.selector || rootElement[0].tagName]), !rootElement.is('.ember-application'));
    Ember.assert('You cannot make a new Ember.Application using a root element that is a descendent of an existing Ember.Application', !rootElement.closest('.ember-application').length);
    Ember.assert('You cannot make a new Ember.Application using a root element that is an ancestor of an existing Ember.Application', !rootElement.find('.ember-application').length);

    rootElement.addClass('ember-application');

    Ember.assert('Unable to add "ember-application" class to rootElement. Make sure you set rootElement to the body or an element in the body.', rootElement.is('.ember-application'));

    for (event in events) {
      if (events.hasOwnProperty(event)) {
        this.setupHandler(rootElement, event, events[event]);
      }
    }
  }

Sets up event listeners for standard browser events.

This will be called after the browser sends a `DOMContentReady` event. By
default, it will set up all of the listeners on the document body. If you
would like to register the listeners on a different element, set the event
dispatcher's `root` property.

@private
@method setup
@param addedEvents {Hash}

Sets up event listeners for standard browser events .


function(rootElement, event, eventName) {
    var self = this;

    rootElement.on(event + '.ember', '.ember-view', function(evt, triggeringManager) {
      var view = Ember.View.views[this.id],
          result = true, manager = null;

      manager = self._findNearestEventManager(view, eventName);

      if (manager && manager !== triggeringManager) {
        result = self._dispatchEvent(manager, evt, eventName, view);
      } else if (view) {
        result = self._bubbleEvent(view, evt, eventName);
      } else {
        evt.stopPropagation();
      }

      return result;
    });

    rootElement.on(event + '.ember', '[data-ember-action]', function(evt) {
      var actionId = Ember.$(evt.currentTarget).attr('data-ember-action'),
          action   = Ember.Handlebars.ActionHelper.registeredActions[actionId];

      // We have to check for action here since in some cases, jQuery will trigger
      // an event on `removeChild` (i.e. focusout) after we've already torn down the
      // action handlers for the view.
      if (action && action.eventName === eventName) {
        return action.handler(evt);
      }
    });
  }

Registers an event listener on the document. If the given event is
triggered, the provided event handler will be triggered on the target view.

If the target view does not implement the event handler, or if the handler
returns `false`, the parent view will be called. The event will continue to
bubble to each successive parent view until it reaches the top.

For example, to have the `mouseDown` method called on the target view when
a `mousedown` event is received from the browser, do the following:

```javascript
setupHandler('mousedown', 'mouseDown');
```

@private
@method setupHandler
@param {Element} rootElement
@param {String} event the browser-originated event to listen to
@param {String} eventName the name of the method to call on the view

Registers an event listener on the document . If the given event is triggered the provided event handler will be triggered on the target view .


function(klass) {
    Ember.deprecate("nearestInstanceOf is deprecated and will be removed from future releases. Use nearestOfType.");
    var view = get(this, 'parentView');

    while (view) {
      if (view instanceof klass) { return view; }
      view = get(view, 'parentView');
    }
  }

Return the nearest ancestor that is an instance of the provided
class.

@method nearestInstanceOf
@param {Class} klass Subclass of Ember.View (or Ember.View itself)
@return Ember.View
@deprecated

Return the nearest ancestor that is an instance of the provided class .


function(property) {
    var view = get(this, 'parentView');

    while (view) {
      if (property in view) { return view; }
      view = get(view, 'parentView');
    }
  }

function ( property ) { var view = get ( this , 'parentView' ) ; while ( view ) { if ( property in view ) { return view ; } view = get ( view , 'parentView' ) ; } }

Return the nearest ancestor that has a given property.

@function nearestWithProperty
@param {String} property A property name
@return Ember.View

Return the nearest ancestor that has a given property .


function(klass) {
    var view = get(this, 'parentView');

    while (view) {
      if (get(view, 'parentView') instanceof klass) { return view; }
      view = get(view, 'parentView');
    }
  }

function ( klass ) { var view = get ( this , 'parentView' ) ; while ( view ) { if ( get ( view , 'parentView' ) instanceof klass ) { return view ; } view = get ( view , 'parentView' ) ; } }

Return the nearest ancestor whose parent is an instance of
`klass`.

@method nearestChildOf
@param {Class} klass Subclass of Ember.View (or Ember.View itself)
@return Ember.View

Return the nearest ancestor whose parent is an instance of klass .


function(buffer) {
    // If this view has a layout, it is the responsibility of the
    // the layout to render the view's template. Otherwise, render the template
    // directly.
    var template = get(this, 'layout') || get(this, 'template');

    if (template) {
      var context = get(this, 'context');
      var keywords = this.cloneKeywords();
      var output;

      var data = {
        view: this,
        buffer: buffer,
        isRenderData: true,
        keywords: keywords,
        insideGroup: get(this, 'templateData.insideGroup')
      };

      // Invoke the template with the provided template context, which
      // is the view's controller by default. A hash of data is also passed that provides
      // the template with access to the view and render buffer.

      Ember.assert('template must be a function. Did you mean to call Ember.Handlebars.compile("...") or specify templateName instead?', typeof template === 'function');
      // The template should write directly to the render buffer instead
      // of returning a string.
      output = template(context, { data: data });

      // If the template returned a string instead of writing to the buffer,
      // push the string onto the buffer.
      if (output !== undefined) { buffer.push(output); }
    }
  }

Called on your view when it should push strings of HTML into a
`Ember.RenderBuffer`. Most users will want to override the `template`
or `templateName` properties instead of this method.

By default, `Ember.View` will look for a function in the `template`
property and invoke it with the value of `context`. The value of
`context` will be the view's controller unless you override it.

@method render
@param {Ember.RenderBuffer} buffer The render buffer

Called on your view when it should push strings of HTML into a Ember . RenderBuffer . Most users will want to override the template or templateName properties instead of this method .


function() {
        // Get the current value of the property
        newClass = this._classStringForProperty(binding);
        elem = this.$();

        // If we had previously added a class to the element, remove it.
        if (oldClass) {
          elem.removeClass(oldClass);
          // Also remove from classNames so that if the view gets rerendered,
          // the class doesn't get added back to the DOM.
          classNames.removeObject(oldClass);
        }

        // If necessary, add a new class. Make sure we keep track of it so
        // it can be removed in the future.
        if (newClass) {
          elem.addClass(newClass);
          oldClass = newClass;
        } else {
          oldClass = null;
        }
      }

Set up an observer on the context. If the property changes, toggle the class name.

Set up an observer on the context . If the property changes toggle the class name .


function(buffer, attributeBindings) {
    var attributeValue,
        unspecifiedAttributeBindings = this._unspecifiedAttributeBindings = this._unspecifiedAttributeBindings || {};

    a_forEach(attributeBindings, function(binding) {
      var split = binding.split(':'),
          property = split[0],
          attributeName = split[1] || property;

      if (property in this) {
        this._setupAttributeBindingObservation(property, attributeName);

        // Determine the current value and add it to the render buffer
        // if necessary.
        attributeValue = get(this, property);
        Ember.View.applyAttributeBindings(buffer, attributeName, attributeValue);
      } else {
        unspecifiedAttributeBindings[property] = attributeName;
      }
    }, this);

    // Lazily setup setUnknownProperty after attributeBindings are initially applied
    this.setUnknownProperty = this._setUnknownProperty;
  }

Iterates through the view's attribute bindings, sets up observers for each,
then applies the current value of the attributes to the passed render buffer.

@method _applyAttributeBindings
@param {Ember.RenderBuffer} buffer
@private

Iterates through the view s attribute bindings sets up observers for each then applies the current value of the attributes to the passed render buffer .


function(key, value) {
    var attributeName = this._unspecifiedAttributeBindings && this._unspecifiedAttributeBindings[key];
    if (attributeName) {
      this._setupAttributeBindingObservation(key, attributeName);
    }

    defineProperty(this, key);
    return set(this, key, value);
  }

function ( key , value ) { var attributeName = this . _unspecifiedAttributeBindings && this . _unspecifiedAttributeBindings [ key ] ; if ( attributeName ) { this . _setupAttributeBindingObservation ( key , attributeName ) ; } defineProperty ( this , key ) ; return set ( this , key , value ) ; }

Gets defined after initialization by _applyAttributeBindings


function(path) {
    var split = path.split(':'),
        propertyPath = split[0],
        classNames = "",
        className,
        falsyClassName;

    // check if the property is defined as prop:class or prop:trueClass:falseClass
    if (split.length > 1) {
      className = split[1];
      if (split.length === 3) { falsyClassName = split[2]; }

      classNames = ':' + className;
      if (falsyClassName) { classNames += ":" + falsyClassName; }
    }

    return {
      path: propertyPath,
      classNames: classNames,
      className: (className === '') ? undefined : className,
      falsyClassName: falsyClassName
    };
  }

Parse a path and return an object which holds the parsed properties.

For example a path like "content.isEnabled:enabled:disabled" will return the
following object:

```javascript
{
path: "content.isEnabled",
className: "enabled",
falsyClassName: "disabled",
classNames: ":enabled:disabled"
}
```

@method _parsePropertyPath
@static
@private

Parse a path and return an object which holds the parsed properties .


function(view, childView, options) {
    var buffer = view.buffer, _childViews = view._childViews;

    childView = view.createChildView(childView, options);
    if (!_childViews.length) { _childViews = view._childViews = _childViews.slice(); }
    _childViews.push(childView);

    childView.renderToBuffer(buffer);

    view.propertyDidChange('childViews');

    return childView;
  }

function ( view , childView , options ) { var buffer = view . buffer , _childViews = view . _childViews ; childView = view . createChildView ( childView , options ) ; if ( ! _childViews . length ) { _childViews = view . _childViews = _childViews . slice ( ) ; } _childViews . push ( childView ) ; childView . renderToBuffer ( buffer ) ; view . propertyDidChange ( 'childViews' ) ; return childView ; }

when a view is rendered in a buffer, appending a child view will render that view and append the resulting buffer into its buffer.

when a view is rendered in a buffer appending a child view will render that view and append the resulting buffer into its buffer .


function(view) {
    view.clearBuffer();
    var viewCollection = view._notifyWillDestroyElement();
    viewCollection.transitionTo('preRender', false);

    return view;
  }

function ( view ) { view . clearBuffer ( ) ; var viewCollection = view . _notifyWillDestroyElement ( ) ; viewCollection . transitionTo ( 'preRender' , false ) ; return view ; }

when a view is rendered in a buffer, destroying the element will simply destroy the buffer and put the state back into the preRender state.

when a view is rendered in a buffer destroying the element will simply destroy the buffer and put the state back into the preRender state .


function(view) {
    view.triggerRecursively('willClearRender');

    view.clearRenderedChildren();

    view.domManager.replace(view);
    return view;
  }

function ( view ) { view . triggerRecursively ( 'willClearRender' ) ; view . clearRenderedChildren ( ) ; view . domManager . replace ( view ) ; return view ; }

once the view has been inserted into the DOM, rerendering is deferred to allow bindings to synchronize.

once the view has been inserted into the DOM rerendering is deferred to allow bindings to synchronize .


function(view) {
    view._notifyWillDestroyElement();
    view.domManager.remove(view);
    set(view, 'element', null);
    if (view._scheduledInsert) {
      Ember.run.cancel(view._scheduledInsert);
      view._scheduledInsert = null;
    }
    return view;
  }

function ( view ) { view . _notifyWillDestroyElement ( ) ; view . domManager . remove ( view ) ; set ( view , 'element' , null ) ; if ( view . _scheduledInsert ) { Ember . run . cancel ( view . _scheduledInsert ) ; view . _scheduledInsert = null ; } return view ; }

once the view is already in the DOM, destroying it removes it from the DOM, nukes its element, and puts it back into the preRender state if inDOM.

once the view is already in the DOM destroying it removes it from the DOM nukes its element and puts it back into the preRender state if inDOM .


function(view, eventName, evt) {
    if (view.has(eventName)) {
      // Handler should be able to re-dispatch events, so we don't
      // preventDefault or stopPropagation.
      return view.trigger(eventName, evt);
    } else {
      return true; // continue event propagation
    }
  }

Handle events from `Ember.EventDispatcher`

Handle events from Ember . EventDispatcher


function(views, start, removed) {
    this.propertyWillChange('childViews');

    if (removed > 0) {
      var changedViews = views.slice(start, start+removed);
      // transition to preRender before clearing parentView
      this.currentState.childViewsWillChange(this, views, start, removed);
      this.initializeViews(changedViews, null, null);
    }
  }

When a child view is removed, destroy its element so that
it is removed from the DOM.

The array observer that triggers this action is set up in the
`renderToBuffer` method.

@private
@method childViewsWillChange
@param {Ember.Array} views the child views array before mutation
@param {Number} start the start position of the mutation
@param {Number} removed the number of child views removed

When a child view is removed destroy its element so that it is removed from the DOM .


function(views, start, removed, added) {
    if (added > 0) {
      var changedViews = views.slice(start, start+added);
      this.initializeViews(changedViews, this, get(this, 'templateData'));
      this.currentState.childViewsDidChange(this, views, start, added);
    }
    this.propertyDidChange('childViews');
  }

function ( views , start , removed , added ) { if ( added > 0 ) { var changedViews = views . slice ( start , start + added ) ; this . initializeViews ( changedViews , this , get ( this , 'templateData' ) ) ; this . currentState . childViewsDidChange ( this , views , start , added ) ; } this . propertyDidChange ( 'childViews' ) ; }

When a child view is added, make sure the DOM gets updated appropriately.

If the view has already rendered an element, we tell the child view to
create an element and insert it into the DOM. If the enclosing container
view has already written to a buffer, but not yet converted that buffer
into an element, we insert the string representation of the child into the
appropriate place in the buffer.

@private
@method childViewsDidChange
@param {Ember.Array} views the array of child views afte the mutation has occurred
@param {Number} start the start position of the mutation
@param {Number} removed the number of child views removed
@param {Number} the number of child views added

When a child view is added make sure the DOM gets updated appropriately .


function(content, start, removedCount) {
    // If the contents were empty before and this template collection has an
    // empty view remove it now.
    var emptyView = get(this, 'emptyView');
    if (emptyView && emptyView instanceof Ember.View) {
      emptyView.removeFromParent();
    }

    // Loop through child views that correspond with the removed items.
    // Note that we loop from the end of the array to the beginning because
    // we are mutating it as we go.
    var childViews = this._childViews, childView, idx, len;

    len = this._childViews.length;

    var removingAll = removedCount === len;

    if (removingAll) {
      this.currentState.empty(this);
      this.invokeRecursively(function(view) {
        view.removedFromDOM = true;
      }, false);
    }

    for (idx = start + removedCount - 1; idx >= start; idx--) {
      childView = childViews[idx];
      childView.destroy();
    }
  }

Called when a mutation to the underlying content array will occur.

This method will remove any views that are no longer in the underlying
content array.

Invokes whenever the content array itself will change.

@method arrayWillChange
@param {Array} content the managed collection of objects
@param {Number} start the index at which the changes will occurr
@param {Number} removed number of object to be removed from content

Called when a mutation to the underlying content array will occur .


function(content, start, removed, added) {
    var addedViews = [], view, item, idx, len, itemViewClass,
      emptyView;

    len = content ? get(content, 'length') : 0;

    if (len) {
      itemViewClass = get(this, 'itemViewClass');

      if ('string' === typeof itemViewClass) {
        itemViewClass = get(itemViewClass) || itemViewClass;
      }

      Ember.assert(fmt("itemViewClass must be a subclass of Ember.View, not %@",
                       [itemViewClass]),
                       'string' === typeof itemViewClass || Ember.View.detect(itemViewClass));

      for (idx = start; idx < start+added; idx++) {
        item = content.objectAt(idx);

        view = this.createChildView(itemViewClass, {
          content: item,
          contentIndex: idx
        });

        addedViews.push(view);
      }
    } else {
      emptyView = get(this, 'emptyView');

      if (!emptyView) { return; }

      if ('string' === typeof emptyView) {
        emptyView = get(emptyView) || emptyView;
      }

      emptyView = this.createChildView(emptyView);
      addedViews.push(emptyView);
      set(this, 'emptyView', emptyView);

      if (Ember.CoreView.detect(emptyView)) {
        this._createdEmptyView = emptyView;
      }
    }

    this.replace(start, 0, addedViews);
  }

Called when a mutation to the underlying content array occurs.

This method will replay that mutation against the views that compose the
`Ember.CollectionView`, ensuring that the view reflects the model.

This array observer is added in `contentDidChange`.

@method arrayDidChange
@param {Array} content the managed collection of objects
@param {Number} start the index at which the changes occurred
@param {Number} removed number of object removed from content
@param {Number} added number of object added to content

Called when a mutation to the underlying content array occurs .


function(action) {
    var actionName,
        contexts = a_slice.call(arguments, 1);

    // Send the default action
    if (action === undefined) {
      actionName = get(this, 'action');
      Ember.assert("The default action was triggered on the component " + this.toString() +
                   ", but the action name (" + actionName + ") was not a string.",
                   isNone(actionName) || typeof actionName === 'string');
    } else {
      actionName = get(this, action);
      Ember.assert("The " + action + " action was triggered on the component " +
                   this.toString() + ", but the action name (" + actionName +
                   ") was not a string.",
                   isNone(actionName) || typeof actionName === 'string');
    }

    // If no action name for that action could be found, just abort.
    if (actionName === undefined) { return; }

    this.triggerAction({
      action: actionName,
      actionContext: contexts
    });
  }

Triggers a named action on the controller context where the component is used if
this controller has registered for notifications of the action.

For example a component for playing or pausing music may translate click events
into action notifications of "play" or "stop" depending on some internal state
of the component:

```javascript
App.PlayButtonComponent = Ember.Component.extend({
click: function(){
if (this.get('isPlaying')) {
this.sendAction('play');
} else {
this.sendAction('stop');
}
}
});
```

When used inside a template these component actions are configured to
trigger actions in the outer application context:

```handlebars
{{! application.hbs }}
{{play-button play="musicStarted" stop="musicStopped"}}
```

When the component receives a browser `click` event it translate this
interaction into application-specific semantics ("play" or "stop") and
triggers the specified action name on the controller for the template
where the component is used:

```javascript
App.ApplicationController = Ember.Controller.extend({
actions: {
musicStarted: function(){
called when the play button is clicked
and the music started playing
},
musicStopped: function(){
called when the play button is clicked
and the music stopped playing
}
}
});
```

If no action name is passed to `sendAction` a default name of "action"
is assumed.

```javascript
App.NextButtonComponent = Ember.Component.extend({
click: function(){
this.sendAction();
}
});
```

```handlebars
{{! application.hbs }}
{{next-button action="playNextSongInAlbum"}}
```

```javascript
App.ApplicationController = Ember.Controller.extend({
actions: {
playNextSongInAlbum: function(){
...
}
}
});
```

@method sendAction
@param [action] {String} the action to trigger
@param [context] {*} a context to send with the action

Triggers a named action on the controller context where the component is used if this controller has registered for notifications of the action .


function evaluateUnboundHelper(context, fn, normalizedProperties, options) {
  var args = [],
   hash = options.hash,
   boundOptions = hash.boundOptions,
   types = slice.call(options.types, 1),
   loc,
   len,
   property,
   propertyType,
   boundOption;

  for (boundOption in boundOptions) {
    if (!boundOptions.hasOwnProperty(boundOption)) { continue; }
    hash[boundOption] = Ember.Handlebars.get(context, boundOptions[boundOption], options);
  }

  for(loc = 0, len = normalizedProperties.length; loc < len; ++loc) {
    property = normalizedProperties[loc];
    propertyType = types[loc];
    if(propertyType === "ID") {
      args.push(Ember.Handlebars.get(property.root, property.path, options));
    } else {
      args.push(property.path);
    }
  }
  args.push(options);
  return fn.apply(context, args);
}

function evaluateUnboundHelper ( context , fn , normalizedProperties , options ) { var args = [ ] , hash = options . hash , boundOptions = hash . boundOptions , types = slice . call ( options . types , 1 ) , loc , len , property , propertyType , boundOption ; for ( boundOption in boundOptions ) { if ( ! boundOptions . hasOwnProperty ( boundOption ) ) { continue ; } hash [ boundOption ] = Ember . Handlebars . get ( context , boundOptions [ boundOption ] , options ) ; } for ( loc = 0 , len = normalizedProperties . length ; loc < len ; ++ loc ) { property = normalizedProperties [ loc ] ; propertyType = types [ loc ] ; if ( propertyType === "ID" ) { args . push ( Ember . Handlebars . get ( property . root , property . path , options ) ) ; } else { args . push ( property . path ) ; } } args . push ( options ) ; return fn . apply ( context , args ) ; }

Renders the unbound form of an otherwise bound helper function.

@private
@method evaluateUnboundHelper
@param {Function} fn
@param {Object} context
@param {Array} normalizedProperties
@param {String} options

Renders the unbound form of an otherwise bound helper function .