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
    };
  }

function ( path ) { var split = path . split ( ':' ) , propertyPath = split [ 0 ] , classNames = "" , className , falsyClassName ; 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
    }
  }

function ( view , eventName , evt ) { if ( view . has ( eventName ) ) { return view . trigger ( eventName , evt ) ; } else { return true ; } }

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);
    }
  }

function ( views , start , removed ) { this . propertyWillChange ( 'childViews' ) ; if ( removed > 0 ) { var changedViews = views . slice ( start , start + removed ) ; 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();
    }
  }

function ( content , start , removedCount ) { var emptyView = get ( this , 'emptyView' ) ; if ( emptyView && emptyView instanceof Ember . View ) { emptyView . removeFromParent ( ) ; } 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 .


function(view) {
    var morph = view.morph;

    view.transitionTo('preRender');

    Ember.run.schedule('render', this, function renderMetamorphView() {
      if (view.isDestroying) { return; }

      view.clearRenderedChildren();
      var buffer = view.renderToBuffer();

      view.invokeRecursively(function(view) {
        view.propertyWillChange('element');
      });
      view.triggerRecursively('willInsertElement');

      morph.replaceWith(buffer.string());
      view.transitionTo('inDOM');

      view.invokeRecursively(function(view) {
        view.propertyDidChange('element');
      });
      view.triggerRecursively('didInsertElement');

      notifyMutationListeners();
    });
  }

function ( view ) { var morph = view . morph ; view . transitionTo ( 'preRender' ) ; Ember . run . schedule ( 'render' , this , function renderMetamorphView ( ) { if ( view . isDestroying ) { return ; } view . clearRenderedChildren ( ) ; var buffer = view . renderToBuffer ( ) ; view . invokeRecursively ( function ( view ) { view . propertyWillChange ( 'element' ) ; } ) ; view . triggerRecursively ( 'willInsertElement' ) ; morph . replaceWith ( buffer . string ( ) ) ; view . transitionTo ( 'inDOM' ) ; view . invokeRecursively ( function ( view ) { view . propertyDidChange ( 'element' ) ; } ) ; view . triggerRecursively ( 'didInsertElement' ) ; notifyMutationListeners ( ) ; } ) ; }


function bind(property, options, preserveContext, shouldDisplay, valueNormalizer, childProperties) {
  var data = options.data,
      fn = options.fn,
      inverse = options.inverse,
      view = data.view,
      currentContext = this,
      normalized, observer, i;

  normalized = normalizePath(currentContext, property, data);

  // Set up observers for observable objects
  if ('object' === typeof this) {
    if (data.insideGroup) {
      observer = function() {
        Ember.run.once(view, 'rerender');
      };

      var template, context, result = handlebarsGet(currentContext, property, options);

      result = valueNormalizer ? valueNormalizer(result) : result;

      context = preserveContext ? currentContext : result;
      if (shouldDisplay(result)) {
        template = fn;
      } else if (inverse) {
        template = inverse;
      }

      template(context, { data: options.data });
    } else {
      // Create the view that will wrap the output of this template/property
      // and add it to the nearest view's childViews array.
      // See the documentation of Ember._HandlebarsBoundView for more.
      var bindView = view.createChildView(Ember._HandlebarsBoundView, {
        preserveContext: preserveContext,
        shouldDisplayFunc: shouldDisplay,
        valueNormalizerFunc: valueNormalizer,
        displayTemplate: fn,
        inverseTemplate: inverse,
        path: property,
        pathRoot: currentContext,
        previousContext: currentContext,
        isEscaped: !options.hash.unescaped,
        templateData: options.data
      });

      if (options.hash.controller) {
        bindView.set('_contextController', this.container.lookupFactory('controller:'+options.hash.controller).create({
          container: currentContext.container,
          parentController: currentContext,
          target: currentContext
        }));
      }

      view.appendChild(bindView);

      observer = function() {
        Ember.run.scheduleOnce('render', bindView, 'rerenderIfNeeded');
      };
    }

    // Observes the given property on the context and
    // tells the Ember._HandlebarsBoundView to re-render. If property
    // is an empty string, we are printing the current context
    // object ({{this}}) so updating it is not our responsibility.
    if (normalized.path !== '') {
      view.registerObserver(normalized.root, normalized.path, observer);
      if (childProperties) {
        for (i=0; i<childProperties.length; i++) {
          view.registerObserver(normalized.root, normalized.path+'.'+childProperties[i], observer);
        }
      }
    }
  } else {
    // The object is not observable, so just render it out and
    // be done with it.
    data.buffer.push(handlebarsGetEscaped(currentContext, property, options));
  }
}

function bind ( property , options , preserveContext , shouldDisplay , valueNormalizer , childProperties ) { var data = options . data , fn = options . fn , inverse = options . inverse , view = data . view , currentContext = this , normalized , observer , i ; normalized = normalizePath ( currentContext , property , data ) ; if ( 'object' === typeof this ) { if ( data . insideGroup ) { observer = function ( ) { Ember . run . once ( view , 'rerender' ) ; } ; var template , context , result = handlebarsGet ( currentContext , property , options ) ; result = valueNormalizer ? valueNormalizer ( result ) : result ; context = preserveContext ? currentContext : result ; if ( shouldDisplay ( result ) ) { template = fn ; } else if ( inverse ) { template = inverse ; } template ( context , { data : options . data } ) ; } else { var bindView = view . createChildView ( Ember . _HandlebarsBoundView , { preserveContext : preserveContext , shouldDisplayFunc : shouldDisplay , valueNormalizerFunc : valueNormalizer , displayTemplate : fn , inverseTemplate : inverse , path : property , pathRoot : currentContext , previousContext : currentContext , isEscaped : ! options . hash . unescaped , templateData : options . data } ) ; if ( options . hash . controller ) { bindView . set ( '_contextController' , this . container . lookupFactory ( 'controller:' + options . hash . controller ) . create ( { container : currentContext . container , parentController : currentContext , target : currentContext } ) ) ; } view . appendChild ( bindView ) ; observer = function ( ) { Ember . run . scheduleOnce ( 'render' , bindView , 'rerenderIfNeeded' ) ; } ; } if ( normalized . path !== '' ) { view . registerObserver ( normalized . root , normalized . path , observer ) ; if ( childProperties ) { for ( i = 0 ; i < childProperties . length ; i ++ ) { view . registerObserver ( normalized . root , normalized . path + '.' + childProperties [ i ] , observer ) ; } } } } else { data . buffer . push ( handlebarsGetEscaped ( currentContext , property , options ) ) ; } }

Binds a property into the DOM. This will create a hook in DOM that the KVO system will look for and update if the property changes.

Binds a property into the DOM . This will create a hook in DOM that the KVO system will look for and update if the property changes .


function _addMetamorphCheck() {
  Ember.Handlebars.EachView.reopen({
    _checkMetamorph: Ember.on('didInsertElement', function() {
      Ember.assert("The metamorph tags, " +
                   this.morph.start + " and " + this.morph.end +
                   ", have different parents.\nThe browser has fixed your template to output valid HTML (for example, check that you have properly closed all tags and have used a TBODY tag when creating a table with '{{#each}}')",
        document.getElementById( this.morph.start ).parentNode ===
        document.getElementById( this.morph.end ).parentNode
      );
    })
  });
}

Defeatureify doesn't seem to like nested functions that need to be removed

Defeatureify doesn t seem to like nested functions that need to be removed


function() {
        if (this.state) {
          forEach(this.state.handlerInfos, function(handlerInfo) {
            var handler = handlerInfo.handler;
            if (handler.exit) {
              handler.exit();
            }
          });
        }

        this.state = new TransitionState();
        this.currentHandlerInfos = null;
      }

function ( ) { if ( this . state ) { forEach ( this . state . handlerInfos , function ( handlerInfo ) { var handler = handlerInfo . handler ; if ( handler . exit ) { handler . exit ( ) ; } } ) ; } this . state = new TransitionState ( ) ; this . currentHandlerInfos = null ; }

Clears the current and target route handlers and triggers exit
on each of them starting at the leaf and traversing up through
its ancestors.

Clears the current and target route handlers and triggers exit on each of them starting at the leaf and traversing up through its ancestors .


function() {
    this.router = this.router || this.constructor.map(Ember.K);

    var router = this.router,
        location = get(this, 'location'),
        container = this.container,
        self = this,
        initialURL = get(this, 'initialURL');

      // Allow the Location class to cancel the router setup while it refreshes
      // the page
      if (get(location, 'cancelRouterSetup')) {
        return;
      }

    this._setupRouter(router, location);

    container.register('view:default', DefaultView);
    container.register('view:toplevel', Ember.View.extend());

    location.onUpdateURL(function(url) {
      self.handleURL(url);
    });

    if (typeof initialURL === "undefined") {
      initialURL = location.getURL();
    }

    this.handleURL(initialURL);
  }

function ( ) { this . router = this . router || this . constructor . map ( Ember . K ) ; var router = this . router , location = get ( this , 'location' ) , container = this . container , self = this , initialURL = get ( this , 'initialURL' ) ; if ( get ( location , 'cancelRouterSetup' ) ) { return ; } this . _setupRouter ( router , location ) ; container . register ( 'view:default' , DefaultView ) ; container . register ( 'view:toplevel' , Ember . View . extend ( ) ) ; location . onUpdateURL ( function ( url ) { self . handleURL ( url ) ; } ) ; if ( typeof initialURL === "undefined" ) { initialURL = location . getURL ( ) ; } this . handleURL ( initialURL ) ; }

Initializes the current router instance and sets up the change handling
event listeners used by the instances `location` implementation.

A property named `initialURL` will be used to determine the initial URL.
If no value is found `/` will be used.

@method startRouting
@private

Initializes the current router instance and sets up the change handling event listeners used by the instances location implementation .


function(context, transition) {
    var controllerName = this.controllerName || this.routeName,
        controller = this.controllerFor(controllerName, true);
    if (!controller) {
      controller =  this.generateController(controllerName, context);
    }

    // Assign the route's controller so that it can more easily be
    // referenced in action handlers
    this.controller = controller;

    if (this.setupControllers) {
      Ember.deprecate("Ember.Route.setupControllers is deprecated. Please use Ember.Route.setupController(controller, model) instead.");
      this.setupControllers(controller, context);
    } else {

        this.setupController(controller, context);

    }

    if (this.renderTemplates) {
      Ember.deprecate("Ember.Route.renderTemplates is deprecated. Please use Ember.Route.renderTemplate(controller, model) instead.");
      this.renderTemplates(context);
    } else {
      this.renderTemplate(controller, context);
    }
  }

This hook is the entry point for router.js

@private
@method setup

This hook is the entry point for router . js


function(params, transition) {
    var match, name, sawParams, value;

    for (var prop in params) {
      if (prop === 'queryParams') { continue; }

      if (match = prop.match(/^(.*)_id$/)) {
        name = match[1];
        value = params[prop];
      }
      sawParams = true;
    }

    if (!name && sawParams) { return Ember.copy(params); }
    else if (!name) {

        if (transition.resolveIndex !== transition.state.handlerInfos.length-1) { return; }

        var parentModel = transition.state.handlerInfos[transition.resolveIndex-1].context;

        return parentModel;
          }

    return this.findModel(name, value);
  }

function ( params , transition ) { var match , name , sawParams , value ; for ( var prop in params ) { if ( prop === 'queryParams' ) { continue ; } if ( match = prop . match ( / ^(.*)_id$ / ) ) { name = match [ 1 ] ; value = params [ prop ] ; } sawParams = true ; } if ( ! name && sawParams ) { return Ember . copy ( params ) ; } else if ( ! name ) { if ( transition . resolveIndex !== transition . state . handlerInfos . length - 1 ) { return ; } var parentModel = transition . state . handlerInfos [ transition . resolveIndex - 1 ] . context ; return parentModel ; } return this . findModel ( name , value ) ; }

A hook you can implement to convert the URL into the model for
this route.

```js
App.Router.map(function() {
this.resource('post', {path: '/posts/:post_id'});
});
```

The model for the `post` route is `App.Post.find(params.post_id)`.

By default, if your route has a dynamic segment ending in `_id`:

The model class is determined from the segment (`post_id`'s
class is `App.Post`)
The find method is called on the model class with the value of
the dynamic segment.

Note that for routes with dynamic segments, this hook is only
executed when entered via the URL. If the route is entered
through a transition (e.g. when using the `link-to` Handlebars
helper), then a model context is already provided and this hook
is not called. Routes without dynamic segments will always
execute the model hook.

This hook follows the asynchronous/promise semantics
described in the documentation for `beforeModel`. In particular,
if a promise returned from `model` fails, the error will be
handled by the `error` hook on `Ember.Route`.

Example

```js
App.PostRoute = Ember.Route.extend({
model: function(params) {
return App.Post.find(params.post_id);
}
});
```

@method model
@param {Object} params the parameters extracted from the URL
@param {Transition} transition
@param {Object} queryParams the query params for this route
@return {Object|Promise} the model for this route. If
a promise is returned, the transition will pause until
the promise resolves, and the resolved value of the promise
will be used as the model for this route.

A hook you can implement to convert the URL into the model for this route .


function(model, params) {
    if (params.length < 1) { return; }
    if (!model) { return; }

    var name = params[0], object = {};

    if (/_id$/.test(name) && params.length === 1) {
      object[name] = get(model, "id");
    } else {
      object = getProperties(model, params);
    }

    return object;
  }

function ( model , params ) { if ( params . length < 1 ) { return ; } if ( ! model ) { return ; } var name = params [ 0 ] , object = { } ; if ( / _id$ / . test ( name ) && params . length === 1 ) { object [ name ] = get ( model , "id" ) ; } else { object = getProperties ( model , params ) ; } return object ; }

A hook you can implement to convert the route's model into parameters
for the URL.

```js
App.Router.map(function() {
this.resource('post', {path: '/posts/:post_id'});
});

App.PostRoute = Ember.Route.extend({
model: function(params) {
the server returns `{ id: 12 }`
return jQuery.getJSON("/posts/" + params.post_id);
},

serialize: function(model) {
this will make the URL `/posts/12`
return { post_id: model.id };
}
});
```

The default `serialize` method will insert the model's `id` into the
route's dynamic segment (in this case, `:post_id`) if the segment contains '_id'.
If the route has multiple dynamic segments or does not contain '_id', `serialize`
will return `Ember.getProperties(model, params)`

This method is called when `transitionTo` is called with a context
in order to populate the URL.

@method serialize
@param {Object} model the route's model
@param {Array} params an Array of parameter names for the current
route (in the example, `['post_id']`.
@return {Object} the serialized parameters

A hook you can implement to convert the route s model into parameters for the URL .


function(name, _skipAssert) {
    var container = this.container,
        route = container.lookup('route:'+name),
        controller;

    if (route && route.controllerName) {
      name = route.controllerName;
    }

    controller = container.lookup('controller:' + name);

    // NOTE: We're specifically checking that skipAssert is true, because according
    //   to the old API the second parameter was model. We do not want people who
    //   passed a model to skip the assertion.
    Ember.assert("The controller named '"+name+"' could not be found. Make sure " +
                 "that this route exists and has already been entered at least " +
                 "once. If you are accessing a controller not associated with a " +
                 "route, make sure the controller class is explicitly defined.",
                 controller || _skipAssert === true);

    return controller;
  }

Returns the controller for a particular route or name.

The controller instance must already have been created, either through entering the
associated route or using `generateController`.

```js
App.PostRoute = Ember.Route.extend({
setupController: function(controller, post) {
this._super(controller, post);
this.controllerFor('posts').set('currentPost', post);
}
});
```

@method controllerFor
@param {String} name the name of the route or controller
@return {Ember.Controller}

Returns the controller for a particular route or name .


function(options) {
    if (!options || typeof options === "string") {
      var outletName = options;
      options = {};
      options.outlet = outletName;
    }
    options.parentView = options.parentView ? options.parentView.replace(/\//g, '.') : parentTemplate(this);
    options.outlet = options.outlet || 'main';

    var parentView = this.router._lookupActiveView(options.parentView);
    if (parentView) { parentView.disconnectOutlet(options.outlet); }
  }

function ( options ) { if ( ! options || typeof options === "string" ) { var outletName = options ; options = { } ; options . outlet = outletName ; } options . parentView = options . parentView ? options . parentView . replace ( / \/ / g , '.' ) : parentTemplate ( this ) ; options . outlet = options . outlet || 'main' ; var parentView = this . router . _lookupActiveView ( options . parentView ) ; if ( parentView ) { parentView . disconnectOutlet ( options . outlet ) ; } }

Disconnects a view that has been rendered into an outlet.

You may pass any or all of the following options to `disconnectOutlet`:

`outlet`: the name of the outlet to clear (default: 'main')
`parentView`: the name of the view containing the outlet to clear
(default: the view rendered by the parent route)

Example:

```js
App.ApplicationRoute = App.Route.extend({
actions: {
showModal: function(evt) {
this.render(evt.modalName, {
outlet: 'modal',
into: 'application'
});
},
hideModal: function(evt) {
this.disconnectOutlet({
outlet: 'modal',
parentView: 'application'
});
}
}
});
```

Alternatively, you can pass the `outlet` name directly as a string.

Example:

```js
hideModal: function(evt) {
this.disconnectOutlet('modal');
}
```

@method disconnectOutlet
@param {Object|String} options the options hash or outlet name

Disconnects a view that has been rendered into an outlet .


function(){
      var helperParameters = this.parameters,
          linkTextPath     = helperParameters.options.linkTextPath,
          paths = getResolvedPaths(helperParameters),
          length = paths.length,
          path, i, normalizedPath;

      if (linkTextPath) {
        normalizedPath = Ember.Handlebars.normalizePath(helperParameters.context, linkTextPath, helperParameters.options.data);
        this.registerObserver(normalizedPath.root, normalizedPath.path, this, this.rerender);
      }

      for(i=0; i < length; i++) {
        path = paths[i];
        if (null === path) {
          // A literal value was provided, not a path, so nothing to observe.
          continue;
        }

        normalizedPath = Ember.Handlebars.normalizePath(helperParameters.context, path, helperParameters.options.data);
        this.registerObserver(normalizedPath.root, normalizedPath.path, this, this._paramsChanged);
      }

      var queryParamsObject = this.queryParamsObject;
      if (queryParamsObject) {
        var values = queryParamsObject.values;

        // Install observers for all of the hash options
        // provided in the (query-params) subexpression.
        for (var k in values) {
          if (!values.hasOwnProperty(k)) { continue; }

          if (queryParamsObject.types[k] === 'ID') {
            normalizedPath = Ember.Handlebars.normalizePath(helperParameters.context, values[k], helperParameters.options.data);
            this.registerObserver(normalizedPath.root, normalizedPath.path, this, this._paramsChanged);
          }
        }
      }
    }

function ( ) { var helperParameters = this . parameters , linkTextPath = helperParameters . options . linkTextPath , paths = getResolvedPaths ( helperParameters ) , length = paths . length , path , i , normalizedPath ; if ( linkTextPath ) { normalizedPath = Ember . Handlebars . normalizePath ( helperParameters . context , linkTextPath , helperParameters . options . data ) ; this . registerObserver ( normalizedPath . root , normalizedPath . path , this , this . rerender ) ; } for ( i = 0 ; i < length ; i ++ ) { path = paths [ i ] ; if ( null === path ) { continue ; } normalizedPath = Ember . Handlebars . normalizePath ( helperParameters . context , path , helperParameters . options . data ) ; this . registerObserver ( normalizedPath . root , normalizedPath . path , this , this . _paramsChanged ) ; } var queryParamsObject = this . queryParamsObject ; if ( queryParamsObject ) { var values = queryParamsObject . values ; for ( var k in values ) { if ( ! values . hasOwnProperty ( k ) ) { continue ; } if ( queryParamsObject . types [ k ] === 'ID' ) { normalizedPath = Ember . Handlebars . normalizePath ( helperParameters . context , values [ k ] , helperParameters . options . data ) ; this . registerObserver ( normalizedPath . root , normalizedPath . path , this , this . _paramsChanged ) ; } } } }

This is called to setup observers that will trigger a rerender.

@private
@method _setupPathObservers

This is called to setup observers that will trigger a rerender .


function(event) {
      if (!isSimpleClick(event)) { return true; }

      if (this.preventDefault !== false) { event.preventDefault(); }
      if (this.bubbles === false) { event.stopPropagation(); }

      if (get(this, '_isDisabled')) { return false; }

      if (get(this, 'loading')) {
        Ember.Logger.warn("This link-to is in an inactive loading state because at least one of its parameters presently has a null/undefined value, or the provided route name is invalid.");
        return false;
      }

      var router = get(this, 'router'),
          routeArgs = get(this, 'routeArgs');

      var transition;
      if (get(this, 'replace')) {
        transition = router.replaceWith.apply(router, routeArgs);
      } else {
        transition = router.transitionTo.apply(router, routeArgs);
      }

      // Schedule eager URL update, but after we've given the transition
      // a chance to synchronously redirect.

        // We need to always generate the URL instead of using the href because
        // the href will include any rootURL set, but the router expects a URL
        // without it! Note that we don't use the first level router because it
        // calls location.formatURL(), which also would add the rootURL!
        var url = router.router.generate.apply(router.router, get(this, 'routeArgs'));
        Ember.run.scheduleOnce('routerTransitions', this, this._eagerUpdateUrl, transition, url);

    }

Event handler that invokes the link, activating the associated route.

@private
@method _invoke
@param {Event} event

Event handler that invokes the link activating the associated route .


function() {
    // target may be either another controller or a router
    var target = get(this, 'target'),
        method = target.replaceRoute || target.replaceWith;
    return method.apply(target, arguments);
  }

function ( ) { var target = get ( this , 'target' ) , method = target . replaceRoute || target . replaceWith ; return method . apply ( target , arguments ) ; }

Transition into another route while replacing the current URL, if possible.
This will replace the current history entry instead of adding a new one.
Beside that, it is identical to `transitionToRoute` in all other respects.

```javascript
aController.replaceRoute('blogPosts');
aController.replaceRoute('blogPosts.recentEntries');
```

Optionally supply a model for the route in question. The model
will be serialized into the URL using the `serialize` hook of
the route:

```javascript
aController.replaceRoute('blogPost', aPost);
```

If a literal is passed (such as a number or a string), it will
be treated as an identifier instead. In this case, the `model`
hook of the route will be triggered:

```javascript
aController.replaceRoute('blogPost', 1);
```

Multiple models will be applied last to first recursively up the
resource tree.

```javascript
App.Router.map(function() {
this.resource('blogPost', {path:':blogPostId'}, function(){
this.resource('blogComment', {path: ':blogCommentId'});
});
});

aController.replaceRoute('blogComment', aPost, aComment);
aController.replaceRoute('blogComment', 1, 13);
```

It is also possible to pass a URL (a string that starts with a
`/`). This is intended for testing and debugging purposes and
should rarely be used in production code.

```javascript
aController.replaceRoute('/');
aController.replaceRoute('/blog/post/1/comment/13');
```

@param {String} name the name of the route or a URL
@param {...Object} models the model(s) or identifier(s) to be used
while transitioning to the route.
@for Ember.ControllerMixin
@method replaceRoute

Transition into another route while replacing the current URL if possible . This will replace the current history entry instead of adding a new one . Beside that it is identical to transitionToRoute in all other respects .


function(outletName, view) {
    var existingView = get(this, '_outlets.'+outletName);
    return existingView &&
      existingView.constructor === view.constructor &&
      existingView.get('template') === view.get('template') &&
      existingView.get('context') === view.get('context');
  }

function ( outletName , view ) { var existingView = get ( this , '_outlets.' + outletName ) ; return existingView && existingView . constructor === view . constructor && existingView . get ( 'template' ) === view . get ( 'template' ) && existingView . get ( 'context' ) === view . get ( 'context' ) ; }

Determines if the view has already been created by checking if
the view has the same constructor, template, and context as the
view in the `_outlets` object.

@private
@method _hasEquivalentView
@param  {String} outletName The name of the outlet we are checking
@param  {Object} view       An Ember.View
@return {Boolean}

Determines if the view has already been created by checking if the view has the same constructor template and context as the view in the _outlets object .


function() {
    if (this.isDestroyed) return; // _outlets will be gone anyway
    var outlets = get(this, '_outlets');
    var pendingDisconnections = this._pendingDisconnections;
    this._pendingDisconnections = null;

    for (var outletName in pendingDisconnections) {
      set(outlets, outletName, null);
    }
  }

function ( ) { if ( this . isDestroyed ) return ; var outlets = get ( this , '_outlets' ) ; var pendingDisconnections = this . _pendingDisconnections ; this . _pendingDisconnections = null ; for ( var outletName in pendingDisconnections ) { set ( outlets , outletName , null ) ; } }

Gets an outlet that is pending disconnection and then
nullifys the object on the `_outlet` object.

@private
@method _finishDisconnections

Gets an outlet that is pending disconnection and then nullifys the object on the _outlet object .


function () {
    // AutoLocation has it at _location, HashLocation at .location.
    // Being nice and not changing
    var href = (this._location || this.location).href,
        hashIndex = href.indexOf('#');

    if (hashIndex === -1) {
      return '';
    } else {
      return href.substr(hashIndex);
    }
  }

function ( ) { var href = ( this . _location || this . location ) . href , hashIndex = href . indexOf ( '#' ) ; if ( hashIndex === - 1 ) { return '' ; } else { return href . substr ( hashIndex ) ; } }

Returns the current `location.hash` by parsing location.href since browsers
inconsistently URL-decode `location.hash`.

https://bugzilla.mozilla.org/show_bug.cgi?id=483304

@private
@method getHash

Returns the current location . hash by parsing location . href since browsers inconsistently URL - decode location . hash .


function(path) {
    var state = { path: path };

    get(this, 'history').replaceState(state, null, path);

    // store state if browser doesn't support `history.state`
    if (!supportsHistoryState) {
      this._historyState = state;
    }

    // used for webkit workaround
    this._previousURL = this.getURL();
  }

function ( path ) { var state = { path : path } ; get ( this , 'history' ) . replaceState ( state , null , path ) ; if ( ! supportsHistoryState ) { this . _historyState = state ; } this . _previousURL = this . getURL ( ) ; }

Replaces the current state.

@private
@method replaceState
@param path {String}


function(callback) {
    var guid = Ember.guidFor(this),
        self = this;

    Ember.$(window).on('popstate.ember-location-'+guid, function(e) {
      // Ignore initial page load popstate event in Chrome
      if (!popstateFired) {
        popstateFired = true;
        if (self.getURL() === self._previousURL) { return; }
      }
      callback(self.getURL());
    });
  }

function ( callback ) { var guid = Ember . guidFor ( this ) , self = this ; Ember . $ ( window ) . on ( 'popstate.ember-location-' + guid , function ( e ) { if ( ! popstateFired ) { popstateFired = true ; if ( self . getURL ( ) === self . _previousURL ) { return ; } } callback ( self . getURL ( ) ) ; } ) ; }

Register a callback to be invoked whenever the browser
history changes, including using forward and back buttons.

@private
@method onUpdateURL
@param callback {Function}

Register a callback to be invoked whenever the browser history changes including using forward and back buttons .


function (options) {
      if (options && options.rootURL) {
        Ember.assert('rootURL must end with a trailing forward slash e.g. "/app/"', options.rootURL.charAt(options.rootURL.length-1) === '/');
        this.rootURL = options.rootURL;
      }

      var historyPath, hashPath,
          cancelRouterSetup = false,
          implementationClass = this._NoneLocation,
          currentPath = this._getFullPath();

      if (this._getSupportsHistory()) {
        historyPath = this._getHistoryPath();

        // Since we support history paths, let's be sure we're using them else
        // switch the location over to it.
        if (currentPath === historyPath) {
          implementationClass = this._HistoryLocation;
        } else {
          cancelRouterSetup = true;
          this._replacePath(historyPath);
        }

      } else if (this._getSupportsHashChange()) {
        hashPath = this._getHashPath();

        // Be sure we're using a hashed path, otherwise let's switch over it to so
        // we start off clean and consistent. We'll count an index path with no
        // hash as "good enough" as well.
        if (currentPath === hashPath || (currentPath === '/' && hashPath === '/#/')) {
          implementationClass = this._HashLocation;
        } else {
          // Our URL isn't in the expected hash-supported format, so we want to
          // cancel the router setup and replace the URL to start off clean
          cancelRouterSetup = true;
          this._replacePath(hashPath);
        }
      }

      var implementation = implementationClass.create.apply(implementationClass, arguments);

      if (cancelRouterSetup) {
        set(implementation, 'cancelRouterSetup', true);
      }

      return implementation;
    }

Selects the best location option based off browser support and returns an
instance of that Location class.

@see Ember.AutoLocation
@method create

Selects the best location option based off browser support and returns an instance of that Location class .


function(fullName) {
    var parsedName = this.parseName(fullName),
        resolveMethodName = parsedName.resolveMethodName;

    if (!(parsedName.name && parsedName.type)) {
      throw new TypeError("Invalid fullName: `" + fullName + "`, must be of the form `type:name` ");
    }

    if (this[resolveMethodName]) {
      var resolved = this[resolveMethodName](parsedName);
      if (resolved) { return resolved; }
    }
    return this.resolveOther(parsedName);
  }

function
(
fullName
)
{
var
parsedName
=
this
.
parseName
(
fullName
)
,
resolveMethodName
=
parsedName
.
resolveMethodName
;
if
(
!
(
parsedName
.
name
&&
parsedName
.
type
)
)
{
throw
new
TypeError
(
"Invalid fullName: `"
+
fullName
+
"`, must be of the form `type:name` "
)
;
}
if
(
this
[
resolveMethodName
]
)
{
var
resolved
=
this
[
resolveMethodName
]
(
parsedName
)
;
if
(
resolved
)
{
return
resolved
;
}
}
return
this
.
resolveOther
(
parsedName
)
;
}

This method is called via the container's resolver method.
It parses the provided `fullName` and then looks up and
returns the appropriate template or class.

@method resolve
@param {String} fullName the lookup string
@return {Object} the resolved factory

This method is called via the container s resolver method . It parses the provided fullName and then looks up and returns the appropriate template or class .


function(parsedName) {
    var templateName = parsedName.fullNameWithoutType.replace(/\./g, '/');

    if (Ember.TEMPLATES[templateName]) {
      return Ember.TEMPLATES[templateName];
    }

    templateName = decamelize(templateName);
    if (Ember.TEMPLATES[templateName]) {
      return Ember.TEMPLATES[templateName];
    }
  }

function ( parsedName ) { var templateName = parsedName . fullNameWithoutType . replace ( / \. / g , '/' ) ; if ( Ember . TEMPLATES [ templateName ] ) { return Ember . TEMPLATES [ templateName ] ; } templateName = decamelize ( templateName ) ; if ( Ember . TEMPLATES [ templateName ] ) { return Ember . TEMPLATES [ templateName ] ; } }

Look up the template in Ember.TEMPLATES

@protected
@param {Object} parsedName a parseName object with the parsed
fullName lookup string
@method resolveTemplate

Look up the template in Ember . TEMPLATES


function() {
    if (this.Router === false) { return; }
    var container = this.__container__;

    if (this.Router) {
      container.unregister('router:main');
      container.register('router:main', this.Router);
    }

    return container.lookupFactory('router:main');
  }

function ( ) { if ( this . Router === false ) { return ; } var container = this . __container__ ; if ( this . Router ) { container . unregister ( 'router:main' ) ; container . register ( 'router:main' , this . Router ) ; } return container . lookupFactory ( 'router:main' ) ; }

If the application has not opted out of routing and has not explicitly
defined a router, supply a default router for the application author
to configure.

This allows application developers to do:

```javascript
var App = Ember.Application.create();

App.Router.map(function() {
this.resource('posts');
});
```

@private
@method defaultRouter
@return {Ember.Router} the default router

If the application has not opted out of routing and has not explicitly defined a router supply a default router for the application author to configure .


function() {
    var self = this;

    if (!this.$ || this.$.isReady) {
      Ember.run.schedule('actions', self, '_initialize');
    } else {
      this.$().ready(function runInitialize() {
        Ember.run(self, '_initialize');
      });
    }
  }

function ( ) { var self = this ; if ( ! this . $ || this . $ . isReady ) { Ember . run . schedule ( 'actions' , self , '_initialize' ) ; } else { this . $ ( ) . ready ( function runInitialize ( ) { Ember . run ( self , '_initialize' ) ; } ) ; } }

Automatically initialize the application once the DOM has
become ready.

The initialization itself is scheduled on the actions queue
which ensures that application loading finishes before
booting.

If you are asynchronously loading code, you should call
`deferReadiness()` to defer booting, and then call
`advanceReadiness()` once all of your code has finished
loading.

@private
@method scheduleInitialize

Automatically initialize the application once the DOM has become ready .


function() {
    Ember.assert("You must call advanceReadiness on an instance of Ember.Application", this instanceof Ember.Application);
    this._readinessDeferrals--;

    if (this._readinessDeferrals === 0) {
      Ember.run.once(this, this.didBecomeReady);
    }
  }

Call `advanceReadiness` after any asynchronous setup logic has completed.
Each call to `deferReadiness` must be matched by a call to `advanceReadiness`
or the application will never become ready and routing will not begin.

@method advanceReadiness
@see {Ember.Application#deferReadiness}

Call advanceReadiness after any asynchronous setup logic has completed . Each call to deferReadiness must be matched by a call to advanceReadiness or the application will never become ready and routing will not begin .


function() {
    var customEvents = get(this, 'customEvents'),
        rootElement = get(this, 'rootElement'),
        dispatcher = this.__container__.lookup('event_dispatcher:main');

    set(this, 'eventDispatcher', dispatcher);
    dispatcher.setup(customEvents, rootElement);
  }

function ( ) { var customEvents = get ( this , 'customEvents' ) , rootElement = get ( this , 'rootElement' ) , dispatcher = this . __container__ . lookup ( 'event_dispatcher:main' ) ; set ( this , 'eventDispatcher' , dispatcher ) ; dispatcher . setup ( customEvents , rootElement ) ; }

Setup up the event dispatcher to receive events on the
application's `rootElement` with any registered
`customEvents`.

@private
@method setupEventDispatcher

Setup up the event dispatcher to receive events on the application s rootElement with any registered customEvents .


function(namespace) {
    var container = new Ember.Container();

    Ember.Container.defaultContainer = new DeprecatedContainer(container);

    container.set = Ember.set;
    container.resolver  = resolverFor(namespace);
    container.normalize = container.resolver.normalize;
    container.describe  = container.resolver.describe;
    container.makeToString = container.resolver.makeToString;

    container.optionsForType('component', { singleton: false });
    container.optionsForType('view', { singleton: false });
    container.optionsForType('template', { instantiate: false });
    container.optionsForType('helper', { instantiate: false });

    container.register('application:main', namespace, { instantiate: false });

    container.register('controller:basic', Ember.Controller, { instantiate: false });
    container.register('controller:object', Ember.ObjectController, { instantiate: false });
    container.register('controller:array', Ember.ArrayController, { instantiate: false });
    container.register('route:basic', Ember.Route, { instantiate: false });
    container.register('event_dispatcher:main', Ember.EventDispatcher);

    container.register('router:main',  Ember.Router);
    container.injection('router:main', 'namespace', 'application:main');

      container.register('location:auto', Ember.AutoLocation);

    container.register('location:hash', Ember.HashLocation);
    container.register('location:history', Ember.HistoryLocation);
    container.register('location:none', Ember.NoneLocation);

    container.injection('controller', 'target', 'router:main');
    container.injection('controller', 'namespace', 'application:main');

    container.injection('route', 'router', 'router:main');
    container.injection('location', 'rootURL', '-location-setting:root-url');

    // DEBUGGING
    container.register('resolver-for-debugging:main', container.resolver.__resolver__, { instantiate: false });
    container.injection('container-debug-adapter:main', 'resolver', 'resolver-for-debugging:main');
    container.injection('data-adapter:main', 'containerDebugAdapter', 'container-debug-adapter:main');
    // Custom resolver authors may want to register their own ContainerDebugAdapter with this key
    container.register('container-debug-adapter:main', Ember.ContainerDebugAdapter);

    return container;
  }

function ( namespace ) { var container = new Ember . Container ( ) ; Ember . Container . defaultContainer = new DeprecatedContainer ( container ) ; container . set = Ember . set ; container . resolver = resolverFor ( namespace ) ; container . normalize = container . resolver . normalize ; container . describe = container . resolver . describe ; container . makeToString = container . resolver . makeToString ; container . optionsForType ( 'component' , { singleton : false } ) ; container . optionsForType ( 'view' , { singleton : false } ) ; container . optionsForType ( 'template' , { instantiate : false } ) ; container . optionsForType ( 'helper' , { instantiate : false } ) ; container . register ( 'application:main' , namespace , { instantiate : false } ) ; container . register ( 'controller:basic' , Ember . Controller , { instantiate : false } ) ; container . register ( 'controller:object' , Ember . ObjectController , { instantiate : false } ) ; container . register ( 'controller:array' , Ember . ArrayController , { instantiate : false } ) ; container . register ( 'route:basic' , Ember . Route , { instantiate : false } ) ; container . register ( 'event_dispatcher:main' , Ember . EventDispatcher ) ; container . register ( 'router:main' , Ember . Router ) ; container . injection ( 'router:main' , 'namespace' , 'application:main' ) ; container . register ( 'location:auto' , Ember . AutoLocation ) ; container . register ( 'location:hash' , Ember . HashLocation ) ; container . register ( 'location:history' , Ember . HistoryLocation ) ; container . register ( 'location:none' , Ember . NoneLocation ) ; container . injection ( 'controller' , 'target' , 'router:main' ) ; container . injection ( 'controller' , 'namespace' , 'application:main' ) ; container . injection ( 'route' , 'router' , 'router:main' ) ; container . injection ( 'location' , 'rootURL' , '-location-setting:root-url' ) ; container . register ( 'resolver-for-debugging:main' , container . resolver . __resolver__ , { instantiate : false } ) ; container . injection ( 'container-debug-adapter:main' , 'resolver' , 'resolver-for-debugging:main' ) ; container . injection ( 'data-adapter:main' , 'containerDebugAdapter' , 'container-debug-adapter:main' ) ; container . register ( 'container-debug-adapter:main' , Ember . ContainerDebugAdapter ) ; return container ; }

This creates a container with the default Ember naming conventions.

It also configures the container:

registered views are created every time they are looked up (they are
not singletons)
registered templates are not factories; the registered value is
returned directly.
the router receives the application as its `namespace` property
all controllers receive the router as their `target` and `controllers`
properties
all controllers receive the application as their `namespace` property
the application view receives the application controller as its
`controller` property
the application view receives the application template as its
`defaultTemplate` property

@private
@method buildContainer
@static
@param {Ember.Application} namespace the application to build the
container for.
@return {Ember.Container} the built container

This creates a container with the default Ember naming conventions .


function(type, recordsAdded, recordsUpdated, recordsRemoved) {
    var self = this, releaseMethods = Ember.A(), records = this.getRecords(type), release;

    var recordUpdated = function(updatedRecord) {
      recordsUpdated([updatedRecord]);
    };

    var recordsToSend = records.map(function(record) {
      releaseMethods.push(self.observeRecord(record, recordUpdated));
      return self.wrapRecord(record);
    });

    var contentDidChange = function(array, idx, removedCount, addedCount) {
      for (var i = idx; i < idx + addedCount; i++) {
        var record = array.objectAt(i);
        var wrapped = self.wrapRecord(record);
        releaseMethods.push(self.observeRecord(record, recordUpdated));
        recordsAdded([wrapped]);
      }

      if (removedCount) {
        recordsRemoved(idx, removedCount);
      }
    };

    var observer = { didChange: contentDidChange, willChange: Ember.K };
    records.addArrayObserver(self, observer);

    release = function() {
      releaseMethods.forEach(function(fn) { fn(); });
      records.removeArrayObserver(self, observer);
      self.releaseMethods.removeObject(release);
    };

    recordsAdded(recordsToSend);

    this.releaseMethods.pushObject(release);
    return release;
  }

function ( type , recordsAdded , recordsUpdated , recordsRemoved ) { var self = this , releaseMethods = Ember . A ( ) , records = this . getRecords ( type ) , release ; var recordUpdated = function ( updatedRecord ) { recordsUpdated ( [ updatedRecord ] ) ; } ; var recordsToSend = records . map ( function ( record ) { releaseMethods . push ( self . observeRecord ( record , recordUpdated ) ) ; return self . wrapRecord ( record ) ; } ) ; var contentDidChange = function ( array , idx , removedCount , addedCount ) { for ( var i = idx ; i < idx + addedCount ; i ++ ) { var record = array . objectAt ( i ) ; var wrapped = self . wrapRecord ( record ) ; releaseMethods . push ( self . observeRecord ( record , recordUpdated ) ) ; recordsAdded ( [ wrapped ] ) ; } if ( removedCount ) { recordsRemoved ( idx , removedCount ) ; } } ; var observer = { didChange : contentDidChange , willChange : Ember . K } ; records . addArrayObserver ( self , observer ) ; release = function ( ) { releaseMethods . forEach ( function ( fn ) { fn ( ) ; } ) ; records . removeArrayObserver ( self , observer ) ; self . releaseMethods . removeObject ( release ) ; } ; recordsAdded ( recordsToSend ) ; this . releaseMethods . pushObject ( release ) ; return release ; }

Fetch the records of a given type and observe them for changes.

@public
@method watchRecords

@param {Function} recordsAdded Callback to call to add records.
Takes an array of objects containing wrapped records.
The object should have the following properties:
columnValues: {Object} key and value of a table cell
object: {Object} the actual record object

@param {Function} recordsUpdated Callback to call when a record has changed.
Takes an array of objects containing wrapped records.

@param {Function} recordsRemoved Callback to call when a record has removed.
Takes the following parameters:
index: the array index where the records were removed
count: the number of records removed

@return {Function} Method to call to remove all observers

Fetch the records of a given type and observe them for changes .


function(type, typesUpdated) {
    var self = this, records = this.getRecords(type);

    var onChange = function() {
      typesUpdated([self.wrapModelType(type)]);
    };
    var observer = {
      didChange: function() {
        Ember.run.scheduleOnce('actions', this, onChange);
      },
      willChange: Ember.K
    };

    records.addArrayObserver(this, observer);

    var release = function() {
      records.removeArrayObserver(self, observer);
    };

    return release;
  }

function ( type , typesUpdated ) { var self = this , records = this . getRecords ( type ) ; var onChange = function ( ) { typesUpdated ( [ self . wrapModelType ( type ) ] ) ; } ; var observer = { didChange : function ( ) { Ember . run . scheduleOnce ( 'actions' , this , onChange ) ; } , willChange : Ember . K } ; records . addArrayObserver ( this , observer ) ; var release = function ( ) { records . removeArrayObserver ( self , observer ) ; } ; return release ; }

Adds observers to a model type class.

@private
@method observeModelType
@param {Class} type The model type class
@param {Function} typesUpdated Called when a type is modified.
@return {Function} The function to call to remove observers


function() {
    var namespaces = Ember.A(Ember.Namespace.NAMESPACES), types = Ember.A();

    namespaces.forEach(function(namespace) {
      for (var key in namespace) {
        if (!namespace.hasOwnProperty(key)) { continue; }
        var name = Ember.String.dasherize(key);
        if (!(namespace instanceof Ember.Application) && namespace.toString()) {
          name = namespace + '/' + name;
        }
        types.push(name);
      }
    });
    return types;
  }

function ( ) { var namespaces = Ember . A ( Ember . Namespace . NAMESPACES ) , types = Ember . A ( ) ; namespaces . forEach ( function ( namespace ) { for ( var key in namespace ) { if ( ! namespace . hasOwnProperty ( key ) ) { continue ; } var name = Ember . String . dasherize ( key ) ; if ( ! ( namespace instanceof Ember . Application ) && namespace . toString ( ) ) { name = namespace + '/' + name ; } types . push ( name ) ; } } ) ; return types ; }

Loops over all namespaces and all objects
attached to them

@private
@method _getObjectsOnNamespaces
@return {Array} Array of model type strings


function(context, callback) {
    if (arguments.length === 1) {
      callback = context;
      context = null;
    }
    if (!this.waiters) {
      this.waiters = Ember.A();
    }
    this.waiters.push([context, callback]);
  }

function ( context , callback ) { if ( arguments . length === 1 ) { callback = context ; context = null ; } if ( ! this . waiters ) { this . waiters = Ember . A ( ) ; } this . waiters . push ( [ context , callback ] ) ; }

This allows ember-testing to play nicely with other asynchronous
events, such as an application that is waiting for a CSS3
transition or an IndexDB transaction.

For example:

```javascript
Ember.Test.registerWaiter(function() {
return myPendingTransactions() == 0;
});
```
The `context` argument allows you to optionally specify the `this`
with which your callback will be invoked.

For example:

```javascript
Ember.Test.registerWaiter(MyDB, MyDB.hasPendingTransactions);
```

@public
@method registerWaiter
@param {Object} context (optional)
@param {Function} callback

This allows ember - testing to play nicely with other asynchronous events such as an application that is waiting for a CSS3 transition or an IndexDB transaction .


function(context, callback) {
    var pair;
    if (!this.waiters) { return; }
    if (arguments.length === 1) {
      callback = context;
      context = null;
    }
    pair = [context, callback];
    this.waiters = Ember.A(this.waiters.filter(function(elt) {
      return Ember.compare(elt, pair)!==0;
    }));
  }

function ( context , callback ) { var pair ; if ( ! this . waiters ) { return ; } if ( arguments . length === 1 ) { callback = context ; context = null ; } pair = [ context , callback ] ; this . waiters = Ember . A ( this . waiters . filter ( function ( elt ) { return Ember . compare ( elt , pair ) !== 0 ; } ) ) ; }

`unregisterWaiter` is used to unregister a callback that was
registered with `registerWaiter`.

@public
@method unregisterWaiter
@param {Object} context (optional)
@param {Function} callback

unregisterWaiter is used to unregister a callback that was registered with registerWaiter .


function() {
    for (var name in helpers) {
      this.helperContainer[name] = this.originalMethods[name];
      delete this.testHelpers[name];
      delete this.originalMethods[name];
    }
  }

function ( ) { for ( var name in helpers ) { this . helperContainer [ name ] = this . originalMethods [ name ] ; delete this . testHelpers [ name ] ; delete this . originalMethods [ name ] ; } }

This removes all helpers that have been registered, and resets and functions
that were overridden by the helpers.

Example:

```javascript
App.removeTestHelpers();
```

@public
@method removeTestHelpers

This removes all helpers that have been registered and resets and functions that were overridden by the helpers .


function protoWrap(proto, name, callback, isAsync) {
  proto[name] = function() {
    var args = arguments;
    if (isAsync) {
      return callback.apply(this, args);
    } else {
      return this.then(function() {
        return callback.apply(this, args);
      });
    }
  };
}

function protoWrap ( proto , name , callback , isAsync ) { proto [ name ] = function ( ) { var args = arguments ; if ( isAsync ) { return callback . apply ( this , args ) ; } else { return this . then ( function ( ) { return callback . apply ( this , args ) ; } ) ; } } ; }

This method is no longer needed But still here for backwards compatibility of helper chaining


function toPropertyDescriptor(obj) {
  if (Object(obj) !== obj) {
    throw new TypeError("property descriptor should be an Object, given: "+
                        obj);
  }
  var desc = {};
  if ('enumerable' in obj) { desc.enumerable = !!obj.enumerable; }
  if ('configurable' in obj) { desc.configurable = !!obj.configurable; }
  if ('value' in obj) { desc.value = obj.value; }
  if ('writable' in obj) { desc.writable = !!obj.writable; }
  if ('get' in obj) {
    var getter = obj.get;
    if (getter !== undefined && typeof getter !== "function") {
      throw new TypeError("property descriptor 'get' attribute must be "+
                          "callable or undefined, given: "+getter);
    }
    desc.get = getter;
  }
  if ('set' in obj) {
    var setter = obj.set;
    if (setter !== undefined && typeof setter !== "function") {
      throw new TypeError("property descriptor 'set' attribute must be "+
                          "callable or undefined, given: "+setter);
    }
    desc.set = setter;
  }
  if ('get' in desc || 'set' in desc) {
    if ('value' in desc || 'writable' in desc) {
      throw new TypeError("property descriptor cannot be both a data and an "+
                          "accessor descriptor: "+obj);
    }
  }
  return desc;
}


function normalizePropertyDescriptor(attributes) {
  var desc = toPropertyDescriptor(attributes);
  // Note: no need to call FromGenericPropertyDescriptor(desc), as we represent
  // "internal" property descriptors as proper Objects from the start
  for (var name in attributes) {
    if (!isStandardAttribute(name)) {
      Object.defineProperty(desc, name,
        { value: attributes[name],
          writable: true,
          enumerable: true,
          configurable: true });
    }
  }
  return desc;
}

function normalizePropertyDescriptor ( attributes ) { var desc = toPropertyDescriptor ( attributes ) ; for ( var name in attributes ) { if ( ! isStandardAttribute ( name ) ) { Object . defineProperty ( desc , name , { value : attributes [ name ] , writable : true , enumerable : true , configurable : true } ) ; } } return desc ; }

Returns a fresh property descriptor whose standard
attributes are guaranteed to be data properties of the right type.
Additionally, any non-standard enumerable properties of
attributes are copied over to the fresh descriptor.

If attributes is undefined, will throw a TypeError.

See also: http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics

Returns a fresh property descriptor whose standard attributes are guaranteed to be data properties of the right type . Additionally any non - standard enumerable properties of attributes are copied over to the fresh descriptor .


function isCompatibleDescriptor(extensible, current, desc) {
  if (current === undefined && extensible === false) {
    return false;
  }
  if (current === undefined && extensible === true) {
    return true;
  }
  if (isEmptyDescriptor(desc)) {
    return true;
  }
  if (isEquivalentDescriptor(current, desc)) {
    return true;
  }
  if (current.configurable === false) {
    if (desc.configurable === true) {
      return false;
    }
    if ('enumerable' in desc && desc.enumerable !== current.enumerable) {
      return false;
    }
  }
  if (isGenericDescriptor(desc)) {
    return true;
  }
  if (isDataDescriptor(current) !== isDataDescriptor(desc)) {
    if (current.configurable === false) {
      return false;
    }
    return true;
  }
  if (isDataDescriptor(current) && isDataDescriptor(desc)) {
    if (current.configurable === false) {
      if (current.writable === false && desc.writable === true) {
        return false;
      }
      if (current.writable === false) {
        if ('value' in desc && !sameValue(desc.value, current.value)) {
          return false;
        }
      }
    }
    return true;
  }
  if (isAccessorDescriptor(current) && isAccessorDescriptor(desc)) {
    if (current.configurable === false) {
      if ('set' in desc && !sameValue(desc.set, current.set)) {
        return false;
      }
      if ('get' in desc && !sameValue(desc.get, current.get)) {
        return false;
      }
    }
  }
  return true;
}

function isCompatibleDescriptor ( extensible , current , desc ) { if ( current === undefined && extensible === false ) { return false ; } if ( current === undefined && extensible === true ) { return true ; } if ( isEmptyDescriptor ( desc ) ) { return true ; } if ( isEquivalentDescriptor ( current , desc ) ) { return true ; } if ( current . configurable === false ) { if ( desc . configurable === true ) { return false ; } if ( 'enumerable' in desc && desc . enumerable !== current . enumerable ) { return false ; } } if ( isGenericDescriptor ( desc ) ) { return true ; } if ( isDataDescriptor ( current ) !== isDataDescriptor ( desc ) ) { if ( current . configurable === false ) { return false ; } return true ; } if ( isDataDescriptor ( current ) && isDataDescriptor ( desc ) ) { if ( current . configurable === false ) { if ( current . writable === false && desc . writable === true ) { return false ; } if ( current . writable === false ) { if ( 'value' in desc && ! sameValue ( desc . value , current . value ) ) { return false ; } } } return true ; } if ( isAccessorDescriptor ( current ) && isAccessorDescriptor ( desc ) ) { if ( current . configurable === false ) { if ( 'set' in desc && ! sameValue ( desc . set , current . set ) ) { return false ; } if ( 'get' in desc && ! sameValue ( desc . get , current . get ) ) { return false ; } } } return true ; }

Performs all validation that Object.defineProperty performs,
without actually defining the property. Returns a boolean
indicating whether validation succeeded.

Implementation transliterated from ES5.1 section 8.12.9

Performs all validation that Object . defineProperty performs without actually defining the property . Returns a boolean indicating whether validation succeeded .


function(trapName) {
    var trap = this.handler[trapName];
    if (trap === undefined) {
      // the trap was not defined,
      // perform the default forwarding behavior
      return undefined;
    }

    if (typeof trap !== "function") {
      throw new TypeError(trapName + " trap is not callable: "+trap);
    }

    return trap;
  }

function
(
trapName
)
{
var
trap
=
this
.
handler
[
trapName
]
;
if
(
trap
===
undefined
)
{
return
undefined
;
}
if
(
typeof
trap
!==
"function"
)
{
throw
new
TypeError
(
trapName
+
" trap is not callable: "
+
trap
)
;
}
return
trap
;
}

If getTrap returns undefined, the caller should perform the
default forwarding behavior.
If getTrap returns normally otherwise, the return value
will be a callable trap function. When calling the trap function,
the caller is responsible for binding its |this| to |this.handler|.

If getTrap returns undefined the caller should perform the default forwarding behavior . If getTrap returns normally otherwise the return value will be a callable trap function . When calling the trap function the caller is responsible for binding its |this| to |this . handler| .


function(name) {
    var handler = this;

    if (!handler.has(name)) return undefined;

    return {
      get: function() {
        return handler.get(this, name);
      },
      set: function(val) {
        if (handler.set(this, name, val)) {
          return val;
        } else {
          throw new TypeError("failed assignment to "+name);
        }
      },
      enumerable: true,
      configurable: true
    };
  }

function
(
name
)
{
var
handler
=
this
;
if
(
!
handler
.
has
(
name
)
)
return
undefined
;
return
{
get
:
function
(
)
{
return
handler
.
get
(
this
,
name
)
;
}
,
set
:
function
(
val
)
{
if
(
handler
.
set
(
this
,
name
,
val
)
)
{
return
val
;
}
else
{
throw
new
TypeError
(
"failed assignment to "
+
name
)
;
}
}
,
enumerable
:
true
,
configurable
:
true
}
;
}

In the direct proxies design with refactored prototype climbing,
this trap is deprecated. For proxies-as-prototypes, instead
of calling this trap, the get, set, has or enumerate traps are
called instead.

In this implementation, we "abuse" getPropertyDescriptor to
support trapping the get or set traps for proxies-as-prototypes.
We do this by returning a getter/setter pair that invokes
the corresponding traps.

While this hack works for inherited property access, it has some
quirks:

In Firefox, this trap is only called after a prior invocation
of the 'has' trap has returned true. Hence, expect the following
behavior:

var child = Object.create(Proxy(target, handler));
child[name] // triggers handler.has(target, name)
// if that returns true, triggers handler.get(target, name, child)

On v8, the 'in' operator, when applied to an object that inherits
from a proxy, will call getPropertyDescriptor and walk the proto-chain.
That calls the below getPropertyDescriptor trap on the proxy. The
result of the 'in'-operator is then determined by whether this trap
returns undefined or a property descriptor object. That is why
we first explicitly trigger the 'has' trap to determine whether
the property exists.

This has the side-effect that when enumerating properties on
an object that inherits from a proxy in v8, only properties
for which 'has' returns true are returned:

var child = Object.create(Proxy(target, handler));
for (var prop in child) {
// only enumerates prop if (prop in child) returns true
}

In the direct proxies design with refactored prototype climbing this trap is deprecated . For proxies - as - prototypes instead of calling this trap the get set has or enumerate traps are called instead .


function() {
    var trap = this.getTrap("freeze");
    if (trap === undefined) {
      // default forwarding behavior
      return Reflect.freeze(this.target);
    }

    var success = trap.call(this.handler, this.target);
    success = !!success; // coerce to Boolean
    if (success) {
      if (!Object_isFrozen(this.target)) {
        throw new TypeError("can't report non-frozen object as frozen: "+
                            this.target);
      }
    }
    return success;
  }

On success, check whether the target object is indeed frozen.

On success check whether the target object is indeed frozen .


function() {
    var trap = this.getTrap("seal");
    if (trap === undefined) {
      // default forwarding behavior
      return Reflect.seal(this.target);
    }

    var success = trap.call(this.handler, this.target);
    success = !!success; // coerce to Boolean
    if (success) {
      if (!Object_isSealed(this.target)) {
        throw new TypeError("can't report non-sealed object as sealed: "+
                            this.target);
      }
    }
    return success;
  }

On success, check whether the target object is indeed sealed.

On success check whether the target object is indeed sealed .


function() {
    var trap = this.getTrap("preventExtensions");
    if (trap === undefined) {
      // default forwarding behavior
      return Reflect.preventExtensions(this.target);
    }

    var success = trap.call(this.handler, this.target);
    success = !!success; // coerce to Boolean
    if (success) {
      if (Object_isExtensible(this.target)) {
        throw new TypeError("can't report extensible object as non-extensible: "+
                            this.target);
      }
    }
    return success;
  }

On success, check whether the target object is indeed non-extensible.

On success check whether the target object is indeed non - extensible .


function(name) {
    "use strict";
    var trap = this.getTrap("deleteProperty");
    if (trap === undefined) {
      // default forwarding behavior
      return Reflect.deleteProperty(this.target, name);
    }

    name = String(name);
    var res = trap.call(this.handler, this.target, name);
    res = !!res; // coerce to Boolean

    if (res === true) {
      if (isSealed(name, this.target)) {
        throw new TypeError("property '"+name+"' is non-configurable "+
                            "and can't be deleted");
      }
    }

    return res;
  }

function
(
name
)
{
"use strict"
;
var
trap
=
this
.
getTrap
(
"deleteProperty"
)
;
if
(
trap
===
undefined
)
{
return
Reflect
.
deleteProperty
(
this
.
target
,
name
)
;
}
name
=
String
(
name
)
;
var
res
=
trap
.
call
(
this
.
handler
,
this
.
target
,
name
)
;
res
=
!
!
res
;
if
(
res
===
true
)
{
if
(
isSealed
(
name
,
this
.
target
)
)
{
throw
new
TypeError
(
"property '"
+
name
+
"' is non-configurable "
+
"and can't be deleted"
)
;
}
}
return
res
;
}

If name denotes a sealed property, check whether handler rejects.

If name denotes a sealed property check whether handler rejects .


function() {
    var trap = this.getTrap("iterate");
    if (trap === undefined) {
      // default forwarding behavior
      return Reflect.iterate(this.target);
    }

    var trapResult = trap.call(this.handler, this.target);

    if (Object(trapResult) !== trapResult) {
      throw new TypeError("iterate trap should return an iterator object, "+
                          "got: "+ trapResult);
    }
    return trapResult;
  }

The iterate trap should return an iterator object.

The iterate trap should return an iterator object .


function() {
    var trap = this.getTrap("keys");
    if (trap === undefined) {
      // default forwarding behavior
      return Reflect.keys(this.target);
    }

    var trapResult = trap.call(this.handler, this.target);

    // propNames is used as a set of strings
    var propNames = Object.create(null);
    var numProps = +trapResult.length;
    var result = new Array(numProps);

    for (var i = 0; i < numProps; i++) {
     var s = String(trapResult[i]);
     if (propNames[s]) {
       throw new TypeError("keys trap cannot list a "+
                           "duplicate property '"+s+"'");
     }
     if (!Object.isExtensible(this.target) && !isFixed(s, this.target)) {
       // non-extensible proxies don't tolerate new own property names
       throw new TypeError("keys trap cannot list a new "+
                           "property '"+s+"' on a non-extensible object");
     }

     propNames[s] = true;
     result[i] = s;
    }

    var ownEnumerableProps = Object.keys(this.target);
    var target = this.target;
    ownEnumerableProps.forEach(function (ownEnumerableProp) {
      if (!propNames[ownEnumerableProp]) {
        if (isSealed(ownEnumerableProp, target)) {
          throw new TypeError("keys trap failed to include "+
                              "non-configurable enumerable property '"+
                              ownEnumerableProp+"'");
        }
        if (!Object.isExtensible(target) &&
            isFixed(ownEnumerableProp, target)) {
            // if handler is allowed not to report ownEnumerableProp as an own
            // property, we cannot guarantee that it will never report it as
            // an own property later. Once a property has been reported as
            // non-existent on a non-extensible object, it should forever be
            // reported as non-existent
            throw new TypeError("cannot report existing own property '"+
                                ownEnumerableProp+"' as non-existent on a "+
                                "non-extensible object");
        }
      }
    });

    return result;
  }

Any own non-configurable properties of the target that are not included
in the trap result give rise to a TypeError. As such, we check whether the
returned result contains at least all sealed properties of the target
object.

The trap result is normalized.
The trap result is not returned directly. Instead:
- create and return a fresh Array,
- of which each element is coerced to String,
- which does not contain duplicates

Any own non - configurable properties of the target that are not included in the trap result give rise to a TypeError . As such we check whether the returned result contains at least all sealed properties of the target object .


function() {
    var trap = this.getTrap("ownKeys");
    if (trap === undefined) {
      // default forwarding behavior
      return Reflect.ownKeys(this.target);
    }

    var trapResult = trap.call(this.handler, this.target);

    if (trapResult === null || typeof trapResult !== "object") {
      throw new TypeError("ownKeys should return an iterator object, got " +
                          trapResult);
    }

    return trapResult;
  }

In ES6, this trap is called for all operations that require a list
of an object's properties, including Object.getOwnPropertyNames
and Object.keys.

The trap should return an iterator. The proxy implementation only
checks whether the return value is an object.

In ES6 this trap is called for all operations that require a list of an object s properties including Object . getOwnPropertyNames and Object . keys .


function makeUnwrapping0ArgMethod(primitive) {
  return function builtin() {
    var vHandler = safeWeakMapGet(directProxies, this);
    if (vHandler !== undefined) {
      return builtin.call(vHandler.target);
    } else {
      return primitive.call(this);
    }
  }
}

function makeUnwrapping0ArgMethod ( primitive ) { return function builtin ( ) { var vHandler = safeWeakMapGet ( directProxies , this ) ; if ( vHandler !== undefined ) { return builtin . call ( vHandler . target ) ; } else { return primitive . call ( this ) ; } } }

returns a new function of zero arguments that recursively unwraps any proxies specified as the |this|-value. The primitive is assumed to be a zero-argument method that uses its |this|-binding.

returns a new function of zero arguments that recursively unwraps any proxies specified as the |this| - value . The primitive is assumed to be a zero - argument method that uses its |this| - binding .


function load(obj) {
  var name, root;
  root = typeof global !== "undefined" && global !== null ? global : this;
  for(name in obj) {
    if(obj.hasOwnProperty(name)) {
      root[name] = obj[name];
    }
  }
}

function load ( obj ) { var name , root ; root = typeof global !== "undefined" && global !== null ? global : this ; for ( name in obj ) { if ( obj . hasOwnProperty ( name ) ) { root [ name ] = obj [ name ] ; } } }

load all the contract identifiers into the global scope


function(record, options) {
    var json = {};

    if (options && options.includeId) {
      var id = get(record, 'id');

      if (id) {
        json[get(this, 'primaryKey')] = id;
      }
    }

    record.eachAttribute(function(key, attribute) {
      this.serializeAttribute(record, json, key, attribute);
    }, this);

    record.eachRelationship(function(key, relationship) {
      if (relationship.kind === 'belongsTo') {
        this.serializeBelongsTo(record, json, relationship);
      } else if (relationship.kind === 'hasMany') {
        this.serializeHasMany(record, json, relationship);
      }
    }, this);

    return json;
  }

function ( record , options ) { var json = { } ; if ( options && options . includeId ) { var id = get ( record , 'id' ) ; if ( id ) { json [ get ( this , 'primaryKey' ) ] = id ; } } record . eachAttribute ( function ( key , attribute ) { this . serializeAttribute ( record , json , key , attribute ) ; } , this ) ; record . eachRelationship ( function ( key , relationship ) { if ( relationship . kind === 'belongsTo' ) { this . serializeBelongsTo ( record , json , relationship ) ; } else if ( relationship . kind === 'hasMany' ) { this . serializeHasMany ( record , json , relationship ) ; } } , this ) ; return json ; }

SERIALIZE
Called when a record is saved in order to convert the
record into JSON.

By default, it creates a JSON object with a key for
each attribute and belongsTo relationship.

For example, consider this model:

```javascript
App.Comment = DS.Model.extend({
title: DS.attr(),
body: DS.attr(),

author: DS.belongsTo('user')
});
```

The default serialization would create a JSON object like:

```javascript
{
"title": "Rails is unagi",
"body": "Rails? Omakase? O_O",
"author": 12
}
```

By default, attributes are passed through as-is, unless
you specified an attribute type (`DS.attr('date')`). If
you specify a transform, the JavaScript value will be
serialized when inserted into the JSON hash.

By default, belongs-to relationships are converted into
IDs when inserted into the JSON hash.

## IDs

`serialize` takes an options hash with a single option:
`includeId`. If this option is `true`, `serialize` will,
by default include the ID in the JSON object it builds.

The adapter passes in `includeId: true` when serializing
a record for `createRecord`, but not for `updateRecord`.

## Customization

Your server may expect a different JSON format than the
built-in serialization format.

In that case, you can implement `serialize` yourself and
return a JSON hash of your choosing.

```javascript
App.PostSerializer = DS.JSONSerializer.extend({
serialize: function(post, options) {
var json = {
POST_TTL: post.get('title'),
POST_BDY: post.get('body'),
POST_CMS: post.get('comments').mapProperty('id')
}

if (options.includeId) {
json.POST_ID_ = post.get('id');
}

return json;
}
});
```

## Customizing an App-Wide Serializer

If you want to define a serializer for your entire
application, you'll probably want to use `eachAttribute`
and `eachRelationship` on the record.

```javascript
App.ApplicationSerializer = DS.JSONSerializer.extend({
serialize: function(record, options) {
var json = {};

record.eachAttribute(function(name) {
json[serverAttributeName(name)] = record.get(name);
})

record.eachRelationship(function(name, relationship) {
if (relationship.kind === 'hasMany') {
json[serverHasManyName(name)] = record.get(name).mapBy('id');
}
});

if (options.includeId) {
json.ID_ = record.get('id');
}

return json;
}
});

function serverAttributeName(attribute) {
return attribute.underscore().toUpperCase();
}

function serverHasManyName(name) {
return serverAttributeName(name.singularize()) + "_IDS";
}
```

This serializer will generate JSON that looks like this:

```javascript
{
"TITLE": "Rails is omakase",
"BODY": "Yep. Omakase.",
"COMMENT_IDS": [ 1, 2, 3 ]
}
```

## Tweaking the Default JSON

If you just want to do some small tweaks on the default JSON,
you can call super first and make the tweaks on the returned
JSON.

```javascript
App.PostSerializer = DS.JSONSerializer.extend({
serialize: function(record, options) {
var json = this._super.apply(this, arguments);

json.subject = json.title;
delete json.title;

return json;
}
});
```

@method serialize
@param {subclass of DS.Model} record
@param {Object} options
@return {Object} json

SERIALIZE Called when a record is saved in order to convert the record into JSON .


function(record, json, key, attribute) {
    var attrs = get(this, 'attrs');
    var value = get(record, key), type = attribute.type;

    if (type) {
      var transform = this.transformFor(type);
      value = transform.serialize(value);
    }

    // if provided, use the mapping provided by `attrs` in
    // the serializer
    key = attrs && attrs[key] || (this.keyForAttribute ? this.keyForAttribute(key) : key);

    json[key] = value;
  }

function ( record , json , key , attribute ) { var attrs = get ( this , 'attrs' ) ; var value = get ( record , key ) , type = attribute . type ; if ( type ) { var transform = this . transformFor ( type ) ; value = transform . serialize ( value ) ; } key = attrs && attrs [ key ] || ( this . keyForAttribute ? this . keyForAttribute ( key ) : key ) ; json [ key ] = value ; }

`serializeAttribute` can be used to customize how `DS.attr`
properties are serialized

For example if you wanted to ensure all you attributes were always
serialized as properties on an `attributes` object you could
write:

```javascript
App.ApplicationSerializer = DS.JSONSerializer.extend({
serializeAttribute: function(record, json, key, attributes) {
json.attributes = json.attributes || {};
this._super(record, json.attributes, key, attributes);
}
});
```

@method serializeAttribute
@param {DS.Model} record
@param {Object} json
@param {String} key
@param {Object} attribute

serializeAttribute can be used to customize how DS . attr properties are serialized


function(record, json, relationship) {
    var key = relationship.key;

    var belongsTo = get(record, key);

    key = this.keyForRelationship ? this.keyForRelationship(key, "belongsTo") : key;

    if (isNone(belongsTo)) {
      json[key] = belongsTo;
    } else {
      json[key] = get(belongsTo, 'id');
    }

    if (relationship.options.polymorphic) {
      this.serializePolymorphicType(record, json, relationship);
    }
  }

function ( record , json , relationship ) { var key = relationship . key ; var belongsTo = get ( record , key ) ; key = this . keyForRelationship ? this . keyForRelationship ( key , "belongsTo" ) : key ; if ( isNone ( belongsTo ) ) { json [ key ] = belongsTo ; } else { json [ key ] = get ( belongsTo , 'id' ) ; } if ( relationship . options . polymorphic ) { this . serializePolymorphicType ( record , json , relationship ) ; } }

`serializeBelongsTo` can be used to customize how `DS.belongsTo`
properties are serialized.

Example

```javascript
App.PostSerializer = DS.JSONSerializer.extend({
serializeBelongsTo: function(record, json, relationship) {
var key = relationship.key;

var belongsTo = get(record, key);

key = this.keyForRelationship ? this.keyForRelationship(key, "belongsTo") : key;

json[key] = Ember.isNone(belongsTo) ? belongsTo : belongsTo.toJSON();
}
});
```

@method serializeBelongsTo
@param {DS.Model} record
@param {Object} json
@param {Object} relationship

serializeBelongsTo can be used to customize how DS . belongsTo properties are serialized .


function(record, json, relationship) {
    var key = relationship.key;

    var relationshipType = DS.RelationshipChange.determineRelationshipType(record.constructor, relationship);

    if (relationshipType === 'manyToNone' || relationshipType === 'manyToMany') {
      json[key] = get(record, key).mapBy('id');
      // TODO support for polymorphic manyToNone and manyToMany relationships
    }
  }

function ( record , json , relationship ) { var key = relationship . key ; var relationshipType = DS . RelationshipChange . determineRelationshipType ( record . constructor , relationship ) ; if ( relationshipType === 'manyToNone' || relationshipType === 'manyToMany' ) { json [ key ] = get ( record , key ) . mapBy ( 'id' ) ; } }

`serializeHasMany` can be used to customize how `DS.hasMany`
properties are serialized.

Example

```javascript
App.PostSerializer = DS.JSONSerializer.extend({
serializeHasMany: function(record, json, relationship) {
var key = relationship.key;
if (key === 'comments') {
return;
} else {
this._super.apply(this, arguments);
}
}
});
```

@method serializeHasMany
@param {DS.Model} record
@param {Object} json
@param {Object} relationship

serializeHasMany can be used to customize how DS . hasMany properties are serialized .


function(store, type, payload, id, requestType) {
    this.extractMeta(store, type, payload);

    var specificExtract = "extract" + requestType.charAt(0).toUpperCase() + requestType.substr(1);
    return this[specificExtract](store, type, payload, id, requestType);
  }

function ( store , type , payload , id , requestType ) { this . extractMeta ( store , type , payload ) ; var specificExtract = "extract" + requestType . charAt ( 0 ) . toUpperCase ( ) + requestType . substr ( 1 ) ; return this [ specificExtract ] ( store , type , payload , id , requestType ) ; }

EXTRACT
The `extract` method is used to deserialize payload data from the
server. By default the `JSONSerializer` does not push the records
into the store. However records that subclass `JSONSerializer`
such as the `RESTSerializer` may push records into the store as
part of the extract call.

This method deletegates to a more specific extract method based on
the `requestType`.

Example

```javascript
var get = Ember.get;
socket.on('message', function(message) {
var modelName = message.model;
var data = message.data;
var type = store.modelFor(modelName);
var serializer = store.serializerFor(type.typeKey);
var record = serializer.extract(store, type, data, get(data, 'id'), 'single');
store.push(modelName, record);
});
```

@method extract
@param {DS.Store} store
@param {subclass of DS.Model} type
@param {Object} payload
@param {String or Number} id
@param {String} requestType
@return {Object} json The deserialized payload

EXTRACT The extract method is used to deserialize payload data from the server . By default the JSONSerializer does not push the records into the store . However records that subclass JSONSerializer such as the RESTSerializer may push records into the store as part of the extract call .


function(store, type, payload) {
    if (payload && payload.meta) {
      store.metaForType(type, payload.meta);
      delete payload.meta;
    }
  }

function ( store , type , payload ) { if ( payload && payload . meta ) { store . metaForType ( type , payload . meta ) ; delete payload . meta ; } }

`extractMeta` is used to deserialize any meta information in the
adapter payload. By default Ember Data expects meta information to
be located on the `meta` property of the payload object.

Example

```javascript
App.PostSerializer = DS.JSONSerializer.extend({
extractMeta: function(store, type, payload) {
if (payload && payload._pagination) {
store.metaForType(type, payload._pagination);
delete payload._pagination;
}
}
});
```

@method extractMeta
@param {DS.Store} store
@param {subclass of DS.Model} type
@param {Object} payload

extractMeta is used to deserialize any meta information in the adapter payload . By default Ember Data expects meta information to be located on the meta property of the payload object .


function() {
    var promiseLabel = "DS: RecordArray#save " + get(this, 'type');
    var promise = Ember.RSVP.all(this.invoke("save"), promiseLabel).then(function(array) {
      return Ember.A(array);
    }, null, "DS: RecordArray#save apply Ember.NativeArray");

    return DS.PromiseArray.create({ promise: promise });
  }

Saves all of the records in the `RecordArray`.

Example

```javascript
var messages = store.all(App.Message);
messages.forEach(function(message) {
message.set('hasBeenSeen', true);
});
messages.save();
```

@method save
@return {DS.PromiseArray} promise

Saves all of the records in the RecordArray .