<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[163429] trunk/PerformanceTests</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/163429">163429</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2014-02-04 21:36:04 -0800 (Tue, 04 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>DoYouEvenBench: Update Ember.js test case
https://bugs.webkit.org/show_bug.cgi?id=128227

Reviewed by Benjamin Poulain.

Updated the Ember.js TodoMVC implementation.

* DoYouEvenBench/resources/tests.js:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower.json:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember-data/ember-data.js: Added.
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember-localstorage-adapter/localstorage_adapter.js:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember/ember.js:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/handlebars/handlebars.js:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/jquery/jquery.js:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/todomvc-common/base.css:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/todomvc-common/base.js:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/index.html:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/app.js:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/controllers/todo_controller.js:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/controllers/todos_controller.js:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/helpers/pluralize.js: Added.
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/libs/ember-data.js: Removed.
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/models/store.js: Removed.
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/models/todo.js:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/router.js:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/views/edit_todo_view.js:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/views/todos_view.js: Added.
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/readme.md:
* DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/test.html:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkPerformanceTestsChangeLog">trunk/PerformanceTests/ChangeLog</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestestsjs">trunk/PerformanceTests/DoYouEvenBench/resources/tests.js</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbowerjson">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower.json</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbower_componentsemberemberjs">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember/ember.js</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbower_componentsemberlocalstorageadapterlocalstorage_adapterjs">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember-localstorage-adapter/localstorage_adapter.js</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbower_componentshandlebarshandlebarsjs">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/handlebars/handlebars.js</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbower_componentsjqueryjqueryjs">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/jquery/jquery.js</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbower_componentstodomvccommonbasecss">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/todomvc-common/base.css</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbower_componentstodomvccommonbasejs">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/todomvc-common/base.js</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsindexhtml">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/index.html</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjsappjs">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/app.js</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjscontrollerstodo_controllerjs">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/controllers/todo_controller.js</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjscontrollerstodos_controllerjs">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/controllers/todos_controller.js</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjsmodelstodojs">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/models/todo.js</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjsrouterjs">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/router.js</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjsviewsedit_todo_viewjs">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/views/edit_todo_view.js</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsreadmemd">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/readme.md</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjstesthtml">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/test.html</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember-data/</li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbower_componentsemberdataemberdatajs">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember-data/ember-data.js</a></li>
<li>trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/helpers/</li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjshelperspluralizejs">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/helpers/pluralize.js</a></li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjsviewstodos_viewjs">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/views/todos_view.js</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li>trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/libs/</li>
<li><a href="#trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjsmodelsstorejs">trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/models/store.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkPerformanceTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/ChangeLog (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/ChangeLog        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/ChangeLog        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -1,3 +1,35 @@
</span><ins>+2014-02-04  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
+        DoYouEvenBench: Update Ember.js test case
+        https://bugs.webkit.org/show_bug.cgi?id=128227
+
+        Reviewed by Benjamin Poulain.
+
+        Updated the Ember.js TodoMVC implementation.
+
+        * DoYouEvenBench/resources/tests.js:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower.json:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember-data/ember-data.js: Added.
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember-localstorage-adapter/localstorage_adapter.js:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember/ember.js:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/handlebars/handlebars.js:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/jquery/jquery.js:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/todomvc-common/base.css:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/todomvc-common/base.js:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/index.html:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/app.js:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/controllers/todo_controller.js:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/controllers/todos_controller.js:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/helpers/pluralize.js: Added.
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/libs/ember-data.js: Removed.
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/models/store.js: Removed.
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/models/todo.js:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/router.js:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/views/edit_todo_view.js:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/views/todos_view.js: Added.
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/readme.md:
+        * DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/test.html:
+
</ins><span class="cx"> 2014-02-04  Zoltan Horvath  &lt;zoltan@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         [CSS Shapes] Add initial performance test for shape-outside: content-box
</span></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestestsjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/tests.js (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/tests.js        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/tests.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -35,12 +35,6 @@
</span><span class="cx">     name: 'EmberJS-TodoMVC',
</span><span class="cx">     url: 'todomvc/architecture-examples/emberjs/index.html',
</span><span class="cx">     prepare: function (runner, contentWindow, contentDocument) {
</span><del>-        contentWindow.Todos.Store = contentWindow.DS.Store.extend({
-            revision: 12,
-            adapter: 'Todos.LSAdapter',
-            commit: function () { }
-        });
-
</del><span class="cx">         return runner.waitForElement('#new-todo').then(function (element) {
</span><span class="cx">             element.focus();
</span><span class="cx">             return {
</span></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbowerjson"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower.json (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower.json        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower.json        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -3,9 +3,10 @@
</span><span class="cx">   &quot;version&quot;: &quot;0.0.0&quot;,
</span><span class="cx">   &quot;dependencies&quot;: {
</span><span class="cx">     &quot;todomvc-common&quot;: &quot;~0.1.4&quot;,
</span><del>-    &quot;jquery&quot;: &quot;~1.9.1&quot;,
-    &quot;handlebars&quot;: &quot;~1.0.0-rc.3&quot;,
-    &quot;ember&quot;: &quot;~1.0.0-rc.1&quot;,
</del><ins>+    &quot;jquery&quot;: &quot;~2.1.0&quot;,
+    &quot;handlebars&quot;: &quot;~1.3.0&quot;,
+    &quot;ember&quot;: &quot;~1.3.1&quot;,
+    &quot;ember-data&quot;: &quot;1.0.0-beta.6&quot;,
</ins><span class="cx">     &quot;ember-localstorage-adapter&quot;: &quot;latest&quot;
</span><span class="cx">   }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbower_componentsemberemberjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember/ember.js (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember/ember.js        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember/ember.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -1,5 +1,12 @@
</span><del>-// Version: v1.0.0-rc.1
-// Last commit: 8b061b4 (2013-02-15 12:10:22 -0800)
</del><ins>+/*!
+ * @overview  Ember - JavaScript Application Framework
+ * @copyright Copyright 2011-2014 Tilde Inc. and contributors
+ *            Portions Copyright 2006-2011 Strobe Inc.
+ *            Portions Copyright 2008-2011 Apple Inc. All rights reserved.
+ * @license   Licensed under MIT license
+ *            See https://raw.github.com/emberjs/ember.js/master/LICENSE
+ * @version   1.3.1
+ */
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><span class="lines">@@ -24,7 +31,20 @@
</span><span class="cx">   }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ember.ENV = 'undefined' === typeof ENV ? {} : ENV;
</del><ins>+// This needs to be kept in sync with the logic in
+// `packages/ember-metal/lib/core.js`.
+//
+// This is duplicated here to ensure that `Ember.ENV`
+// is setup even if `Ember` is not loaded yet.
+if (Ember.ENV) {
+  // do nothing if Ember.ENV is already setup
+} else if ('undefined' !== typeof EmberENV) {
+  Ember.ENV = EmberENV;
+} else if('undefined' !== typeof ENV) {
+  Ember.ENV = ENV;
+} else {
+  Ember.ENV = {};
+}
</ins><span class="cx"> 
</span><span class="cx"> if (!('MANDATORY_SETTER' in Ember.ENV)) {
</span><span class="cx">   Ember.ENV.MANDATORY_SETTER = true; // default to true for debug dist
</span><span class="lines">@@ -49,7 +69,14 @@
</span><span class="cx">     falsy, an exception will be thrown.
</span><span class="cx"> */
</span><span class="cx"> Ember.assert = function(desc, test) {
</span><del>-  if (!test) throw new Error(&quot;assertion failed: &quot;+desc);
</del><ins>+  if (!test) {
+    Ember.Logger.assert(test, desc);
+  }
+
+  if (Ember.testing &amp;&amp; !test) {
+    // when testing, ensure test failures when assertions fail
+    throw new Ember.Error(&quot;Assertion Failed: &quot; + desc);
+  }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -95,12 +122,12 @@
</span><span class="cx">     will be displayed.
</span><span class="cx"> */
</span><span class="cx"> Ember.deprecate = function(message, test) {
</span><del>-  if (Ember &amp;&amp; Ember.TESTING_DEPRECATION) { return; }
</del><ins>+  if (Ember.TESTING_DEPRECATION) { return; }
</ins><span class="cx"> 
</span><span class="cx">   if (arguments.length === 1) { test = false; }
</span><span class="cx">   if (test) { return; }
</span><span class="cx"> 
</span><del>-  if (Ember &amp;&amp; Ember.ENV.RAISE_ON_DEPRECATION) { throw new Error(message); }
</del><ins>+  if (Ember.ENV.RAISE_ON_DEPRECATION) { throw new Ember.Error(message); }
</ins><span class="cx"> 
</span><span class="cx">   var error;
</span><span class="cx"> 
</span><span class="lines">@@ -131,15 +158,22 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+  Alias an old, deprecated method with its new counterpart.
+
</ins><span class="cx">   Display a deprecation warning with the provided message and a stack trace
</span><del>-  (Chrome and Firefox only) when the wrapped method is called.
</del><ins>+  (Chrome and Firefox only) when the assigned method is called.
</ins><span class="cx"> 
</span><span class="cx">   Ember build tools will not remove calls to `Ember.deprecateFunc()`, though
</span><span class="cx">   no warnings will be shown in production.
</span><span class="cx"> 
</span><ins>+  ```javascript
+  Ember.oldMethod = Ember.deprecateFunc(&quot;Please use the new, updated method&quot;, Ember.newMethod);
+  ```
+
</ins><span class="cx">   @method deprecateFunc
</span><span class="cx">   @param {String} message A description of the deprecation.
</span><del>-  @param {Function} func The function to be deprecated.
</del><ins>+  @param {Function} func The new function called to replace its deprecated counterpart.
+  @return {Function} a new function that wrapped the original function with a deprecation warning
</ins><span class="cx"> */
</span><span class="cx"> Ember.deprecateFunc = function(message, func) {
</span><span class="cx">   return function() {
</span><span class="lines">@@ -148,14 +182,33 @@
</span><span class="cx">   };
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+
+// Inform the developer about the Ember Inspector if not installed.
+if (!Ember.testing) {
+  if (typeof window !== 'undefined' &amp;&amp; window.chrome &amp;&amp; window.addEventListener) {
+    window.addEventListener(&quot;load&quot;, function() {
+      if (document.body &amp;&amp; document.body.dataset &amp;&amp; !document.body.dataset.emberExtension) {
+        Ember.debug('For more advanced debugging, install the Ember Inspector from https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi');
+      }
+    }, false);
+  }
+}
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><del>-// Version: v1.0.0-rc.1
-// Last commit: 8b061b4 (2013-02-15 12:10:22 -0800)
</del><ins>+/*!
+ * @overview  Ember - JavaScript Application Framework
+ * @copyright Copyright 2011-2014 Tilde Inc. and contributors
+ *            Portions Copyright 2006-2011 Strobe Inc.
+ *            Portions Copyright 2008-2011 Apple Inc. All rights reserved.
+ * @license   Licensed under MIT license
+ *            See https://raw.github.com/emberjs/ember.js/master/LICENSE
+ * @version   1.3.1
+ */
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-var define, requireModule;
</del><ins>+var define, requireModule, require, requirejs;
</ins><span class="cx"> 
</span><span class="cx"> (function() {
</span><span class="cx">   var registry = {}, seen = {};
</span><span class="lines">@@ -164,10 +217,16 @@
</span><span class="cx">     registry[name] = { deps: deps, callback: callback };
</span><span class="cx">   };
</span><span class="cx"> 
</span><del>-  requireModule = function(name) {
</del><ins>+  requirejs = require = requireModule = function(name) {
+  requirejs._eak_seen = registry;
+
</ins><span class="cx">     if (seen[name]) { return seen[name]; }
</span><span class="cx">     seen[name] = {};
</span><span class="cx"> 
</span><ins>+    if (!registry[name]) {
+      throw new Error(&quot;Could not find module &quot; + name);
+    }
+
</ins><span class="cx">     var mod = registry[name],
</span><span class="cx">         deps = mod.deps,
</span><span class="cx">         callback = mod.callback,
</span><span class="lines">@@ -178,16 +237,32 @@
</span><span class="cx">       if (deps[i] === 'exports') {
</span><span class="cx">         reified.push(exports = {});
</span><span class="cx">       } else {
</span><del>-        reified.push(requireModule(deps[i]));
</del><ins>+        reified.push(requireModule(resolve(deps[i])));
</ins><span class="cx">       }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     var value = callback.apply(this, reified);
</span><span class="cx">     return seen[name] = exports || value;
</span><ins>+
+    function resolve(child) {
+      if (child.charAt(0) !== '.') { return child; }
+      var parts = child.split(&quot;/&quot;);
+      var parentBase = name.split(&quot;/&quot;).slice(0, -1);
+
+      for (var i=0, l=parts.length; i&lt;l; i++) {
+        var part = parts[i];
+
+        if (part === '..') { parentBase.pop(); }
+        else if (part === '.') { continue; }
+        else { parentBase.push(part); }
+      }
+
+      return parentBase.join(&quot;/&quot;);
+    }
</ins><span class="cx">   };
</span><span class="cx"> })();
</span><span class="cx"> (function() {
</span><del>-/*globals Em:true ENV */
</del><ins>+/*globals Em:true ENV EmberENV MetamorphENV:true */
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><span class="cx"> @module ember
</span><span class="lines">@@ -211,7 +286,7 @@
</span><span class="cx"> 
</span><span class="cx">   @class Ember
</span><span class="cx">   @static
</span><del>-  @version 1.0.0-rc.1
</del><ins>+  @version 1.3.1
</ins><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> if ('undefined' === typeof Ember) {
</span><span class="lines">@@ -238,23 +313,86 @@
</span><span class="cx"> /**
</span><span class="cx">   @property VERSION
</span><span class="cx">   @type String
</span><del>-  @default '1.0.0-rc.1'
-  @final
</del><ins>+  @default '1.3.1'
+  @static
</ins><span class="cx"> */
</span><del>-Ember.VERSION = '1.0.0-rc.1';
</del><ins>+Ember.VERSION = '1.3.1';
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  Standard environmental variables. You can define these in a global `ENV`
-  variable before loading Ember to control various configuration
-  settings.
</del><ins>+  Standard environmental variables. You can define these in a global `EmberENV`
+  variable before loading Ember to control various configuration settings.
</ins><span class="cx"> 
</span><ins>+  For backwards compatibility with earlier versions of Ember the global `ENV`
+  variable will be used if `EmberENV` is not defined.
+
</ins><span class="cx">   @property ENV
</span><span class="cx">   @type Hash
</span><span class="cx"> */
</span><del>-Ember.ENV = Ember.ENV || ('undefined' === typeof ENV ? {} : ENV);
</del><span class="cx"> 
</span><ins>+// This needs to be kept in sync with the logic in
+// `packages/ember-debug/lib/main.js`.
+if (Ember.ENV) {
+  // do nothing if Ember.ENV is already setup
+} else if ('undefined' !== typeof EmberENV) {
+  Ember.ENV = EmberENV;
+} else if('undefined' !== typeof ENV) {
+  Ember.ENV = ENV;
+} else {
+  Ember.ENV = {};
+}
+
</ins><span class="cx"> Ember.config = Ember.config || {};
</span><span class="cx"> 
</span><ins>+// We disable the RANGE API by default for performance reasons
+if ('undefined' === typeof Ember.ENV.DISABLE_RANGE_API) {
+  Ember.ENV.DISABLE_RANGE_API = true;
+}
+
+if (&quot;undefined&quot; === typeof MetamorphENV) {
+  exports.MetamorphENV = {};
+}
+
+MetamorphENV.DISABLE_RANGE_API = Ember.ENV.DISABLE_RANGE_API;
+
+/**
+  Hash of enabled Canary features. Add to before creating your application.
+
+  You can also define `ENV.FEATURES` if you need to enable features flagged at runtime.
+
+  @property FEATURES
+  @type Hash
+*/
+
+Ember.FEATURES = Ember.ENV.FEATURES || {};
+
+/**
+  Test that a feature is enabled. Parsed by Ember's build tools to leave
+  experimental features out of beta/stable builds.
+
+  You can define the following configuration options:
+
+  * `ENV.ENABLE_ALL_FEATURES` - force all features to be enabled.
+  * `ENV.ENABLE_OPTIONAL_FEATURES` - enable any features that have not been explicitly
+    enabled/disabled.
+
+  @method isEnabled
+  @param {string} feature
+*/
+
+Ember.FEATURES.isEnabled = function(feature) {
+  var featureValue = Ember.FEATURES[feature];
+
+  if (Ember.ENV.ENABLE_ALL_FEATURES) {
+    return true;
+  } else if (featureValue === true || featureValue === false || featureValue === undefined) {
+    return featureValue;
+  } else if (Ember.ENV.ENABLE_OPTIONAL_FEATURES) {
+    return true;
+  } else {
+    return false;
+  }
+};
+
</ins><span class="cx"> // ..........................................................
</span><span class="cx"> // BOOTSTRAP
</span><span class="cx"> //
</span><span class="lines">@@ -298,8 +436,17 @@
</span><span class="cx"> Ember.SHIM_ES5 = (Ember.ENV.SHIM_ES5 === false) ? false : Ember.EXTEND_PROTOTYPES;
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  Empty function. Useful for some operations.
</del><ins>+  Determines whether Ember logs info about version of used libraries
</ins><span class="cx"> 
</span><ins>+  @property LOG_VERSION
+  @type Boolean
+  @default true
+*/
+Ember.LOG_VERSION = (Ember.ENV.LOG_VERSION === false) ? false : true;
+
+/**
+  Empty function. Useful for some operations. Always returns `this`.
+
</ins><span class="cx">   @method K
</span><span class="cx">   @private
</span><span class="cx">   @return {Object}
</span><span class="lines">@@ -327,87 +474,80 @@
</span><span class="cx"> */
</span><span class="cx"> Ember.uuid = 0;
</span><span class="cx"> 
</span><del>-// ..........................................................
-// LOGGER
-//
</del><ins>+/**
+  Merge the contents of two objects together into the first object.
</ins><span class="cx"> 
</span><del>-function consoleMethod(name) {
-  if (imports.console &amp;&amp; imports.console[name]) {
-    // Older IE doesn't support apply, but Chrome needs it
-    if (imports.console[name].apply) {
-      return function() {
-        imports.console[name].apply(imports.console, arguments);
-      };
-    } else {
-      return function() {
-        var message = Array.prototype.join.call(arguments, ', ');
-        imports.console[name](message);
-      };
-    }
-  }
-}
</del><ins>+  ```javascript
+  Ember.merge({first: 'Tom'}, {last: 'Dale'}); // {first: 'Tom', last: 'Dale'}
+  var a = {first: 'Yehuda'}, b = {last: 'Katz'};
+  Ember.merge(a, b); // a == {first: 'Yehuda', last: 'Katz'}, b == {last: 'Katz'}
+  ```
</ins><span class="cx"> 
</span><del>-/**
-  Inside Ember-Metal, simply uses the methods from `imports.console`.
-  Override this to provide more robust logging functionality.
-
-  @class Logger
-  @namespace Ember
</del><ins>+  @method merge
+  @for Ember
+  @param {Object} original The object to merge into
+  @param {Object} updates The object to copy properties from
+  @return {Object}
</ins><span class="cx"> */
</span><del>-Ember.Logger = {
-  log:   consoleMethod('log')   || Ember.K,
-  warn:  consoleMethod('warn')  || Ember.K,
-  error: consoleMethod('error') || Ember.K,
-  info:  consoleMethod('info')  || Ember.K,
-  debug: consoleMethod('debug') || consoleMethod('info') || Ember.K
</del><ins>+Ember.merge = function(original, updates) {
+  for (var prop in updates) {
+    if (!updates.hasOwnProperty(prop)) { continue; }
+    original[prop] = updates[prop];
+  }
+  return original;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><ins>+/**
+  Returns true if the passed value is null or undefined. This avoids errors
+  from JSLint complaining about use of ==, which can be technically
+  confusing.
</ins><span class="cx"> 
</span><del>-// ..........................................................
-// ERROR HANDLING
-//
</del><ins>+  ```javascript
+  Ember.isNone();              // true
+  Ember.isNone(null);          // true
+  Ember.isNone(undefined);     // true
+  Ember.isNone('');            // false
+  Ember.isNone([]);            // false
+  Ember.isNone(function() {});  // false
+  ```
</ins><span class="cx"> 
</span><del>-/**
-  A function may be assigned to `Ember.onerror` to be called when Ember
-  internals encounter an error. This is useful for specialized error handling
-  and reporting code.
-
-  @event onerror
</del><ins>+  @method isNone
</ins><span class="cx">   @for Ember
</span><del>-  @param {Exception} error the error object
</del><ins>+  @param {Object} obj Value to test
+  @return {Boolean}
</ins><span class="cx"> */
</span><del>-Ember.onerror = null;
</del><ins>+Ember.isNone = function(obj) {
+  return obj === null || obj === undefined;
+};
+Ember.none = Ember.deprecateFunc(&quot;Ember.none is deprecated. Please use Ember.isNone instead.&quot;, Ember.isNone);
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
</del><ins>+  Verifies that a value is `null` or an empty string, empty array,
+  or empty function.
</ins><span class="cx"> 
</span><del>-  Wrap code block in a try/catch if {{#crossLink &quot;Ember/onerror&quot;}}{{/crossLink}} is set.
</del><ins>+  Constrains the rules on `Ember.isNone` by returning false for empty
+  string and empty arrays.
</ins><span class="cx"> 
</span><del>-  @method handleErrors
</del><ins>+  ```javascript
+  Ember.isEmpty();                // true
+  Ember.isEmpty(null);            // true
+  Ember.isEmpty(undefined);       // true
+  Ember.isEmpty('');              // true
+  Ember.isEmpty([]);              // true
+  Ember.isEmpty('Adam Hawkins');  // false
+  Ember.isEmpty([0,1,2]);         // false
+  ```
+
+  @method isEmpty
</ins><span class="cx">   @for Ember
</span><del>-  @param {Function} func
-  @param [context]
</del><ins>+  @param {Object} obj Value to test
+  @return {Boolean}
</ins><span class="cx"> */
</span><del>-Ember.handleErrors = function(func, context) {
-  // Unfortunately in some browsers we lose the backtrace if we rethrow the existing error,
-  // so in the event that we don't have an `onerror` handler we don't wrap in a try/catch
-  if ('function' === typeof Ember.onerror) {
-    try {
-      return func.apply(context || this);
-    } catch (error) {
-      Ember.onerror(error);
-    }
-  } else {
-    return func.apply(context || this);
-  }
</del><ins>+Ember.isEmpty = function(obj) {
+  return Ember.isNone(obj) || (obj.length === 0 &amp;&amp; typeof obj !== 'function') || (typeof obj === 'object' &amp;&amp; Ember.get(obj, 'length') === 0);
</ins><span class="cx"> };
</span><ins>+Ember.empty = Ember.deprecateFunc(&quot;Ember.empty is deprecated. Please use Ember.isEmpty instead.&quot;, Ember.isEmpty) ;
</ins><span class="cx"> 
</span><del>-Ember.merge = function(original, updates) {
-  for (var prop in updates) {
-    if (!updates.hasOwnProperty(prop)) { continue; }
-    original[prop] = updates[prop];
-  }
-};
</del><span class="cx"> 
</span><span class="cx"> })();
</span><span class="cx"> 
</span><span class="lines">@@ -437,6 +577,13 @@
</span><span class="cx"> */
</span><span class="cx"> Ember.create = Object.create;
</span><span class="cx"> 
</span><ins>+// IE8 has Object.create but it couldn't treat property descriptors.
+if (Ember.create) {
+  if (Ember.create({a: 1}, {a: {value: 2}}).a !== 2) {
+    Ember.create = null;
+  }
+}
+
</ins><span class="cx"> // STUB_OBJECT_CREATE allows us to override other libraries that stub
</span><span class="cx"> // Object.create different than we would prefer
</span><span class="cx"> if (!Ember.create || Ember.ENV.STUB_OBJECT_CREATE) {
</span><span class="lines">@@ -466,7 +613,7 @@
</span><span class="cx"> // Catch IE8 where Object.defineProperty exists but only works on DOM elements
</span><span class="cx"> if (defineProperty) {
</span><span class="cx">   try {
</span><del>-    defineProperty({}, 'a',{get:function(){}});
</del><ins>+    defineProperty({}, 'a',{get:function() {}});
</ins><span class="cx">   } catch (e) {
</span><span class="cx">     defineProperty = null;
</span><span class="cx">   }
</span><span class="lines">@@ -497,7 +644,7 @@
</span><span class="cx"> 
</span><span class="cx">   // This is for Safari 5.0, which supports Object.defineProperty, but not
</span><span class="cx">   // on DOM nodes.
</span><del>-  canDefinePropertyOnDOM = (function(){
</del><ins>+  canDefinePropertyOnDOM = (function() {
</ins><span class="cx">     try {
</span><span class="cx">       defineProperty(document.createElement('div'), 'definePropertyOnDOM', {});
</span><span class="cx">       return true;
</span><span class="lines">@@ -509,7 +656,7 @@
</span><span class="cx">   if (!canRedefineProperties) {
</span><span class="cx">     defineProperty = null;
</span><span class="cx">   } else if (!canDefinePropertyOnDOM) {
</span><del>-    defineProperty = function(obj, keyName, desc){
</del><ins>+    defineProperty = function(obj, keyName, desc) {
</ins><span class="cx">       var isNode;
</span><span class="cx"> 
</span><span class="cx">       if (typeof Node === &quot;object&quot;) {
</span><span class="lines">@@ -572,11 +719,203 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><ins>+/*jshint newcap:false*/
</ins><span class="cx"> /**
</span><span class="cx"> @module ember-metal
</span><span class="cx"> */
</span><span class="cx"> 
</span><ins>+// NOTE: There is a bug in jshint that doesn't recognize `Object()` without `new`
+// as being ok unless both `newcap:false` and not `use strict`.
+// https://github.com/jshint/jshint/issues/392
</ins><span class="cx"> 
</span><ins>+// Testing this is not ideal, but we want to use native functions
+// if available, but not to use versions created by libraries like Prototype
+var isNativeFunc = function(func) {
+  // This should probably work in all browsers likely to have ES5 array methods
+  return func &amp;&amp; Function.prototype.toString.call(func).indexOf('[native code]') &gt; -1;
+};
+
+// From: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/map
+var arrayMap = isNativeFunc(Array.prototype.map) ? Array.prototype.map : function(fun /*, thisp */) {
+  //&quot;use strict&quot;;
+
+  if (this === void 0 || this === null) {
+    throw new TypeError();
+  }
+
+  var t = Object(this);
+  var len = t.length &gt;&gt;&gt; 0;
+  if (typeof fun !== &quot;function&quot;) {
+    throw new TypeError();
+  }
+
+  var res = new Array(len);
+  var thisp = arguments[1];
+  for (var i = 0; i &lt; len; i++) {
+    if (i in t) {
+      res[i] = fun.call(thisp, t[i], i, t);
+    }
+  }
+
+  return res;
+};
+
+// From: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach
+var arrayForEach = isNativeFunc(Array.prototype.forEach) ? Array.prototype.forEach : function(fun /*, thisp */) {
+  //&quot;use strict&quot;;
+
+  if (this === void 0 || this === null) {
+    throw new TypeError();
+  }
+
+  var t = Object(this);
+  var len = t.length &gt;&gt;&gt; 0;
+  if (typeof fun !== &quot;function&quot;) {
+    throw new TypeError();
+  }
+
+  var thisp = arguments[1];
+  for (var i = 0; i &lt; len; i++) {
+    if (i in t) {
+      fun.call(thisp, t[i], i, t);
+    }
+  }
+};
+
+var arrayIndexOf = isNativeFunc(Array.prototype.indexOf) ? Array.prototype.indexOf : function (obj, fromIndex) {
+  if (fromIndex === null || fromIndex === undefined) { fromIndex = 0; }
+  else if (fromIndex &lt; 0) { fromIndex = Math.max(0, this.length + fromIndex); }
+  for (var i = fromIndex, j = this.length; i &lt; j; i++) {
+    if (this[i] === obj) { return i; }
+  }
+  return -1;
+};
+
+/**
+  Array polyfills to support ES5 features in older browsers.
+
+  @namespace Ember
+  @property ArrayPolyfills
+*/
+Ember.ArrayPolyfills = {
+  map: arrayMap,
+  forEach: arrayForEach,
+  indexOf: arrayIndexOf
+};
+
+if (Ember.SHIM_ES5) {
+  if (!Array.prototype.map) {
+    Array.prototype.map = arrayMap;
+  }
+
+  if (!Array.prototype.forEach) {
+    Array.prototype.forEach = arrayForEach;
+  }
+
+  if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = arrayIndexOf;
+  }
+}
+
+})();
+
+
+
+(function() {
+var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
+
+/**
+  A subclass of the JavaScript Error object for use in Ember.
+
+  @class Error
+  @namespace Ember
+  @extends Error
+  @constructor
+*/
+Ember.Error = function() {
+  var tmp = Error.apply(this, arguments);
+
+  // Adds a `stack` property to the given error object that will yield the
+  // stack trace at the time captureStackTrace was called.
+  // When collecting the stack trace all frames above the topmost call
+  // to this function, including that call, will be left out of the
+  // stack trace.
+  // This is useful because we can hide Ember implementation details
+  // that are not very helpful for the user.
+  if (Error.captureStackTrace) {
+    Error.captureStackTrace(this, Ember.Error);
+  }
+  // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
+  for (var idx = 0; idx &lt; errorProps.length; idx++) {
+    this[errorProps[idx]] = tmp[errorProps[idx]];
+  }
+};
+
+Ember.Error.prototype = Ember.create(Error.prototype);
+
+// ..........................................................
+// ERROR HANDLING
+//
+
+/**
+  A function may be assigned to `Ember.onerror` to be called when Ember
+  internals encounter an error. This is useful for specialized error handling
+  and reporting code.
+
+  ```javascript
+  Ember.onerror = function(error) {
+    Em.$.ajax('/report-error', 'POST', {
+      stack: error.stack,
+      otherInformation: 'whatever app state you want to provide'
+    });
+  };
+  ```
+
+  @event onerror
+  @for Ember
+  @param {Exception} error the error object
+*/
+Ember.onerror = null;
+
+/**
+  Wrap code block in a try/catch if `Ember.onerror` is set.
+
+  @private
+  @method handleErrors
+  @for Ember
+  @param {Function} func
+  @param [context]
+*/
+Ember.handleErrors = function(func, context) {
+  // Unfortunately in some browsers we lose the backtrace if we rethrow the existing error,
+  // so in the event that we don't have an `onerror` handler we don't wrap in a try/catch
+  if ('function' === typeof Ember.onerror) {
+    try {
+      return func.call(context || this);
+    } catch (error) {
+      Ember.onerror(error);
+    }
+  } else {
+    return func.call(context || this);
+  }
+};
+
+})();
+
+
+
+(function() {
+/**
+@module ember-metal
+*/
+
+/**
+  Prefix used for guids through out Ember.
+  @private
+*/
+Ember.GUID_PREFIX = 'ember';
+
+
</ins><span class="cx"> var o_defineProperty = Ember.platform.defineProperty,
</span><span class="cx">     o_create = Ember.create,
</span><span class="cx">     // Used for guid generation...
</span><span class="lines">@@ -588,8 +927,6 @@
</span><span class="cx"> var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   A unique key used to assign guids and other private metadata to objects.
</span><span class="cx">   If you inspect an object in your browser debugger you will often see these.
</span><span class="cx">   They can be safely ignored.
</span><span class="lines">@@ -597,6 +934,7 @@
</span><span class="cx">   On browsers that support it, these properties are added with enumeration
</span><span class="cx">   disabled so they won't show up when you iterate over your properties.
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @property GUID_KEY
</span><span class="cx">   @for Ember
</span><span class="cx">   @type String
</span><span class="lines">@@ -612,12 +950,11 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   Generates a new guid, optionally saving the guid to the object that you
</span><span class="cx">   pass in. You will rarely need to use this method. Instead you should
</span><span class="cx">   call `Ember.guidFor(obj)`, which return an existing guid if available.
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method generateGuid
</span><span class="cx">   @for Ember
</span><span class="cx">   @param {Object} [obj] Object the guid will be used for. If passed in, the guid will
</span><span class="lines">@@ -630,18 +967,16 @@
</span><span class="cx">   @return {String} the guid
</span><span class="cx"> */
</span><span class="cx"> Ember.generateGuid = function generateGuid(obj, prefix) {
</span><del>-  if (!prefix) prefix = 'ember';
</del><ins>+  if (!prefix) prefix = Ember.GUID_PREFIX;
</ins><span class="cx">   var ret = (prefix + (uuid++));
</span><span class="cx">   if (obj) {
</span><span class="cx">     GUID_DESC.value = ret;
</span><span class="cx">     o_defineProperty(obj, GUID_KEY, GUID_DESC);
</span><span class="cx">   }
</span><del>-  return ret ;
</del><ins>+  return ret;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   Returns a unique id for the object. If the object does not yet have a guid,
</span><span class="cx">   one will be assigned to it. You can call this on any object,
</span><span class="cx">   `Ember.Object`-based or not, but be aware that it will add a `_guid`
</span><span class="lines">@@ -649,9 +984,10 @@
</span><span class="cx"> 
</span><span class="cx">   You can also use this method on DOM Element objects.
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method guidFor
</span><span class="cx">   @for Ember
</span><del>-  @param obj {Object} any object, string, number, Element, or primitive
</del><ins>+  @param {Object} obj any object, string, number, Element, or primitive
</ins><span class="cx">   @return {String} the unique guid for this instance.
</span><span class="cx"> */
</span><span class="cx"> Ember.guidFor = function guidFor(obj) {
</span><span class="lines">@@ -660,7 +996,7 @@
</span><span class="cx">   if (obj === undefined) return &quot;(undefined)&quot;;
</span><span class="cx">   if (obj === null) return &quot;(null)&quot;;
</span><span class="cx"> 
</span><del>-  var cache, ret;
</del><ins>+  var ret;
</ins><span class="cx">   var type = typeof obj;
</span><span class="cx"> 
</span><span class="cx">   // Don't allow prototype changes to String etc. to change the guidFor
</span><span class="lines">@@ -713,18 +1049,6 @@
</span><span class="cx"> */
</span><span class="cx"> Ember.META_KEY = META_KEY;
</span><span class="cx"> 
</span><del>-// Placeholder for non-writable metas.
-var EMPTY_META = {
-  descs: {},
-  watching: {}
-};
-
-if (MANDATORY_SETTER) { EMPTY_META.values = {}; }
-
-Ember.EMPTY_META = EMPTY_META;
-
-if (Object.freeze) Object.freeze(EMPTY_META);
-
</del><span class="cx"> var isDefinePropertySimulated = Ember.platform.defineProperty.isSimulated;
</span><span class="cx"> 
</span><span class="cx"> function Meta(obj) {
</span><span class="lines">@@ -734,6 +1058,20 @@
</span><span class="cx">   this.source = obj;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Meta.prototype = {
+  descs: null,
+  deps: null,
+  watching: null,
+  listeners: null,
+  cache: null,
+  source: null,
+  mixins: null,
+  bindings: null,
+  chains: null,
+  chainWatchers: null,
+  values: null
+};
+
</ins><span class="cx"> if (isDefinePropertySimulated) {
</span><span class="cx">   // on platforms that don't support enumerable false
</span><span class="cx">   // make meta fail jQuery.isPlainObject() to hide from
</span><span class="lines">@@ -746,6 +1084,13 @@
</span><span class="cx">   Meta.prototype.toJSON = function () { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// Placeholder for non-writable metas.
+var EMPTY_META = new Meta(null);
+
+if (MANDATORY_SETTER) { EMPTY_META.values = {}; }
+
+Ember.EMPTY_META = EMPTY_META;
+
</ins><span class="cx"> /**
</span><span class="cx">   Retrieves the meta hash for an object. If `writable` is true ensures the
</span><span class="cx">   hash is writable for this object as well.
</span><span class="lines">@@ -762,7 +1107,7 @@
</span><span class="cx">   @param {Object} obj The object to retrieve meta for
</span><span class="cx">   @param {Boolean} [writable=true] Pass `false` if you do not intend to modify
</span><span class="cx">     the meta hash, allowing the method to avoid making an unnecessary copy.
</span><del>-  @return {Hash}
</del><ins>+  @return {Object} the meta hash for an object
</ins><span class="cx"> */
</span><span class="cx"> Ember.meta = function meta(obj, writable) {
</span><span class="cx"> 
</span><span class="lines">@@ -809,6 +1154,7 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+  @deprecated
</ins><span class="cx">   @private
</span><span class="cx"> 
</span><span class="cx">   In order to store defaults for a class, a prototype may need to create
</span><span class="lines">@@ -841,6 +1187,7 @@
</span><span class="cx">     shared with its constructor
</span><span class="cx"> */
</span><span class="cx"> Ember.metaPath = function metaPath(obj, path, writable) {
</span><ins>+  Ember.deprecate(&quot;Ember.metaPath is deprecated and will be removed from future releases.&quot;);
</ins><span class="cx">   var meta = Ember.meta(obj, writable), keyName, value;
</span><span class="cx"> 
</span><span class="cx">   for (var i=0, l=path.length; i&lt;l; i++) {
</span><span class="lines">@@ -863,12 +1210,11 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   Wraps the passed function so that `this._super` will point to the superFunc
</span><span class="cx">   when the function is invoked. This is the primitive we use to implement
</span><span class="cx">   calls to super.
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method wrap
</span><span class="cx">   @for Ember
</span><span class="cx">   @param {Function} func The function to call
</span><span class="lines">@@ -889,6 +1235,7 @@
</span><span class="cx">   superWrapper.wrappedFunction = func;
</span><span class="cx">   superWrapper.__ember_observes__ = func.__ember_observes__;
</span><span class="cx">   superWrapper.__ember_observesBefore__ = func.__ember_observesBefore__;
</span><ins>+  superWrapper.__ember_listens__ = func.__ember_listens__;
</ins><span class="cx"> 
</span><span class="cx">   return superWrapper;
</span><span class="cx"> };
</span><span class="lines">@@ -914,7 +1261,7 @@
</span><span class="cx">   @method isArray
</span><span class="cx">   @for Ember
</span><span class="cx">   @param {Object} obj The object to test
</span><del>-  @return {Boolean}
</del><ins>+  @return {Boolean} true if the passed object is an array or Array-like
</ins><span class="cx"> */
</span><span class="cx"> Ember.isArray = function(obj) {
</span><span class="cx">   if (!obj || obj.setInterval) { return false; }
</span><span class="lines">@@ -957,10 +1304,18 @@
</span><span class="cx"> /**
</span><span class="cx">   Checks to see if the `methodName` exists on the `obj`.
</span><span class="cx"> 
</span><ins>+  ```javascript
+  var foo = {bar: Ember.K, baz: null};
+  Ember.canInvoke(foo, 'bar'); // true
+  Ember.canInvoke(foo, 'baz'); // false
+  Ember.canInvoke(foo, 'bat'); // false
+  ```
+
</ins><span class="cx">   @method canInvoke
</span><span class="cx">   @for Ember
</span><span class="cx">   @param {Object} obj The object to check for the method
</span><span class="cx">   @param {String} methodName The method name to check for
</span><ins>+  @return {Boolean}
</ins><span class="cx"> */
</span><span class="cx"> Ember.canInvoke = canInvoke;
</span><span class="cx"> 
</span><span class="lines">@@ -968,12 +1323,19 @@
</span><span class="cx">   Checks to see if the `methodName` exists on the `obj`,
</span><span class="cx">   and if it does, invokes it with the arguments passed.
</span><span class="cx"> 
</span><ins>+  ```javascript
+  var d = new Date('03/15/2013');
+  Ember.tryInvoke(d, 'getTime'); // 1363320000000
+  Ember.tryInvoke(d, 'setFullYear', [2014]); // 1394856000000
+  Ember.tryInvoke(d, 'noSuchMethod', [2014]); // undefined
+  ```
+
</ins><span class="cx">   @method tryInvoke
</span><span class="cx">   @for Ember
</span><span class="cx">   @param {Object} obj The object to check for the method
</span><span class="cx">   @param {String} methodName The method name to check for
</span><span class="cx">   @param {Array} [args] The arguments to pass to the method
</span><del>-  @return {anything} the return value of the invoked method or undefined if it cannot be invoked
</del><ins>+  @return {*} the return value of the invoked method or undefined if it cannot be invoked
</ins><span class="cx"> */
</span><span class="cx"> Ember.tryInvoke = function(obj, methodName, args) {
</span><span class="cx">   if (canInvoke(obj, methodName)) {
</span><span class="lines">@@ -999,13 +1361,24 @@
</span><span class="cx">   Provides try { } finally { } functionality, while working
</span><span class="cx">   around Safari's double finally bug.
</span><span class="cx"> 
</span><ins>+  ```javascript
+  var tryable = function() {
+    someResource.lock();
+    runCallback(); // May throw error.
+  };
+  var finalizer = function() {
+    someResource.unlock();
+  };
+  Ember.tryFinally(tryable, finalizer);
+  ```
+
</ins><span class="cx">   @method tryFinally
</span><span class="cx">   @for Ember
</span><del>-  @param {Function} function The function to run the try callback
-  @param {Function} function The function to run the finally callback
-  @param [binding]
-  @return {anything} The return value is the that of the finalizer,
-  unless that valueis undefined, in which case it is the return value
</del><ins>+  @param {Function} tryable The function to run the try callback
+  @param {Function} finalizer The function to run the finally callback
+  @param {Object} [binding] The optional calling object. Defaults to 'this'
+  @return {*} The return value is the that of the finalizer,
+  unless that value is undefined, in which case it is the return value
</ins><span class="cx">   of the tryable
</span><span class="cx"> */
</span><span class="cx"> 
</span><span class="lines">@@ -1020,7 +1393,7 @@
</span><span class="cx">     } finally {
</span><span class="cx">       try {
</span><span class="cx">         finalResult = finalizer.call(binding);
</span><del>-      } catch (e){
</del><ins>+      } catch (e) {
</ins><span class="cx">         finalError = e;
</span><span class="cx">       }
</span><span class="cx">     }
</span><span class="lines">@@ -1049,19 +1422,43 @@
</span><span class="cx">   Provides try { } catch finally { } functionality, while working
</span><span class="cx">   around Safari's double finally bug.
</span><span class="cx"> 
</span><ins>+  ```javascript
+  var tryable = function() {
+    for (i=0, l=listeners.length; i&lt;l; i++) {
+      listener = listeners[i];
+      beforeValues[i] = listener.before(name, time(), payload);
+    }
+
+    return callback.call(binding);
+  };
+
+  var catchable = function(e) {
+    payload = payload || {};
+    payload.exception = e;
+  };
+
+  var finalizer = function() {
+    for (i=0, l=listeners.length; i&lt;l; i++) {
+      listener = listeners[i];
+      listener.after(name, time(), payload, beforeValues[i]);
+    }
+  };
+  Ember.tryCatchFinally(tryable, catchable, finalizer);
+  ```
+
</ins><span class="cx">   @method tryCatchFinally
</span><span class="cx">   @for Ember
</span><del>-  @param {Function} function The function to run the try callback
-  @param {Function} function The function to run the catchable callback
-  @param {Function} function The function to run the finally callback
-  @param [binding]
-  @return {anything} The return value is the that of the finalizer,
</del><ins>+  @param {Function} tryable The function to run the try callback
+  @param {Function} catchable The function to run the catchable callback
+  @param {Function} finalizer The function to run the finally callback
+  @param {Object} [binding] The optional calling object. Defaults to 'this'
+  @return {*} The return value is the that of the finalizer,
</ins><span class="cx">   unless that value is undefined, in which case it is the return value
</span><span class="cx">   of the tryable.
</span><span class="cx"> */
</span><span class="cx"> if (needsFinallyFix) {
</span><span class="cx">   Ember.tryCatchFinally = function(tryable, catchable, finalizer, binding) {
</span><del>-    var result, finalResult, finalError, finalReturn;
</del><ins>+    var result, finalResult, finalError;
</ins><span class="cx"> 
</span><span class="cx">     binding = binding || this;
</span><span class="cx"> 
</span><span class="lines">@@ -1072,7 +1469,7 @@
</span><span class="cx">     } finally {
</span><span class="cx">       try {
</span><span class="cx">         finalResult = finalizer.call(binding);
</span><del>-      } catch (e){
</del><ins>+      } catch (e) {
</ins><span class="cx">         finalError = e;
</span><span class="cx">       }
</span><span class="cx">     }
</span><span class="lines">@@ -1099,6 +1496,86 @@
</span><span class="cx">   };
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// ........................................
+// TYPING &amp; ARRAY MESSAGING
+//
+
+var TYPE_MAP = {};
+var t = &quot;Boolean Number String Function Array Date RegExp Object&quot;.split(&quot; &quot;);
+Ember.ArrayPolyfills.forEach.call(t, function(name) {
+  TYPE_MAP[ &quot;[object &quot; + name + &quot;]&quot; ] = name.toLowerCase();
+});
+
+var toString = Object.prototype.toString;
+
+/**
+  Returns a consistent type for the passed item.
+
+  Use this instead of the built-in `typeof` to get the type of an item.
+  It will return the same result across all browsers and includes a bit
+  more detail. Here is what will be returned:
+
+      | Return Value  | Meaning                                              |
+      |---------------|------------------------------------------------------|
+      | 'string'      | String primitive or String object.                   |
+      | 'number'      | Number primitive or Number object.                   |
+      | 'boolean'     | Boolean primitive or Boolean object.                 |
+      | 'null'        | Null value                                           |
+      | 'undefined'   | Undefined value                                      |
+      | 'function'    | A function                                           |
+      | 'array'       | An instance of Array                                 |
+      | 'regexp'      | An instance of RegExp                                |
+      | 'date'        | An instance of Date                                  |
+      | 'class'       | An Ember class (created using Ember.Object.extend()) |
+      | 'instance'    | An Ember object instance                             |
+      | 'error'       | An instance of the Error object                      |
+      | 'object'      | A JavaScript object not inheriting from Ember.Object |
+
+  Examples:
+
+  ```javascript
+  Ember.typeOf();                       // 'undefined'
+  Ember.typeOf(null);                   // 'null'
+  Ember.typeOf(undefined);              // 'undefined'
+  Ember.typeOf('michael');              // 'string'
+  Ember.typeOf(new String('michael'));  // 'string'
+  Ember.typeOf(101);                    // 'number'
+  Ember.typeOf(new Number(101));        // 'number'
+  Ember.typeOf(true);                   // 'boolean'
+  Ember.typeOf(new Boolean(true));      // 'boolean'
+  Ember.typeOf(Ember.makeArray);        // 'function'
+  Ember.typeOf([1,2,90]);               // 'array'
+  Ember.typeOf(/abc/);                  // 'regexp'
+  Ember.typeOf(new Date());             // 'date'
+  Ember.typeOf(Ember.Object.extend());  // 'class'
+  Ember.typeOf(Ember.Object.create());  // 'instance'
+  Ember.typeOf(new Error('teamocil'));  // 'error'
+
+  // &quot;normal&quot; JavaScript object
+  Ember.typeOf({a: 'b'});              // 'object'
+  ```
+
+  @method typeOf
+  @for Ember
+  @param {Object} item the item to check
+  @return {String} the type
+*/
+Ember.typeOf = function(item) {
+  var ret;
+
+  ret = (item === null || item === undefined) ? String(item) : TYPE_MAP[toString.call(item)] || 'object';
+
+  if (ret === 'function') {
+    if (Ember.Object &amp;&amp; Ember.Object.detect(item)) ret = 'class';
+  } else if (ret === 'object') {
+    if (item instanceof Error) ret = 'error';
+    else if (Ember.Object &amp;&amp; item instanceof Ember.Object) ret = 'instance';
+    else if (item instanceof Date) ret = 'date';
+  }
+
+  return ret;
+};
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -1171,13 +1648,23 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> var time = (function() {
</span><del>-    var perf = 'undefined' !== typeof window ? window.performance || {} : {};
-    var fn = perf.now || perf.mozNow || perf.webkitNow || perf.msNow || perf.oNow;
-    // fn.bind will be available in all the browsers that support the advanced window.performance... ;-)
-    return fn ? fn.bind(perf) : function() { return +new Date(); };
</del><ins>+  var perf = 'undefined' !== typeof window ? window.performance || {} : {};
+  var fn = perf.now || perf.mozNow || perf.webkitNow || perf.msNow || perf.oNow;
+  // fn.bind will be available in all the browsers that support the advanced window.performance... ;-)
+  return fn ? fn.bind(perf) : function() { return +new Date(); };
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><ins>+/**
+  Notifies event's subscribers, calls `before` and `after` hooks.
</ins><span class="cx"> 
</span><ins>+  @method instrument
+  @namespace Ember.Instrumentation
+
+  @param {String} [name] Namespaced event name.
+  @param {Object} payload
+  @param {Function} callback Function that you're instrumenting.
+  @param {Object} binding Context that instrument function is called with.
+*/
</ins><span class="cx"> Ember.Instrumentation.instrument = function(name, payload, callback, binding) {
</span><span class="cx">   var listeners = cache[name], timeName, ret;
</span><span class="cx"> 
</span><span class="lines">@@ -1198,7 +1685,7 @@
</span><span class="cx"> 
</span><span class="cx">   var beforeValues = [], listener, i, l;
</span><span class="cx"> 
</span><del>-  function tryable(){
</del><ins>+  function tryable() {
</ins><span class="cx">     for (i=0, l=listeners.length; i&lt;l; i++) {
</span><span class="cx">       listener = listeners[i];
</span><span class="cx">       beforeValues[i] = listener.before(name, time(), payload);
</span><span class="lines">@@ -1207,7 +1694,7 @@
</span><span class="cx">     return callback.call(binding);
</span><span class="cx">   }
</span><span class="cx"> 
</span><del>-  function catchable(e){
</del><ins>+  function catchable(e) {
</ins><span class="cx">     payload = payload || {};
</span><span class="cx">     payload.exception = e;
</span><span class="cx">   }
</span><span class="lines">@@ -1226,6 +1713,17 @@
</span><span class="cx">   return Ember.tryCatchFinally(tryable, catchable, finalizer);
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+/**
+  Subscribes to a particular event or instrumented block of code.
+
+  @method subscribe
+  @namespace Ember.Instrumentation
+
+  @param {String} [pattern] Namespaced event name.
+  @param {Object} [object] Before and After hooks.
+
+  @return {Subscriber}
+*/
</ins><span class="cx"> Ember.Instrumentation.subscribe = function(pattern, object) {
</span><span class="cx">   var paths = pattern.split(&quot;.&quot;), path, regex = [];
</span><span class="cx"> 
</span><span class="lines">@@ -1253,6 +1751,14 @@
</span><span class="cx">   return subscriber;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+/**
+  Unsubscribes from a particular event or instrumented block of code.
+
+  @method unsubscribe
+  @namespace Ember.Instrumentation
+
+  @param {Object} [subscriber]
+*/
</ins><span class="cx"> Ember.Instrumentation.unsubscribe = function(subscriber) {
</span><span class="cx">   var index;
</span><span class="cx"> 
</span><span class="lines">@@ -1266,6 +1772,12 @@
</span><span class="cx">   cache = {};
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+/**
+  Resets `Ember.Instrumentation` by flushing list of subscribers.
+
+  @method reset
+  @namespace Ember.Instrumentation
+*/
</ins><span class="cx"> Ember.Instrumentation.reset = function() {
</span><span class="cx">   subscribers = [];
</span><span class="cx">   cache = {};
</span><span class="lines">@@ -1273,23 +1785,28 @@
</span><span class="cx"> 
</span><span class="cx"> Ember.instrument = Ember.Instrumentation.instrument;
</span><span class="cx"> Ember.subscribe = Ember.Instrumentation.subscribe;
</span><del>-
</del><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><ins>+var map, forEach, indexOf, splice;
+map     = Array.prototype.map     || Ember.ArrayPolyfills.map;
+forEach = Array.prototype.forEach || Ember.ArrayPolyfills.forEach;
+indexOf = Array.prototype.indexOf || Ember.ArrayPolyfills.indexOf;
+splice = Array.prototype.splice;
+
</ins><span class="cx"> var utils = Ember.EnumerableUtils = {
</span><span class="cx">   map: function(obj, callback, thisArg) {
</span><del>-    return obj.map ? obj.map.call(obj, callback, thisArg) : Array.prototype.map.call(obj, callback, thisArg);
</del><ins>+    return obj.map ? obj.map.call(obj, callback, thisArg) : map.call(obj, callback, thisArg);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   forEach: function(obj, callback, thisArg) {
</span><del>-    return obj.forEach ? obj.forEach.call(obj, callback, thisArg) : Array.prototype.forEach.call(obj, callback, thisArg);
</del><ins>+    return obj.forEach ? obj.forEach.call(obj, callback, thisArg) : forEach.call(obj, callback, thisArg);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   indexOf: function(obj, element, index) {
</span><del>-    return obj.indexOf ? obj.indexOf.call(obj, element, index) : Array.prototype.indexOf.call(obj, element, index);
</del><ins>+    return obj.indexOf ? obj.indexOf.call(obj, element, index) : indexOf.call(obj, element, index);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   indexesOf: function(obj, elements) {
</span><span class="lines">@@ -1308,20 +1825,39 @@
</span><span class="cx">     if (index !== -1) { array.splice(index, 1); }
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  _replace: function(array, idx, amt, objects) {
+    var args = [].concat(objects), chunk, ret = [],
+        // https://code.google.com/p/chromium/issues/detail?id=56588
+        size = 60000, start = idx, ends = amt, count;
+
+    while (args.length) {
+      count = ends &gt; size ? size : ends;
+      if (count &lt;= 0) { count = 0; }
+
+      chunk = args.splice(0, size);
+      chunk = [start, count].concat(chunk);
+
+      start += size;
+      ends -= count;
+
+      ret = ret.concat(splice.apply(array, chunk));
+    }
+    return ret;
+  },
+
</ins><span class="cx">   replace: function(array, idx, amt, objects) {
</span><span class="cx">     if (array.replace) {
</span><span class="cx">       return array.replace(idx, amt, objects);
</span><span class="cx">     } else {
</span><del>-      var args = Array.prototype.concat.apply([idx, amt], objects);
-      return array.splice.apply(array, args);
</del><ins>+      return utils._replace(array, idx, amt, objects);
</ins><span class="cx">     }
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   intersection: function(array1, array2) {
</span><span class="cx">     var intersection = [];
</span><span class="cx"> 
</span><del>-    array1.forEach(function(element) {
-      if (array2.indexOf(element) &gt;= 0) {
</del><ins>+    utils.forEach(array1, function(element) {
+      if (utils.indexOf(array2, element) &gt;= 0) {
</ins><span class="cx">         intersection.push(element);
</span><span class="cx">       }
</span><span class="cx">     });
</span><span class="lines">@@ -1335,98 +1871,1019 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-/*jshint newcap:false*/
</del><span class="cx"> /**
</span><span class="cx"> @module ember-metal
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-// NOTE: There is a bug in jshint that doesn't recognize `Object()` without `new`
-// as being ok unless both `newcap:false` and not `use strict`.
-// https://github.com/jshint/jshint/issues/392
</del><ins>+var META_KEY = Ember.META_KEY, get;
</ins><span class="cx"> 
</span><del>-// Testing this is not ideal, but we want to use native functions
-// if available, but not to use versions created by libraries like Prototype
-var isNativeFunc = function(func) {
-  // This should probably work in all browsers likely to have ES5 array methods
-  return func &amp;&amp; Function.prototype.toString.call(func).indexOf('[native code]') &gt; -1;
</del><ins>+var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;
+
+var IS_GLOBAL_PATH = /^([A-Z$]|([0-9][A-Z$])).*[\.\*]/;
+var HAS_THIS  = /^this[\.\*]/;
+var FIRST_KEY = /^([^\.\*]+)/;
+
+// ..........................................................
+// GET AND SET
+//
+// If we are on a platform that supports accessors we can use those.
+// Otherwise simulate accessors by looking up the property directly on the
+// object.
+
+/**
+  Gets the value of a property on an object. If the property is computed,
+  the function will be invoked. If the property is not defined but the
+  object implements the `unknownProperty` method then that will be invoked.
+
+  If you plan to run on IE8 and older browsers then you should use this
+  method anytime you want to retrieve a property on an object that you don't
+  know for sure is private. (Properties beginning with an underscore '_'
+  are considered private.)
+
+  On all newer browsers, you only need to use this method to retrieve
+  properties if the property might not be defined on the object and you want
+  to respect the `unknownProperty` handler. Otherwise you can ignore this
+  method.
+
+  Note that if the object itself is `undefined`, this method will throw
+  an error.
+
+  @method get
+  @for Ember
+  @param {Object} obj The object to retrieve from.
+  @param {String} keyName The property key to retrieve
+  @return {Object} the property value or `null`.
+*/
+get = function get(obj, keyName) {
+  // Helpers that operate with 'this' within an #each
+  if (keyName === '') {
+    return obj;
+  }
+
+  if (!keyName &amp;&amp; 'string'===typeof obj) {
+    keyName = obj;
+    obj = null;
+  }
+
+  Ember.assert(&quot;Cannot call get with &quot;+ keyName +&quot; key.&quot;, !!keyName);
+  Ember.assert(&quot;Cannot call get with '&quot;+ keyName +&quot;' on an undefined object.&quot;, obj !== undefined);
+
+  if (obj === null || keyName.indexOf('.') !== -1) {
+    return getPath(obj, keyName);
+  }
+
+  var meta = obj[META_KEY], desc = meta &amp;&amp; meta.descs[keyName], ret;
+  if (desc) {
+    return desc.get(obj, keyName);
+  } else {
+    if (MANDATORY_SETTER &amp;&amp; meta &amp;&amp; meta.watching[keyName] &gt; 0) {
+      ret = meta.values[keyName];
+    } else {
+      ret = obj[keyName];
+    }
+
+    if (ret === undefined &amp;&amp;
+        'object' === typeof obj &amp;&amp; !(keyName in obj) &amp;&amp; 'function' === typeof obj.unknownProperty) {
+      return obj.unknownProperty(keyName);
+    }
+
+    return ret;
+  }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-// From: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/map
-var arrayMap = isNativeFunc(Array.prototype.map) ? Array.prototype.map : function(fun /*, thisp */) {
-  //&quot;use strict&quot;;
</del><ins>+// Currently used only by Ember Data tests
+if (Ember.config.overrideAccessors) {
+  Ember.get = get;
+  Ember.config.overrideAccessors();
+  get = Ember.get;
+}
</ins><span class="cx"> 
</span><del>-  if (this === void 0 || this === null) {
-    throw new TypeError();
</del><ins>+/**
+  Normalizes a target/path pair to reflect that actual target/path that should
+  be observed, etc. This takes into account passing in global property
+  paths (i.e. a path beginning with a captial letter not defined on the
+  target) and * separators.
+
+  @private
+  @method normalizeTuple
+  @for Ember
+  @param {Object} target The current target. May be `null`.
+  @param {String} path A path on the target or a global property path.
+  @return {Array} a temporary array with the normalized target/path pair.
+*/
+var normalizeTuple = Ember.normalizeTuple = function(target, path) {
+  var hasThis  = HAS_THIS.test(path),
+      isGlobal = !hasThis &amp;&amp; IS_GLOBAL_PATH.test(path),
+      key;
+
+  if (!target || isGlobal) target = Ember.lookup;
+  if (hasThis) path = path.slice(5);
+
+  if (target === Ember.lookup) {
+    key = path.match(FIRST_KEY)[0];
+    target = get(target, key);
+    path   = path.slice(key.length+1);
</ins><span class="cx">   }
</span><span class="cx"> 
</span><del>-  var t = Object(this);
-  var len = t.length &gt;&gt;&gt; 0;
-  if (typeof fun !== &quot;function&quot;) {
-    throw new TypeError();
</del><ins>+  // must return some kind of path to be valid else other things will break.
+  if (!path || path.length===0) throw new Ember.Error('Invalid Path');
+
+  return [ target, path ];
+};
+
+var getPath = Ember._getPath = function(root, path) {
+  var hasThis, parts, tuple, idx, len;
+
+  // If there is no root and path is a key name, return that
+  // property from the global object.
+  // E.g. get('Ember') -&gt; Ember
+  if (root === null &amp;&amp; path.indexOf('.') === -1) { return get(Ember.lookup, path); }
+
+  // detect complicated paths and normalize them
+  hasThis  = HAS_THIS.test(path);
+
+  if (!root || hasThis) {
+    tuple = normalizeTuple(root, path);
+    root = tuple[0];
+    path = tuple[1];
+    tuple.length = 0;
</ins><span class="cx">   }
</span><span class="cx"> 
</span><del>-  var res = new Array(len);
-  var thisp = arguments[1];
-  for (var i = 0; i &lt; len; i++) {
-    if (i in t) {
-      res[i] = fun.call(thisp, t[i], i, t);
</del><ins>+  parts = path.split(&quot;.&quot;);
+  len = parts.length;
+  for (idx = 0; root != null &amp;&amp; idx &lt; len; idx++) {
+    root = get(root, parts[idx], true);
+    if (root &amp;&amp; root.isDestroyed) { return undefined; }
+  }
+  return root;
+};
+
+Ember.getWithDefault = function(root, key, defaultValue) {
+  var value = get(root, key);
+
+  if (value === undefined) { return defaultValue; }
+  return value;
+};
+
+
+Ember.get = get;
+
+})();
+
+
+
+(function() {
+/**
+@module ember-metal
+*/
+
+var o_create = Ember.create,
+    metaFor = Ember.meta,
+    META_KEY = Ember.META_KEY,
+    a_slice = [].slice,
+    /* listener flags */
+    ONCE = 1, SUSPENDED = 2;
+
+/*
+  The event system uses a series of nested hashes to store listeners on an
+  object. When a listener is registered, or when an event arrives, these
+  hashes are consulted to determine which target and action pair to invoke.
+
+  The hashes are stored in the object's meta hash, and look like this:
+
+      // Object's meta hash
+      {
+        listeners: {       // variable name: `listenerSet`
+          &quot;foo:changed&quot;: [ // variable name: `actions`
+            target, method, flags
+          ]
+        }
+      }
+
+*/
+
+function indexOf(array, target, method) {
+  var index = -1;
+  for (var i = 0, l = array.length; i &lt; l; i += 3) {
+    if (target === array[i] &amp;&amp; method === array[i+1]) { index = i; break; }
+  }
+  return index;
+}
+
+function actionsFor(obj, eventName) {
+  var meta = metaFor(obj, true),
+      actions;
+
+  if (!meta.listeners) { meta.listeners = {}; }
+
+  if (!meta.hasOwnProperty('listeners')) {
+    // setup inherited copy of the listeners object
+    meta.listeners = o_create(meta.listeners);
+  }
+
+  actions = meta.listeners[eventName];
+
+  // if there are actions, but the eventName doesn't exist in our listeners, then copy them from the prototype
+  if (actions &amp;&amp; !meta.listeners.hasOwnProperty(eventName)) {
+    actions = meta.listeners[eventName] = meta.listeners[eventName].slice();
+  } else if (!actions) {
+    actions = meta.listeners[eventName] = [];
+  }
+
+  return actions;
+}
+
+function actionsUnion(obj, eventName, otherActions) {
+  var meta = obj[META_KEY],
+      actions = meta &amp;&amp; meta.listeners &amp;&amp; meta.listeners[eventName];
+
+  if (!actions) { return; }
+  for (var i = actions.length - 3; i &gt;= 0; i -= 3) {
+    var target = actions[i],
+        method = actions[i+1],
+        flags = actions[i+2],
+        actionIndex = indexOf(otherActions, target, method);
+
+    if (actionIndex === -1) {
+      otherActions.push(target, method, flags);
</ins><span class="cx">     }
</span><span class="cx">   }
</span><ins>+}
</ins><span class="cx"> 
</span><del>-  return res;
</del><ins>+function actionsDiff(obj, eventName, otherActions) {
+  var meta = obj[META_KEY],
+      actions = meta &amp;&amp; meta.listeners &amp;&amp; meta.listeners[eventName],
+      diffActions = [];
+
+  if (!actions) { return; }
+  for (var i = actions.length - 3; i &gt;= 0; i -= 3) {
+    var target = actions[i],
+        method = actions[i+1],
+        flags = actions[i+2],
+        actionIndex = indexOf(otherActions, target, method);
+
+    if (actionIndex !== -1) { continue; }
+
+    otherActions.push(target, method, flags);
+    diffActions.push(target, method, flags);
+  }
+
+  return diffActions;
+}
+
+/**
+  Add an event listener
+
+  @method addListener
+  @for Ember
+  @param obj
+  @param {String} eventName
+  @param {Object|Function} targetOrMethod A target object or a function
+  @param {Function|String} method A function or the name of a function to be called on `target`
+  @param {Boolean} once A flag whether a function should only be called once
+*/
+function addListener(obj, eventName, target, method, once) {
+  Ember.assert(&quot;You must pass at least an object and event name to Ember.addListener&quot;, !!obj &amp;&amp; !!eventName);
+
+  if (!method &amp;&amp; 'function' === typeof target) {
+    method = target;
+    target = null;
+  }
+
+  var actions = actionsFor(obj, eventName),
+      actionIndex = indexOf(actions, target, method),
+      flags = 0;
+
+  if (once) flags |= ONCE;
+
+  if (actionIndex !== -1) { return; }
+
+  actions.push(target, method, flags);
+
+  if ('function' === typeof obj.didAddListener) {
+    obj.didAddListener(eventName, target, method);
+  }
+}
+
+/**
+  Remove an event listener
+
+  Arguments should match those passed to `Ember.addListener`.
+
+  @method removeListener
+  @for Ember
+  @param obj
+  @param {String} eventName
+  @param {Object|Function} targetOrMethod A target object or a function
+  @param {Function|String} method A function or the name of a function to be called on `target`
+*/
+function removeListener(obj, eventName, target, method) {
+  Ember.assert(&quot;You must pass at least an object and event name to Ember.removeListener&quot;, !!obj &amp;&amp; !!eventName);
+
+  if (!method &amp;&amp; 'function' === typeof target) {
+    method = target;
+    target = null;
+  }
+
+  function _removeListener(target, method) {
+    var actions = actionsFor(obj, eventName),
+        actionIndex = indexOf(actions, target, method);
+
+    // action doesn't exist, give up silently
+    if (actionIndex === -1) { return; }
+
+    actions.splice(actionIndex, 3);
+
+    if ('function' === typeof obj.didRemoveListener) {
+      obj.didRemoveListener(eventName, target, method);
+    }
+  }
+
+  if (method) {
+    _removeListener(target, method);
+  } else {
+    var meta = obj[META_KEY],
+        actions = meta &amp;&amp; meta.listeners &amp;&amp; meta.listeners[eventName];
+
+    if (!actions) { return; }
+    for (var i = actions.length - 3; i &gt;= 0; i -= 3) {
+      _removeListener(actions[i], actions[i+1]);
+    }
+  }
+}
+
+/**
+  Suspend listener during callback.
+
+  This should only be used by the target of the event listener
+  when it is taking an action that would cause the event, e.g.
+  an object might suspend its property change listener while it is
+  setting that property.
+
+  @private
+  @method suspendListener
+  @for Ember
+  @param obj
+  @param {String} eventName
+  @param {Object|Function} targetOrMethod A target object or a function
+  @param {Function|String} method A function or the name of a function to be called on `target`
+  @param {Function} callback
+*/
+function suspendListener(obj, eventName, target, method, callback) {
+  if (!method &amp;&amp; 'function' === typeof target) {
+    method = target;
+    target = null;
+  }
+
+  var actions = actionsFor(obj, eventName),
+      actionIndex = indexOf(actions, target, method);
+
+  if (actionIndex !== -1) {
+    actions[actionIndex+2] |= SUSPENDED; // mark the action as suspended
+  }
+
+  function tryable()   { return callback.call(target); }
+  function finalizer() { if (actionIndex !== -1) { actions[actionIndex+2] &amp;= ~SUSPENDED; } }
+
+  return Ember.tryFinally(tryable, finalizer);
+}
+
+/**
+  Suspends multiple listeners during a callback.
+
+  @private
+  @method suspendListeners
+  @for Ember
+  @param obj
+  @param {Array} eventName Array of event names
+  @param {Object|Function} targetOrMethod A target object or a function
+  @param {Function|String} method A function or the name of a function to be called on `target`
+  @param {Function} callback
+*/
+function suspendListeners(obj, eventNames, target, method, callback) {
+  if (!method &amp;&amp; 'function' === typeof target) {
+    method = target;
+    target = null;
+  }
+
+  var suspendedActions = [],
+      actionsList = [],
+      eventName, actions, i, l;
+
+  for (i=0, l=eventNames.length; i&lt;l; i++) {
+    eventName = eventNames[i];
+    actions = actionsFor(obj, eventName);
+    var actionIndex = indexOf(actions, target, method);
+
+    if (actionIndex !== -1) {
+      actions[actionIndex+2] |= SUSPENDED;
+      suspendedActions.push(actionIndex);
+      actionsList.push(actions);
+    }
+  }
+
+  function tryable() { return callback.call(target); }
+
+  function finalizer() {
+    for (var i = 0, l = suspendedActions.length; i &lt; l; i++) {
+      var actionIndex = suspendedActions[i];
+      actionsList[i][actionIndex+2] &amp;= ~SUSPENDED;
+    }
+  }
+
+  return Ember.tryFinally(tryable, finalizer);
+}
+
+/**
+  Return a list of currently watched events
+
+  @private
+  @method watchedEvents
+  @for Ember
+  @param obj
+*/
+function watchedEvents(obj) {
+  var listeners = obj[META_KEY].listeners, ret = [];
+
+  if (listeners) {
+    for(var eventName in listeners) {
+      if (listeners[eventName]) { ret.push(eventName); }
+    }
+  }
+  return ret;
+}
+
+/**
+  Send an event. The execution of suspended listeners
+  is skipped, and once listeners are removed. A listener without
+  a target is executed on the passed object. If an array of actions
+  is not passed, the actions stored on the passed object are invoked.
+
+  @method sendEvent
+  @for Ember
+  @param obj
+  @param {String} eventName
+  @param {Array} params Optional parameters for each listener.
+  @param {Array} actions Optional array of actions (listeners).
+  @return true
+*/
+function sendEvent(obj, eventName, params, actions) {
+  // first give object a chance to handle it
+  if (obj !== Ember &amp;&amp; 'function' === typeof obj.sendEvent) {
+    obj.sendEvent(eventName, params);
+  }
+
+  if (!actions) {
+    var meta = obj[META_KEY];
+    actions = meta &amp;&amp; meta.listeners &amp;&amp; meta.listeners[eventName];
+  }
+
+  if (!actions) { return; }
+
+  for (var i = actions.length - 3; i &gt;= 0; i -= 3) { // looping in reverse for once listeners
+    var target = actions[i], method = actions[i+1], flags = actions[i+2];
+    if (!method) { continue; }
+    if (flags &amp; SUSPENDED) { continue; }
+    if (flags &amp; ONCE) { removeListener(obj, eventName, target, method); }
+    if (!target) { target = obj; }
+    if ('string' === typeof method) { method = target[method]; }
+    if (params) {
+      method.apply(target, params);
+    } else {
+      method.call(target);
+    }
+  }
+  return true;
+}
+
+/**
+  @private
+  @method hasListeners
+  @for Ember
+  @param obj
+  @param {String} eventName
+*/
+function hasListeners(obj, eventName) {
+  var meta = obj[META_KEY],
+      actions = meta &amp;&amp; meta.listeners &amp;&amp; meta.listeners[eventName];
+
+  return !!(actions &amp;&amp; actions.length);
+}
+
+/**
+  @private
+  @method listenersFor
+  @for Ember
+  @param obj
+  @param {String} eventName
+*/
+function listenersFor(obj, eventName) {
+  var ret = [];
+  var meta = obj[META_KEY],
+      actions = meta &amp;&amp; meta.listeners &amp;&amp; meta.listeners[eventName];
+
+  if (!actions) { return ret; }
+
+  for (var i = 0, l = actions.length; i &lt; l; i += 3) {
+    var target = actions[i],
+        method = actions[i+1];
+    ret.push([target, method]);
+  }
+
+  return ret;
+}
+
+/**
+  Define a property as a function that should be executed when
+  a specified event or events are triggered.
+
+
+  ``` javascript
+  var Job = Ember.Object.extend({
+    logCompleted: Ember.on('completed', function(){
+      console.log('Job completed!');
+    })
+  });
+  var job = Job.create();
+  Ember.sendEvent(job, 'completed'); // Logs &quot;Job completed!&quot;
+ ```
+
+  @method on
+  @for Ember
+  @param {String} eventNames*
+  @param {Function} func
+  @return func
+*/
+Ember.on = function(){
+  var func = a_slice.call(arguments, -1)[0],
+      events = a_slice.call(arguments, 0, -1);
+  func.__ember_listens__ = events;
+  return func;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-// From: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach
-var arrayForEach = isNativeFunc(Array.prototype.forEach) ? Array.prototype.forEach : function(fun /*, thisp */) {
-  //&quot;use strict&quot;;
</del><ins>+Ember.addListener = addListener;
+Ember.removeListener = removeListener;
+Ember._suspendListener = suspendListener;
+Ember._suspendListeners = suspendListeners;
+Ember.sendEvent = sendEvent;
+Ember.hasListeners = hasListeners;
+Ember.watchedEvents = watchedEvents;
+Ember.listenersFor = listenersFor;
+Ember.listenersDiff = actionsDiff;
+Ember.listenersUnion = actionsUnion;
</ins><span class="cx"> 
</span><del>-  if (this === void 0 || this === null) {
-    throw new TypeError();
</del><ins>+})();
+
+
+
+(function() {
+var guidFor = Ember.guidFor,
+    sendEvent = Ember.sendEvent;
+
+/*
+  this.observerSet = {
+    [senderGuid]: { // variable name: `keySet`
+      [keyName]: listIndex
+    }
+  },
+  this.observers = [
+    {
+      sender: obj,
+      keyName: keyName,
+      eventName: eventName,
+      listeners: [
+        [target, method, flags]
+      ]
+    },
+    ...
+  ]
+*/
+var ObserverSet = Ember._ObserverSet = function() {
+  this.clear();
+};
+
+ObserverSet.prototype.add = function(sender, keyName, eventName) {
+  var observerSet = this.observerSet,
+      observers = this.observers,
+      senderGuid = guidFor(sender),
+      keySet = observerSet[senderGuid],
+      index;
+
+  if (!keySet) {
+    observerSet[senderGuid] = keySet = {};
</ins><span class="cx">   }
</span><ins>+  index = keySet[keyName];
+  if (index === undefined) {
+    index = observers.push({
+      sender: sender,
+      keyName: keyName,
+      eventName: eventName,
+      listeners: []
+    }) - 1;
+    keySet[keyName] = index;
+  }
+  return observers[index].listeners;
+};
</ins><span class="cx"> 
</span><del>-  var t = Object(this);
-  var len = t.length &gt;&gt;&gt; 0;
-  if (typeof fun !== &quot;function&quot;) {
-    throw new TypeError();
</del><ins>+ObserverSet.prototype.flush = function() {
+  var observers = this.observers, i, len, observer, sender;
+  this.clear();
+  for (i=0, len=observers.length; i &lt; len; ++i) {
+    observer = observers[i];
+    sender = observer.sender;
+    if (sender.isDestroying || sender.isDestroyed) { continue; }
+    sendEvent(sender, observer.eventName, [sender, observer.keyName], observer.listeners);
</ins><span class="cx">   }
</span><ins>+};
</ins><span class="cx"> 
</span><del>-  var thisp = arguments[1];
-  for (var i = 0; i &lt; len; i++) {
-    if (i in t) {
-      fun.call(thisp, t[i], i, t);
</del><ins>+ObserverSet.prototype.clear = function() {
+  this.observerSet = {};
+  this.observers = [];
+};
+})();
+
+
+
+(function() {
+var metaFor = Ember.meta,
+    guidFor = Ember.guidFor,
+    tryFinally = Ember.tryFinally,
+    sendEvent = Ember.sendEvent,
+    listenersUnion = Ember.listenersUnion,
+    listenersDiff = Ember.listenersDiff,
+    ObserverSet = Ember._ObserverSet,
+    beforeObserverSet = new ObserverSet(),
+    observerSet = new ObserverSet(),
+    deferred = 0;
+
+// ..........................................................
+// PROPERTY CHANGES
+//
+
+/**
+  This function is called just before an object property is about to change.
+  It will notify any before observers and prepare caches among other things.
+
+  Normally you will not need to call this method directly but if for some
+  reason you can't directly watch a property you can invoke this method
+  manually along with `Ember.propertyDidChange()` which you should call just
+  after the property value changes.
+
+  @method propertyWillChange
+  @for Ember
+  @param {Object} obj The object with the property that will change
+  @param {String} keyName The property key (or path) that will change.
+  @return {void}
+*/
+function propertyWillChange(obj, keyName) {
+  var m = metaFor(obj, false),
+      watching = m.watching[keyName] &gt; 0 || keyName === 'length',
+      proto = m.proto,
+      desc = m.descs[keyName];
+
+  if (!watching) { return; }
+  if (proto === obj) { return; }
+  if (desc &amp;&amp; desc.willChange) { desc.willChange(obj, keyName); }
+  dependentKeysWillChange(obj, keyName, m);
+  chainsWillChange(obj, keyName, m);
+  notifyBeforeObservers(obj, keyName);
+}
+Ember.propertyWillChange = propertyWillChange;
+
+/**
+  This function is called just after an object property has changed.
+  It will notify any observers and clear caches among other things.
+
+  Normally you will not need to call this method directly but if for some
+  reason you can't directly watch a property you can invoke this method
+  manually along with `Ember.propertyWillChange()` which you should call just
+  before the property value changes.
+
+  @method propertyDidChange
+  @for Ember
+  @param {Object} obj The object with the property that will change
+  @param {String} keyName The property key (or path) that will change.
+  @return {void}
+*/
+function propertyDidChange(obj, keyName) {
+  var m = metaFor(obj, false),
+      watching = m.watching[keyName] &gt; 0 || keyName === 'length',
+      proto = m.proto,
+      desc = m.descs[keyName];
+
+  if (proto === obj) { return; }
+
+  // shouldn't this mean that we're watching this key?
+  if (desc &amp;&amp; desc.didChange) { desc.didChange(obj, keyName); }
+  if (!watching &amp;&amp; keyName !== 'length') { return; }
+
+  dependentKeysDidChange(obj, keyName, m);
+  chainsDidChange(obj, keyName, m, false);
+  notifyObservers(obj, keyName);
+}
+Ember.propertyDidChange = propertyDidChange;
+
+var WILL_SEEN, DID_SEEN;
+
+// called whenever a property is about to change to clear the cache of any dependent keys (and notify those properties of changes, etc...)
+function dependentKeysWillChange(obj, depKey, meta) {
+  if (obj.isDestroying) { return; }
+
+  var seen = WILL_SEEN, top = !seen;
+  if (top) { seen = WILL_SEEN = {}; }
+  iterDeps(propertyWillChange, obj, depKey, seen, meta);
+  if (top) { WILL_SEEN = null; }
+}
+
+// called whenever a property has just changed to update dependent keys
+function dependentKeysDidChange(obj, depKey, meta) {
+  if (obj.isDestroying) { return; }
+
+  var seen = DID_SEEN, top = !seen;
+  if (top) { seen = DID_SEEN = {}; }
+  iterDeps(propertyDidChange, obj, depKey, seen, meta);
+  if (top) { DID_SEEN = null; }
+}
+
+function iterDeps(method, obj, depKey, seen, meta) {
+  var guid = guidFor(obj);
+  if (!seen[guid]) seen[guid] = {};
+  if (seen[guid][depKey]) return;
+  seen[guid][depKey] = true;
+
+  var deps = meta.deps;
+  deps = deps &amp;&amp; deps[depKey];
+  if (deps) {
+    for(var key in deps) {
+      var desc = meta.descs[key];
+      if (desc &amp;&amp; desc._suspended === obj) continue;
+      method(obj, key);
</ins><span class="cx">     }
</span><span class="cx">   }
</span><ins>+}
+
+function chainsWillChange(obj, keyName, m) {
+  if (!(m.hasOwnProperty('chainWatchers') &amp;&amp;
+        m.chainWatchers[keyName])) {
+    return;
+  }
+
+  var nodes = m.chainWatchers[keyName],
+      events = [],
+      i, l;
+
+  for(i = 0, l = nodes.length; i &lt; l; i++) {
+    nodes[i].willChange(events);
+  }
+
+  for (i = 0, l = events.length; i &lt; l; i += 2) {
+    propertyWillChange(events[i], events[i+1]);
+  }
+}
+
+function chainsDidChange(obj, keyName, m, suppressEvents) {
+  if (!(m.hasOwnProperty('chainWatchers') &amp;&amp;
+        m.chainWatchers[keyName])) {
+    return;
+  }
+
+  var nodes = m.chainWatchers[keyName],
+      events = suppressEvents ? null : [],
+      i, l;
+
+  for(i = 0, l = nodes.length; i &lt; l; i++) {
+    nodes[i].didChange(events);
+  }
+
+  if (suppressEvents) {
+    return;
+  }
+
+  for (i = 0, l = events.length; i &lt; l; i += 2) {
+    propertyDidChange(events[i], events[i+1]);
+  }
+}
+
+Ember.overrideChains = function(obj, keyName, m) {
+  chainsDidChange(obj, keyName, m, true);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-var arrayIndexOf = isNativeFunc(Array.prototype.indexOf) ? Array.prototype.indexOf : function (obj, fromIndex) {
-  if (fromIndex === null || fromIndex === undefined) { fromIndex = 0; }
-  else if (fromIndex &lt; 0) { fromIndex = Math.max(0, this.length + fromIndex); }
-  for (var i = fromIndex, j = this.length; i &lt; j; i++) {
-    if (this[i] === obj) { return i; }
</del><ins>+/**
+  @method beginPropertyChanges
+  @chainable
+  @private
+*/
+function beginPropertyChanges() {
+  deferred++;
+}
+
+Ember.beginPropertyChanges = beginPropertyChanges;
+
+/**
+  @method endPropertyChanges
+  @private
+*/
+function endPropertyChanges() {
+  deferred--;
+  if (deferred&lt;=0) {
+    beforeObserverSet.clear();
+    observerSet.flush();
</ins><span class="cx">   }
</span><del>-  return -1;
</del><ins>+}
+
+Ember.endPropertyChanges = endPropertyChanges;
+
+/**
+  Make a series of property changes together in an
+  exception-safe way.
+
+  ```javascript
+  Ember.changeProperties(function() {
+    obj1.set('foo', mayBlowUpWhenSet);
+    obj2.set('bar', baz);
+  });
+  ```
+
+  @method changeProperties
+  @param {Function} callback
+  @param [binding]
+*/
+Ember.changeProperties = function(cb, binding) {
+  beginPropertyChanges();
+  tryFinally(cb, endPropertyChanges, binding);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-Ember.ArrayPolyfills = {
-  map: arrayMap,
-  forEach: arrayForEach,
-  indexOf: arrayIndexOf
</del><ins>+function notifyBeforeObservers(obj, keyName) {
+  if (obj.isDestroying) { return; }
+
+  var eventName = keyName + ':before', listeners, diff;
+  if (deferred) {
+    listeners = beforeObserverSet.add(obj, keyName, eventName);
+    diff = listenersDiff(obj, eventName, listeners);
+    sendEvent(obj, eventName, [obj, keyName], diff);
+  } else {
+    sendEvent(obj, eventName, [obj, keyName]);
+  }
+}
+
+function notifyObservers(obj, keyName) {
+  if (obj.isDestroying) { return; }
+
+  var eventName = keyName + ':change', listeners;
+  if (deferred) {
+    listeners = observerSet.add(obj, keyName, eventName);
+    listenersUnion(obj, eventName, listeners);
+  } else {
+    sendEvent(obj, eventName, [obj, keyName]);
+  }
+}
+
+})();
+
+
+
+(function() {
+// META_KEY
+// _getPath
+// propertyWillChange, propertyDidChange
+
+var META_KEY = Ember.META_KEY,
+    MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER,
+    IS_GLOBAL = /^([A-Z$]|([0-9][A-Z$]))/,
+    getPath = Ember._getPath;
+
+/**
+  Sets the value of a property on an object, respecting computed properties
+  and notifying observers and other listeners of the change. If the
+  property is not defined but the object implements the `setUnknownProperty`
+  method then that will be invoked as well.
+
+  If you plan to run on IE8 and older browsers then you should use this
+  method anytime you want to set a property on an object that you don't
+  know for sure is private. (Properties beginning with an underscore '_'
+  are considered private.)
+
+  On all newer browsers, you only need to use this method to set
+  properties if the property might not be defined on the object and you want
+  to respect the `setUnknownProperty` handler. Otherwise you can ignore this
+  method.
+
+  @method set
+  @for Ember
+  @param {Object} obj The object to modify.
+  @param {String} keyName The property key to set
+  @param {Object} value The value to set
+  @return {Object} the passed value.
+*/
+var set = function set(obj, keyName, value, tolerant) {
+  if (typeof obj === 'string') {
+    Ember.assert(&quot;Path '&quot; + obj + &quot;' must be global if no obj is given.&quot;, IS_GLOBAL.test(obj));
+    value = keyName;
+    keyName = obj;
+    obj = null;
+  }
+
+  Ember.assert(&quot;Cannot call set with &quot;+ keyName +&quot; key.&quot;, !!keyName);
+
+  if (!obj || keyName.indexOf('.') !== -1) {
+    return setPath(obj, keyName, value, tolerant);
+  }
+
+  Ember.assert(&quot;You need to provide an object and key to `set`.&quot;, !!obj &amp;&amp; keyName !== undefined);
+  Ember.assert('calling set on destroyed object', !obj.isDestroyed);
+
+  var meta = obj[META_KEY], desc = meta &amp;&amp; meta.descs[keyName],
+      isUnknown, currentValue;
+  if (desc) {
+    desc.set(obj, keyName, value);
+  } else {
+    isUnknown = 'object' === typeof obj &amp;&amp; !(keyName in obj);
+
+    // setUnknownProperty is called if `obj` is an object,
+    // the property does not already exist, and the
+    // `setUnknownProperty` method exists on the object
+    if (isUnknown &amp;&amp; 'function' === typeof obj.setUnknownProperty) {
+      obj.setUnknownProperty(keyName, value);
+    } else if (meta &amp;&amp; meta.watching[keyName] &gt; 0) {
+      if (MANDATORY_SETTER) {
+        currentValue = meta.values[keyName];
+      } else {
+        currentValue = obj[keyName];
+      }
+      // only trigger a change if the value has changed
+      if (value !== currentValue) {
+        Ember.propertyWillChange(obj, keyName);
+        if (MANDATORY_SETTER) {
+          if ((currentValue === undefined &amp;&amp; !(keyName in obj)) || !obj.propertyIsEnumerable(keyName)) {
+            Ember.defineProperty(obj, keyName, null, value); // setup mandatory setter
+          } else {
+            meta.values[keyName] = value;
+          }
+        } else {
+          obj[keyName] = value;
+        }
+        Ember.propertyDidChange(obj, keyName);
+      }
+    } else {
+      obj[keyName] = value;
+    }
+  }
+  return value;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-if (Ember.SHIM_ES5) {
-  if (!Array.prototype.map) {
-    Array.prototype.map = arrayMap;
</del><ins>+// Currently used only by Ember Data tests
+if (Ember.config.overrideAccessors) {
+  Ember.set = set;
+  Ember.config.overrideAccessors();
+  set = Ember.set;
+}
+
+function setPath(root, path, value, tolerant) {
+  var keyName;
+
+  // get the last part of the path
+  keyName = path.slice(path.lastIndexOf('.') + 1);
+
+  // get the first part of the part
+  path    = (path === keyName) ? keyName : path.slice(0, path.length-(keyName.length+1));
+
+  // unless the path is this, look up the first part to
+  // get the root
+  if (path !== 'this') {
+    root = getPath(root, path);
</ins><span class="cx">   }
</span><span class="cx"> 
</span><del>-  if (!Array.prototype.forEach) {
-    Array.prototype.forEach = arrayForEach;
</del><ins>+  if (!keyName || keyName.length === 0) {
+    throw new Ember.Error('Property set failed: You passed an empty path');
</ins><span class="cx">   }
</span><span class="cx"> 
</span><del>-  if (!Array.prototype.indexOf) {
-    Array.prototype.indexOf = arrayIndexOf;
</del><ins>+  if (!root) {
+    if (tolerant) { return; }
+    else { throw new Ember.Error('Property set failed: object in path &quot;'+path+'&quot; could not be found or was destroyed.'); }
</ins><span class="cx">   }
</span><ins>+
+  return set(root, keyName, value);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Ember.set = set;
+
+/**
+  Error-tolerant form of `Ember.set`. Will not blow up if any part of the
+  chain is `undefined`, `null`, or destroyed.
+
+  This is primarily used when syncing bindings, which may try to update after
+  an object has been destroyed.
+
+  @method trySet
+  @for Ember
+  @param {Object} obj The object to modify.
+  @param {String} path The property path to set
+  @param {Object} value The value to set
+*/
+Ember.trySet = function(root, path, value) {
+  return set(root, path, value, true);
+};
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -1455,7 +2912,8 @@
</span><span class="cx">   Map is mocked out to look like an Ember object, so you can do
</span><span class="cx">   `Ember.Map.create()` for symmetry with other Ember classes.
</span><span class="cx"> */
</span><del>-var guidFor = Ember.guidFor,
</del><ins>+var set = Ember.set,
+    guidFor = Ember.guidFor,
</ins><span class="cx">     indexOf = Ember.ArrayPolyfills.indexOf;
</span><span class="cx"> 
</span><span class="cx"> var copy = function(obj) {
</span><span class="lines">@@ -1474,6 +2932,7 @@
</span><span class="cx"> 
</span><span class="cx">   newObject.keys = keys;
</span><span class="cx">   newObject.values = values;
</span><ins>+  newObject.length = original.length;
</ins><span class="cx"> 
</span><span class="cx">   return newObject;
</span><span class="cx"> };
</span><span class="lines">@@ -1565,12 +3024,12 @@
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     @method forEach
</span><del>-    @param {Function} function
-    @param target
</del><ins>+    @param {Function} fn
+    @param self
</ins><span class="cx">   */
</span><span class="cx">   forEach: function(fn, self) {
</span><span class="cx">     // allow mutation during iteration
</span><del>-    var list = this.list.slice();
</del><ins>+    var list = this.toArray();
</ins><span class="cx"> 
</span><span class="cx">     for (var i = 0, j = list.length; i &lt; j; i++) {
</span><span class="cx">       fn.call(self, list[i]);
</span><span class="lines">@@ -1593,7 +3052,7 @@
</span><span class="cx">     var set = new OrderedSet();
</span><span class="cx"> 
</span><span class="cx">     set.presenceSet = copy(this.presenceSet);
</span><del>-    set.list = this.list.slice();
</del><ins>+    set.list = this.toArray();
</ins><span class="cx"> 
</span><span class="cx">     return set;
</span><span class="cx">   }
</span><span class="lines">@@ -1634,11 +3093,21 @@
</span><span class="cx"> 
</span><span class="cx"> Map.prototype = {
</span><span class="cx">   /**
</span><ins>+    This property will change as the number of objects in the map changes.
+   
+    @property length
+    @type number
+    @default 0
+  */
+  length: 0,
+    
+    
+  /**
</ins><span class="cx">     Retrieve the value associated with a given key.
</span><span class="cx"> 
</span><span class="cx">     @method get
</span><del>-    @param {anything} key
-    @return {anything} the value associated with the key, or `undefined`
</del><ins>+    @param {*} key
+    @return {*} the value associated with the key, or `undefined`
</ins><span class="cx">   */
</span><span class="cx">   get: function(key) {
</span><span class="cx">     var values = this.values,
</span><span class="lines">@@ -1652,8 +3121,8 @@
</span><span class="cx">     provided, the new value will replace the old value.
</span><span class="cx"> 
</span><span class="cx">     @method set
</span><del>-    @param {anything} key
-    @param {anything} value
</del><ins>+    @param {*} key
+    @param {*} value
</ins><span class="cx">   */
</span><span class="cx">   set: function(key, value) {
</span><span class="cx">     var keys = this.keys,
</span><span class="lines">@@ -1662,13 +3131,14 @@
</span><span class="cx"> 
</span><span class="cx">     keys.add(key);
</span><span class="cx">     values[guid] = value;
</span><ins>+    set(this, 'length', keys.list.length);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     Removes a value from the map for an associated key.
</span><span class="cx"> 
</span><span class="cx">     @method remove
</span><del>-    @param {anything} key
</del><ins>+    @param {*} key
</ins><span class="cx">     @return {Boolean} true if an item was removed, false otherwise
</span><span class="cx">   */
</span><span class="cx">   remove: function(key) {
</span><span class="lines">@@ -1676,13 +3146,12 @@
</span><span class="cx">     // to use in browsers that are not ES6 friendly;
</span><span class="cx">     var keys = this.keys,
</span><span class="cx">         values = this.values,
</span><del>-        guid = guidFor(key),
-        value;
</del><ins>+        guid = guidFor(key);
</ins><span class="cx"> 
</span><span class="cx">     if (values.hasOwnProperty(guid)) {
</span><span class="cx">       keys.remove(key);
</span><del>-      value = values[guid];
</del><span class="cx">       delete values[guid];
</span><ins>+      set(this, 'length', keys.list.length);
</ins><span class="cx">       return true;
</span><span class="cx">     } else {
</span><span class="cx">       return false;
</span><span class="lines">@@ -1693,7 +3162,7 @@
</span><span class="cx">     Check whether a key is present.
</span><span class="cx"> 
</span><span class="cx">     @method has
</span><del>-    @param {anything} key
</del><ins>+    @param {*} key
</ins><span class="cx">     @return {Boolean} true if the item was present, false otherwise
</span><span class="cx">   */
</span><span class="cx">   has: function(key) {
</span><span class="lines">@@ -1711,7 +3180,7 @@
</span><span class="cx"> 
</span><span class="cx">     @method forEach
</span><span class="cx">     @param {Function} callback
</span><del>-    @param {anything} self if passed, the `this` value inside the
</del><ins>+    @param {*} self if passed, the `this` value inside the
</ins><span class="cx">       callback. By default, `this` is the map.
</span><span class="cx">   */
</span><span class="cx">   forEach: function(callback, self) {
</span><span class="lines">@@ -1740,7 +3209,7 @@
</span><span class="cx">   @private
</span><span class="cx">   @constructor
</span><span class="cx">   @param [options]
</span><del>-    @param {anything} [options.defaultValue]
</del><ins>+    @param {*} [options.defaultValue]
</ins><span class="cx"> */
</span><span class="cx"> var MapWithDefault = Ember.MapWithDefault = function(options) {
</span><span class="cx">   Map.call(this);
</span><span class="lines">@@ -1751,8 +3220,8 @@
</span><span class="cx">   @method create
</span><span class="cx">   @static
</span><span class="cx">   @param [options]
</span><del>-    @param {anything} [options.defaultValue]
-  @return {Ember.MapWithDefault|Ember.Map} If options are passed, returns 
</del><ins>+    @param {*} [options.defaultValue]
+  @return {Ember.MapWithDefault|Ember.Map} If options are passed, returns
</ins><span class="cx">     `Ember.MapWithDefault` otherwise returns `Ember.Map`
</span><span class="cx"> */
</span><span class="cx"> MapWithDefault.create = function(options) {
</span><span class="lines">@@ -1769,8 +3238,8 @@
</span><span class="cx">   Retrieve the value associated with a given key.
</span><span class="cx"> 
</span><span class="cx">   @method get
</span><del>-  @param {anything} key
-  @return {anything} the value associated with the key, or the default value
</del><ins>+  @param {*} key
+  @return {*} the value associated with the key, or the default value
</ins><span class="cx"> */
</span><span class="cx"> MapWithDefault.prototype.get = function(key) {
</span><span class="cx">   var hasValue = this.has(key);
</span><span class="lines">@@ -1799,317 +3268,143 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-/**
-@module ember-metal
-*/
-
-var META_KEY = Ember.META_KEY, get, set;
-
-var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;
-
-var IS_GLOBAL = /^([A-Z$]|([0-9][A-Z$]))/;
-var IS_GLOBAL_PATH = /^([A-Z$]|([0-9][A-Z$])).*[\.\*]/;
-var HAS_THIS  = /^this[\.\*]/;
-var FIRST_KEY = /^([^\.\*]+)/;
-
-// ..........................................................
-// GET AND SET
-//
-// If we are on a platform that supports accessors we can get use those.
-// Otherwise simulate accessors by looking up the property directly on the
-// object.
-
-/**
-  Gets the value of a property on an object. If the property is computed,
-  the function will be invoked. If the property is not defined but the
-  object implements the `unknownProperty` method then that will be invoked.
-
-  If you plan to run on IE8 and older browsers then you should use this
-  method anytime you want to retrieve a property on an object that you don't
-  know for sure is private. (Properties beginning with an underscore '_' 
-  are considered private.)
-
-  On all newer browsers, you only need to use this method to retrieve
-  properties if the property might not be defined on the object and you want
-  to respect the `unknownProperty` handler. Otherwise you can ignore this
-  method.
-
-  Note that if the object itself is `undefined`, this method will throw
-  an error.
-
-  @method get
-  @for Ember
-  @param {Object} obj The object to retrieve from.
-  @param {String} keyName The property key to retrieve
-  @return {Object} the property value or `null`.
-*/
-get = function get(obj, keyName) {
-  // Helpers that operate with 'this' within an #each
-  if (keyName === '') {
-    return obj;
</del><ins>+function consoleMethod(name) {
+  var consoleObj, logToConsole;
+  if (Ember.imports.console) {
+    consoleObj = Ember.imports.console;
+  } else if (typeof console !== 'undefined') {
+    consoleObj = console;
</ins><span class="cx">   }
</span><span class="cx"> 
</span><del>-  if (!keyName &amp;&amp; 'string'===typeof obj) {
-    keyName = obj;
-    obj = null;
-  }
</del><ins>+  var method = typeof consoleObj === 'object' ? consoleObj[name] : null;
</ins><span class="cx"> 
</span><del>-  if (!obj || keyName.indexOf('.') !== -1) {
-    Ember.assert(&quot;Cannot call get with '&quot;+ keyName +&quot;' on an undefined object.&quot;, obj !== undefined);
-    return getPath(obj, keyName);
-  }
-
-  Ember.assert(&quot;You need to provide an object and key to `get`.&quot;, !!obj &amp;&amp; keyName);
-
-  var meta = obj[META_KEY], desc = meta &amp;&amp; meta.descs[keyName], ret;
-  if (desc) {
-    return desc.get(obj, keyName);
-  } else {
-    if (MANDATORY_SETTER &amp;&amp; meta &amp;&amp; meta.watching[keyName] &gt; 0) {
-      ret = meta.values[keyName];
</del><ins>+  if (method) {
+    // Older IE doesn't support apply, but Chrome needs it
+    if (method.apply) {
+      logToConsole = function() {
+        method.apply(consoleObj, arguments);
+      };
+      logToConsole.displayName = 'console.' + name;
+      return logToConsole;
</ins><span class="cx">     } else {
</span><del>-      ret = obj[keyName];
</del><ins>+      return function() {
+        var message = Array.prototype.join.call(arguments, ', ');
+        method(message);
+      };
</ins><span class="cx">     }
</span><ins>+  }
+}
</ins><span class="cx"> 
</span><del>-    if (ret === undefined &amp;&amp;
-        'object' === typeof obj &amp;&amp; !(keyName in obj) &amp;&amp; 'function' === typeof obj.unknownProperty) {
-      return obj.unknownProperty(keyName);
</del><ins>+function assertPolyfill(test, message) {
+  if (!test) {
+    try {
+      // attempt to preserve the stack
+      throw new Ember.Error(&quot;assertion failed: &quot; + message);
+    } catch(error) {
+      setTimeout(function() {
+        throw error;
+      }, 0);
</ins><span class="cx">     }
</span><del>-
-    return ret;
</del><span class="cx">   }
</span><del>-};
</del><ins>+}
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  Sets the value of a property on an object, respecting computed properties
-  and notifying observers and other listeners of the change. If the
-  property is not defined but the object implements the `unknownProperty`
-  method then that will be invoked as well.
</del><ins>+  Inside Ember-Metal, simply uses the methods from `imports.console`.
+  Override this to provide more robust logging functionality.
</ins><span class="cx"> 
</span><del>-  If you plan to run on IE8 and older browsers then you should use this
-  method anytime you want to set a property on an object that you don't
-  know for sure is private. (Properties beginning with an underscore '_' 
-  are considered private.)
-
-  On all newer browsers, you only need to use this method to set
-  properties if the property might not be defined on the object and you want
-  to respect the `unknownProperty` handler. Otherwise you can ignore this
-  method.
-
-  @method set
-  @for Ember
-  @param {Object} obj The object to modify.
-  @param {String} keyName The property key to set
-  @param {Object} value The value to set
-  @return {Object} the passed value.
</del><ins>+  @class Logger
+  @namespace Ember
</ins><span class="cx"> */
</span><del>-set = function set(obj, keyName, value, tolerant) {
-  if (typeof obj === 'string') {
-    Ember.assert(&quot;Path '&quot; + obj + &quot;' must be global if no obj is given.&quot;, IS_GLOBAL.test(obj));
-    value = keyName;
-    keyName = obj;
-    obj = null;
-  }
</del><ins>+Ember.Logger = {
+  /**
+   Logs the arguments to the console.
+   You can pass as many arguments as you want and they will be joined together with a space.
</ins><span class="cx"> 
</span><del>-  if (!obj || keyName.indexOf('.') !== -1) {
-    return setPath(obj, keyName, value, tolerant);
-  }
</del><ins>+    ```javascript
+    var foo = 1;
+    Ember.Logger.log('log value of foo:', foo); // &quot;log value of foo: 1&quot; will be printed to the console
+    ```
</ins><span class="cx"> 
</span><del>-  Ember.assert(&quot;You need to provide an object and key to `set`.&quot;, !!obj &amp;&amp; keyName !== undefined);
-  Ember.assert('calling set on destroyed object', !obj.isDestroyed);
</del><ins>+   @method log
+   @for Ember.Logger
+   @param {*} arguments
+  */
+  log:   consoleMethod('log')   || Ember.K,
</ins><span class="cx"> 
</span><del>-  var meta = obj[META_KEY], desc = meta &amp;&amp; meta.descs[keyName],
-      isUnknown, currentValue;
-  if (desc) {
-    desc.set(obj, keyName, value);
-  } else {
-    isUnknown = 'object' === typeof obj &amp;&amp; !(keyName in obj);
</del><ins>+  /**
+   Prints the arguments to the console with a warning icon.
+   You can pass as many arguments as you want and they will be joined together with a space.
</ins><span class="cx"> 
</span><del>-    // setUnknownProperty is called if `obj` is an object,
-    // the property does not already exist, and the
-    // `setUnknownProperty` method exists on the object
-    if (isUnknown &amp;&amp; 'function' === typeof obj.setUnknownProperty) {
-      obj.setUnknownProperty(keyName, value);
-    } else if (meta &amp;&amp; meta.watching[keyName] &gt; 0) {
-      if (MANDATORY_SETTER) {
-        currentValue = meta.values[keyName];
-      } else {
-        currentValue = obj[keyName];
-      }
-      // only trigger a change if the value has changed
-      if (value !== currentValue) {
-        Ember.propertyWillChange(obj, keyName);
-        if (MANDATORY_SETTER) {
-          if (currentValue === undefined &amp;&amp; !(keyName in obj)) {
-            Ember.defineProperty(obj, keyName, null, value); // setup mandatory setter
-          } else {
-            meta.values[keyName] = value;
-          }
-        } else {
-          obj[keyName] = value;
-        }
-        Ember.propertyDidChange(obj, keyName);
-      }
-    } else {
-      obj[keyName] = value;
-    }
-  }
-  return value;
-};
</del><ins>+    ```javascript
+    Ember.Logger.warn('Something happened!'); // &quot;Something happened!&quot; will be printed to the console with a warning icon.
+    ```
</ins><span class="cx"> 
</span><del>-// Currently used only by Ember Data tests
-if (Ember.config.overrideAccessors) {
-  Ember.get = get;
-  Ember.set = set;
-  Ember.config.overrideAccessors();
-  get = Ember.get;
-  set = Ember.set;
-}
</del><ins>+   @method warn
+   @for Ember.Logger
+   @param {*} arguments
+  */
+  warn:  consoleMethod('warn')  || Ember.K,
</ins><span class="cx"> 
</span><del>-function firstKey(path) {
-  return path.match(FIRST_KEY)[0];
-}
</del><ins>+  /**
+   Prints the arguments to the console with an error icon, red text and a stack trace.
+   You can pass as many arguments as you want and they will be joined together with a space.
</ins><span class="cx"> 
</span><del>-// assumes path is already normalized
-function normalizeTuple(target, path) {
-  var hasThis  = HAS_THIS.test(path),
-      isGlobal = !hasThis &amp;&amp; IS_GLOBAL_PATH.test(path),
-      key;
</del><ins>+    ```javascript
+    Ember.Logger.error('Danger! Danger!'); // &quot;Danger! Danger!&quot; will be printed to the console in red text.
+    ```
</ins><span class="cx"> 
</span><del>-  if (!target || isGlobal) target = Ember.lookup;
-  if (hasThis) path = path.slice(5);
</del><ins>+   @method error
+   @for Ember.Logger
+   @param {*} arguments
+  */
+  error: consoleMethod('error') || Ember.K,
</ins><span class="cx"> 
</span><del>-  if (target === Ember.lookup) {
-    key = firstKey(path);
-    target = get(target, key);
-    path   = path.slice(key.length+1);
-  }
</del><ins>+  /**
+   Logs the arguments to the console.
+   You can pass as many arguments as you want and they will be joined together with a space.
</ins><span class="cx"> 
</span><del>-  // must return some kind of path to be valid else other things will break.
-  if (!path || path.length===0) throw new Error('Invalid Path');
</del><ins>+    ```javascript
+    var foo = 1;
+    Ember.Logger.info('log value of foo:', foo); // &quot;log value of foo: 1&quot; will be printed to the console
+    ```
</ins><span class="cx"> 
</span><del>-  return [ target, path ];
-}
</del><ins>+   @method info
+   @for Ember.Logger
+   @param {*} arguments
+  */
+  info:  consoleMethod('info')  || Ember.K,
</ins><span class="cx"> 
</span><del>-function getPath(root, path) {
-  var hasThis, parts, tuple, idx, len;
</del><ins>+  /**
+   Logs the arguments to the console in blue text.
+   You can pass as many arguments as you want and they will be joined together with a space.
</ins><span class="cx"> 
</span><del>-  // If there is no root and path is a key name, return that
-  // property from the global object.
-  // E.g. get('Ember') -&gt; Ember
-  if (root === null &amp;&amp; path.indexOf('.') === -1) { return get(Ember.lookup, path); }
</del><ins>+    ```javascript
+    var foo = 1;
+    Ember.Logger.debug('log value of foo:', foo); // &quot;log value of foo: 1&quot; will be printed to the console
+    ```
</ins><span class="cx"> 
</span><del>-  // detect complicated paths and normalize them
-  hasThis  = HAS_THIS.test(path);
</del><ins>+   @method debug
+   @for Ember.Logger
+   @param {*} arguments
+  */
+  debug: consoleMethod('debug') || consoleMethod('info') || Ember.K,
</ins><span class="cx"> 
</span><del>-  if (!root || hasThis) {
-    tuple = normalizeTuple(root, path);
-    root = tuple[0];
-    path = tuple[1];
-    tuple.length = 0;
-  }
</del><ins>+  /**
+   If the value passed into `Ember.Logger.assert` is not truthy it will throw an error with a stack trace.
</ins><span class="cx"> 
</span><del>-  parts = path.split(&quot;.&quot;);
-  len = parts.length;
-  for (idx=0; root &amp;&amp; idx&lt;len; idx++) {
-    root = get(root, parts[idx], true);
-    if (root &amp;&amp; root.isDestroyed) { return undefined; }
-  }
-  return root;
-}
</del><ins>+    ```javascript
+    Ember.Logger.assert(true); // undefined
+    Ember.Logger.assert(true === false); // Throws an Assertion failed error.
+    ```
</ins><span class="cx"> 
</span><del>-function setPath(root, path, value, tolerant) {
-  var keyName;
-
-  // get the last part of the path
-  keyName = path.slice(path.lastIndexOf('.') + 1);
-
-  // get the first part of the part
-  path    = path.slice(0, path.length-(keyName.length+1));
-
-  // unless the path is this, look up the first part to
-  // get the root
-  if (path !== 'this') {
-    root = getPath(root, path);
-  }
-
-  if (!keyName || keyName.length === 0) {
-    throw new Error('You passed an empty path');
-  }
-
-  if (!root) {
-    if (tolerant) { return; }
-    else { throw new Error('Object in path '+path+' could not be found or was destroyed.'); }
-  }
-
-  return set(root, keyName, value);
-}
-
-/**
-  @private
-
-  Normalizes a target/path pair to reflect that actual target/path that should
-  be observed, etc. This takes into account passing in global property
-  paths (i.e. a path beginning with a captial letter not defined on the
-  target) and * separators.
-
-  @method normalizeTuple
-  @for Ember
-  @param {Object} target The current target. May be `null`.
-  @param {String} path A path on the target or a global property path.
-  @return {Array} a temporary array with the normalized target/path pair.
-*/
-Ember.normalizeTuple = function(target, path) {
-  return normalizeTuple(target, path);
</del><ins>+   @method assert
+   @for Ember.Logger
+   @param {Boolean} bool Value to test
+  */
+  assert: consoleMethod('assert') || assertPolyfill
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-Ember.getWithDefault = function(root, key, defaultValue) {
-  var value = get(root, key);
</del><span class="cx"> 
</span><del>-  if (value === undefined) { return defaultValue; }
-  return value;
-};
-
-
-Ember.get = get;
-Ember.getPath = Ember.deprecateFunc('getPath is deprecated since get now supports paths', Ember.get);
-
-Ember.set = set;
-Ember.setPath = Ember.deprecateFunc('setPath is deprecated since set now supports paths', Ember.set);
-
-/**
-  Error-tolerant form of `Ember.set`. Will not blow up if any part of the
-  chain is `undefined`, `null`, or destroyed.
-
-  This is primarily used when syncing bindings, which may try to update after
-  an object has been destroyed.
-
-  @method trySet
-  @for Ember
-  @param {Object} obj The object to modify.
-  @param {String} keyName The property key to set
-  @param {Object} value The value to set
-*/
-Ember.trySet = function(root, path, value) {
-  return set(root, path, value, true);
-};
-Ember.trySetPath = Ember.deprecateFunc('trySetPath has been renamed to trySet', Ember.trySet);
-
-/**
-  Returns true if the provided path is global (e.g., `MyApp.fooController.bar`)
-  instead of local (`foo.bar.baz`).
-
-  @method isGlobalPath
-  @for Ember
-  @private
-  @param {String} path
-  @return Boolean
-*/
-Ember.isGlobalPath = function(path) {
-  return IS_GLOBAL.test(path);
-};
-
-
</del><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -2119,11 +3414,8 @@
</span><span class="cx"> @module ember-metal
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var GUID_KEY = Ember.GUID_KEY,
-    META_KEY = Ember.META_KEY,
-    EMPTY_META = Ember.EMPTY_META,
</del><ins>+var META_KEY = Ember.META_KEY,
</ins><span class="cx">     metaFor = Ember.meta,
</span><del>-    o_create = Ember.create,
</del><span class="cx">     objectDefineProperty = Ember.platform.defineProperty;
</span><span class="cx"> 
</span><span class="cx"> var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;
</span><span class="lines">@@ -2133,7 +3425,7 @@
</span><span class="cx"> //
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  Objects of this type can implement an interface to responds requests to
</del><ins>+  Objects of this type can implement an interface to respond to requests to
</ins><span class="cx">   get and set. The default implementation handles simple properties.
</span><span class="cx"> 
</span><span class="cx">   You generally won't need to create or subclass this directly.
</span><span class="lines">@@ -2143,7 +3435,7 @@
</span><span class="cx">   @private
</span><span class="cx">   @constructor
</span><span class="cx"> */
</span><del>-var Descriptor = Ember.Descriptor = function() {};
</del><ins>+Ember.Descriptor = function() {};
</ins><span class="cx"> 
</span><span class="cx"> // ..........................................................
</span><span class="cx"> // DEFINING PROPERTIES API
</span><span class="lines">@@ -2161,8 +3453,6 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   NOTE: This is a low-level method used by other parts of the API. You almost
</span><span class="cx">   never want to call this method directly. Instead you should use
</span><span class="cx">   `Ember.mixin()` to define new properties.
</span><span class="lines">@@ -2196,6 +3486,7 @@
</span><span class="cx">   }).property('firstName', 'lastName'));
</span><span class="cx">   ```
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method defineProperty
</span><span class="cx">   @for Ember
</span><span class="cx">   @param {Object} obj the object to define this property on. This may be a prototype.
</span><span class="lines">@@ -2203,7 +3494,7 @@
</span><span class="cx">   @param {Ember.Descriptor} [desc] an instance of `Ember.Descriptor` (typically a
</span><span class="cx">     computed property) or an ES5 descriptor.
</span><span class="cx">     You must provide this or `data` but not both.
</span><del>-  @param {anything} [data] something other than a descriptor, that will
</del><ins>+  @param {*} [data] something other than a descriptor, that will
</ins><span class="cx">     become the explicit value of this property.
</span><span class="cx"> */
</span><span class="cx"> Ember.defineProperty = function(obj, keyName, desc, data, meta) {
</span><span class="lines">@@ -2232,7 +3523,6 @@
</span><span class="cx">     } else {
</span><span class="cx">       obj[keyName] = undefined; // make enumerable
</span><span class="cx">     }
</span><del>-    desc.setup(obj, keyName);
</del><span class="cx">   } else {
</span><span class="cx">     descs[keyName] = undefined; // shadow descriptor in proto
</span><span class="cx">     if (desc == null) {
</span><span class="lines">@@ -2274,341 +3564,183 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-// Ember.tryFinally
</del><ins>+var get = Ember.get;
+
</ins><span class="cx"> /**
</span><del>-@module ember-metal
-*/
</del><ins>+  To get multiple properties at once, call `Ember.getProperties`
+  with an object followed by a list of strings or an array:
</ins><span class="cx"> 
</span><del>-var AFTER_OBSERVERS = ':change';
-var BEFORE_OBSERVERS = ':before';
</del><ins>+  ```javascript
+  Ember.getProperties(record, 'firstName', 'lastName', 'zipCode');  // { firstName: 'John', lastName: 'Doe', zipCode: '10011' }
+  ```
</ins><span class="cx"> 
</span><del>-var guidFor = Ember.guidFor;
</del><ins>+  is equivalent to:
</ins><span class="cx"> 
</span><del>-var deferred = 0;
</del><ins>+  ```javascript
+  Ember.getProperties(record, ['firstName', 'lastName', 'zipCode']);  // { firstName: 'John', lastName: 'Doe', zipCode: '10011' }
+  ```
</ins><span class="cx"> 
</span><del>-/*
-  this.observerSet = {
-    [senderGuid]: { // variable name: `keySet`
-      [keyName]: listIndex
-    }
-  },
-  this.observers = [
-    {
-      sender: obj,
-      keyName: keyName,
-      eventName: eventName,
-      listeners: [
-        [target, method, onceFlag, suspendedFlag]
-      ]
-    },
-    ...
-  ]
</del><ins>+  @method getProperties
+  @param obj
+  @param {String...|Array} list of keys to get
+  @return {Hash}
</ins><span class="cx"> */
</span><del>-function ObserverSet() {
-  this.clear();
-}
</del><ins>+Ember.getProperties = function(obj) {
+  var ret = {},
+      propertyNames = arguments,
+      i = 1;
</ins><span class="cx"> 
</span><del>-ObserverSet.prototype.add = function(sender, keyName, eventName) {
-  var observerSet = this.observerSet,
-      observers = this.observers,
-      senderGuid = Ember.guidFor(sender),
-      keySet = observerSet[senderGuid],
-      index;
-
-  if (!keySet) {
-    observerSet[senderGuid] = keySet = {};
</del><ins>+  if (arguments.length === 2 &amp;&amp; Ember.typeOf(arguments[1]) === 'array') {
+    i = 0;
+    propertyNames = arguments[1];
</ins><span class="cx">   }
</span><del>-  index = keySet[keyName];
-  if (index === undefined) {
-    index = observers.push({
-      sender: sender,
-      keyName: keyName,
-      eventName: eventName,
-      listeners: []
-    }) - 1;
-    keySet[keyName] = index;
</del><ins>+  for(var len = propertyNames.length; i &lt; len; i++) {
+    ret[propertyNames[i]] = get(obj, propertyNames[i]);
</ins><span class="cx">   }
</span><del>-  return observers[index].listeners;
</del><ins>+  return ret;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-ObserverSet.prototype.flush = function() {
-  var observers = this.observers, i, len, observer, sender;
-  this.clear();
-  for (i=0, len=observers.length; i &lt; len; ++i) {
-    observer = observers[i];
-    sender = observer.sender;
-    if (sender.isDestroying || sender.isDestroyed) { continue; }
-    Ember.sendEvent(sender, observer.eventName, [sender, observer.keyName], observer.listeners);
-  }
-};
</del><ins>+})();
</ins><span class="cx"> 
</span><del>-ObserverSet.prototype.clear = function() {
-  this.observerSet = {};
-  this.observers = [];
-};
</del><span class="cx"> 
</span><del>-var beforeObserverSet = new ObserverSet(), observerSet = new ObserverSet();
</del><span class="cx"> 
</span><del>-/**
-  @method beginPropertyChanges
-  @chainable
-*/
-Ember.beginPropertyChanges = function() {
-  deferred++;
-};
</del><ins>+(function() {
+var changeProperties = Ember.changeProperties,
+    set = Ember.set;
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @method endPropertyChanges
-*/
-Ember.endPropertyChanges = function() {
-  deferred--;
-  if (deferred&lt;=0) {
-    beforeObserverSet.clear();
-    observerSet.flush();
-  }
-};
</del><ins>+  Set a list of properties on an object. These properties are set inside
+  a single `beginPropertyChanges` and `endPropertyChanges` batch, so
+  observers will be buffered.
</ins><span class="cx"> 
</span><del>-/**
-  Make a series of property changes together in an
-  exception-safe way.
-
</del><span class="cx">   ```javascript
</span><del>-  Ember.changeProperties(function() {
-    obj1.set('foo', mayBlowUpWhenSet);
-    obj2.set('bar', baz);
-  });
</del><ins>+  anObject.setProperties({
+    firstName: &quot;Stanley&quot;,
+    lastName: &quot;Stuart&quot;,
+    age: &quot;21&quot;
+  })
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><del>-  @method changeProperties
-  @param {Function} callback
-  @param [binding]
-*/
-Ember.changeProperties = function(cb, binding){
-  Ember.beginPropertyChanges();
-  Ember.tryFinally(cb, Ember.endPropertyChanges, binding);
-};
-
-/**
-  Set a list of properties on an object. These properties are set inside
-  a single `beginPropertyChanges` and `endPropertyChanges` batch, so
-  observers will be buffered.
-
</del><span class="cx">   @method setProperties
</span><del>-  @param target
-  @param {Hash} properties
-  @return target
</del><ins>+  @param self
+  @param {Object} hash
+  @return self
</ins><span class="cx"> */
</span><span class="cx"> Ember.setProperties = function(self, hash) {
</span><del>-  Ember.changeProperties(function(){
</del><ins>+  changeProperties(function() {
</ins><span class="cx">     for(var prop in hash) {
</span><del>-      if (hash.hasOwnProperty(prop)) Ember.set(self, prop, hash[prop]);
</del><ins>+      if (hash.hasOwnProperty(prop)) { set(self, prop, hash[prop]); }
</ins><span class="cx">     }
</span><span class="cx">   });
</span><span class="cx">   return self;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+})();
</ins><span class="cx"> 
</span><del>-function changeEvent(keyName) {
-  return keyName+AFTER_OBSERVERS;
-}
</del><span class="cx"> 
</span><del>-function beforeEvent(keyName) {
-  return keyName+BEFORE_OBSERVERS;
-}
</del><span class="cx"> 
</span><del>-/**
-  @method addObserver
-  @param obj
-  @param {String} path
-  @param {Object|Function} targetOrMethod
-  @param {Function|String} [method]
-*/
-Ember.addObserver = function(obj, path, target, method) {
-  Ember.addListener(obj, changeEvent(path), target, method);
-  Ember.watch(obj, path);
-  return this;
-};
</del><ins>+(function() {
+var metaFor = Ember.meta, // utils.js
+    typeOf = Ember.typeOf, // utils.js
+    MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER,
+    o_defineProperty = Ember.platform.defineProperty;
</ins><span class="cx"> 
</span><del>-Ember.observersFor = function(obj, path) {
-  return Ember.listenersFor(obj, changeEvent(path));
-};
</del><ins>+Ember.watchKey = function(obj, keyName) {
+  // can't watch length on Array - it is special...
+  if (keyName === 'length' &amp;&amp; typeOf(obj) === 'array') { return; }
</ins><span class="cx"> 
</span><del>-/**
-  @method removeObserver
-  @param obj
-  @param {String} path
-  @param {Object|Function} targetOrMethod
-  @param {Function|String} [method]
-*/
-Ember.removeObserver = function(obj, path, target, method) {
-  Ember.unwatch(obj, path);
-  Ember.removeListener(obj, changeEvent(path), target, method);
-  return this;
-};
</del><ins>+  var m = metaFor(obj), watching = m.watching;
</ins><span class="cx"> 
</span><del>-/**
-  @method addBeforeObserver
-  @param obj
-  @param {String} path
-  @param {Object|Function} targetOrMethod
-  @param {Function|String} [method]
-*/
-Ember.addBeforeObserver = function(obj, path, target, method) {
-  Ember.addListener(obj, beforeEvent(path), target, method);
-  Ember.watch(obj, path);
-  return this;
-};
</del><ins>+  // activate watching first time
+  if (!watching[keyName]) {
+    watching[keyName] = 1;
</ins><span class="cx"> 
</span><del>-// Suspend observer during callback.
-//
-// This should only be used by the target of the observer
-// while it is setting the observed path.
-Ember._suspendBeforeObserver = function(obj, path, target, method, callback) {
-  return Ember._suspendListener(obj, beforeEvent(path), target, method, callback);
-};
</del><ins>+    if ('function' === typeof obj.willWatchProperty) {
+      obj.willWatchProperty(keyName);
+    }
</ins><span class="cx"> 
</span><del>-Ember._suspendObserver = function(obj, path, target, method, callback) {
-  return Ember._suspendListener(obj, changeEvent(path), target, method, callback);
</del><ins>+    if (MANDATORY_SETTER &amp;&amp; keyName in obj) {
+      m.values[keyName] = obj[keyName];
+      o_defineProperty(obj, keyName, {
+        configurable: true,
+        enumerable: obj.propertyIsEnumerable(keyName),
+        set: Ember.MANDATORY_SETTER_FUNCTION,
+        get: Ember.DEFAULT_GETTER_FUNCTION(keyName)
+      });
+    }
+  } else {
+    watching[keyName] = (watching[keyName] || 0) + 1;
+  }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-var map = Ember.ArrayPolyfills.map;
</del><span class="cx"> 
</span><del>-Ember._suspendBeforeObservers = function(obj, paths, target, method, callback) {
-  var events = map.call(paths, beforeEvent);
-  return Ember._suspendListeners(obj, events, target, method, callback);
-};
</del><ins>+Ember.unwatchKey = function(obj, keyName) {
+  var m = metaFor(obj), watching = m.watching;
</ins><span class="cx"> 
</span><del>-Ember._suspendObservers = function(obj, paths, target, method, callback) {
-  var events = map.call(paths, changeEvent);
-  return Ember._suspendListeners(obj, events, target, method, callback);
-};
</del><ins>+  if (watching[keyName] === 1) {
+    watching[keyName] = 0;
</ins><span class="cx"> 
</span><del>-Ember.beforeObserversFor = function(obj, path) {
-  return Ember.listenersFor(obj, beforeEvent(path));
-};
</del><ins>+    if ('function' === typeof obj.didUnwatchProperty) {
+      obj.didUnwatchProperty(keyName);
+    }
</ins><span class="cx"> 
</span><del>-/**
-  @method removeBeforeObserver
-  @param obj
-  @param {String} path
-  @param {Object|Function} targetOrMethod
-  @param {Function|String} [method]
-*/
-Ember.removeBeforeObserver = function(obj, path, target, method) {
-  Ember.unwatch(obj, path);
-  Ember.removeListener(obj, beforeEvent(path), target, method);
-  return this;
-};
-
-Ember.notifyBeforeObservers = function(obj, keyName) {
-  if (obj.isDestroying) { return; }
-
-  var eventName = beforeEvent(keyName), listeners, listenersDiff;
-  if (deferred) {
-    listeners = beforeObserverSet.add(obj, keyName, eventName);
-    listenersDiff = Ember.listenersDiff(obj, eventName, listeners);
-    Ember.sendEvent(obj, eventName, [obj, keyName], listenersDiff);
-  } else {
-    Ember.sendEvent(obj, eventName, [obj, keyName]);
</del><ins>+    if (MANDATORY_SETTER &amp;&amp; keyName in obj) {
+      o_defineProperty(obj, keyName, {
+        configurable: true,
+        enumerable: obj.propertyIsEnumerable(keyName),
+        set: function(val) {
+          // redefine to set as enumerable
+          o_defineProperty(obj, keyName, {
+            configurable: true,
+            writable: true,
+            enumerable: true,
+            value: val
+          });
+          delete m.values[keyName];
+        },
+        get: Ember.DEFAULT_GETTER_FUNCTION(keyName)
+      });
+    }
+  } else if (watching[keyName] &gt; 1) {
+    watching[keyName]--;
</ins><span class="cx">   }
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-Ember.notifyObservers = function(obj, keyName) {
-  if (obj.isDestroying) { return; }
-
-  var eventName = changeEvent(keyName), listeners;
-  if (deferred) {
-    listeners = observerSet.add(obj, keyName, eventName);
-    Ember.listenersUnion(obj, eventName, listeners);
-  } else {
-    Ember.sendEvent(obj, eventName, [obj, keyName]);
-  }
-};
-
</del><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-/**
-@module ember-metal
-*/
-
-var guidFor = Ember.guidFor, // utils.js
-    metaFor = Ember.meta, // utils.js
-    get = Ember.get, // accessors.js
-    set = Ember.set, // accessors.js
-    normalizeTuple = Ember.normalizeTuple, // accessors.js
-    GUID_KEY = Ember.GUID_KEY, // utils.js
-    META_KEY = Ember.META_KEY, // utils.js
-    // circular reference observer depends on Ember.watch
-    // we should move change events to this file or its own property_events.js
-    notifyObservers = Ember.notifyObservers, // observer.js
</del><ins>+var metaFor = Ember.meta, // utils.js
+    get = Ember.get, // property_get.js
+    normalizeTuple = Ember.normalizeTuple, // property_get.js
</ins><span class="cx">     forEach = Ember.ArrayPolyfills.forEach, // array.js
</span><del>-    FIRST_KEY = /^([^\.\*]+)/,
-    IS_PATH = /[\.\*]/;
</del><ins>+    warn = Ember.warn,
+    watchKey = Ember.watchKey,
+    unwatchKey = Ember.unwatchKey,
+    FIRST_KEY = /^([^\.\*]+)/;
</ins><span class="cx"> 
</span><del>-var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER,
-o_defineProperty = Ember.platform.defineProperty;
-
</del><span class="cx"> function firstKey(path) {
</span><span class="cx">   return path.match(FIRST_KEY)[0];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// returns true if the passed path is just a keyName
-function isKeyName(path) {
-  return path==='*' || !IS_PATH.test(path);
-}
</del><ins>+var pendingQueue = [];
</ins><span class="cx"> 
</span><del>-// ..........................................................
-// DEPENDENT KEYS
-//
</del><ins>+// attempts to add the pendingQueue chains again. If some of them end up
+// back in the queue and reschedule is true, schedules a timeout to try
+// again.
+Ember.flushPendingChains = function() {
+  if (pendingQueue.length === 0) { return; } // nothing to do
</ins><span class="cx"> 
</span><del>-function iterDeps(method, obj, depKey, seen, meta) {
</del><ins>+  var queue = pendingQueue;
+  pendingQueue = [];
</ins><span class="cx"> 
</span><del>-  var guid = guidFor(obj);
-  if (!seen[guid]) seen[guid] = {};
-  if (seen[guid][depKey]) return;
-  seen[guid][depKey] = true;
</del><ins>+  forEach.call(queue, function(q) { q[0].add(q[1]); });
</ins><span class="cx"> 
</span><del>-  var deps = meta.deps;
-  deps = deps &amp;&amp; deps[depKey];
-  if (deps) {
-    for(var key in deps) {
-      var desc = meta.descs[key];
-      if (desc &amp;&amp; desc._suspended === obj) continue;
-      method(obj, key);
-    }
-  }
-}
</del><ins>+  warn('Watching an undefined global, Ember expects watched globals to be setup by the time the run loop is flushed, check for typos', pendingQueue.length === 0);
+};
</ins><span class="cx"> 
</span><span class="cx"> 
</span><del>-var WILL_SEEN, DID_SEEN;
-
-// called whenever a property is about to change to clear the cache of any dependent keys (and notify those properties of changes, etc...)
-function dependentKeysWillChange(obj, depKey, meta) {
-  if (obj.isDestroying) { return; }
-
-  var seen = WILL_SEEN, top = !seen;
-  if (top) { seen = WILL_SEEN = {}; }
-  iterDeps(propertyWillChange, obj, depKey, seen, meta);
-  if (top) { WILL_SEEN = null; }
-}
-
-// called whenever a property has just changed to update dependent keys
-function dependentKeysDidChange(obj, depKey, meta) {
-  if (obj.isDestroying) { return; }
-
-  var seen = DID_SEEN, top = !seen;
-  if (top) { seen = DID_SEEN = {}; }
-  iterDeps(propertyDidChange, obj, depKey, seen, meta);
-  if (top) { DID_SEEN = null; }
-}
-
-// ..........................................................
-// CHAIN
-//
-
</del><span class="cx"> function addChainWatcher(obj, keyName, node) {
</span><span class="cx">   if (!obj || ('object' !== typeof obj)) { return; } // nothing to do
</span><span class="cx"> 
</span><span class="lines">@@ -2620,10 +3752,10 @@
</span><span class="cx"> 
</span><span class="cx">   if (!nodes[keyName]) { nodes[keyName] = []; }
</span><span class="cx">   nodes[keyName].push(node);
</span><del>-  Ember.watch(obj, keyName);
</del><ins>+  watchKey(obj, keyName);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-function removeChainWatcher(obj, keyName, node) {
</del><ins>+var removeChainWatcher = Ember.removeChainWatcher = function(obj, keyName, node) {
</ins><span class="cx">   if (!obj || 'object' !== typeof obj) { return; } // nothing to do
</span><span class="cx"> 
</span><span class="cx">   var m = metaFor(obj, false);
</span><span class="lines">@@ -2637,34 +3769,13 @@
</span><span class="cx">       if (nodes[i] === node) { nodes.splice(i, 1); }
</span><span class="cx">     }
</span><span class="cx">   }
</span><del>-  Ember.unwatch(obj, keyName);
-}
</del><ins>+  unwatchKey(obj, keyName);
+};
</ins><span class="cx"> 
</span><del>-var pendingQueue = [];
-
-// attempts to add the pendingQueue chains again. If some of them end up
-// back in the queue and reschedule is true, schedules a timeout to try
-// again.
-function flushPendingChains() {
-  if (pendingQueue.length === 0) { return; } // nothing to do
-
-  var queue = pendingQueue;
-  pendingQueue = [];
-
-  forEach.call(queue, function(q) { q[0].add(q[1]); });
-
-  Ember.warn('Watching an undefined global, Ember expects watched globals to be setup by the time the run loop is flushed, check for typos', pendingQueue.length === 0);
-}
-
-function isProto(pvalue) {
-  return metaFor(pvalue, false).proto === pvalue;
-}
-
</del><span class="cx"> // A ChainNode watches a single key on an object. If you provide a starting
</span><span class="cx"> // value for the key then the node won't actually watch it. For a root node
</span><span class="cx"> // pass null for parent and key and object for value.
</span><del>-var ChainNode = function(parent, key, value) {
-  var obj;
</del><ins>+var ChainNode = Ember._ChainNode = function(parent, key, value) {
</ins><span class="cx">   this._parent = parent;
</span><span class="cx">   this._key    = key;
</span><span class="cx"> 
</span><span class="lines">@@ -2695,10 +3806,32 @@
</span><span class="cx"> 
</span><span class="cx"> var ChainNodePrototype = ChainNode.prototype;
</span><span class="cx"> 
</span><ins>+function lazyGet(obj, key) {
+  if (!obj) return undefined;
+
+  var meta = metaFor(obj, false);
+  // check if object meant only to be a prototype
+  if (meta.proto === obj) return undefined;
+
+  if (key === &quot;@each&quot;) return get(obj, key);
+
+  // if a CP only return cached value
+  var desc = meta.descs[key];
+  if (desc &amp;&amp; desc._cacheable) {
+    if (key in meta.cache) {
+      return meta.cache[key];
+    } else {
+      return undefined;
+    }
+  }
+
+  return get(obj, key);
+}
+
</ins><span class="cx"> ChainNodePrototype.value = function() {
</span><span class="cx">   if (this._value === undefined &amp;&amp; this._watching) {
</span><span class="cx">     var obj = this._parent.value();
</span><del>-    this._value = (obj &amp;&amp; !isProto(obj)) ? get(obj, this._key) : undefined;
</del><ins>+    this._value = lazyGet(obj, this._key);
</ins><span class="cx">   }
</span><span class="cx">   return this._value;
</span><span class="cx"> };
</span><span class="lines">@@ -2818,42 +3951,50 @@
</span><span class="cx"> 
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-ChainNodePrototype.willChange = function() {
</del><ins>+ChainNodePrototype.willChange = function(events) {
</ins><span class="cx">   var chains = this._chains;
</span><span class="cx">   if (chains) {
</span><span class="cx">     for(var key in chains) {
</span><span class="cx">       if (!chains.hasOwnProperty(key)) { continue; }
</span><del>-      chains[key].willChange();
</del><ins>+      chains[key].willChange(events);
</ins><span class="cx">     }
</span><span class="cx">   }
</span><span class="cx"> 
</span><del>-  if (this._parent) { this._parent.chainWillChange(this, this._key, 1); }
</del><ins>+  if (this._parent) { this._parent.chainWillChange(this, this._key, 1, events); }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-ChainNodePrototype.chainWillChange = function(chain, path, depth) {
</del><ins>+ChainNodePrototype.chainWillChange = function(chain, path, depth, events) {
</ins><span class="cx">   if (this._key) { path = this._key + '.' + path; }
</span><span class="cx"> 
</span><span class="cx">   if (this._parent) {
</span><del>-    this._parent.chainWillChange(this, path, depth+1);
</del><ins>+    this._parent.chainWillChange(this, path, depth+1, events);
</ins><span class="cx">   } else {
</span><del>-    if (depth &gt; 1) { Ember.propertyWillChange(this.value(), path); }
</del><ins>+    if (depth &gt; 1) {
+      events.push(this.value(), path);
+    }
</ins><span class="cx">     path = 'this.' + path;
</span><del>-    if (this._paths[path] &gt; 0) { Ember.propertyWillChange(this.value(), path); }
</del><ins>+    if (this._paths[path] &gt; 0) {
+      events.push(this.value(), path);
+    }
</ins><span class="cx">   }
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-ChainNodePrototype.chainDidChange = function(chain, path, depth) {
</del><ins>+ChainNodePrototype.chainDidChange = function(chain, path, depth, events) {
</ins><span class="cx">   if (this._key) { path = this._key + '.' + path; }
</span><span class="cx">   if (this._parent) {
</span><del>-    this._parent.chainDidChange(this, path, depth+1);
</del><ins>+    this._parent.chainDidChange(this, path, depth+1, events);
</ins><span class="cx">   } else {
</span><del>-    if (depth &gt; 1) { Ember.propertyDidChange(this.value(), path); }
</del><ins>+    if (depth &gt; 1) {
+      events.push(this.value(), path);
+    }
</ins><span class="cx">     path = 'this.' + path;
</span><del>-    if (this._paths[path] &gt; 0) { Ember.propertyDidChange(this.value(), path); }
</del><ins>+    if (this._paths[path] &gt; 0) {
+      events.push(this.value(), path);
+    }
</ins><span class="cx">   }
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-ChainNodePrototype.didChange = function(suppressEvent) {
</del><ins>+ChainNodePrototype.didChange = function(events) {
</ins><span class="cx">   // invalidate my own value first.
</span><span class="cx">   if (this._watching) {
</span><span class="cx">     var obj = this._parent.value();
</span><span class="lines">@@ -2875,16 +4016,42 @@
</span><span class="cx">   if (chains) {
</span><span class="cx">     for(var key in chains) {
</span><span class="cx">       if (!chains.hasOwnProperty(key)) { continue; }
</span><del>-      chains[key].didChange(suppressEvent);
</del><ins>+      chains[key].didChange(events);
</ins><span class="cx">     }
</span><span class="cx">   }
</span><span class="cx"> 
</span><del>-  if (suppressEvent) { return; }
</del><ins>+  // if no events are passed in then we only care about the above wiring update
+  if (events === null) { return; }
</ins><span class="cx"> 
</span><span class="cx">   // and finally tell parent about my path changing...
</span><del>-  if (this._parent) { this._parent.chainDidChange(this, this._key, 1); }
</del><ins>+  if (this._parent) { this._parent.chainDidChange(this, this._key, 1, events); }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><ins>+Ember.finishChains = function(obj) {
+  var m = metaFor(obj, false), chains = m.chains;
+  if (chains) {
+    if (chains.value() !== obj) {
+      m.chains = chains = chains.copy(obj);
+    }
+    chains.didChange(null);
+  }
+};
+
+})();
+
+
+
+(function() {
+
+})();
+
+
+
+(function() {
+var metaFor = Ember.meta, // utils.js
+    typeOf = Ember.typeOf, // utils.js
+    ChainNode = Ember._ChainNode; // chains.js
+
</ins><span class="cx"> // get the chains for the current object. If the current object has
</span><span class="cx"> // chains inherited from the proto they will be cloned and reconfigured for
</span><span class="cx"> // the current object.
</span><span class="lines">@@ -2898,89 +4065,78 @@
</span><span class="cx">   return ret;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ember.overrideChains = function(obj, keyName, m) {
-  chainsDidChange(obj, keyName, m, true);
-};
</del><ins>+Ember.watchPath = function(obj, keyPath) {
+  // can't watch length on Array - it is special...
+  if (keyPath === 'length' &amp;&amp; typeOf(obj) === 'array') { return; }
</ins><span class="cx"> 
</span><del>-function chainsWillChange(obj, keyName, m, arg) {
-  if (!m.hasOwnProperty('chainWatchers')) { return; } // nothing to do
</del><ins>+  var m = metaFor(obj), watching = m.watching;
</ins><span class="cx"> 
</span><del>-  var nodes = m.chainWatchers;
</del><ins>+  if (!watching[keyPath]) { // activate watching first time
+    watching[keyPath] = 1;
+    chainsFor(obj).add(keyPath);
+  } else {
+    watching[keyPath] = (watching[keyPath] || 0) + 1;
+  }
+};
</ins><span class="cx"> 
</span><del>-  nodes = nodes[keyName];
-  if (!nodes) { return; }
</del><ins>+Ember.unwatchPath = function(obj, keyPath) {
+  var m = metaFor(obj), watching = m.watching;
</ins><span class="cx"> 
</span><del>-  for(var i = 0, l = nodes.length; i &lt; l; i++) {
-    nodes[i].willChange(arg);
</del><ins>+  if (watching[keyPath] === 1) {
+    watching[keyPath] = 0;
+    chainsFor(obj).remove(keyPath);
+  } else if (watching[keyPath] &gt; 1) {
+    watching[keyPath]--;
</ins><span class="cx">   }
</span><del>-}
</del><ins>+};
+})();
</ins><span class="cx"> 
</span><del>-function chainsDidChange(obj, keyName, m, arg) {
-  if (!m.hasOwnProperty('chainWatchers')) { return; } // nothing to do
</del><span class="cx"> 
</span><del>-  var nodes = m.chainWatchers;
</del><span class="cx"> 
</span><del>-  nodes = nodes[keyName];
-  if (!nodes) { return; }
</del><ins>+(function() {
+/**
+@module ember-metal
+*/
</ins><span class="cx"> 
</span><del>-  // looping in reverse because the chainWatchers array can be modified inside didChange
-  for (var i = nodes.length - 1; i &gt;= 0; i--) {
-    nodes[i].didChange(arg);
-  }
</del><ins>+var metaFor = Ember.meta, // utils.js
+    GUID_KEY = Ember.GUID_KEY, // utils.js
+    META_KEY = Ember.META_KEY, // utils.js
+    removeChainWatcher = Ember.removeChainWatcher,
+    watchKey = Ember.watchKey, // watch_key.js
+    unwatchKey = Ember.unwatchKey,
+    watchPath = Ember.watchPath, // watch_path.js
+    unwatchPath = Ember.unwatchPath,
+    typeOf = Ember.typeOf, // utils.js
+    generateGuid = Ember.generateGuid,
+    IS_PATH = /[\.\*]/;
+
+// returns true if the passed path is just a keyName
+function isKeyName(path) {
+  return path==='*' || !IS_PATH.test(path);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-// ..........................................................
-// WATCH
-//
-
</del><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   Starts watching a property on an object. Whenever the property changes,
</span><span class="cx">   invokes `Ember.propertyWillChange` and `Ember.propertyDidChange`. This is the
</span><span class="cx">   primitive used by observers and dependent keys; usually you will never call
</span><span class="cx">   this method directly but instead use higher level methods like
</span><span class="cx">   `Ember.addObserver()`
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method watch
</span><span class="cx">   @for Ember
</span><span class="cx">   @param obj
</span><span class="cx">   @param {String} keyName
</span><span class="cx"> */
</span><del>-Ember.watch = function(obj, keyName) {
</del><ins>+Ember.watch = function(obj, _keyPath) {
</ins><span class="cx">   // can't watch length on Array - it is special...
</span><del>-  if (keyName === 'length' &amp;&amp; Ember.typeOf(obj) === 'array') { return this; }
</del><ins>+  if (_keyPath === 'length' &amp;&amp; typeOf(obj) === 'array') { return; }
</ins><span class="cx"> 
</span><del>-  var m = metaFor(obj), watching = m.watching, desc;
-
-  // activate watching first time
-  if (!watching[keyName]) {
-    watching[keyName] = 1;
-    if (isKeyName(keyName)) {
-      desc = m.descs[keyName];
-      if (desc &amp;&amp; desc.willWatch) { desc.willWatch(obj, keyName); }
-
-      if ('function' === typeof obj.willWatchProperty) {
-        obj.willWatchProperty(keyName);
-      }
-
-      if (MANDATORY_SETTER &amp;&amp; keyName in obj) {
-        m.values[keyName] = obj[keyName];
-        o_defineProperty(obj, keyName, {
-          configurable: true,
-          enumerable: true,
-          set: Ember.MANDATORY_SETTER_FUNCTION,
-          get: Ember.DEFAULT_GETTER_FUNCTION(keyName)
-        });
-      }
-    } else {
-      chainsFor(obj).add(keyName);
-    }
-
-  }  else {
-    watching[keyName] = (watching[keyName] || 0) + 1;
</del><ins>+  if (isKeyName(_keyPath)) {
+    watchKey(obj, _keyPath);
+  } else {
+    watchPath(obj, _keyPath);
</ins><span class="cx">   }
</span><del>-  return this;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> Ember.isWatching = function isWatching(obj, key) {
</span><span class="lines">@@ -2988,52 +4144,25 @@
</span><span class="cx">   return (meta &amp;&amp; meta.watching[key]) &gt; 0;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-Ember.watch.flushPending = flushPendingChains;
</del><ins>+Ember.watch.flushPending = Ember.flushPendingChains;
</ins><span class="cx"> 
</span><del>-Ember.unwatch = function(obj, keyName) {
</del><ins>+Ember.unwatch = function(obj, _keyPath) {
</ins><span class="cx">   // can't watch length on Array - it is special...
</span><del>-  if (keyName === 'length' &amp;&amp; Ember.typeOf(obj) === 'array') { return this; }
</del><ins>+  if (_keyPath === 'length' &amp;&amp; typeOf(obj) === 'array') { return; }
</ins><span class="cx"> 
</span><del>-  var m = metaFor(obj), watching = m.watching, desc;
-
-  if (watching[keyName] === 1) {
-    watching[keyName] = 0;
-
-    if (isKeyName(keyName)) {
-      desc = m.descs[keyName];
-      if (desc &amp;&amp; desc.didUnwatch) { desc.didUnwatch(obj, keyName); }
-
-      if ('function' === typeof obj.didUnwatchProperty) {
-        obj.didUnwatchProperty(keyName);
-      }
-
-      if (MANDATORY_SETTER &amp;&amp; keyName in obj) {
-        o_defineProperty(obj, keyName, {
-          configurable: true,
-          enumerable: true,
-          writable: true,
-          value: m.values[keyName]
-        });
-        delete m.values[keyName];
-      }
-    } else {
-      chainsFor(obj).remove(keyName);
-    }
-
-  } else if (watching[keyName]&gt;1) {
-    watching[keyName]--;
</del><ins>+  if (isKeyName(_keyPath)) {
+    unwatchKey(obj, _keyPath);
+  } else {
+    unwatchPath(obj, _keyPath);
</ins><span class="cx">   }
</span><del>-
-  return this;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   Call on an object when you first beget it from another object. This will
</span><span class="cx">   setup any chained watchers on the object instance as needed. This method is
</span><span class="cx">   safe to call multiple times.
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method rewatch
</span><span class="cx">   @for Ember
</span><span class="cx">   @param obj
</span><span class="lines">@@ -3043,96 +4172,15 @@
</span><span class="cx"> 
</span><span class="cx">   // make sure the object has its own guid.
</span><span class="cx">   if (GUID_KEY in obj &amp;&amp; !obj.hasOwnProperty(GUID_KEY)) {
</span><del>-    Ember.generateGuid(obj, 'ember');
</del><ins>+    generateGuid(obj);
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   // make sure any chained watchers update.
</span><span class="cx">   if (chains &amp;&amp; chains.value() !== obj) {
</span><span class="cx">     m.chains = chains.copy(obj);
</span><span class="cx">   }
</span><del>-
-  return this;
</del><span class="cx"> };
</span><span class="cx"> 
</span><del>-Ember.finishChains = function(obj) {
-  var m = metaFor(obj, false), chains = m.chains;
-  if (chains) {
-    if (chains.value() !== obj) {
-      m.chains = chains = chains.copy(obj);
-    }
-    chains.didChange(true);
-  }
-};
-
-// ..........................................................
-// PROPERTY CHANGES
-//
-
-/**
-  This function is called just before an object property is about to change.
-  It will notify any before observers and prepare caches among other things.
-
-  Normally you will not need to call this method directly but if for some
-  reason you can't directly watch a property you can invoke this method
-  manually along with `Ember.propertyDidChange()` which you should call just
-  after the property value changes.
-
-  @method propertyWillChange
-  @for Ember
-  @param {Object} obj The object with the property that will change
-  @param {String} keyName The property key (or path) that will change.
-  @return {void}
-*/
-function propertyWillChange(obj, keyName, value) {
-  var m = metaFor(obj, false),
-      watching = m.watching[keyName] &gt; 0 || keyName === 'length',
-      proto = m.proto,
-      desc = m.descs[keyName];
-
-  if (!watching) { return; }
-  if (proto === obj) { return; }
-  if (desc &amp;&amp; desc.willChange) { desc.willChange(obj, keyName); }
-  dependentKeysWillChange(obj, keyName, m);
-  chainsWillChange(obj, keyName, m);
-  Ember.notifyBeforeObservers(obj, keyName);
-}
-
-Ember.propertyWillChange = propertyWillChange;
-
-/**
-  This function is called just after an object property has changed.
-  It will notify any observers and clear caches among other things.
-
-  Normally you will not need to call this method directly but if for some
-  reason you can't directly watch a property you can invoke this method
-  manually along with `Ember.propertyWilLChange()` which you should call just
-  before the property value changes.
-
-  @method propertyDidChange
-  @for Ember
-  @param {Object} obj The object with the property that will change
-  @param {String} keyName The property key (or path) that will change.
-  @return {void}
-*/
-function propertyDidChange(obj, keyName) {
-  var m = metaFor(obj, false),
-      watching = m.watching[keyName] &gt; 0 || keyName === 'length',
-      proto = m.proto,
-      desc = m.descs[keyName];
-
-  if (proto === obj) { return; }
-
-  // shouldn't this mean that we're watching this key?
-  if (desc &amp;&amp; desc.didChange) { desc.didChange(obj, keyName); }
-  if (!watching &amp;&amp; keyName !== 'length') { return; }
-
-  dependentKeysDidChange(obj, keyName, m);
-  chainsDidChange(obj, keyName, m);
-  Ember.notifyObservers(obj, keyName);
-}
-
-Ember.propertyDidChange = propertyDidChange;
-
</del><span class="cx"> var NODE_STACK = [];
</span><span class="cx"> 
</span><span class="cx"> /**
</span><span class="lines">@@ -3191,13 +4239,13 @@
</span><span class="cx"> var get = Ember.get,
</span><span class="cx">     set = Ember.set,
</span><span class="cx">     metaFor = Ember.meta,
</span><del>-    guidFor = Ember.guidFor,
</del><span class="cx">     a_slice = [].slice,
</span><span class="cx">     o_create = Ember.create,
</span><span class="cx">     META_KEY = Ember.META_KEY,
</span><span class="cx">     watch = Ember.watch,
</span><span class="cx">     unwatch = Ember.unwatch;
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> // ..........................................................
</span><span class="cx"> // DEPENDENT KEYS
</span><span class="cx"> //
</span><span class="lines">@@ -3213,7 +4261,7 @@
</span><span class="cx">   This function returns a map of unique dependencies for a
</span><span class="cx">   given object and key.
</span><span class="cx"> */
</span><del>-function keysForDep(obj, depsMeta, depKey) {
</del><ins>+function keysForDep(depsMeta, depKey) {
</ins><span class="cx">   var keys = depsMeta[depKey];
</span><span class="cx">   if (!keys) {
</span><span class="cx">     // if there are no dependencies yet for a the given key
</span><span class="lines">@@ -3227,20 +4275,8 @@
</span><span class="cx">   return keys;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-/* return obj[META_KEY].deps */
-function metaForDeps(obj, meta) {
-  var deps = meta.deps;
-  // If the current object has no dependencies...
-  if (!deps) {
-    // initialize the dependencies with a pointer back to
-    // the current object
-    deps = meta.deps = {};
-  } else if (!meta.hasOwnProperty('deps')) {
-    // otherwise if the dependencies are inherited from the
-    // object's superclass, clone the deps
-    deps = meta.deps = o_create(deps);
-  }
-  return deps;
</del><ins>+function metaForDeps(meta) {
+  return keysForDep(meta, 'deps');
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function addDependentKeys(desc, obj, keyName, meta) {
</span><span class="lines">@@ -3249,12 +4285,12 @@
</span><span class="cx">   var depKeys = desc._dependentKeys, depsMeta, idx, len, depKey, keys;
</span><span class="cx">   if (!depKeys) return;
</span><span class="cx"> 
</span><del>-  depsMeta = metaForDeps(obj, meta);
</del><ins>+  depsMeta = metaForDeps(meta);
</ins><span class="cx"> 
</span><span class="cx">   for(idx = 0, len = depKeys.length; idx &lt; len; idx++) {
</span><span class="cx">     depKey = depKeys[idx];
</span><span class="cx">     // Lookup keys meta for depKey
</span><del>-    keys = keysForDep(obj, depsMeta, depKey);
</del><ins>+    keys = keysForDep(depsMeta, depKey);
</ins><span class="cx">     // Increment the number of times depKey depends on keyName.
</span><span class="cx">     keys[keyName] = (keys[keyName] || 0) + 1;
</span><span class="cx">     // Watch the depKey
</span><span class="lines">@@ -3268,12 +4304,12 @@
</span><span class="cx">   var depKeys = desc._dependentKeys, depsMeta, idx, len, depKey, keys;
</span><span class="cx">   if (!depKeys) return;
</span><span class="cx"> 
</span><del>-  depsMeta = metaForDeps(obj, meta);
</del><ins>+  depsMeta = metaForDeps(meta);
</ins><span class="cx"> 
</span><span class="cx">   for(idx = 0, len = depKeys.length; idx &lt; len; idx++) {
</span><span class="cx">     depKey = depKeys[idx];
</span><span class="cx">     // Lookup keys meta for depKey
</span><del>-    keys = keysForDep(obj, depsMeta, depKey);
</del><ins>+    keys = keysForDep(depsMeta, depKey);
</ins><span class="cx">     // Increment the number of times depKey depends on keyName.
</span><span class="cx">     keys[keyName] = (keys[keyName] || 0) - 1;
</span><span class="cx">     // Watch the depKey
</span><span class="lines">@@ -3286,6 +4322,81 @@
</span><span class="cx"> //
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+  A computed property transforms an objects function into a property.
+
+  By default the function backing the computed property will only be called
+  once and the result will be cached. You can specify various properties
+  that your computed property is dependent on. This will force the cached
+  result to be recomputed if the dependencies are modified.
+
+  In the following example we declare a computed property (by calling
+  `.property()` on the fullName function) and setup the properties
+  dependencies (depending on firstName and lastName). The fullName function
+  will be called once (regardless of how many times it is accessed) as long
+  as it's dependencies have not been changed. Once firstName or lastName are updated
+  any future calls (or anything bound) to fullName will incorporate the new
+  values.
+
+  ```javascript
+  Person = Ember.Object.extend({
+    // these will be supplied by `create`
+    firstName: null,
+    lastName: null,
+
+    fullName: function() {
+      var firstName = this.get('firstName');
+      var lastName = this.get('lastName');
+
+     return firstName + ' ' + lastName;
+    }.property('firstName', 'lastName')
+  });
+
+  var tom = Person.create({
+    firstName: &quot;Tom&quot;,
+    lastName: &quot;Dale&quot;
+  });
+
+  tom.get('fullName') // &quot;Tom Dale&quot;
+  ```
+
+  You can also define what Ember should do when setting a computed property.
+  If you try to set a computed property, it will be invoked with the key and
+  value you want to set it to. You can also accept the previous value as the
+  third parameter.
+
+  ```javascript
+
+ Person = Ember.Object.extend({
+    // these will be supplied by `create`
+    firstName: null,
+    lastName: null,
+
+    fullName: function(key, value, oldValue) {
+      // getter
+      if (arguments.length === 1) {
+        var firstName = this.get('firstName');
+        var lastName = this.get('lastName');
+
+        return firstName + ' ' + lastName;
+
+      // setter
+      } else {
+        var name = value.split(&quot; &quot;);
+
+        this.set('firstName', name[0]);
+        this.set('lastName', name[1]);
+
+        return value;
+      }
+    }.property('firstName', 'lastName')
+  });
+
+  var person = Person.create();
+  person.set('fullName', &quot;Peter Wagenet&quot;);
+  person.get('firstName') // Peter
+  person.get('lastName') // Wagenet
+  ```
+
</ins><span class="cx">   @class ComputedProperty
</span><span class="cx">   @namespace Ember
</span><span class="cx">   @extends Ember.Descriptor
</span><span class="lines">@@ -3293,8 +4404,10 @@
</span><span class="cx"> */
</span><span class="cx"> function ComputedProperty(func, opts) {
</span><span class="cx">   this.func = func;
</span><ins>+
</ins><span class="cx">   this._cacheable = (opts &amp;&amp; opts.cacheable !== undefined) ? opts.cacheable : true;
</span><span class="cx">   this._dependentKeys = opts &amp;&amp; opts.dependentKeys;
</span><ins>+  this._readOnly = opts &amp;&amp; (opts.readOnly !== undefined || !!opts.readOnly);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ember.ComputedProperty = ComputedProperty;
</span><span class="lines">@@ -3303,26 +4416,18 @@
</span><span class="cx"> var ComputedPropertyPrototype = ComputedProperty.prototype;
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  Call on a computed property to set it into cacheable mode. When in this
-  mode the computed property will automatically cache the return value of
-  your function until one of the dependent keys changes.
</del><ins>+  Properties are cacheable by default. Computed property will automatically
+  cache the return value of your function until one of the dependent keys changes.
</ins><span class="cx"> 
</span><del>-  ```javascript
-  MyApp.president = Ember.Object.create({
-    fullName: function() {
-      return this.get('firstName') + ' ' + this.get('lastName');
</del><ins>+  Call `volatile()` to set it into non-cached mode. When in this mode
+  the computed property will not automatically cache the return value.
</ins><span class="cx"> 
</span><del>-      // After calculating the value of this function, Ember will
-      // return that value without re-executing this function until
-      // one of the dependent properties change.
-    }.property('firstName', 'lastName')
-  });
-  ```
</del><ins>+  However, if a property is properly observable, there is no reason to disable
+  caching.
</ins><span class="cx"> 
</span><del>-  Properties are cacheable by default.
-
</del><span class="cx">   @method cacheable
</span><span class="cx">   @param {Boolean} aFlag optional set to `false` to disable caching
</span><ins>+  @return {Ember.ComputedProperty} this
</ins><span class="cx">   @chainable
</span><span class="cx"> */
</span><span class="cx"> ComputedPropertyPrototype.cacheable = function(aFlag) {
</span><span class="lines">@@ -3335,14 +4440,15 @@
</span><span class="cx">   mode the computed property will not automatically cache the return value.
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><del>-  MyApp.outsideService = Ember.Object.create({
</del><ins>+  MyApp.outsideService = Ember.Object.extend({
</ins><span class="cx">     value: function() {
</span><span class="cx">       return OutsideService.getValue();
</span><span class="cx">     }.property().volatile()
</span><del>-  });
</del><ins>+  }).create();
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   @method volatile
</span><ins>+  @return {Ember.ComputedProperty} this
</ins><span class="cx">   @chainable
</span><span class="cx"> */
</span><span class="cx"> ComputedPropertyPrototype.volatile = function() {
</span><span class="lines">@@ -3350,11 +4456,36 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+  Call on a computed property to set it into read-only mode. When in this
+  mode the computed property will throw an error when set.
+
+  ```javascript
+  MyApp.Person = Ember.Object.extend({
+    guid: function() {
+      return 'guid-guid-guid';
+    }.property().readOnly()
+  });
+
+  MyApp.person = MyApp.Person.create();
+
+  MyApp.person.set('guid', 'new-guid'); // will throw an exception
+  ```
+
+  @method readOnly
+  @return {Ember.ComputedProperty} this
+  @chainable
+*/
+ComputedPropertyPrototype.readOnly = function(readOnly) {
+  this._readOnly = readOnly === undefined || !!readOnly;
+  return this;
+};
+
+/**
</ins><span class="cx">   Sets the dependent keys on this computed property. Pass any number of
</span><span class="cx">   arguments containing key paths that this computed property depends on.
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><del>-  MyApp.president = Ember.Object.create({
</del><ins>+  MyApp.President = Ember.Object.extend({
</ins><span class="cx">     fullName: Ember.computed(function() {
</span><span class="cx">       return this.get('firstName') + ' ' + this.get('lastName');
</span><span class="cx"> 
</span><span class="lines">@@ -3362,17 +4493,26 @@
</span><span class="cx">       // and lastName
</span><span class="cx">     }).property('firstName', 'lastName')
</span><span class="cx">   });
</span><ins>+
+  MyApp.president = MyApp.President.create({
+    firstName: 'Barack',
+    lastName: 'Obama',
+  });
+  MyApp.president.get('fullName'); // Barack Obama
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   @method property
</span><span class="cx">   @param {String} path* zero or more property paths
</span><ins>+  @return {Ember.ComputedProperty} this
</ins><span class="cx">   @chainable
</span><span class="cx"> */
</span><span class="cx"> ComputedPropertyPrototype.property = function() {
</span><del>-  var args = [];
-  for (var i = 0, l = arguments.length; i &lt; l; i++) {
-    args.push(arguments[i]);
-  }
</del><ins>+  var args;
+
+  
+    args = a_slice.call(arguments);
+  
+
</ins><span class="cx">   this._dependentKeys = args;
</span><span class="cx">   return this;
</span><span class="cx"> };
</span><span class="lines">@@ -3412,25 +4552,6 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /* impl descriptor API */
</span><del>-ComputedPropertyPrototype.willWatch = function(obj, keyName) {
-  // watch already creates meta for this instance
-  var meta = obj[META_KEY];
-  Ember.assert('watch should have setup meta to be writable', meta.source === obj);
-  if (!(keyName in meta.cache)) {
-    addDependentKeys(this, obj, keyName, meta);
-  }
-};
-
-ComputedPropertyPrototype.didUnwatch = function(obj, keyName) {
-  var meta = obj[META_KEY];
-  Ember.assert('unwatch should have setup meta to be writable', meta.source === obj);
-  if (!(keyName in meta.cache)) {
-    // unwatch already creates meta for this instance
-    removeDependentKeys(this, obj, keyName, meta);
-  }
-};
-
-/* impl descriptor API */
</del><span class="cx"> ComputedPropertyPrototype.didChange = function(obj, keyName) {
</span><span class="cx">   // _suspended is set via a CP.set to ensure we don't clear
</span><span class="cx">   // the cached value set by the setter
</span><span class="lines">@@ -3438,31 +4559,76 @@
</span><span class="cx">     var meta = metaFor(obj);
</span><span class="cx">     if (keyName in meta.cache) {
</span><span class="cx">       delete meta.cache[keyName];
</span><del>-      if (!meta.watching[keyName]) {
-        removeDependentKeys(this, obj, keyName, meta);
-      }
</del><ins>+      removeDependentKeys(this, obj, keyName, meta);
</ins><span class="cx">     }
</span><span class="cx">   }
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-/* impl descriptor API */
</del><ins>+function finishChains(chainNodes)
+{
+  for (var i=0, l=chainNodes.length; i&lt;l; i++) {
+    chainNodes[i].didChange(null);
+  }
+}
+
+/**
+  Access the value of the function backing the computed property.
+  If this property has already been cached, return the cached result.
+  Otherwise, call the function passing the property name as an argument.
+
+  ```javascript
+  Person = Ember.Object.extend({
+    fullName: function(keyName) {
+      // the keyName parameter is 'fullName' in this case.
+
+      return this.get('firstName') + ' ' + this.get('lastName');
+    }.property('firstName', 'lastName')
+  });
+
+
+  var tom = Person.create({
+    firstName: &quot;Tom&quot;,
+    lastName: &quot;Dale&quot;
+  });
+
+  tom.get('fullName') // &quot;Tom Dale&quot;
+  ```
+
+  @method get
+  @param {String} keyName The key being accessed.
+  @return {Object} The return value of the function backing the CP.
+*/
</ins><span class="cx"> ComputedPropertyPrototype.get = function(obj, keyName) {
</span><del>-  var ret, cache, meta;
</del><ins>+  var ret, cache, meta, chainNodes;
</ins><span class="cx">   if (this._cacheable) {
</span><span class="cx">     meta = metaFor(obj);
</span><span class="cx">     cache = meta.cache;
</span><span class="cx">     if (keyName in cache) { return cache[keyName]; }
</span><span class="cx">     ret = cache[keyName] = this.func.call(obj, keyName);
</span><del>-    if (!meta.watching[keyName]) {
-      addDependentKeys(this, obj, keyName, meta);
-    }
</del><ins>+    chainNodes = meta.chainWatchers &amp;&amp; meta.chainWatchers[keyName];
+    if (chainNodes) { finishChains(chainNodes); }
+    addDependentKeys(this, obj, keyName, meta);
</ins><span class="cx">   } else {
</span><span class="cx">     ret = this.func.call(obj, keyName);
</span><span class="cx">   }
</span><span class="cx">   return ret;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-/* impl descriptor API */
</del><ins>+/**
+  Set the value of a computed property. If the function that backs your
+  computed property does not accept arguments then the default action for
+  setting would be to define the property on the current object, and set
+  the value of the property to the value being set.
+
+  Generally speaking if you intend for your computed property to be set
+  your backing function should accept either two or three arguments.
+
+  @method set
+  @param {String} keyName The key being accessed.
+  @param {Object} newValue The new value being assigned.
+  @param {String} oldValue The old value being replaced.
+  @return {Object} The return value of the function backing the CP.
+*/
</ins><span class="cx"> ComputedPropertyPrototype.set = function(obj, keyName, value) {
</span><span class="cx">   var cacheable = this._cacheable,
</span><span class="cx">       func = this.func,
</span><span class="lines">@@ -3471,27 +4637,33 @@
</span><span class="cx">       oldSuspended = this._suspended,
</span><span class="cx">       hadCachedValue = false,
</span><span class="cx">       cache = meta.cache,
</span><del>-      cachedValue, ret;
</del><ins>+      funcArgLength, cachedValue, ret;
</ins><span class="cx"> 
</span><ins>+  if (this._readOnly) {
+    throw new Ember.Error('Cannot Set: ' + keyName + ' on: ' + obj.toString() );
+  }
+
</ins><span class="cx">   this._suspended = obj;
</span><span class="cx"> 
</span><span class="cx">   try {
</span><ins>+
</ins><span class="cx">     if (cacheable &amp;&amp; cache.hasOwnProperty(keyName)) {
</span><span class="cx">       cachedValue = cache[keyName];
</span><span class="cx">       hadCachedValue = true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Check if the CP has been wrapped
-    if (func.wrappedFunction) { func = func.wrappedFunction; }
</del><ins>+    // Check if the CP has been wrapped. If if has, use the
+    // length from the wrapped function.
+    funcArgLength = (func.wrappedFunction ? func.wrappedFunction.length : func.length);
</ins><span class="cx"> 
</span><span class="cx">     // For backwards-compatibility with computed properties
</span><span class="cx">     // that check for arguments.length === 2 to determine if
</span><span class="cx">     // they are being get or set, only pass the old cached
</span><span class="cx">     // value if the computed property opts into a third
</span><span class="cx">     // argument.
</span><del>-    if (func.length === 3) {
</del><ins>+    if (funcArgLength === 3) {
</ins><span class="cx">       ret = func.call(obj, keyName, value, cachedValue);
</span><del>-    } else if (func.length === 2) {
</del><ins>+    } else if (funcArgLength === 2) {
</ins><span class="cx">       ret = func.call(obj, keyName, value);
</span><span class="cx">     } else {
</span><span class="cx">       Ember.defineProperty(obj, keyName, null, cachedValue);
</span><span class="lines">@@ -3508,7 +4680,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (cacheable) {
</span><del>-      if (!watched &amp;&amp; !hadCachedValue) {
</del><ins>+      if (!hadCachedValue) {
</ins><span class="cx">         addDependentKeys(this, obj, keyName, meta);
</span><span class="cx">       }
</span><span class="cx">       cache[keyName] = ret;
</span><span class="lines">@@ -3521,19 +4693,11 @@
</span><span class="cx">   return ret;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-/* called when property is defined */
-ComputedPropertyPrototype.setup = function(obj, keyName) {
-  var meta = obj[META_KEY];
-  if (meta &amp;&amp; meta.watching[keyName]) {
-    addDependentKeys(this, obj, keyName, metaFor(obj));
-  }
-};
-
</del><span class="cx"> /* called before property is overridden */
</span><span class="cx"> ComputedPropertyPrototype.teardown = function(obj, keyName) {
</span><span class="cx">   var meta = metaFor(obj);
</span><span class="cx"> 
</span><del>-  if (meta.watching[keyName] || keyName in meta.cache) {
</del><ins>+  if (keyName in meta.cache) {
</ins><span class="cx">     removeDependentKeys(this, obj, keyName, meta);
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -3552,7 +4716,6 @@
</span><span class="cx">   The function should accept two parameters, key and value. If value is not
</span><span class="cx">   undefined you should set the value first. In either case return the
</span><span class="cx">   current value of the property.
</span><del>-
</del><span class="cx">   @method computed
</span><span class="cx">   @for Ember
</span><span class="cx">   @param {Function} func The computed property function.
</span><span class="lines">@@ -3566,6 +4729,10 @@
</span><span class="cx">     func = a_slice.call(arguments, -1)[0];
</span><span class="cx">   }
</span><span class="cx"> 
</span><ins>+  if (typeof func !== &quot;function&quot;) {
+    throw new Ember.Error(&quot;Computed Property declared without a property function&quot;);
+  }
+
</ins><span class="cx">   var cp = new ComputedProperty(func);
</span><span class="cx"> 
</span><span class="cx">   if (args) {
</span><span class="lines">@@ -3586,6 +4753,7 @@
</span><span class="cx">   @param {Object} obj the object whose property you want to check
</span><span class="cx">   @param {String} key the name of the property whose cached value you want
</span><span class="cx">     to return
</span><ins>+  @return {Object} the cached value
</ins><span class="cx"> */
</span><span class="cx"> Ember.cacheFor = function cacheFor(obj, key) {
</span><span class="cx">   var cache = metaFor(obj, false).cache;
</span><span class="lines">@@ -3595,622 +4763,1380 @@
</span><span class="cx">   }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+function getProperties(self, propertyNames) {
+  var ret = {};
+  for(var i = 0; i &lt; propertyNames.length; i++) {
+    ret[propertyNames[i]] = get(self, propertyNames[i]);
+  }
+  return ret;
+}
+
+function registerComputed(name, macro) {
+  Ember.computed[name] = function(dependentKey) {
+    var args = a_slice.call(arguments);
+    return Ember.computed(dependentKey, function() {
+      return macro.apply(this, args);
+    });
+  };
+}
+
+function registerComputedWithProperties(name, macro) {
+  Ember.computed[name] = function() {
+    var properties = a_slice.call(arguments);
+
+    var computed = Ember.computed(function() {
+      return macro.apply(this, [getProperties(this, properties)]);
+    });
+
+    return computed.property.apply(computed, properties);
+  };
+}
+
</ins><span class="cx"> /**
</span><del>-  @method computed.not
</del><ins>+  A computed property that returns true if the value of the dependent
+  property is null, an empty string, empty array, or empty function.
+
+  Note: When using `Ember.computed.empty` to watch an array make sure to
+  use the `array.[]` syntax so the computed can subscribe to transitions
+  from empty to non-empty states.
+
+  Example
+
+  ```javascript
+  var ToDoList = Ember.Object.extend({
+    done: Ember.computed.empty('todos.[]') // detect array changes
+  });
+  var todoList = ToDoList.create({todos: ['Unit Test', 'Documentation', 'Release']});
+  todoList.get('done'); // false
+  todoList.get('todos').clear(); // []
+  todoList.get('done'); // true
+  ```
+
+  @method computed.empty
</ins><span class="cx">   @for Ember
</span><span class="cx">   @param {String} dependentKey
</span><ins>+  @return {Ember.ComputedProperty} computed property which negate
+  the original value for property
</ins><span class="cx"> */
</span><del>-Ember.computed.not = function(dependentKey) {
-  return Ember.computed(dependentKey, function(key) {
-    return !get(this, dependentKey);
</del><ins>+registerComputed('empty', function(dependentKey) {
+  return Ember.isEmpty(get(this, dependentKey));
+});
+
+/**
+  A computed property that returns true if the value of the dependent
+  property is NOT null, an empty string, empty array, or empty function.
+
+  Note: When using `Ember.computed.notEmpty` to watch an array make sure to
+  use the `array.[]` syntax so the computed can subscribe to transitions
+  from empty to non-empty states.
+
+  Example
+
+  ```javascript
+  var Hamster = Ember.Object.extend({
+    hasStuff: Ember.computed.notEmpty('backpack.[]')
</ins><span class="cx">   });
</span><del>-};
</del><ins>+  var hamster = Hamster.create({backpack: ['Food', 'Sleeping Bag', 'Tent']});
+  hamster.get('hasStuff'); // true
+  hamster.get('backpack').clear(); // []
+  hamster.get('hasStuff'); // false
+  ```
</ins><span class="cx"> 
</span><del>-/**
-  @method computed.empty
</del><ins>+  @method computed.notEmpty
</ins><span class="cx">   @for Ember
</span><span class="cx">   @param {String} dependentKey
</span><ins>+  @return {Ember.ComputedProperty} computed property which returns true if
+  original value for property is not empty.
</ins><span class="cx"> */
</span><del>-Ember.computed.empty = function(dependentKey) {
-  return Ember.computed(dependentKey, function(key) {
-    var val = get(this, dependentKey);
-    return val === undefined || val === null || val === '' || (Ember.isArray(val) &amp;&amp; get(val, 'length') === 0);
</del><ins>+registerComputed('notEmpty', function(dependentKey) {
+  return !Ember.isEmpty(get(this, dependentKey));
+});
+
+/**
+  A computed property that returns true if the value of the dependent
+  property is null or undefined. This avoids errors from JSLint complaining
+  about use of ==, which can be technically confusing.
+
+  Example
+
+  ```javascript
+  var Hamster = Ember.Object.extend({
+    isHungry: Ember.computed.none('food')
</ins><span class="cx">   });
</span><del>-};
</del><ins>+  var hamster = Hamster.create();
+  hamster.get('isHungry'); // true
+  hamster.set('food', 'Banana');
+  hamster.get('isHungry'); // false
+  hamster.set('food', null);
+  hamster.get('isHungry'); // true
+  ```
</ins><span class="cx"> 
</span><del>-/**
-  @method computed.bool
</del><ins>+  @method computed.none
</ins><span class="cx">   @for Ember
</span><span class="cx">   @param {String} dependentKey
</span><ins>+  @return {Ember.ComputedProperty} computed property which
+  returns true if original value for property is null or undefined.
</ins><span class="cx"> */
</span><del>-Ember.computed.bool = function(dependentKey) {
-  return Ember.computed(dependentKey, function(key) {
-    return !!get(this, dependentKey);
</del><ins>+registerComputed('none', function(dependentKey) {
+  return Ember.isNone(get(this, dependentKey));
+});
+
+/**
+  A computed property that returns the inverse boolean value
+  of the original value for the dependent property.
+
+  Example
+
+  ```javascript
+  var User = Ember.Object.extend({
+    isAnonymous: Ember.computed.not('loggedIn')
</ins><span class="cx">   });
</span><del>-};
</del><ins>+  var user = User.create({loggedIn: false});
+  user.get('isAnonymous'); // true
+  user.set('loggedIn', true);
+  user.get('isAnonymous'); // false
+  ```
</ins><span class="cx"> 
</span><del>-/**
-  @method computed.alias
</del><ins>+  @method computed.not
</ins><span class="cx">   @for Ember
</span><span class="cx">   @param {String} dependentKey
</span><ins>+  @return {Ember.ComputedProperty} computed property which returns
+  inverse of the original value for property
</ins><span class="cx"> */
</span><del>-Ember.computed.alias = function(dependentKey) {
-  return Ember.computed(dependentKey, function(key, value){
-    if (arguments.length === 1) {
-      return get(this, dependentKey);
-    } else {
-      set(this, dependentKey, value);
-      return value;
-    }
</del><ins>+registerComputed('not', function(dependentKey) {
+  return !get(this, dependentKey);
+});
+
+/**
+  A computed property that converts the provided dependent property
+  into a boolean value.
+
+  ```javascript
+  var Hamster = Ember.Object.extend({
+    hasBananas: Ember.computed.bool('numBananas')
</ins><span class="cx">   });
</span><del>-};
</del><ins>+  var hamster = Hamster.create();
+  hamster.get('hasBananas'); // false
+  hamster.set('numBananas', 0);
+  hamster.get('hasBananas'); // false
+  hamster.set('numBananas', 1);
+  hamster.get('hasBananas'); // true
+  hamster.set('numBananas', null);
+  hamster.get('hasBananas'); // false
+  ```
</ins><span class="cx"> 
</span><del>-})();
</del><ins>+  @method computed.bool
+  @for Ember
+  @param {String} dependentKey
+  @return {Ember.ComputedProperty} computed property which converts
+  to boolean the original value for property
+*/
+registerComputed('bool', function(dependentKey) {
+  return !!get(this, dependentKey);
+});
</ins><span class="cx"> 
</span><ins>+/**
+  A computed property which matches the original value for the
+  dependent property against a given RegExp, returning `true`
+  if they values matches the RegExp and `false` if it does not.
</ins><span class="cx"> 
</span><ins>+  Example
</ins><span class="cx"> 
</span><del>-(function() {
-/**
-@module ember-metal
</del><ins>+  ```javascript
+  var User = Ember.Object.extend({
+    hasValidEmail: Ember.computed.match('email', /^.+@.+\..+$/)
+  });
+  var user = User.create({loggedIn: false});
+  user.get('hasValidEmail'); // false
+  user.set('email', '');
+  user.get('hasValidEmail'); // false
+  user.set('email', 'ember_hamster@example.com');
+  user.get('hasValidEmail'); // true
+  ```
+
+  @method computed.match
+  @for Ember
+  @param {String} dependentKey
+  @param {RegExp} regexp
+  @return {Ember.ComputedProperty} computed property which match
+  the original value for property against a given RegExp
</ins><span class="cx"> */
</span><ins>+registerComputed('match', function(dependentKey, regexp) {
+  var value = get(this, dependentKey);
+  return typeof value === 'string' ? regexp.test(value) : false;
+});
</ins><span class="cx"> 
</span><del>-var o_create = Ember.create,
-    metaFor = Ember.meta,
-    metaPath = Ember.metaPath,
-    META_KEY = Ember.META_KEY;
</del><ins>+/**
+  A computed property that returns true if the provided dependent property
+  is equal to the given value.
</ins><span class="cx"> 
</span><del>-/*
-  The event system uses a series of nested hashes to store listeners on an
-  object. When a listener is registered, or when an event arrives, these
-  hashes are consulted to determine which target and action pair to invoke.
</del><ins>+  Example
</ins><span class="cx"> 
</span><del>-  The hashes are stored in the object's meta hash, and look like this:
</del><ins>+  ```javascript
+  var Hamster = Ember.Object.extend({
+    napTime: Ember.computed.equal('state', 'sleepy')
+  });
+  var hamster = Hamster.create();
+  hamster.get('napTime'); // false
+  hamster.set('state', 'sleepy');
+  hamster.get('napTime'); // true
+  hamster.set('state', 'hungry');
+  hamster.get('napTime'); // false
+  ```
</ins><span class="cx"> 
</span><del>-      // Object's meta hash
-      {
-        listeners: {       // variable name: `listenerSet`
-          &quot;foo:changed&quot;: [ // variable name: `actions`
-            [target, method, onceFlag, suspendedFlag]
-          ]
-        }
-      }
-
</del><ins>+  @method computed.equal
+  @for Ember
+  @param {String} dependentKey
+  @param {String|Number|Object} value
+  @return {Ember.ComputedProperty} computed property which returns true if
+  the original value for property is equal to the given value.
</ins><span class="cx"> */
</span><ins>+registerComputed('equal', function(dependentKey, value) {
+  return get(this, dependentKey) === value;
+});
</ins><span class="cx"> 
</span><del>-function indexOf(array, target, method) {
-  var index = -1;
-  for (var i = 0, l = array.length; i &lt; l; i++) {
-    if (target === array[i][0] &amp;&amp; method === array[i][1]) { index = i; break; }
-  }
-  return index;
-}
</del><ins>+/**
+  A computed property that returns true if the provied dependent property
+  is greater than the provided value.
</ins><span class="cx"> 
</span><del>-function actionsFor(obj, eventName) {
-  var meta = metaFor(obj, true),
-      actions;
</del><ins>+  Example
</ins><span class="cx"> 
</span><del>-  if (!meta.listeners) { meta.listeners = {}; }
</del><ins>+  ```javascript
+  var Hamster = Ember.Object.extend({
+    hasTooManyBananas: Ember.computed.gt('numBananas', 10)
+  });
+  var hamster = Hamster.create();
+  hamster.get('hasTooManyBananas'); // false
+  hamster.set('numBananas', 3);
+  hamster.get('hasTooManyBananas'); // false
+  hamster.set('numBananas', 11);
+  hamster.get('hasTooManyBananas'); // true
+  ```
</ins><span class="cx"> 
</span><del>-  if (!meta.hasOwnProperty('listeners')) {
-    // setup inherited copy of the listeners object
-    meta.listeners = o_create(meta.listeners);
-  }
</del><ins>+  @method computed.gt
+  @for Ember
+  @param {String} dependentKey
+  @param {Number} value
+  @return {Ember.ComputedProperty} computed property which returns true if
+  the original value for property is greater then given value.
+*/
+registerComputed('gt', function(dependentKey, value) {
+  return get(this, dependentKey) &gt; value;
+});
</ins><span class="cx"> 
</span><del>-  actions = meta.listeners[eventName];
</del><ins>+/**
+  A computed property that returns true if the provided dependent property
+  is greater than or equal to the provided value.
</ins><span class="cx"> 
</span><del>-  // if there are actions, but the eventName doesn't exist in our listeners, then copy them from the prototype
-  if (actions &amp;&amp; !meta.listeners.hasOwnProperty(eventName)) {
-    actions = meta.listeners[eventName] = meta.listeners[eventName].slice();
-  } else if (!actions) {
-    actions = meta.listeners[eventName] = [];
-  }
</del><ins>+  Example
</ins><span class="cx"> 
</span><del>-  return actions;
-}
</del><ins>+  ```javascript
+  var Hamster = Ember.Object.extend({
+    hasTooManyBananas: Ember.computed.gte('numBananas', 10)
+  });
+  var hamster = Hamster.create();
+  hamster.get('hasTooManyBananas'); // false
+  hamster.set('numBananas', 3);
+  hamster.get('hasTooManyBananas'); // false
+  hamster.set('numBananas', 10);
+  hamster.get('hasTooManyBananas'); // true
+  ```
</ins><span class="cx"> 
</span><del>-function actionsUnion(obj, eventName, otherActions) {
-  var meta = obj[META_KEY],
-      actions = meta &amp;&amp; meta.listeners &amp;&amp; meta.listeners[eventName];
</del><ins>+  @method computed.gte
+  @for Ember
+  @param {String} dependentKey
+  @param {Number} value
+  @return {Ember.ComputedProperty} computed property which returns true if
+  the original value for property is greater or equal then given value.
+*/
+registerComputed('gte', function(dependentKey, value) {
+  return get(this, dependentKey) &gt;= value;
+});
</ins><span class="cx"> 
</span><del>-  if (!actions) { return; }
-  for (var i = actions.length - 1; i &gt;= 0; i--) {
-    var target = actions[i][0],
-        method = actions[i][1],
-        once = actions[i][2],
-        suspended = actions[i][3],
-        actionIndex = indexOf(otherActions, target, method);
</del><ins>+/**
+  A computed property that returns true if the provided dependent property
+  is less than the provided value.
</ins><span class="cx"> 
</span><del>-    if (actionIndex === -1) {
-      otherActions.push([target, method, once, suspended]);
-    }
-  }
-}
</del><ins>+  Example
</ins><span class="cx"> 
</span><del>-function actionsDiff(obj, eventName, otherActions) {
-  var meta = obj[META_KEY],
-      actions = meta &amp;&amp; meta.listeners &amp;&amp; meta.listeners[eventName],
-      diffActions = [];
</del><ins>+  ```javascript
+  var Hamster = Ember.Object.extend({
+    needsMoreBananas: Ember.computed.lt('numBananas', 3)
+  });
+  var hamster = Hamster.create();
+  hamster.get('needsMoreBananas'); // true
+  hamster.set('numBananas', 3);
+  hamster.get('needsMoreBananas'); // false
+  hamster.set('numBananas', 2);
+  hamster.get('needsMoreBananas'); // true
+  ```
</ins><span class="cx"> 
</span><del>-  if (!actions) { return; }
-  for (var i = actions.length - 1; i &gt;= 0; i--) {
-    var target = actions[i][0],
-        method = actions[i][1],
-        once = actions[i][2],
-        suspended = actions[i][3],
-        actionIndex = indexOf(otherActions, target, method);
</del><ins>+  @method computed.lt
+  @for Ember
+  @param {String} dependentKey
+  @param {Number} value
+  @return {Ember.ComputedProperty} computed property which returns true if
+  the original value for property is less then given value.
+*/
+registerComputed('lt', function(dependentKey, value) {
+  return get(this, dependentKey) &lt; value;
+});
</ins><span class="cx"> 
</span><del>-    if (actionIndex !== -1) { continue; }
</del><ins>+/**
+  A computed property that returns true if the provided dependent property
+  is less than or equal to the provided value.
</ins><span class="cx"> 
</span><del>-    otherActions.push([target, method, once, suspended]);
-    diffActions.push([target, method, once, suspended]);
-  }
</del><ins>+  Example
</ins><span class="cx"> 
</span><del>-  return diffActions;
-}
</del><ins>+  ```javascript
+  var Hamster = Ember.Object.extend({
+    needsMoreBananas: Ember.computed.lte('numBananas', 3)
+  });
+  var hamster = Hamster.create();
+  hamster.get('needsMoreBananas'); // true
+  hamster.set('numBananas', 5);
+  hamster.get('needsMoreBananas'); // false
+  hamster.set('numBananas', 3);
+  hamster.get('needsMoreBananas'); // true
+  ```
</ins><span class="cx"> 
</span><del>-/**
-  Add an event listener
-
-  @method addListener
</del><ins>+  @method computed.lte
</ins><span class="cx">   @for Ember
</span><del>-  @param obj
-  @param {String} eventName
-  @param {Object|Function} targetOrMethod A target object or a function
-  @param {Function|String} method A function or the name of a function to be called on `target`
</del><ins>+  @param {String} dependentKey
+  @param {Number} value
+  @return {Ember.ComputedProperty} computed property which returns true if
+  the original value for property is less or equal then given value.
</ins><span class="cx"> */
</span><del>-function addListener(obj, eventName, target, method, once) {
-  Ember.assert(&quot;You must pass at least an object and event name to Ember.addListener&quot;, !!obj &amp;&amp; !!eventName);
</del><ins>+registerComputed('lte', function(dependentKey, value) {
+  return get(this, dependentKey) &lt;= value;
+});
</ins><span class="cx"> 
</span><del>-  if (!method &amp;&amp; 'function' === typeof target) {
-    method = target;
-    target = null;
-  }
</del><ins>+/**
+  A computed property that performs a logical `and` on the
+  original values for the provided dependent properties.
</ins><span class="cx"> 
</span><del>-  var actions = actionsFor(obj, eventName),
-      actionIndex = indexOf(actions, target, method);
</del><ins>+  Example
</ins><span class="cx"> 
</span><del>-  if (actionIndex !== -1) { return; }
</del><ins>+  ```javascript
+  var Hamster = Ember.Object.extend({
+    readyForCamp: Ember.computed.and('hasTent', 'hasBackpack')
+  });
+  var hamster = Hamster.create();
+  hamster.get('readyForCamp'); // false
+  hamster.set('hasTent', true);
+  hamster.get('readyForCamp'); // false
+  hamster.set('hasBackpack', true);
+  hamster.get('readyForCamp'); // true
+  ```
</ins><span class="cx"> 
</span><del>-  actions.push([target, method, once, undefined]);
-
-  if ('function' === typeof obj.didAddListener) {
-    obj.didAddListener(eventName, target, method);
</del><ins>+  @method computed.and
+  @for Ember
+  @param {String} dependentKey*
+  @return {Ember.ComputedProperty} computed property which performs
+  a logical `and` on the values of all the original values for properties.
+*/
+registerComputedWithProperties('and', function(properties) {
+  for (var key in properties) {
+    if (properties.hasOwnProperty(key) &amp;&amp; !properties[key]) {
+      return false;
+    }
</ins><span class="cx">   }
</span><del>-}
</del><ins>+  return true;
+});
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  Remove an event listener
</del><ins>+  A computed property which performs a logical `or` on the
+  original values for the provided dependent properties.
</ins><span class="cx"> 
</span><del>-  Arguments should match those passed to {{#crossLink &quot;Ember/addListener&quot;}}{{/crossLink}}
</del><ins>+  Example
</ins><span class="cx"> 
</span><del>-  @method removeListener
</del><ins>+  ```javascript
+  var Hamster = Ember.Object.extend({
+    readyForRain: Ember.computed.or('hasJacket', 'hasUmbrella')
+  });
+  var hamster = Hamster.create();
+  hamster.get('readyForRain'); // false
+  hamster.set('hasJacket', true);
+  hamster.get('readyForRain'); // true
+  ```
+
+  @method computed.or
</ins><span class="cx">   @for Ember
</span><del>-  @param obj
-  @param {String} eventName
-  @param {Object|Function} targetOrMethod A target object or a function
-  @param {Function|String} method A function or the name of a function to be called on `target`
</del><ins>+  @param {String} dependentKey*
+  @return {Ember.ComputedProperty} computed property which performs
+  a logical `or` on the values of all the original values for properties.
</ins><span class="cx"> */
</span><del>-function removeListener(obj, eventName, target, method) {
-  Ember.assert(&quot;You must pass at least an object and event name to Ember.removeListener&quot;, !!obj &amp;&amp; !!eventName);
-
-  if (!method &amp;&amp; 'function' === typeof target) {
-    method = target;
-    target = null;
</del><ins>+registerComputedWithProperties('or', function(properties) {
+  for (var key in properties) {
+    if (properties.hasOwnProperty(key) &amp;&amp; properties[key]) {
+      return true;
+    }
</ins><span class="cx">   }
</span><ins>+  return false;
+});
</ins><span class="cx"> 
</span><del>-  function _removeListener(target, method, once) {
-    var actions = actionsFor(obj, eventName),
-        actionIndex = indexOf(actions, target, method);
</del><ins>+/**
+  A computed property that returns the first truthy value
+  from a list of dependent properties.
</ins><span class="cx"> 
</span><del>-    // action doesn't exist, give up silently
-    if (actionIndex === -1) { return; }
</del><ins>+  Example
</ins><span class="cx"> 
</span><del>-    actions.splice(actionIndex, 1);
</del><ins>+  ```javascript
+  var Hamster = Ember.Object.extend({
+    hasClothes: Ember.computed.any('hat', 'shirt')
+  });
+  var hamster = Hamster.create();
+  hamster.get('hasClothes'); // null
+  hamster.set('shirt', 'Hawaiian Shirt');
+  hamster.get('hasClothes'); // 'Hawaiian Shirt'
+  ```
</ins><span class="cx"> 
</span><del>-    if ('function' === typeof obj.didRemoveListener) {
-      obj.didRemoveListener(eventName, target, method);
</del><ins>+  @method computed.any
+  @for Ember
+  @param {String} dependentKey*
+  @return {Ember.ComputedProperty} computed property which returns
+  the first truthy value of given list of properties.
+*/
+registerComputedWithProperties('any', function(properties) {
+  for (var key in properties) {
+    if (properties.hasOwnProperty(key) &amp;&amp; properties[key]) {
+      return properties[key];
</ins><span class="cx">     }
</span><span class="cx">   }
</span><ins>+  return null;
+});
</ins><span class="cx"> 
</span><del>-  if (method) {
-    _removeListener(target, method);
-  } else {
-    var meta = obj[META_KEY],
-        actions = meta &amp;&amp; meta.listeners &amp;&amp; meta.listeners[eventName];
</del><ins>+/**
+  A computed property that returns the array of values
+  for the provided dependent properties.
</ins><span class="cx"> 
</span><del>-    if (!actions) { return; }
-    for (var i = actions.length - 1; i &gt;= 0; i--) {
-      _removeListener(actions[i][0], actions[i][1]);
</del><ins>+  Example
+
+  ```javascript
+  var Hamster = Ember.Object.extend({
+    clothes: Ember.computed.collect('hat', 'shirt')
+  });
+  var hamster = Hamster.create();
+  hamster.get('clothes'); // [null, null]
+  hamster.set('hat', 'Camp Hat');
+  hamster.set('shirt', 'Camp Shirt');
+  hamster.get('clothes'); // ['Camp Hat', 'Camp Shirt']
+  ```
+
+  @method computed.collect
+  @for Ember
+  @param {String} dependentKey*
+  @return {Ember.ComputedProperty} computed property which maps
+  values of all passed properties in to an array.
+*/
+registerComputedWithProperties('collect', function(properties) {
+  var res = [];
+  for (var key in properties) {
+    if (properties.hasOwnProperty(key)) {
+      if (Ember.isNone(properties[key])) {
+        res.push(null);
+      } else {
+        res.push(properties[key]);
+      }
</ins><span class="cx">     }
</span><span class="cx">   }
</span><del>-}
</del><ins>+  return res;
+});
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
</del><ins>+  Creates a new property that is an alias for another property
+  on an object. Calls to `get` or `set` this property behave as
+  though they were called on the original property.
</ins><span class="cx"> 
</span><del>-  Suspend listener during callback.
</del><ins>+  ```javascript
+  Person = Ember.Object.extend({
+    name: 'Alex Matchneer',
+    nomen: Ember.computed.alias('name')
+  });
</ins><span class="cx"> 
</span><del>-  This should only be used by the target of the event listener
-  when it is taking an action that would cause the event, e.g.
-  an object might suspend its property change listener while it is
-  setting that property.
</del><ins>+  alex = Person.create();
+  alex.get('nomen'); // 'Alex Matchneer'
+  alex.get('name');  // 'Alex Matchneer'
</ins><span class="cx"> 
</span><del>-  @method suspendListener
</del><ins>+  alex.set('nomen', '@machty');
+  alex.get('name');  // '@machty'
+  ```
+  @method computed.alias
</ins><span class="cx">   @for Ember
</span><del>-  @param obj
-  @param {String} eventName
-  @param {Object|Function} targetOrMethod A target object or a function
-  @param {Function|String} method A function or the name of a function to be called on `target`
-  @param {Function} callback
</del><ins>+  @param {String} dependentKey
+  @return {Ember.ComputedProperty} computed property which creates an
+  alias to the original value for property.
</ins><span class="cx"> */
</span><del>-function suspendListener(obj, eventName, target, method, callback) {
-  if (!method &amp;&amp; 'function' === typeof target) {
-    method = target;
-    target = null;
-  }
</del><ins>+Ember.computed.alias = function(dependentKey) {
+  return Ember.computed(dependentKey, function(key, value) {
+    if (arguments.length &gt; 1) {
+      set(this, dependentKey, value);
+      return value;
+    } else {
+      return get(this, dependentKey);
+    }
+  });
+};
</ins><span class="cx"> 
</span><del>-  var actions = actionsFor(obj, eventName),
-      actionIndex = indexOf(actions, target, method),
-      action;
</del><ins>+/**
+  Where `computed.alias` aliases `get` and `set`, and allows for bidirectional
+  data flow, `computed.oneWay` only provides an aliased `get`. The `set` will
+  not mutate the upstream property, rather causes the current property to
+  become the value set. This causes the downstream property to permentantly
+  diverge from the upstream property.
</ins><span class="cx"> 
</span><del>-  if (actionIndex !== -1) {
-    action = actions[actionIndex].slice(); // copy it, otherwise we're modifying a shared object
-    action[3] = true; // mark the action as suspended
-    actions[actionIndex] = action; // replace the shared object with our copy
-  }
</del><ins>+  Example
</ins><span class="cx"> 
</span><del>-  function tryable()   { return callback.call(target); }
-  function finalizer() { if (action) { action[3] = undefined; } }
</del><ins>+  ```javascript
+  User = Ember.Object.extend({
+    firstName: null,
+    lastName: null,
+    nickName: Ember.computed.oneWay('firstName')
+  });
</ins><span class="cx"> 
</span><del>-  return Ember.tryFinally(tryable, finalizer);
-}
</del><ins>+  user = User.create({
+    firstName: 'Teddy',
+    lastName:  'Zeenny'
+  });
</ins><span class="cx"> 
</span><del>-/**
-  @private
</del><ins>+  user.get('nickName');
+  # 'Teddy'
</ins><span class="cx"> 
</span><del>-  Suspend listener during callback.
</del><ins>+  user.set('nickName', 'TeddyBear');
+  # 'TeddyBear'
</ins><span class="cx"> 
</span><del>-  This should only be used by the target of the event listener
-  when it is taking an action that would cause the event, e.g.
-  an object might suspend its property change listener while it is
-  setting that property.
</del><ins>+  user.get('firstName');
+  # 'Teddy'
+  ```
</ins><span class="cx"> 
</span><del>-  @method suspendListener
</del><ins>+  @method computed.oneWay
</ins><span class="cx">   @for Ember
</span><del>-  @param obj
-  @param {Array} eventName Array of event names
-  @param {Object|Function} targetOrMethod A target object or a function
-  @param {Function|String} method A function or the name of a function to be called on `target`
-  @param {Function} callback
</del><ins>+  @param {String} dependentKey
+  @return {Ember.ComputedProperty} computed property which creates a
+  one way computed property to the original value for property.
</ins><span class="cx"> */
</span><del>-function suspendListeners(obj, eventNames, target, method, callback) {
-  if (!method &amp;&amp; 'function' === typeof target) {
-    method = target;
-    target = null;
-  }
</del><ins>+Ember.computed.oneWay = function(dependentKey) {
+  return Ember.computed(dependentKey, function() {
+    return get(this, dependentKey);
+  });
+};
</ins><span class="cx"> 
</span><del>-  var suspendedActions = [],
-      eventName, actions, action, i, l;
</del><span class="cx"> 
</span><del>-  for (i=0, l=eventNames.length; i&lt;l; i++) {
-    eventName = eventNames[i];
-    actions = actionsFor(obj, eventName);
-    var actionIndex = indexOf(actions, target, method);
</del><ins>+/**
+  A computed property that acts like a standard getter and setter,
+  but returns the value at the provided `defaultPath` if the
+  property itself has not been set to a value
</ins><span class="cx"> 
</span><del>-    if (actionIndex !== -1) {
-      action = actions[actionIndex].slice();
-      action[3] = true;
-      actions[actionIndex] = action;
-      suspendedActions.push(action);
-    }
-  }
</del><ins>+  Example
</ins><span class="cx"> 
</span><del>-  function tryable() { return callback.call(target); }
</del><ins>+  ```javascript
+  var Hamster = Ember.Object.extend({
+    wishList: Ember.computed.defaultTo('favoriteFood')
+  });
+  var hamster = Hamster.create({favoriteFood: 'Banana'});
+  hamster.get('wishList'); // 'Banana'
+  hamster.set('wishList', 'More Unit Tests');
+  hamster.get('wishList'); // 'More Unit Tests'
+  hamster.get('favoriteFood'); // 'Banana'
+  ```
</ins><span class="cx"> 
</span><del>-  function finalizer() {
-    for (i = 0, l = suspendedActions.length; i &lt; l; i++) {
-      suspendedActions[i][3] = undefined;
</del><ins>+  @method computed.defaultTo
+  @for Ember
+  @param {String} defaultPath
+  @return {Ember.ComputedProperty} computed property which acts like
+  a standard getter and setter, but defaults to the value from `defaultPath`.
+*/
+Ember.computed.defaultTo = function(defaultPath) {
+  return Ember.computed(function(key, newValue, cachedValue) {
+    if (arguments.length === 1) {
+      return cachedValue != null ? cachedValue : get(this, defaultPath);
</ins><span class="cx">     }
</span><del>-  }
</del><ins>+    return newValue != null ? newValue : get(this, defaultPath);
+  });
+};
</ins><span class="cx"> 
</span><del>-  return Ember.tryFinally(tryable, finalizer);
-}
</del><span class="cx"> 
</span><del>-/**
-  @private
</del><ins>+})();
</ins><span class="cx"> 
</span><del>-  Return a list of currently watched events
</del><span class="cx"> 
</span><del>-  @method watchedEvents
-  @for Ember
-  @param obj
</del><ins>+
+(function() {
+// Ember.tryFinally
+/**
+@module ember-metal
</ins><span class="cx"> */
</span><del>-function watchedEvents(obj) {
-  var listeners = obj[META_KEY].listeners, ret = [];
</del><span class="cx"> 
</span><del>-  if (listeners) {
-    for(var eventName in listeners) {
-      if (listeners[eventName]) { ret.push(eventName); }
-    }
-  }
-  return ret;
</del><ins>+var AFTER_OBSERVERS = ':change',
+    BEFORE_OBSERVERS = ':before';
+
+function changeEvent(keyName) {
+  return keyName+AFTER_OBSERVERS;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+function beforeEvent(keyName) {
+  return keyName+BEFORE_OBSERVERS;
+}
+
</ins><span class="cx"> /**
</span><del>-  @method sendEvent
-  @for Ember
</del><ins>+  @method addObserver
</ins><span class="cx">   @param obj
</span><del>-  @param {String} eventName
-  @param {Array} params
-  @return true
</del><ins>+  @param {String} path
+  @param {Object|Function} targetOrMethod
+  @param {Function|String} [method]
</ins><span class="cx"> */
</span><del>-function sendEvent(obj, eventName, params, actions) {
-  // first give object a chance to handle it
-  if (obj !== Ember &amp;&amp; 'function' === typeof obj.sendEvent) {
-    obj.sendEvent(eventName, params);
-  }
</del><ins>+Ember.addObserver = function(obj, _path, target, method) {
+  Ember.addListener(obj, changeEvent(_path), target, method);
+  Ember.watch(obj, _path);
</ins><span class="cx"> 
</span><del>-  if (!actions) {
-    var meta = obj[META_KEY];
-    actions = meta &amp;&amp; meta.listeners &amp;&amp; meta.listeners[eventName];
-  }
</del><ins>+  return this;
+};
</ins><span class="cx"> 
</span><del>-  if (!actions) { return; }
</del><ins>+Ember.observersFor = function(obj, path) {
+  return Ember.listenersFor(obj, changeEvent(path));
+};
</ins><span class="cx"> 
</span><del>-  for (var i = actions.length - 1; i &gt;= 0; i--) { // looping in reverse for once listeners
-    if (!actions[i] || actions[i][3] === true) { continue; }
-
-    var target = actions[i][0],
-        method = actions[i][1],
-        once = actions[i][2];
-
-    if (once) { removeListener(obj, eventName, target, method); }
-    if (!target) { target = obj; }
-    if ('string' === typeof method) { method = target[method]; }
-    if (params) {
-      method.apply(target, params);
-    } else {
-      method.apply(target);
-    }
-  }
-  return true;
-}
-
</del><span class="cx"> /**
</span><del>-  @private
-  @method hasListeners
-  @for Ember
</del><ins>+  @method removeObserver
</ins><span class="cx">   @param obj
</span><del>-  @param {String} eventName
</del><ins>+  @param {String} path
+  @param {Object|Function} targetOrMethod
+  @param {Function|String} [method]
</ins><span class="cx"> */
</span><del>-function hasListeners(obj, eventName) {
-  var meta = obj[META_KEY],
-      actions = meta &amp;&amp; meta.listeners &amp;&amp; meta.listeners[eventName];
</del><ins>+Ember.removeObserver = function(obj, _path, target, method) {
+  Ember.unwatch(obj, _path);
+  Ember.removeListener(obj, changeEvent(_path), target, method);
</ins><span class="cx"> 
</span><del>-  return !!(actions &amp;&amp; actions.length);
-}
</del><ins>+  return this;
+};
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-  @method listenersFor
-  @for Ember
</del><ins>+  @method addBeforeObserver
</ins><span class="cx">   @param obj
</span><del>-  @param {String} eventName
</del><ins>+  @param {String} path
+  @param {Object|Function} targetOrMethod
+  @param {Function|String} [method]
</ins><span class="cx"> */
</span><del>-function listenersFor(obj, eventName) {
-  var ret = [];
-  var meta = obj[META_KEY],
-      actions = meta &amp;&amp; meta.listeners &amp;&amp; meta.listeners[eventName];
</del><ins>+Ember.addBeforeObserver = function(obj, _path, target, method) {
+  Ember.addListener(obj, beforeEvent(_path), target, method);
+  Ember.watch(obj, _path);
</ins><span class="cx"> 
</span><del>-  if (!actions) { return ret; }
</del><ins>+  return this;
+};
</ins><span class="cx"> 
</span><del>-  for (var i = 0, l = actions.length; i &lt; l; i++) {
-    var target = actions[i][0],
-        method = actions[i][1];
-    ret.push([target, method]);
-  }
</del><ins>+// Suspend observer during callback.
+//
+// This should only be used by the target of the observer
+// while it is setting the observed path.
+Ember._suspendBeforeObserver = function(obj, path, target, method, callback) {
+  return Ember._suspendListener(obj, beforeEvent(path), target, method, callback);
+};
</ins><span class="cx"> 
</span><del>-  return ret;
-}
</del><ins>+Ember._suspendObserver = function(obj, path, target, method, callback) {
+  return Ember._suspendListener(obj, changeEvent(path), target, method, callback);
+};
</ins><span class="cx"> 
</span><del>-Ember.addListener = addListener;
-Ember.removeListener = removeListener;
-Ember._suspendListener = suspendListener;
-Ember._suspendListeners = suspendListeners;
-Ember.sendEvent = sendEvent;
-Ember.hasListeners = hasListeners;
-Ember.watchedEvents = watchedEvents;
-Ember.listenersFor = listenersFor;
-Ember.listenersDiff = actionsDiff;
-Ember.listenersUnion = actionsUnion;
</del><ins>+var map = Ember.ArrayPolyfills.map;
</ins><span class="cx"> 
</span><ins>+Ember._suspendBeforeObservers = function(obj, paths, target, method, callback) {
+  var events = map.call(paths, beforeEvent);
+  return Ember._suspendListeners(obj, events, target, method, callback);
+};
+
+Ember._suspendObservers = function(obj, paths, target, method, callback) {
+  var events = map.call(paths, changeEvent);
+  return Ember._suspendListeners(obj, events, target, method, callback);
+};
+
+Ember.beforeObserversFor = function(obj, path) {
+  return Ember.listenersFor(obj, beforeEvent(path));
+};
+
+/**
+  @method removeBeforeObserver
+  @param obj
+  @param {String} path
+  @param {Object|Function} targetOrMethod
+  @param {Function|String} [method]
+*/
+Ember.removeBeforeObserver = function(obj, _path, target, method) {
+  Ember.unwatch(obj, _path);
+  Ember.removeListener(obj, beforeEvent(_path), target, method);
+
+  return this;
+};
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-// Ember.Logger
-// Ember.watch.flushPending
-// Ember.beginPropertyChanges, Ember.endPropertyChanges
-// Ember.guidFor, Ember.tryFinally
</del><ins>+define(&quot;backburner/queue&quot;,
+  [&quot;exports&quot;],
+  function(__exports__) {
+    &quot;use strict&quot;;
+    function Queue(daq, name, options) {
+      this.daq = daq;
+      this.name = name;
+      this.options = options;
+      this._queue = [];
+    }
</ins><span class="cx"> 
</span><del>-/**
-@module ember-metal
-*/
</del><ins>+    Queue.prototype = {
+      daq: null,
+      name: null,
+      options: null,
+      _queue: null,
</ins><span class="cx"> 
</span><del>-// ..........................................................
-// HELPERS
-//
</del><ins>+      push: function(target, method, args, stack) {
+        var queue = this._queue;
+        queue.push(target, method, args, stack);
+        return {queue: this, target: target, method: method};
+      },
</ins><span class="cx"> 
</span><del>-var slice = [].slice,
-    forEach = Ember.ArrayPolyfills.forEach;
</del><ins>+      pushUnique: function(target, method, args, stack) {
+        var queue = this._queue, currentTarget, currentMethod, i, l;
</ins><span class="cx"> 
</span><del>-// invokes passed params - normalizing so you can pass target/func,
-// target/string or just func
-function invoke(target, method, args, ignore) {
</del><ins>+        for (i = 0, l = queue.length; i &lt; l; i += 4) {
+          currentTarget = queue[i];
+          currentMethod = queue[i+1];
</ins><span class="cx"> 
</span><del>-  if (method === undefined) {
-    method = target;
-    target = undefined;
-  }
</del><ins>+          if (currentTarget === target &amp;&amp; currentMethod === method) {
+            queue[i+2] = args; // replace args
+            queue[i+3] = stack; // replace stack
+            return {queue: this, target: target, method: method}; // TODO: test this code path
+          }
+        }
</ins><span class="cx"> 
</span><del>-  if ('string' === typeof method) { method = target[method]; }
-  if (args &amp;&amp; ignore &gt; 0) {
-    args = args.length &gt; ignore ? slice.call(args, ignore) : null;
-  }
</del><ins>+        this._queue.push(target, method, args, stack);
+        return {queue: this, target: target, method: method};
+      },
</ins><span class="cx"> 
</span><del>-  return Ember.handleErrors(function() {
-    // IE8's Function.prototype.apply doesn't accept undefined/null arguments.
-    return method.apply(target || this, args || []);
-  }, this);
-}
</del><ins>+      // TODO: remove me, only being used for Ember.run.sync
+      flush: function() {
+        var queue = this._queue,
+            options = this.options,
+            before = options &amp;&amp; options.before,
+            after = options &amp;&amp; options.after,
+            target, method, args, stack, i, l = queue.length;
</ins><span class="cx"> 
</span><ins>+        if (l &amp;&amp; before) { before(); }
+        for (i = 0; i &lt; l; i += 4) {
+          target = queue[i];
+          method = queue[i+1];
+          args   = queue[i+2];
+          stack  = queue[i+3]; // Debugging assistance
</ins><span class="cx"> 
</span><del>-// ..........................................................
-// RUNLOOP
-//
</del><ins>+          // TODO: error handling
+          if (args &amp;&amp; args.length &gt; 0) {
+            method.apply(target, args);
+          } else {
+            method.call(target);
+          }
+        }
+        if (l &amp;&amp; after) { after(); }
</ins><span class="cx"> 
</span><del>-var timerMark; // used by timers...
</del><ins>+        // check if new items have been added
+        if (queue.length &gt; l) {
+          this._queue = queue.slice(l);
+          this.flush();
+        } else {
+          this._queue.length = 0;
+        }
+      },
</ins><span class="cx"> 
</span><del>-/**
-Ember RunLoop (Private)
</del><ins>+      cancel: function(actionToCancel) {
+        var queue = this._queue, currentTarget, currentMethod, i, l;
</ins><span class="cx"> 
</span><del>-@class RunLoop
-@namespace Ember
-@private
-@constructor
-*/
-var RunLoop = function(prev) {
-  this._prev = prev || null;
-  this.onceTimers = {};
-};
</del><ins>+        for (i = 0, l = queue.length; i &lt; l; i += 4) {
+          currentTarget = queue[i];
+          currentMethod = queue[i+1];
</ins><span class="cx"> 
</span><del>-RunLoop.prototype = {
-  /**
-    @method end
-  */
-  end: function() {
-    this.flush();
-  },
</del><ins>+          if (currentTarget === actionToCancel.target &amp;&amp; currentMethod === actionToCancel.method) {
+            queue.splice(i, 4);
+            return true;
+          }
+        }
</ins><span class="cx"> 
</span><del>-  /**
-    @method prev
-  */
-  prev: function() {
-    return this._prev;
-  },
</del><ins>+        // if not found in current queue
+        // could be in the queue that is being flushed
+        queue = this._queueBeingFlushed;
+        if (!queue) {
+          return;
+        }
+        for (i = 0, l = queue.length; i &lt; l; i += 4) {
+          currentTarget = queue[i];
+          currentMethod = queue[i+1];
</ins><span class="cx"> 
</span><del>-  // ..........................................................
-  // Delayed Actions
-  //
</del><ins>+          if (currentTarget === actionToCancel.target &amp;&amp; currentMethod === actionToCancel.method) {
+            // don't mess with array during flush
+            // just nullify the method
+            queue[i+1] = null;
+            return true;
+          }
+        }
+      }
+    };
</ins><span class="cx"> 
</span><del>-  /**
-    @method schedule
-    @param {String} queueName
-    @param target
-    @param method
-  */
-  schedule: function(queueName, target, method) {
-    var queues = this._queues, queue;
-    if (!queues) { queues = this._queues = {}; }
-    queue = queues[queueName];
-    if (!queue) { queue = queues[queueName] = []; }
</del><span class="cx"> 
</span><del>-    var args = arguments.length &gt; 3 ? slice.call(arguments, 3) : null;
-    queue.push({ target: target, method: method, args: args });
-    return this;
-  },
</del><ins>+    __exports__.Queue = Queue;
+  });
</ins><span class="cx"> 
</span><del>-  /**
-    @method flush
-    @param {String} queueName
-  */
-  flush: function(queueName) {
-    var queueNames, idx, len, queue, log;
</del><ins>+define(&quot;backburner/deferred_action_queues&quot;,
+  [&quot;backburner/queue&quot;,&quot;exports&quot;],
+  function(__dependency1__, __exports__) {
+    &quot;use strict&quot;;
+    var Queue = __dependency1__.Queue;
</ins><span class="cx"> 
</span><del>-    if (!this._queues) { return this; } // nothing to do
</del><ins>+    function DeferredActionQueues(queueNames, options) {
+      var queues = this.queues = {};
+      this.queueNames = queueNames = queueNames || [];
</ins><span class="cx"> 
</span><del>-    function iter(item) {
-      invoke(item.target, item.method, item.args);
</del><ins>+      var queueName;
+      for (var i = 0, l = queueNames.length; i &lt; l; i++) {
+        queueName = queueNames[i];
+        queues[queueName] = new Queue(this, queueName, options[queueName]);
+      }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    function tryable() {
-      forEach.call(queue, iter);
-    }
</del><ins>+    DeferredActionQueues.prototype = {
+      queueNames: null,
+      queues: null,
</ins><span class="cx"> 
</span><del>-    Ember.watch.flushPending(); // make sure all chained watchers are setup
</del><ins>+      schedule: function(queueName, target, method, args, onceFlag, stack) {
+        var queues = this.queues,
+            queue = queues[queueName];
</ins><span class="cx"> 
</span><del>-    if (queueName) {
-      while (this._queues &amp;&amp; (queue = this._queues[queueName])) {
-        this._queues[queueName] = null;
</del><ins>+        if (!queue) { throw new Error(&quot;You attempted to schedule an action in a queue (&quot; + queueName + &quot;) that doesn't exist&quot;); }
</ins><span class="cx"> 
</span><del>-        // the sync phase is to allow property changes to propagate. don't
-        // invoke observers until that is finished.
-        if (queueName === 'sync') {
-          log = Ember.LOG_BINDINGS;
-          if (log) { Ember.Logger.log('Begin: Flush Sync Queue'); }
</del><ins>+        if (onceFlag) {
+          return queue.pushUnique(target, method, args, stack);
+        } else {
+          return queue.push(target, method, args, stack);
+        }
+      },
</ins><span class="cx"> 
</span><del>-          Ember.beginPropertyChanges();
</del><ins>+      flush: function() {
+        var queues = this.queues,
+            queueNames = this.queueNames,
+            queueName, queue, queueItems, priorQueueNameIndex,
+            queueNameIndex = 0, numberOfQueues = queueNames.length;
</ins><span class="cx"> 
</span><del>-          Ember.tryFinally(tryable, Ember.endPropertyChanges);
</del><ins>+        outerloop:
+        while (queueNameIndex &lt; numberOfQueues) {
+          queueName = queueNames[queueNameIndex];
+          queue = queues[queueName];
+          queueItems = queue._queueBeingFlushed = queue._queue.slice();
+          queue._queue = [];
</ins><span class="cx"> 
</span><del>-          if (log) { Ember.Logger.log('End: Flush Sync Queue'); }
</del><ins>+          var options = queue.options,
+              before = options &amp;&amp; options.before,
+              after = options &amp;&amp; options.after,
+              target, method, args, stack,
+              queueIndex = 0, numberOfQueueItems = queueItems.length;
</ins><span class="cx"> 
</span><del>-        } else {
-          forEach.call(queue, iter);
</del><ins>+          if (numberOfQueueItems &amp;&amp; before) { before(); }
+          while (queueIndex &lt; numberOfQueueItems) {
+            target = queueItems[queueIndex];
+            method = queueItems[queueIndex+1];
+            args   = queueItems[queueIndex+2];
+            stack  = queueItems[queueIndex+3]; // Debugging assistance
+
+            if (typeof method === 'string') { method = target[method]; }
+
+            // method could have been nullified / canceled during flush
+            if (method) {
+              // TODO: error handling
+              if (args &amp;&amp; args.length &gt; 0) {
+                method.apply(target, args);
+              } else {
+                method.call(target);
+              }
+            }
+
+            queueIndex += 4;
+          }
+          queue._queueBeingFlushed = null;
+          if (numberOfQueueItems &amp;&amp; after) { after(); }
+
+          if ((priorQueueNameIndex = indexOfPriorQueueWithActions(this, queueNameIndex)) !== -1) {
+            queueNameIndex = priorQueueNameIndex;
+            continue outerloop;
+          }
+
+          queueNameIndex++;
</ins><span class="cx">         }
</span><span class="cx">       }
</span><ins>+    };
</ins><span class="cx"> 
</span><del>-    } else {
-      queueNames = Ember.run.queues;
-      len = queueNames.length;
-      idx = 0;
</del><ins>+    function indexOfPriorQueueWithActions(daq, currentQueueIndex) {
+      var queueName, queue;
</ins><span class="cx"> 
</span><del>-      outerloop:
-      while (idx &lt; len) {
-        queueName = queueNames[idx];
-        queue = this._queues &amp;&amp; this._queues[queueName];
-        delete this._queues[queueName];
</del><ins>+      for (var i = 0, l = currentQueueIndex; i &lt;= l; i++) {
+        queueName = daq.queueNames[i];
+        queue = daq.queues[queueName];
+        if (queue._queue.length) { return i; }
+      }
</ins><span class="cx"> 
</span><del>-        if (queue) {
-          // the sync phase is to allow property changes to propagate. don't
-          // invoke observers until that is finished.
-          if (queueName === 'sync') {
-            log = Ember.LOG_BINDINGS;
-            if (log) { Ember.Logger.log('Begin: Flush Sync Queue'); }
</del><ins>+      return -1;
+    }
</ins><span class="cx"> 
</span><del>-            Ember.beginPropertyChanges();
</del><span class="cx"> 
</span><del>-            Ember.tryFinally(tryable, Ember.endPropertyChanges);
</del><ins>+    __exports__.DeferredActionQueues = DeferredActionQueues;
+  });
</ins><span class="cx"> 
</span><del>-            if (log) { Ember.Logger.log('End: Flush Sync Queue'); }
</del><ins>+define(&quot;backburner&quot;,
+  [&quot;backburner/deferred_action_queues&quot;,&quot;exports&quot;],
+  function(__dependency1__, __exports__) {
+    &quot;use strict&quot;;
+    var DeferredActionQueues = __dependency1__.DeferredActionQueues;
+
+    var slice = [].slice,
+        pop = [].pop,
+        throttlers = [],
+        debouncees = [],
+        timers = [],
+        autorun, laterTimer, laterTimerExpiresAt,
+        global = this,
+        NUMBER = /\d+/;
+
+    function isCoercableNumber(number) {
+      return typeof number === 'number' || NUMBER.test(number);
+    }
+
+    function Backburner(queueNames, options) {
+      this.queueNames = queueNames;
+      this.options = options || {};
+      if (!this.options.defaultQueue) {
+        this.options.defaultQueue = queueNames[0];
+      }
+      this.instanceStack = [];
+    }
+
+    Backburner.prototype = {
+      queueNames: null,
+      options: null,
+      currentInstance: null,
+      instanceStack: null,
+
+      begin: function() {
+        var onBegin = this.options &amp;&amp; this.options.onBegin,
+            previousInstance = this.currentInstance;
+
+        if (previousInstance) {
+          this.instanceStack.push(previousInstance);
+        }
+
+        this.currentInstance = new DeferredActionQueues(this.queueNames, this.options);
+        if (onBegin) {
+          onBegin(this.currentInstance, previousInstance);
+        }
+      },
+
+      end: function() {
+        var onEnd = this.options &amp;&amp; this.options.onEnd,
+            currentInstance = this.currentInstance,
+            nextInstance = null;
+
+        try {
+          currentInstance.flush();
+        } finally {
+          this.currentInstance = null;
+
+          if (this.instanceStack.length) {
+            nextInstance = this.instanceStack.pop();
+            this.currentInstance = nextInstance;
+          }
+
+          if (onEnd) {
+            onEnd(currentInstance, nextInstance);
+          }
+        }
+      },
+
+      run: function(target, method /*, args */) {
+        var ret;
+        this.begin();
+
+        if (!method) {
+          method = target;
+          target = null;
+        }
+
+        if (typeof method === 'string') {
+          method = target[method];
+        }
+
+        // Prevent Safari double-finally.
+        var finallyAlreadyCalled = false;
+        try {
+          if (arguments.length &gt; 2) {
+            ret = method.apply(target, slice.call(arguments, 2));
</ins><span class="cx">           } else {
</span><del>-            forEach.call(queue, iter);
</del><ins>+            ret = method.call(target);
</ins><span class="cx">           }
</span><ins>+        } finally {
+          if (!finallyAlreadyCalled) {
+            finallyAlreadyCalled = true;
+            this.end();
+          }
</ins><span class="cx">         }
</span><ins>+        return ret;
+      },
</ins><span class="cx"> 
</span><del>-        // Loop through prior queues
-        for (var i = 0; i &lt;= idx; i++) {
-          if (this._queues &amp;&amp; this._queues[queueNames[i]]) {
-            // Start over at the first queue with contents
-            idx = i;
-            continue outerloop;
</del><ins>+      defer: function(queueName, target, method /* , args */) {
+        if (!method) {
+          method = target;
+          target = null;
+        }
+
+        if (typeof method === 'string') {
+          method = target[method];
+        }
+
+        var stack = this.DEBUG ? new Error() : undefined,
+            args = arguments.length &gt; 3 ? slice.call(arguments, 3) : undefined;
+        if (!this.currentInstance) { createAutorun(this); }
+        return this.currentInstance.schedule(queueName, target, method, args, false, stack);
+      },
+
+      deferOnce: function(queueName, target, method /* , args */) {
+        if (!method) {
+          method = target;
+          target = null;
+        }
+
+        if (typeof method === 'string') {
+          method = target[method];
+        }
+
+        var stack = this.DEBUG ? new Error() : undefined,
+            args = arguments.length &gt; 3 ? slice.call(arguments, 3) : undefined;
+        if (!this.currentInstance) { createAutorun(this); }
+        return this.currentInstance.schedule(queueName, target, method, args, true, stack);
+      },
+
+      setTimeout: function() {
+        var args = slice.call(arguments);
+        var length = args.length;
+        var method, wait, target;
+        var self = this;
+        var methodOrTarget, methodOrWait, methodOrArgs;
+
+        if (length === 0) {
+          return;
+        } else if (length === 1) {
+          method = args.shift();
+          wait = 0;
+        } else if (length === 2) {
+          methodOrTarget = args[0];
+          methodOrWait = args[1];
+
+          if (typeof methodOrWait === 'function' || typeof  methodOrTarget[methodOrWait] === 'function') {
+            target = args.shift();
+            method = args.shift();
+            wait = 0;
+          } else if (isCoercableNumber(methodOrWait)) {
+            method = args.shift();
+            wait = args.shift();
+          } else {
+            method = args.shift();
+            wait =  0;
</ins><span class="cx">           }
</span><ins>+        } else {
+          var last = args[args.length - 1];
+
+          if (isCoercableNumber(last)) {
+            wait = args.pop();
+          }
+
+          methodOrTarget = args[0];
+          methodOrArgs = args[1];
+
+          if (typeof methodOrArgs === 'function' || (typeof methodOrArgs === 'string' &amp;&amp;
+                                                     methodOrTarget !== null &amp;&amp;
+                                                     methodOrArgs in methodOrTarget)) {
+            target = args.shift();
+            method = args.shift();
+          } else {
+            method = args.shift();
+          }
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        idx++;
</del><ins>+        var executeAt = (+new Date()) + parseInt(wait, 10);
+
+        if (typeof method === 'string') {
+          method = target[method];
+        }
+
+        function fn() {
+          method.apply(target, args);
+        }
+
+        // find position to insert - TODO: binary search
+        var i, l;
+        for (i = 0, l = timers.length; i &lt; l; i += 2) {
+          if (executeAt &lt; timers[i]) { break; }
+        }
+
+        timers.splice(i, 0, executeAt, fn);
+
+        updateLaterTimer(self, executeAt, wait);
+
+        return fn;
+      },
+
+      throttle: function(target, method /* , args, wait */) {
+        var self = this,
+            args = arguments,
+            wait = parseInt(pop.call(args), 10),
+            throttler,
+            index,
+            timer;
+
+        index = findThrottler(target, method);
+        if (index &gt; -1) { return throttlers[index]; } // throttled
+
+        timer = global.setTimeout(function() {
+          self.run.apply(self, args);
+
+          var index = findThrottler(target, method);
+          if (index &gt; -1) { throttlers.splice(index, 1); }
+        }, wait);
+
+        throttler = [target, method, timer];
+
+        throttlers.push(throttler);
+
+        return throttler;
+      },
+
+      debounce: function(target, method /* , args, wait, [immediate] */) {
+        var self = this,
+            args = arguments,
+            immediate = pop.call(args),
+            wait,
+            index,
+            debouncee,
+            timer;
+
+        if (typeof immediate === &quot;number&quot; || typeof immediate === &quot;string&quot;) {
+          wait = immediate;
+          immediate = false;
+        } else {
+          wait = pop.call(args);
+        }
+
+        wait = parseInt(wait, 10);
+        // Remove debouncee
+        index = findDebouncee(target, method);
+
+        if (index &gt; -1) {
+          debouncee = debouncees[index];
+          debouncees.splice(index, 1);
+          clearTimeout(debouncee[2]);
+        }
+
+        timer = global.setTimeout(function() {
+          if (!immediate) {
+            self.run.apply(self, args);
+          }
+          var index = findDebouncee(target, method);
+          if (index &gt; -1) {
+            debouncees.splice(index, 1);
+          }
+        }, wait);
+
+        if (immediate &amp;&amp; index === -1) {
+          self.run.apply(self, args);
+        }
+
+        debouncee = [target, method, timer];
+
+        debouncees.push(debouncee);
+
+        return debouncee;
+      },
+
+      cancelTimers: function() {
+        var i, len;
+
+        for (i = 0, len = throttlers.length; i &lt; len; i++) {
+          clearTimeout(throttlers[i][2]);
+        }
+        throttlers = [];
+
+        for (i = 0, len = debouncees.length; i &lt; len; i++) {
+          clearTimeout(debouncees[i][2]);
+        }
+        debouncees = [];
+
+        if (laterTimer) {
+          clearTimeout(laterTimer);
+          laterTimer = null;
+        }
+        timers = [];
+
+        if (autorun) {
+          clearTimeout(autorun);
+          autorun = null;
+        }
+      },
+
+      hasTimers: function() {
+        return !!timers.length || autorun;
+      },
+
+      cancel: function(timer) {
+        var timerType = typeof timer;
+
+        if (timer &amp;&amp; timerType === 'object' &amp;&amp; timer.queue &amp;&amp; timer.method) { // we're cancelling a deferOnce
+          return timer.queue.cancel(timer);
+        } else if (timerType === 'function') { // we're cancelling a setTimeout
+          for (var i = 0, l = timers.length; i &lt; l; i += 2) {
+            if (timers[i + 1] === timer) {
+              timers.splice(i, 2); // remove the two elements
+              return true;
+            }
+          }
+        } else if (window.toString.call(timer) === &quot;[object Array]&quot;){ // we're cancelling a throttle or debounce
+          return this._cancelItem(findThrottler, throttlers, timer) || 
+                   this._cancelItem(findDebouncee, debouncees, timer);
+        } else {
+          return; // timer was null or not a timer
+        }
+      },
+
+      _cancelItem: function(findMethod, array, timer){
+        var item,
+            index;
+
+        if (timer.length &lt; 3) { return false; }
+
+        index = findMethod(timer[0], timer[1]);
+
+        if(index &gt; -1) {
+
+          item = array[index];
+
+          if(item[2] === timer[2]){
+            array.splice(index, 1);
+            clearTimeout(timer[2]);
+            return true;
+          }
+        }
+
+        return false;
</ins><span class="cx">       }
</span><ins>+
+    };
+
+    Backburner.prototype.schedule = Backburner.prototype.defer;
+    Backburner.prototype.scheduleOnce = Backburner.prototype.deferOnce;
+    Backburner.prototype.later = Backburner.prototype.setTimeout;
+
+    function createAutorun(backburner) {
+      backburner.begin();
+      autorun = global.setTimeout(function() {
+        autorun = null;
+        backburner.end();
+      });
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    timerMark = null;
</del><ins>+    function updateLaterTimer(self, executeAt, wait) {
+      if (!laterTimer || executeAt &lt; laterTimerExpiresAt) {
+        if (laterTimer) {
+          clearTimeout(laterTimer);
+        }
+        laterTimer = global.setTimeout(function() {
+          laterTimer = null;
+          laterTimerExpiresAt = null;
+          executeTimers(self);
+        }, wait);
+        laterTimerExpiresAt = executeAt;
+      }
+    }
</ins><span class="cx"> 
</span><del>-    return this;
-  }
</del><ins>+    function executeTimers(self) {
+      var now = +new Date(),
+          time, fns, i, l;
</ins><span class="cx"> 
</span><ins>+      self.run(function() {
+        // TODO: binary search
+        for (i = 0, l = timers.length; i &lt; l; i += 2) {
+          time = timers[i];
+          if (time &gt; now) { break; }
+        }
+
+        fns = timers.splice(0, i);
+
+        for (i = 1, l = fns.length; i &lt; l; i += 2) {
+          self.schedule(self.options.defaultQueue, null, fns[i]);
+        }
+      });
+
+      if (timers.length) {
+        updateLaterTimer(self, timers[0], timers[0] - now);
+      }
+    }
+
+    function findDebouncee(target, method) {
+      var debouncee,
+          index = -1;
+
+      for (var i = 0, l = debouncees.length; i &lt; l; i++) {
+        debouncee = debouncees[i];
+        if (debouncee[0] === target &amp;&amp; debouncee[1] === method) {
+          index = i;
+          break;
+        }
+      }
+
+      return index;
+    }
+
+    function findThrottler(target, method) {
+      var throttler,
+          index = -1;
+
+      for (var i = 0, l = throttlers.length; i &lt; l; i++) {
+        throttler = throttlers[i];
+        if (throttler[0] === target &amp;&amp; throttler[1] === method) {
+          index = i;
+          break;
+        }
+      }
+
+      return index;
+    }
+
+
+    __exports__.Backburner = Backburner;
+  });
+})();
+
+
+
+(function() {
+var onBegin = function(current) {
+  Ember.run.currentRunLoop = current;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-Ember.RunLoop = RunLoop;
</del><ins>+var onEnd = function(current, next) {
+  Ember.run.currentRunLoop = next;
+};
</ins><span class="cx"> 
</span><ins>+var Backburner = requireModule('backburner').Backburner,
+    backburner = new Backburner(['sync', 'actions', 'destroy'], {
+      sync: {
+        before: Ember.beginPropertyChanges,
+        after: Ember.endPropertyChanges
+      },
+      defaultQueue: 'actions',
+      onBegin: onBegin,
+      onEnd: onEnd
+    }),
+    slice = [].slice;
+
</ins><span class="cx"> // ..........................................................
</span><span class="cx"> // Ember.run - this is ideally the only public API the dev sees
</span><span class="cx"> //
</span><span class="lines">@@ -4226,8 +6152,8 @@
</span><span class="cx">   call.
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><del>-  Ember.run(function(){
-    // code to be execute within a RunLoop 
</del><ins>+  Ember.run(function() {
+    // code to be execute within a RunLoop
</ins><span class="cx">   });
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="lines">@@ -4243,30 +6169,84 @@
</span><span class="cx">   @return {Object} return value from invoking the passed function.
</span><span class="cx"> */
</span><span class="cx"> Ember.run = function(target, method) {
</span><del>-  var loop,
-  args = arguments;
-  run.begin();
</del><ins>+  var ret;
</ins><span class="cx"> 
</span><del>-  function tryable() {
-    if (target || method) {
-      return invoke(target, method, args, 2);
</del><ins>+  if (Ember.onerror) {
+    try {
+      ret = backburner.run.apply(backburner, arguments);
+    } catch (e) {
+      Ember.onerror(e);
</ins><span class="cx">     }
</span><ins>+  } else {
+    ret = backburner.run.apply(backburner, arguments);
</ins><span class="cx">   }
</span><span class="cx"> 
</span><del>-  return Ember.tryFinally(tryable, run.end);
</del><ins>+  return ret;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><ins>+/**
+  If no run-loop is present, it creates a new one. If a run loop is
+  present it will queue itself to run on the existing run-loops action
+  queue.
+
+  Please note: This is not for normal usage, and should be used sparingly.
+
+  If invoked when not within a run loop:
+
+  ```javascript
+  Ember.run.join(function() {
+    // creates a new run-loop
+  });
+  ```
+
+  Alternatively, if called within an existing run loop:
+
+  ```javascript
+  Ember.run(function() {
+    // creates a new run-loop
+    Ember.run.join(function() {
+      // joins with the existing run-loop, and queues for invocation on
+      // the existing run-loops action queue.
+    });
+  });
+  ```
+
+  @method join
+  @namespace Ember
+  @param {Object} [target] target of method to call
+  @param {Function|String} method Method to invoke.
+    May be a function or a string. If you pass a string
+    then it will be looked up on the passed target.
+  @param {Object} [args*] Any additional arguments you wish to pass to the method.
+  @return {Object} Return value from invoking the passed function. Please note,
+  when called within an existing loop, no return value is possible.
+*/
+Ember.run.join = function(target, method) {
+  if (!Ember.run.currentRunLoop) {
+    return Ember.run.apply(Ember.run, arguments);
+  }
+
+  var args = slice.call(arguments);
+  args.unshift('actions');
+  Ember.run.schedule.apply(Ember.run, args);
+};
+
+Ember.run.backburner = backburner;
+
</ins><span class="cx"> var run = Ember.run;
</span><span class="cx"> 
</span><ins>+Ember.run.currentRunLoop = null;
</ins><span class="cx"> 
</span><ins>+Ember.run.queues = backburner.queueNames;
+
</ins><span class="cx"> /**
</span><span class="cx">   Begins a new RunLoop. Any deferred actions invoked after the begin will
</span><span class="cx">   be buffered until you invoke a matching call to `Ember.run.end()`. This is
</span><del>-  an lower-level way to use a RunLoop instead of using `Ember.run()`.
</del><ins>+  a lower-level way to use a RunLoop instead of using `Ember.run()`.
</ins><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="cx">   Ember.run.begin();
</span><del>-  // code to be execute within a RunLoop 
</del><ins>+  // code to be execute within a RunLoop
</ins><span class="cx">   Ember.run.end();
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="lines">@@ -4274,7 +6254,7 @@
</span><span class="cx">   @return {void}
</span><span class="cx"> */
</span><span class="cx"> Ember.run.begin = function() {
</span><del>-  run.currentRunLoop = new RunLoop(run.currentRunLoop);
</del><ins>+  backburner.begin();
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><span class="lines">@@ -4284,7 +6264,7 @@
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="cx">   Ember.run.begin();
</span><del>-  // code to be execute within a RunLoop 
</del><ins>+  // code to be execute within a RunLoop
</ins><span class="cx">   Ember.run.end();
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="lines">@@ -4292,12 +6272,7 @@
</span><span class="cx">   @return {void}
</span><span class="cx"> */
</span><span class="cx"> Ember.run.end = function() {
</span><del>-  Ember.assert('must have a current run loop', run.currentRunLoop);
-
-  function tryable()   { run.currentRunLoop.end();  }
-  function finalizer() { run.currentRunLoop = run.currentRunLoop.prev(); }
-
-  Ember.tryFinally(tryable, finalizer);
</del><ins>+  backburner.end();
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><span class="lines">@@ -4308,9 +6283,8 @@
</span><span class="cx"> 
</span><span class="cx">   @property queues
</span><span class="cx">   @type Array
</span><del>-  @default ['sync', 'actions', 'destroy', 'timers']
</del><ins>+  @default ['sync', 'actions', 'destroy']
</ins><span class="cx"> */
</span><del>-Ember.run.queues = ['sync', 'actions', 'destroy', 'timers'];
</del><span class="cx"> 
</span><span class="cx"> /**
</span><span class="cx">   Adds the passed target/method and any optional arguments to the named
</span><span class="lines">@@ -4320,22 +6294,23 @@
</span><span class="cx"> 
</span><span class="cx">   At the end of a RunLoop, any methods scheduled in this way will be invoked.
</span><span class="cx">   Methods will be invoked in an order matching the named queues defined in
</span><del>-  the `run.queues` property.
</del><ins>+  the `Ember.run.queues` property.
</ins><span class="cx"> 
</span><span class="cx">   ```javascript
</span><del>-  Ember.run.schedule('timers', this, function(){
-    // this will be executed at the end of the RunLoop, when timers are run
-    console.log(&quot;scheduled on timers queue&quot;);
</del><ins>+  Ember.run.schedule('sync', this, function() {
+    // this will be executed in the first RunLoop queue, when bindings are synced
+    console.log(&quot;scheduled on sync queue&quot;);
</ins><span class="cx">   });
</span><span class="cx"> 
</span><del>-  Ember.run.schedule('sync', this, function(){
-    // this will be executed at the end of the RunLoop, when bindings are synced
-    console.log(&quot;scheduled on sync queue&quot;);
</del><ins>+  Ember.run.schedule('actions', this, function() {
+    // this will be executed in the 'actions' queue, after bindings have synced.
+    console.log(&quot;scheduled on actions queue&quot;);
</ins><span class="cx">   });
</span><span class="cx"> 
</span><del>-  // Note the functions will be run in order based on the run queues order. Output would be:
</del><ins>+  // Note the functions will be run in order based on the run queues order.
+  // Output would be:
</ins><span class="cx">   //   scheduled on sync queue
</span><del>-  //   scheduled on timers queue
</del><ins>+  //   scheduled on actions queue
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   @method schedule
</span><span class="lines">@@ -4349,70 +6324,28 @@
</span><span class="cx">   @return {void}
</span><span class="cx"> */
</span><span class="cx"> Ember.run.schedule = function(queue, target, method) {
</span><del>-  var loop = run.autorun();
-  loop.schedule.apply(loop, arguments);
</del><ins>+  checkAutoRun();
+  backburner.schedule.apply(backburner, arguments);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-var scheduledAutorun;
-function autorun() {
-  scheduledAutorun = null;
-  if (run.currentRunLoop) { run.end(); }
-}
-
</del><span class="cx"> // Used by global test teardown
</span><span class="cx"> Ember.run.hasScheduledTimers = function() {
</span><del>-  return !!(scheduledAutorun || scheduledLater || scheduledNext);
</del><ins>+  return backburner.hasTimers();
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> // Used by global test teardown
</span><span class="cx"> Ember.run.cancelTimers = function () {
</span><del>-  if (scheduledAutorun) {
-    clearTimeout(scheduledAutorun);
-    scheduledAutorun = null;
-  }
-  if (scheduledLater) {
-    clearTimeout(scheduledLater);
-    scheduledLater = null;
-  }
-  if (scheduledNext) {
-    clearTimeout(scheduledNext);
-    scheduledNext = null;
-  }
-  timers = {};
</del><ins>+  backburner.cancelTimers();
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  Begins a new RunLoop if necessary and schedules a timer to flush the
-  RunLoop at a later time. This method is used by parts of Ember to
-  ensure the RunLoop always finishes. You normally do not need to call this
-  method directly. Instead use `Ember.run()`
-
-  @method autorun
-  @example
-    Ember.run.autorun();
-  @return {Ember.RunLoop} the new current RunLoop
-*/
-Ember.run.autorun = function() {
-  if (!run.currentRunLoop) {
-    Ember.assert(&quot;You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in an Ember.run&quot;, !Ember.testing);
-
-    run.begin();
-
-    if (!scheduledAutorun) {
-      scheduledAutorun = setTimeout(autorun, 1);
-    }
-  }
-
-  return run.currentRunLoop;
-};
-
-/**
</del><span class="cx">   Immediately flushes any events scheduled in the 'sync' queue. Bindings
</span><span class="cx">   use this queue so this method is a useful way to immediately force all
</span><span class="cx">   bindings in the application to sync.
</span><span class="cx"> 
</span><span class="cx">   You should call this method anytime you need any changed state to propagate
</span><del>-  throughout the app immediately without repainting the UI.
</del><ins>+  throughout the app immediately without repainting the UI (which happens
+  in the later 'render' queue added by the `ember-views` package).
</ins><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="cx">   Ember.run.sync();
</span><span class="lines">@@ -4422,37 +6355,11 @@
</span><span class="cx">   @return {void}
</span><span class="cx"> */
</span><span class="cx"> Ember.run.sync = function() {
</span><del>-  run.autorun();
-  run.currentRunLoop.flush('sync');
</del><ins>+  if (backburner.currentInstance) {
+    backburner.currentInstance.queues.sync.flush();
+  }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-// ..........................................................
-// TIMERS
-//
-
-var timers = {}; // active timers...
-
-var scheduledLater;
-function invokeLaterTimers() {
-  scheduledLater = null;
-  var now = (+ new Date()), earliest = -1;
-  for (var key in timers) {
-    if (!timers.hasOwnProperty(key)) { continue; }
-    var timer = timers[key];
-    if (timer &amp;&amp; timer.expires) {
-      if (now &gt;= timer.expires) {
-        delete timers[key];
-        invoke(timer.target, timer.method, timer.args, 2);
-      } else {
-        if (earliest&lt;0 || (timer.expires &lt; earliest)) earliest=timer.expires;
-      }
-    }
-  }
-
-  // schedule next timeout to fire...
-  if (earliest &gt; 0) { scheduledLater = setTimeout(invokeLaterTimers, earliest-(+ new Date())); }
-}
-
</del><span class="cx"> /**
</span><span class="cx">   Invokes the passed target/method and optional arguments after a specified
</span><span class="cx">   period if time. The last parameter of this method must always be a number
</span><span class="lines">@@ -4464,7 +6371,7 @@
</span><span class="cx">   together, which is often more efficient than using a real setTimeout.
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><del>-  Ember.run.later(myContext, function(){
</del><ins>+  Ember.run.later(myContext, function() {
</ins><span class="cx">     // code here will execute within a RunLoop in about 500ms with this == myContext
</span><span class="cx">   }, 500);
</span><span class="cx">   ```
</span><span class="lines">@@ -4475,124 +6382,132 @@
</span><span class="cx">     If you pass a string it will be resolved on the
</span><span class="cx">     target at the time the method is invoked.
</span><span class="cx">   @param {Object} [args*] Optional arguments to pass to the timeout.
</span><del>-  @param {Number} wait
-    Number of milliseconds to wait.
</del><ins>+  @param {Number} wait Number of milliseconds to wait.
</ins><span class="cx">   @return {String} a string you can use to cancel the timer in
</span><del>-    {{#crossLink &quot;Ember/run.cancel&quot;}}{{/crossLink}} later.
</del><ins>+    `Ember.run.cancel` later.
</ins><span class="cx"> */
</span><span class="cx"> Ember.run.later = function(target, method) {
</span><del>-  var args, expires, timer, guid, wait;
</del><ins>+  return backburner.later.apply(backburner, arguments);
+};
</ins><span class="cx"> 
</span><del>-  // setTimeout compatibility...
-  if (arguments.length===2 &amp;&amp; 'function' === typeof target) {
-    wait   = method;
-    method = target;
-    target = undefined;
-    args   = [target, method];
-  } else {
-    args = slice.call(arguments);
-    wait = args.pop();
-  }
</del><ins>+/**
+  Schedule a function to run one time during the current RunLoop. This is equivalent
+  to calling `scheduleOnce` with the &quot;actions&quot; queue.
</ins><span class="cx"> 
</span><del>-  expires = (+ new Date()) + wait;
-  timer   = { target: target, method: method, expires: expires, args: args };
-  guid    = Ember.guidFor(timer);
-  timers[guid] = timer;
-  run.once(timers, invokeLaterTimers);
-  return guid;
</del><ins>+  @method once
+  @param {Object} [target] The target of the method to invoke.
+  @param {Function|String} method The method to invoke.
+    If you pass a string it will be resolved on the
+    target at the time the method is invoked.
+  @param {Object} [args*] Optional arguments to pass to the timeout.
+  @return {Object} timer
+*/
+Ember.run.once = function(target, method) {
+  checkAutoRun();
+  var args = slice.call(arguments);
+  args.unshift('actions');
+  return backburner.scheduleOnce.apply(backburner, args);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-function invokeOnceTimer(guid, onceTimers) {
-  if (onceTimers[this.tguid]) { delete onceTimers[this.tguid][this.mguid]; }
-  if (timers[guid]) { invoke(this.target, this.method, this.args); }
-  delete timers[guid];
-}
-
-function scheduleOnce(queue, target, method, args) {
-  var tguid = Ember.guidFor(target),
-    mguid = Ember.guidFor(method),
-    onceTimers = run.autorun().onceTimers,
-    guid = onceTimers[tguid] &amp;&amp; onceTimers[tguid][mguid],
-    timer;
-
-  if (guid &amp;&amp; timers[guid]) {
-    timers[guid].args = args; // replace args
-  } else {
-    timer = {
-      target: target,
-      method: method,
-      args:   args,
-      tguid:  tguid,
-      mguid:  mguid
-    };
-
-    guid  = Ember.guidFor(timer);
-    timers[guid] = timer;
-    if (!onceTimers[tguid]) { onceTimers[tguid] = {}; }
-    onceTimers[tguid][mguid] = guid; // so it isn't scheduled more than once
-
-    run.schedule(queue, timer, invokeOnceTimer, guid, onceTimers);
-  }
-
-  return guid;
-}
-
</del><span class="cx"> /**
</span><del>-  Schedules an item to run one time during the current RunLoop. Calling
-  this method with the same target/method combination will have no effect.
</del><ins>+  Schedules a function to run one time in a given queue of the current RunLoop.
+  Calling this method with the same queue/target/method combination will have
+  no effect (past the initial call).
</ins><span class="cx"> 
</span><span class="cx">   Note that although you can pass optional arguments these will not be
</span><span class="cx">   considered when looking for duplicates. New arguments will replace previous
</span><span class="cx">   calls.
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><del>-  Ember.run(function(){
-    var doFoo = function() { foo(); }
-    Ember.run.once(myContext, doFoo);
-    Ember.run.once(myContext, doFoo);
-    // doFoo will only be executed once at the end of the RunLoop
</del><ins>+  Ember.run(function() {
+    var sayHi = function() { console.log('hi'); }
+    Ember.run.scheduleOnce('afterRender', myContext, sayHi);
+    Ember.run.scheduleOnce('afterRender', myContext, sayHi);
+    // sayHi will only be executed once, in the afterRender queue of the RunLoop
</ins><span class="cx">   });
</span><span class="cx">   ```
</span><span class="cx"> 
</span><del>-  @method once
-  @param {Object} [target] target of method to invoke
</del><ins>+  Also note that passing an anonymous function to `Ember.run.scheduleOnce` will
+  not prevent additional calls with an identical anonymous function from
+  scheduling the items multiple times, e.g.:
+
+  ```javascript
+  function scheduleIt() {
+    Ember.run.scheduleOnce('actions', myContext, function() { console.log(&quot;Closure&quot;); });
+  }
+  scheduleIt();
+  scheduleIt();
+  // &quot;Closure&quot; will print twice, even though we're using `Ember.run.scheduleOnce`,
+  // because the function we pass to it is anonymous and won't match the
+  // previously scheduled operation.
+  ```
+
+  Available queues, and their order, can be found at `Ember.run.queues`
+
+  @method scheduleOnce
+  @param {String} [queue] The name of the queue to schedule against. Default queues are 'sync' and 'actions'.
+  @param {Object} [target] The target of the method to invoke.
</ins><span class="cx">   @param {Function|String} method The method to invoke.
</span><span class="cx">     If you pass a string it will be resolved on the
</span><span class="cx">     target at the time the method is invoked.
</span><span class="cx">   @param {Object} [args*] Optional arguments to pass to the timeout.
</span><span class="cx">   @return {Object} timer
</span><span class="cx"> */
</span><del>-Ember.run.once = function(target, method) {
-  return scheduleOnce('actions', target, method, slice.call(arguments, 2));
</del><ins>+Ember.run.scheduleOnce = function(queue, target, method) {
+  checkAutoRun();
+  return backburner.scheduleOnce.apply(backburner, arguments);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-Ember.run.scheduleOnce = function(queue, target, method, args) {
-  return scheduleOnce(queue, target, method, slice.call(arguments, 3));
-};
</del><ins>+/**
+  Schedules an item to run from within a separate run loop, after
+  control has been returned to the system. This is equivalent to calling
+  `Ember.run.later` with a wait time of 1ms.
</ins><span class="cx"> 
</span><del>-var scheduledNext;
-function invokeNextTimers() {
-  scheduledNext = null;
-  for(var key in timers) {
-    if (!timers.hasOwnProperty(key)) { continue; }
-    var timer = timers[key];
-    if (timer.next) {
-      delete timers[key];
-      invoke(timer.target, timer.method, timer.args, 2);
-    }
-  }
-}
</del><ins>+  ```javascript
+  Ember.run.next(myContext, function() {
+    // code to be executed in the next run loop,
+    // which will be scheduled after the current one
+  });
+  ```
</ins><span class="cx"> 
</span><del>-/**
-  Schedules an item to run after control has been returned to the system.
-  This is often equivalent to calling `setTimeout(function() {}, 1)`.
</del><ins>+  Multiple operations scheduled with `Ember.run.next` will coalesce
+  into the same later run loop, along with any other operations
+  scheduled by `Ember.run.later` that expire right around the same
+  time that `Ember.run.next` operations will fire.
</ins><span class="cx"> 
</span><ins>+  Note that there are often alternatives to using `Ember.run.next`.
+  For instance, if you'd like to schedule an operation to happen
+  after all DOM element operations have completed within the current
+  run loop, you can make use of the `afterRender` run loop queue (added
+  by the `ember-views` package, along with the preceding `render` queue
+  where all the DOM element operations happen). Example:
+
</ins><span class="cx">   ```javascript
</span><del>-  Ember.run.next(myContext, function(){
-    // code to be executed in the next RunLoop, which will be scheduled after the current one
</del><ins>+  App.MyCollectionView = Ember.CollectionView.extend({
+    didInsertElement: function() {
+      Ember.run.scheduleOnce('afterRender', this, 'processChildElements');
+    },
+    processChildElements: function() {
+      // ... do something with collectionView's child view
+      // elements after they've finished rendering, which
+      // can't be done within the CollectionView's
+      // `didInsertElement` hook because that gets run
+      // before the child elements have been added to the DOM.
+    }
</ins><span class="cx">   });
</span><span class="cx">   ```
</span><span class="cx"> 
</span><ins>+  One benefit of the above approach compared to using `Ember.run.next` is
+  that you will be able to perform DOM/CSS operations before unprocessed
+  elements are rendered to the screen, which may prevent flickering or
+  other artifacts caused by delaying processing until after rendering.
+
+  The other major benefit to the above approach is that `Ember.run.next`
+  introduces an element of non-determinism, which can make things much
+  harder to test, due to its reliance on `setTimeout`; it's much harder
+  to guarantee the order of scheduled operations when they are scheduled
+  outside of the current run loop, i.e. with `Ember.run.next`.
+
</ins><span class="cx">   @method next
</span><span class="cx">   @param {Object} [target] target of method to invoke
</span><span class="cx">   @param {Function|String} method The method to invoke.
</span><span class="lines">@@ -4601,20 +6516,10 @@
</span><span class="cx">   @param {Object} [args*] Optional arguments to pass to the timeout.
</span><span class="cx">   @return {Object} timer
</span><span class="cx"> */
</span><del>-Ember.run.next = function(target, method) {
-  var guid,
-      timer = {
-        target: target,
-        method: method,
-        args: slice.call(arguments),
-        next: true
-      };
-
-  guid = Ember.guidFor(timer);
-  timers[guid] = timer;
-
-  if (!scheduledNext) { scheduledNext = setTimeout(invokeNextTimers, 1); }
-  return guid;
</del><ins>+Ember.run.next = function() {
+  var args = slice.call(arguments);
+  args.push(1);
+  return backburner.later.apply(backburner, args);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><span class="lines">@@ -4622,17 +6527,17 @@
</span><span class="cx">   `Ember.run.once()`, or `Ember.run.next()`.
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><del>-  var runNext = Ember.run.next(myContext, function(){
</del><ins>+  var runNext = Ember.run.next(myContext, function() {
</ins><span class="cx">     // will not be executed
</span><span class="cx">   });
</span><span class="cx">   Ember.run.cancel(runNext);
</span><span class="cx"> 
</span><del>-  var runLater = Ember.run.later(myContext, function(){
</del><ins>+  var runLater = Ember.run.later(myContext, function() {
</ins><span class="cx">     // will not be executed
</span><span class="cx">   }, 500);
</span><span class="cx">   Ember.run.cancel(runLater);
</span><span class="cx"> 
</span><del>-  var runOnce = Ember.run.once(myContext, function(){
</del><ins>+  var runOnce = Ember.run.once(myContext, function() {
</ins><span class="cx">     // will not be executed
</span><span class="cx">   });
</span><span class="cx">   Ember.run.cancel(runOnce);
</span><span class="lines">@@ -4643,17 +6548,102 @@
</span><span class="cx">   @return {void}
</span><span class="cx"> */
</span><span class="cx"> Ember.run.cancel = function(timer) {
</span><del>-  delete timers[timer];
</del><ins>+  return backburner.cancel(timer);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><ins>+/**
+  Delay calling the target method until the debounce period has elapsed
+  with no additional debounce calls. If `debounce` is called again before
+  the specified time has elapsed, the timer is reset and the entire period
+  must pass again before the target method is called.
+
+  This method should be used when an event may be called multiple times
+  but the action should only be called once when the event is done firing.
+  A common example is for scroll events where you only want updates to
+  happen once scrolling has ceased.
+
+  ```javascript
+    var myFunc = function() { console.log(this.name + ' ran.'); };
+    var myContext = {name: 'debounce'};
+
+    Ember.run.debounce(myContext, myFunc, 150);
+
+    // less than 150ms passes
+
+    Ember.run.debounce(myContext, myFunc, 150);
+
+    // 150ms passes
+    // myFunc is invoked with context myContext
+    // console logs 'debounce ran.' one time.
+  ```
+
+  @method debounce
+  @param {Object} [target] target of method to invoke
+  @param {Function|String} method The method to invoke.
+    May be a function or a string. If you pass a string
+    then it will be looked up on the passed target.
+  @param {Object} [args*] Optional arguments to pass to the timeout.
+  @param {Number} wait Number of milliseconds to wait.
+  @param {Boolean} immediate Trigger the function on the leading instead of the trailing edge of the wait interval.
+  @return {void}
+*/
+Ember.run.debounce = function() {
+  return backburner.debounce.apply(backburner, arguments);
+};
+
+/**
+  Ensure that the target method is never called more frequently than
+  the specified spacing period.
+
+  ```javascript
+    var myFunc = function() { console.log(this.name + ' ran.'); };
+    var myContext = {name: 'throttle'};
+
+    Ember.run.throttle(myContext, myFunc, 150);
+
+    // 50ms passes
+    Ember.run.throttle(myContext, myFunc, 150);
+
+    // 50ms passes
+    Ember.run.throttle(myContext, myFunc, 150);
+
+    // 50ms passes
+    Ember.run.throttle(myContext, myFunc, 150);
+
+    // 150ms passes
+    // myFunc is invoked with context myContext
+    // console logs 'throttle ran.' twice, 150ms apart.
+  ```
+
+  @method throttle
+  @param {Object} [target] target of method to invoke
+  @param {Function|String} method The method to invoke.
+    May be a function or a string. If you pass a string
+    then it will be looked up on the passed target.
+  @param {Object} [args*] Optional arguments to pass to the timeout.
+  @param {Number} spacing Number of milliseconds to space out requests.
+  @return {void}
+*/
+Ember.run.throttle = function() {
+  return backburner.throttle.apply(backburner, arguments);
+};
+
+// Make sure it's not an autorun during testing
+function checkAutoRun() {
+  if (!Ember.run.currentRunLoop) {
+    Ember.assert(&quot;You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in an Ember.run&quot;, !Ember.testing);
+  }
+}
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><span class="cx"> // Ember.Logger
</span><del>-// get, set, trySet
-// guidFor, isArray, meta
</del><ins>+// get
+// set
+// guidFor, meta
</ins><span class="cx"> // addObserver, removeObserver
</span><span class="cx"> // Ember.run.schedule
</span><span class="cx"> /**
</span><span class="lines">@@ -4679,9 +6669,22 @@
</span><span class="cx"> var get     = Ember.get,
</span><span class="cx">     set     = Ember.set,
</span><span class="cx">     guidFor = Ember.guidFor,
</span><del>-    isGlobalPath = Ember.isGlobalPath;
</del><ins>+    IS_GLOBAL = /^([A-Z$]|([0-9][A-Z$]))/;
</ins><span class="cx"> 
</span><ins>+/**
+  Returns true if the provided path is global (e.g., `MyApp.fooController.bar`)
+  instead of local (`foo.bar.baz`).
</ins><span class="cx"> 
</span><ins>+  @method isGlobalPath
+  @for Ember
+  @private
+  @param {String} path
+  @return Boolean
+*/
+var isGlobalPath = Ember.isGlobalPath = function(path) {
+  return IS_GLOBAL.test(path);
+};
+
</ins><span class="cx"> function getWithGlobals(obj, path) {
</span><span class="cx">   return get(isGlobalPath(path) ? Ember.lookup : obj, path);
</span><span class="cx"> }
</span><span class="lines">@@ -4707,7 +6710,7 @@
</span><span class="cx">     This copies the Binding so it can be connected to another object.
</span><span class="cx"> 
</span><span class="cx">     @method copy
</span><del>-    @return {Ember.Binding}
</del><ins>+    @return {Ember.Binding} `this`
</ins><span class="cx">   */
</span><span class="cx">   copy: function () {
</span><span class="cx">     var copy = new Binding(this._to, this._from);
</span><span class="lines">@@ -4729,7 +6732,7 @@
</span><span class="cx">     `get()` - see that method for more information.
</span><span class="cx"> 
</span><span class="cx">     @method from
</span><del>-    @param {String} propertyPath the property path to connect to
</del><ins>+    @param {String} path the property path to connect to
</ins><span class="cx">     @return {Ember.Binding} `this`
</span><span class="cx">   */
</span><span class="cx">   from: function(path) {
</span><span class="lines">@@ -4747,7 +6750,7 @@
</span><span class="cx">     `get()` - see that method for more information.
</span><span class="cx"> 
</span><span class="cx">     @method to
</span><del>-    @param {String|Tuple} propertyPath A property path or tuple
</del><ins>+    @param {String|Tuple} path A property path or tuple
</ins><span class="cx">     @return {Ember.Binding} `this`
</span><span class="cx">   */
</span><span class="cx">   to: function(path) {
</span><span class="lines">@@ -4769,6 +6772,10 @@
</span><span class="cx">     return this;
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    @method toString
+    @return {String} string representation of binding
+  */
</ins><span class="cx">   toString: function() {
</span><span class="cx">     var oneWay = this._oneWay ? '[oneWay]' : '';
</span><span class="cx">     return &quot;Ember.Binding&lt;&quot; + guidFor(this) + &quot;&gt;(&quot; + this._from + &quot; -&gt; &quot; + this._to + &quot;)&quot; + oneWay;
</span><span class="lines">@@ -4911,8 +6918,8 @@
</span><span class="cx"> 
</span><span class="cx"> mixinProperties(Binding, {
</span><span class="cx"> 
</span><del>-  /**
-    See {{#crossLink &quot;Ember.Binding/from&quot;}}{{/crossLink}}
</del><ins>+  /*
+    See `Ember.Binding.from`.
</ins><span class="cx"> 
</span><span class="cx">     @method from
</span><span class="cx">     @static
</span><span class="lines">@@ -4922,8 +6929,8 @@
</span><span class="cx">     return binding.from.apply(binding, arguments);
</span><span class="cx">   },
</span><span class="cx"> 
</span><del>-  /**
-    See {{#crossLink &quot;Ember.Binding/to&quot;}}{{/crossLink}}
</del><ins>+  /*
+    See `Ember.Binding.to`.
</ins><span class="cx"> 
</span><span class="cx">     @method to
</span><span class="cx">     @static
</span><span class="lines">@@ -4940,13 +6947,14 @@
</span><span class="cx">     This means that if you change the &quot;to&quot; side directly, the &quot;from&quot; side may have
</span><span class="cx">     a different value.
</span><span class="cx"> 
</span><del>-    See {{#crossLink &quot;Binding/oneWay&quot;}}{{/crossLink}}
</del><ins>+    See `Binding.oneWay`.
</ins><span class="cx"> 
</span><span class="cx">     @method oneWay
</span><span class="cx">     @param {String} from from path.
</span><span class="cx">     @param {Boolean} [flag] (Optional) passing nothing here will make the
</span><span class="cx">       binding `oneWay`. You can instead pass `false` to disable `oneWay`, making the
</span><span class="cx">       binding two way again.
</span><ins>+    @return {Ember.Binding} `this`
</ins><span class="cx">   */
</span><span class="cx">   oneWay: function(from, flag) {
</span><span class="cx">     var C = this, binding = new C(null, from);
</span><span class="lines">@@ -4968,7 +6976,7 @@
</span><span class="cx">   Properties ending in a `Binding` suffix will be converted to `Ember.Binding`
</span><span class="cx">   instances. The value of this property should be a string representing a path
</span><span class="cx">   to another object or a custom binding instanced created using Binding helpers
</span><del>-  (see &quot;Customizing Your Bindings&quot;):
</del><ins>+  (see &quot;One Way Bindings&quot;):
</ins><span class="cx"> 
</span><span class="cx">   ```
</span><span class="cx">   valueBinding: &quot;MyApp.someController.title&quot;
</span><span class="lines">@@ -5001,7 +7009,7 @@
</span><span class="cx"> 
</span><span class="cx">   You should consider using one way bindings anytime you have an object that
</span><span class="cx">   may be created frequently and you do not intend to change a property; only
</span><del>-  to monitor it for changes. (such as in the example above).
</del><ins>+  to monitor it for changes (such as in the example above).
</ins><span class="cx"> 
</span><span class="cx">   ## Adding Bindings Manually
</span><span class="cx"> 
</span><span class="lines">@@ -5111,7 +7119,8 @@
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><span class="cx"> /**
</span><del>-@module ember-metal
</del><ins>+@module ember
+@submodule ember-metal
</ins><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> var Mixin, REQUIRED, Alias,
</span><span class="lines">@@ -5119,11 +7128,11 @@
</span><span class="cx">     a_indexOf = Ember.ArrayPolyfills.indexOf,
</span><span class="cx">     a_forEach = Ember.ArrayPolyfills.forEach,
</span><span class="cx">     a_slice = [].slice,
</span><del>-    EMPTY_META = {}, // dummy for non-writable meta
</del><span class="cx">     o_create = Ember.create,
</span><span class="cx">     defineProperty = Ember.defineProperty,
</span><span class="cx">     guidFor = Ember.guidFor;
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> function mixinsMeta(obj) {
</span><span class="cx">   var m = Ember.meta(obj, true), ret = m.mixins;
</span><span class="cx">   if (!ret) {
</span><span class="lines">@@ -5171,13 +7180,13 @@
</span><span class="cx">   }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function concatenatedProperties(props, values, base) {
</del><ins>+function concatenatedMixinProperties(concatProp, props, values, base) {
</ins><span class="cx">   var concats;
</span><span class="cx"> 
</span><span class="cx">   // reset before adding each new mixin to pickup concats from previous
</span><del>-  concats = values.concatenatedProperties || base.concatenatedProperties;
-  if (props.concatenatedProperties) {
-    concats = concats ? concats.concat(props.concatenatedProperties) : props.concatenatedProperties;
</del><ins>+  concats = values[concatProp] || base[concatProp];
+  if (props[concatProp]) {
+    concats = concats ? concats.concat(props[concatProp]) : props[concatProp];
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   return concats;
</span><span class="lines">@@ -5244,7 +7253,28 @@
</span><span class="cx">   }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function addNormalizedProperty(base, key, value, meta, descs, values, concats) {
</del><ins>+function applyMergedProperties(obj, key, value, values) {
+  var baseValue = values[key] || obj[key];
+
+  if (!baseValue) { return value; }
+
+  var newBase = Ember.merge({}, baseValue);
+  for (var prop in value) {
+    if (!value.hasOwnProperty(prop)) { continue; }
+
+    var propValue = value[prop];
+    if (isMethod(propValue)) {
+      // TODO: support for Computed Properties, etc?
+      newBase[prop] = giveMethodSuper(obj, prop, propValue, baseValue, {});
+    } else {
+      newBase[prop] = propValue;
+    }
+  }
+
+  return newBase;
+}
+
+function addNormalizedProperty(base, key, value, meta, descs, values, concats, mergings) {
</ins><span class="cx">   if (value instanceof Ember.Descriptor) {
</span><span class="cx">     if (value === REQUIRED &amp;&amp; descs[key]) { return CONTINUE; }
</span><span class="cx"> 
</span><span class="lines">@@ -5257,11 +7287,14 @@
</span><span class="cx">     descs[key]  = value;
</span><span class="cx">     values[key] = undefined;
</span><span class="cx">   } else {
</span><del>-    // impl super if needed...
-    if (isMethod(value)) {
</del><ins>+    if ((concats &amp;&amp; a_indexOf.call(concats, key) &gt;= 0) ||
+                key === 'concatenatedProperties' ||
+                key === 'mergedProperties') {
+      value = applyConcatenatedProperties(base, key, value, values);
+    } else if ((mergings &amp;&amp; a_indexOf.call(mergings, key) &gt;= 0)) {
+      value = applyMergedProperties(base, key, value, values);
+    } else if (isMethod(value)) {
</ins><span class="cx">       value = giveMethodSuper(base, key, value, values, descs);
</span><del>-    } else if ((concats &amp;&amp; a_indexOf.call(concats, key) &gt;= 0) || key === 'concatenatedProperties') {
-      value = applyConcatenatedProperties(base, key, value, values);
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     descs[key] = undefined;
</span><span class="lines">@@ -5269,8 +7302,8 @@
</span><span class="cx">   }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function mergeMixins(mixins, m, descs, values, base) {
-  var mixin, props, key, concats, meta;
</del><ins>+function mergeMixins(mixins, m, descs, values, base, keys) {
+  var mixin, props, key, concats, mergings, meta;
</ins><span class="cx"> 
</span><span class="cx">   function removeKeys(keyName) {
</span><span class="cx">     delete descs[keyName];
</span><span class="lines">@@ -5279,37 +7312,33 @@
</span><span class="cx"> 
</span><span class="cx">   for(var i=0, l=mixins.length; i&lt;l; i++) {
</span><span class="cx">     mixin = mixins[i];
</span><del>-    Ember.assert('Expected hash or Mixin instance, got ' + Object.prototype.toString.call(mixin), typeof mixin === 'object' &amp;&amp; mixin !== null &amp;&amp; Object.prototype.toString.call(mixin) !== '[object Array]');
</del><ins>+    Ember.assert('Expected hash or Mixin instance, got ' + Object.prototype.toString.call(mixin),
+                 typeof mixin === 'object' &amp;&amp; mixin !== null &amp;&amp; Object.prototype.toString.call(mixin) !== '[object Array]');
</ins><span class="cx"> 
</span><span class="cx">     props = mixinProperties(m, mixin);
</span><span class="cx">     if (props === CONTINUE) { continue; }
</span><span class="cx"> 
</span><span class="cx">     if (props) {
</span><span class="cx">       meta = Ember.meta(base);
</span><del>-      concats = concatenatedProperties(props, values, base);
</del><ins>+      if (base.willMergeMixin) { base.willMergeMixin(props); }
+      concats = concatenatedMixinProperties('concatenatedProperties', props, values, base);
+      mergings = concatenatedMixinProperties('mergedProperties', props, values, base);
</ins><span class="cx"> 
</span><span class="cx">       for (key in props) {
</span><span class="cx">         if (!props.hasOwnProperty(key)) { continue; }
</span><del>-        addNormalizedProperty(base, key, props[key], meta, descs, values, concats);
</del><ins>+        keys.push(key);
+        addNormalizedProperty(base, key, props[key], meta, descs, values, concats, mergings);
</ins><span class="cx">       }
</span><span class="cx"> 
</span><span class="cx">       // manually copy toString() because some JS engines do not enumerate it
</span><span class="cx">       if (props.hasOwnProperty('toString')) { base.toString = props.toString; }
</span><span class="cx">     } else if (mixin.mixins) {
</span><del>-      mergeMixins(mixin.mixins, m, descs, values, base);
</del><ins>+      mergeMixins(mixin.mixins, m, descs, values, base, keys);
</ins><span class="cx">       if (mixin._without) { a_forEach.call(mixin._without, removeKeys); }
</span><span class="cx">     }
</span><span class="cx">   }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function writableReq(obj) {
-  var m = Ember.meta(obj), req = m.required;
-  if (!req || !m.hasOwnProperty('required')) {
-    req = m.required = req ? o_create(req) : {};
-  }
-  return req;
-}
-
</del><span class="cx"> var IS_BINDING = Ember.IS_BINDING = /^.+Binding$/;
</span><span class="cx"> 
</span><span class="cx"> function detectBinding(obj, key, value, m) {
</span><span class="lines">@@ -5368,42 +7397,48 @@
</span><span class="cx">   return { desc: desc, value: value };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function updateObservers(obj, key, observer, observerKey, method) {
-  if ('function' !== typeof observer) { return; }
</del><ins>+function updateObserversAndListeners(obj, key, observerOrListener, pathsKey, updateMethod) {
+  var paths = observerOrListener[pathsKey];
</ins><span class="cx"> 
</span><del>-  var paths = observer[observerKey];
-
</del><span class="cx">   if (paths) {
</span><span class="cx">     for (var i=0, l=paths.length; i&lt;l; i++) {
</span><del>-      Ember[method](obj, paths[i], null, key);
</del><ins>+      Ember[updateMethod](obj, paths[i], null, key);
</ins><span class="cx">     }
</span><span class="cx">   }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function replaceObservers(obj, key, observer) {
-  var prevObserver = obj[key];
</del><ins>+function replaceObserversAndListeners(obj, key, observerOrListener) {
+  var prev = obj[key];
</ins><span class="cx"> 
</span><del>-  updateObservers(obj, key, prevObserver, '__ember_observesBefore__', 'removeBeforeObserver');
-  updateObservers(obj, key, prevObserver, '__ember_observes__', 'removeObserver');
</del><ins>+  if ('function' === typeof prev) {
+    updateObserversAndListeners(obj, key, prev, '__ember_observesBefore__', 'removeBeforeObserver');
+    updateObserversAndListeners(obj, key, prev, '__ember_observes__', 'removeObserver');
+    updateObserversAndListeners(obj, key, prev, '__ember_listens__', 'removeListener');
+  }
</ins><span class="cx"> 
</span><del>-  updateObservers(obj, key, observer, '__ember_observesBefore__', 'addBeforeObserver');
-  updateObservers(obj, key, observer, '__ember_observes__', 'addObserver');
</del><ins>+  if ('function' === typeof observerOrListener) {
+    updateObserversAndListeners(obj, key, observerOrListener, '__ember_observesBefore__', 'addBeforeObserver');
+    updateObserversAndListeners(obj, key, observerOrListener, '__ember_observes__', 'addObserver');
+    updateObserversAndListeners(obj, key, observerOrListener, '__ember_listens__', 'addListener');
+  }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function applyMixin(obj, mixins, partial) {
</span><span class="cx">   var descs = {}, values = {}, m = Ember.meta(obj),
</span><del>-      key, value, desc;
</del><ins>+      key, value, desc, keys = [];
</ins><span class="cx"> 
</span><span class="cx">   // Go through all mixins and hashes passed in, and:
</span><span class="cx">   //
</span><span class="cx">   // * Handle concatenated properties
</span><ins>+  // * Handle merged properties
</ins><span class="cx">   // * Set up _super wrapping if necessary
</span><span class="cx">   // * Set up computed property descriptors
</span><span class="cx">   // * Copying `toString` in broken browsers
</span><del>-  mergeMixins(mixins, mixinsMeta(obj), descs, values, obj);
</del><ins>+  mergeMixins(mixins, mixinsMeta(obj), descs, values, obj, keys);
</ins><span class="cx"> 
</span><del>-  for(key in values) {
-    if (key === 'contructor' || !values.hasOwnProperty(key)) { continue; }
</del><ins>+  for(var i = 0, l = keys.length; i &lt; l; i++) {
+    key = keys[i];
+    if (key === 'constructor' || !values.hasOwnProperty(key)) { continue; }
</ins><span class="cx"> 
</span><span class="cx">     desc = descs[key];
</span><span class="cx">     value = values[key];
</span><span class="lines">@@ -5418,7 +7453,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (desc === undefined &amp;&amp; value === undefined) { continue; }
</span><span class="cx"> 
</span><del>-    replaceObservers(obj, key, value);
</del><ins>+    replaceObserversAndListeners(obj, key, value);
</ins><span class="cx">     detectBinding(obj, key, value, m);
</span><span class="cx">     defineProperty(obj, key, desc, value, m);
</span><span class="cx">   }
</span><span class="lines">@@ -5457,9 +7492,9 @@
</span><span class="cx">   });
</span><span class="cx"> 
</span><span class="cx">   // Mix mixins into classes by passing them as the first arguments to
</span><del>-  // .extend or .create.
</del><ins>+  // .extend.
</ins><span class="cx">   App.CommentView = Ember.View.extend(App.Editable, {
</span><del>-    template: Ember.Handlebars.compile('{{#if isEditing}}...{{else}}...{{/if}}')
</del><ins>+    template: Ember.Handlebars.compile('{{#if view.isEditing}}...{{else}}...{{/if}}')
</ins><span class="cx">   });
</span><span class="cx"> 
</span><span class="cx">   commentView = App.CommentView.create();
</span><span class="lines">@@ -5469,6 +7504,31 @@
</span><span class="cx">   Note that Mixins are created with `Ember.Mixin.create`, not
</span><span class="cx">   `Ember.Mixin.extend`.
</span><span class="cx"> 
</span><ins>+  Note that mixins extend a constructor's prototype so arrays and object literals
+  defined as properties will be shared amongst objects that implement the mixin.
+  If you want to define an property in a mixin that is not shared, you can define
+  it either as a computed property or have it be created on initialization of the object.
+
+  ```javascript
+  //filters array will be shared amongst any object implementing mixin
+  App.Filterable = Ember.Mixin.create({
+    filters: Ember.A()
+  });
+
+  //filters will be a separate  array for every object implementing the mixin
+  App.Filterable = Ember.Mixin.create({
+    filters: Ember.computed(function(){return Ember.A();})
+  });
+
+  //filters will be created as a separate array during the object's initialization
+  App.Filterable = Ember.Mixin.create({
+    init: function() {
+      this._super();
+      this.set(&quot;filters&quot;, Ember.A());
+    }
+  });
+  ```
+
</ins><span class="cx">   @class Mixin
</span><span class="cx">   @namespace Ember
</span><span class="cx"> */
</span><span class="lines">@@ -5476,6 +7536,12 @@
</span><span class="cx"> 
</span><span class="cx"> Mixin = Ember.Mixin;
</span><span class="cx"> 
</span><ins>+Mixin.prototype = {
+  properties: null,
+  mixins: null,
+  ownerConstructor: null
+};
+
</ins><span class="cx"> Mixin._apply = applyMixin;
</span><span class="cx"> 
</span><span class="cx"> Mixin.applyPartial = function(obj) {
</span><span class="lines">@@ -5520,7 +7586,8 @@
</span><span class="cx"> 
</span><span class="cx">   for(idx=0; idx &lt; len; idx++) {
</span><span class="cx">     mixin = arguments[idx];
</span><del>-    Ember.assert('Expected hash or Mixin instance, got ' + Object.prototype.toString.call(mixin), typeof mixin === 'object' &amp;&amp; mixin !== null &amp;&amp; Object.prototype.toString.call(mixin) !== '[object Array]');
</del><ins>+    Ember.assert('Expected hash or Mixin instance, got ' + Object.prototype.toString.call(mixin),
+                 typeof mixin === 'object' &amp;&amp; mixin !== null &amp;&amp; Object.prototype.toString.call(mixin) !== '[object Array]');
</ins><span class="cx"> 
</span><span class="cx">     if (mixin instanceof Mixin) {
</span><span class="cx">       mixins.push(mixin);
</span><span class="lines">@@ -5647,7 +7714,7 @@
</span><span class="cx">   App.PaintSample = Ember.Object.extend({
</span><span class="cx">     color: 'red',
</span><span class="cx">     colour: Ember.alias('color'),
</span><del>-    name: function(){
</del><ins>+    name: function() {
</ins><span class="cx">       return &quot;Zed&quot;;
</span><span class="cx">     },
</span><span class="cx">     moniker: Ember.alias(&quot;name&quot;)
</span><span class="lines">@@ -5665,17 +7732,16 @@
</span><span class="cx">   @deprecated Use `Ember.aliasMethod` or `Ember.computed.alias` instead
</span><span class="cx"> */
</span><span class="cx"> Ember.alias = function(methodName) {
</span><ins>+  Ember.deprecate(&quot;Ember.alias is deprecated. Please use Ember.aliasMethod or Ember.computed.alias instead.&quot;);
</ins><span class="cx">   return new Alias(methodName);
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-Ember.deprecateFunc(&quot;Ember.alias is deprecated. Please use Ember.aliasMethod or Ember.computed.alias instead.&quot;, Ember.alias);
-
</del><span class="cx"> /**
</span><span class="cx">   Makes a method available via an additional name.
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="cx">   App.Person = Ember.Object.extend({
</span><del>-    name: function(){
</del><ins>+    name: function() {
</ins><span class="cx">       return 'Tomhuda Katzdale';
</span><span class="cx">     },
</span><span class="cx">     moniker: Ember.aliasMethod('name')
</span><span class="lines">@@ -5698,25 +7764,72 @@
</span><span class="cx"> //
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+  Specify a method that observes property changes.
+
+  ```javascript
+  Ember.Object.extend({
+    valueObserver: Ember.observer('value', function() {
+      // Executes whenever the &quot;value&quot; property changes
+    })
+  });
+  ```
+
+  In the future this method may become asynchronous. If you want to ensure
+  synchronous behavior, use `immediateObserver`.
+
+  Also available as `Function.prototype.observes` if prototype extensions are
+  enabled.
+
</ins><span class="cx">   @method observer
</span><span class="cx">   @for Ember
</span><ins>+  @param {String} propertyNames*
</ins><span class="cx">   @param {Function} func
</span><del>-  @param {String} propertyNames*
</del><span class="cx">   @return func
</span><span class="cx"> */
</span><del>-Ember.observer = function(func) {
-  var paths = a_slice.call(arguments, 1);
</del><ins>+Ember.observer = function() {
+  var func  = a_slice.call(arguments, -1)[0];
+  var paths;
+
+  
+    paths = a_slice.call(arguments, 0, -1);
+
+    if (typeof func !== &quot;function&quot;) {
+      // revert to old, soft-deprecated argument ordering
+
+      func  = arguments[0];
+      paths = a_slice.call(arguments, 1);
+    }
+  
+
+  if (typeof func !== &quot;function&quot;) {
+    throw new Ember.Error(&quot;Ember.observer called without a function&quot;);
+  }
+
</ins><span class="cx">   func.__ember_observes__ = paths;
</span><span class="cx">   return func;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-// If observers ever become asynchronous, Ember.immediateObserver
-// must remain synchronous.
</del><span class="cx"> /**
</span><ins>+  Specify a method that observes property changes.
+
+  ```javascript
+  Ember.Object.extend({
+    valueObserver: Ember.immediateObserver('value', function() {
+      // Executes whenever the &quot;value&quot; property changes
+    })
+  });
+  ```
+
+  In the future, `Ember.observer` may become asynchronous. In this event,
+  `Ember.immediateObserver` will maintain the synchronous behavior.
+
+  Also available as `Function.prototype.observesImmediately` if prototype extensions are
+  enabled.
+
</ins><span class="cx">   @method immediateObserver
</span><span class="cx">   @for Ember
</span><ins>+  @param {String} propertyNames*
</ins><span class="cx">   @param {Function} func
</span><del>-  @param {String} propertyNames*
</del><span class="cx">   @return func
</span><span class="cx"> */
</span><span class="cx"> Ember.immediateObserver = function() {
</span><span class="lines">@@ -5729,14 +7842,67 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+  When observers fire, they are called with the arguments `obj`, `keyName`.
+
+  Note, `@each.property` observer is called per each add or replace of an element
+  and it's not called with a specific enumeration item.
+
+  A `beforeObserver` fires before a property changes.
+
+  A `beforeObserver` is an alternative form of `.observesBefore()`.
+
+  ```javascript
+  App.PersonView = Ember.View.extend({
+
+    friends: [{ name: 'Tom' }, { name: 'Stefan' }, { name: 'Kris' }],
+
+    valueWillChange: Ember.beforeObserver('content.value', function(obj, keyName) {
+      this.changingFrom = obj.get(keyName);
+    }),
+
+    valueDidChange: Ember.observer('content.value', function(obj, keyName) {
+        // only run if updating a value already in the DOM
+        if (this.get('state') === 'inDOM') {
+          var color = obj.get(keyName) &gt; this.changingFrom ? 'green' : 'red';
+          // logic
+        }
+    }),
+
+    friendsDidChange: Ember.observer('friends.@each.name', function(obj, keyName) {
+      // some logic
+      // obj.get(keyName) returns friends array
+    })
+  });
+  ```
+
+  Also available as `Function.prototype.observesBefore` if prototype extensions are
+  enabled.
+
</ins><span class="cx">   @method beforeObserver
</span><span class="cx">   @for Ember
</span><ins>+  @param {String} propertyNames*
</ins><span class="cx">   @param {Function} func
</span><del>-  @param {String} propertyNames*
</del><span class="cx">   @return func
</span><span class="cx"> */
</span><del>-Ember.beforeObserver = function(func) {
-  var paths = a_slice.call(arguments, 1);
</del><ins>+Ember.beforeObserver = function() {
+  var func  = a_slice.call(arguments, -1)[0];
+  var paths;
+
+  
+    paths = a_slice.call(arguments, 0, -1);
+
+    if (typeof func !== &quot;function&quot;) {
+      // revert to old, soft-deprecated argument ordering
+
+      func  = arguments[0];
+      paths = a_slice.call(arguments, 1);
+    }
+  
+
+  if (typeof func !== &quot;function&quot;) {
+    throw new Ember.Error(&quot;Ember.beforeObserver called without a function&quot;);
+  }
+
</ins><span class="cx">   func.__ember_observesBefore__ = paths;
</span><span class="cx">   return func;
</span><span class="cx"> };
</span><span class="lines">@@ -5746,6 +7912,55 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><ins>+// Provides a way to register library versions with ember.
+var forEach = Ember.EnumerableUtils.forEach,
+    indexOf = Ember.EnumerableUtils.indexOf;
+
+Ember.libraries = function() {
+  var libraries    = [];
+  var coreLibIndex = 0;
+
+  var getLibrary = function(name) {
+    for (var i = 0; i &lt; libraries.length; i++) {
+      if (libraries[i].name === name) {
+        return libraries[i];
+      }
+    }
+  };
+
+  libraries.register = function(name, version) {
+    if (!getLibrary(name)) {
+      libraries.push({name: name, version: version});
+    }
+  };
+
+  libraries.registerCoreLibrary = function(name, version) {
+    if (!getLibrary(name)) {
+      libraries.splice(coreLibIndex++, 0, {name: name, version: version});
+    }
+  };
+
+  libraries.deRegister = function(name) {
+    var lib = getLibrary(name);
+    if (lib) libraries.splice(indexOf(libraries, lib), 1);
+  };
+
+  libraries.each = function (callback) {
+    forEach(libraries, function(lib) {
+      callback(lib.name, lib.version);
+    });
+  };
+
+  return libraries;
+}();
+
+Ember.libraries.registerCoreLibrary('Ember', Ember.VERSION);
+
+})();
+
+
+
+(function() {
</ins><span class="cx"> /**
</span><span class="cx"> Ember Metal
</span><span class="cx"> 
</span><span class="lines">@@ -5756,69 +7971,232 @@
</span><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-define(&quot;rsvp&quot;,
-  [],
-  function() {
</del><ins>+/**
+  @class RSVP
+  @module RSVP
+  */
+define(&quot;rsvp/all&quot;, 
+  [&quot;./promise&quot;,&quot;exports&quot;],
+  function(__dependency1__, __exports__) {
</ins><span class="cx">     &quot;use strict&quot;;
</span><del>-    var browserGlobal = (typeof window !== 'undefined') ? window : {};
</del><ins>+    var Promise = __dependency1__[&quot;default&quot;];
</ins><span class="cx"> 
</span><del>-    var MutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
-    var RSVP, async;
</del><ins>+    /**
+      This is a convenient alias for `RSVP.Promise.all`.
</ins><span class="cx"> 
</span><del>-    if (typeof process !== 'undefined' &amp;&amp;
-      {}.toString.call(process) === '[object process]') {
-      async = function(callback, binding) {
-        process.nextTick(function() {
-          callback.call(binding);
-        });
-      };
-    } else if (MutationObserver) {
-      var queue = [];
</del><ins>+      @method all
+      @for RSVP
+      @param {Array} array Array of promises.
+      @param {String} label An optional label. This is useful
+      for tooling.
+      @static
+    */
+    __exports__[&quot;default&quot;] = function all(array, label) {
+      return Promise.all(array, label);
+    };
+  });
+define(&quot;rsvp/all_settled&quot;, 
+  [&quot;./promise&quot;,&quot;./utils&quot;,&quot;exports&quot;],
+  function(__dependency1__, __dependency2__, __exports__) {
+    &quot;use strict&quot;;
+    var Promise = __dependency1__[&quot;default&quot;];
+    var isArray = __dependency2__.isArray;
+    var isNonThenable = __dependency2__.isNonThenable;
</ins><span class="cx"> 
</span><del>-      var observer = new MutationObserver(function() {
-        var toProcess = queue.slice();
-        queue = [];
</del><ins>+    /**
+      `RSVP.allSettled` is similar to `RSVP.all`, but instead of implementing
+      a fail-fast method, it waits until all the promises have returned and
+      shows you all the results. This is useful if you want to handle multiple
+      promises' failure states together as a set.
</ins><span class="cx"> 
</span><del>-        toProcess.forEach(function(tuple) {
-          var callback = tuple[0], binding = tuple[1];
-          callback.call(binding);
-        });
-      });
</del><ins>+      Returns a promise that is fulfilled when all the given promises have been
+      settled. The return promise is fulfilled with an array of the states of
+      the promises passed into the `promises` array argument.
</ins><span class="cx"> 
</span><del>-      var element = document.createElement('div');
-      observer.observe(element, { attributes: true });
</del><ins>+      Each state object will either indicate fulfillment or rejection, and
+      provide the corresponding value or reason. The states will take one of
+      the following formats:
</ins><span class="cx"> 
</span><del>-      // Chrome Memory Leak: https://bugs.webkit.org/show_bug.cgi?id=93661
-      window.addEventListener('unload', function(){
-        observer.disconnect();
-        observer = null;
</del><ins>+      ```javascript
+      { state: 'fulfilled', value: value }
+        or
+      { state: 'rejected', reason: reason }
+      ```
+
+      Example:
+
+      ```javascript
+      var promise1 = RSVP.Promise.resolve(1);
+      var promise2 = RSVP.Promise.reject(new Error('2'));
+      var promise3 = RSVP.Promise.reject(new Error('3'));
+      var promises = [ promise1, promise2, promise3 ];
+
+      RSVP.allSettled(promises).then(function(array){
+        // array == [
+        //   { state: 'fulfilled', value: 1 },
+        //   { state: 'rejected', reason: Error },
+        //   { state: 'rejected', reason: Error }
+        // ]
+        // Note that for the second item, reason.message will be &quot;2&quot;, and for the
+        // third item, reason.message will be &quot;3&quot;.
+      }, function(error) {
+        // Not run. (This block would only be called if allSettled had failed,
+        // for instance if passed an incorrect argument type.)
</ins><span class="cx">       });
</span><ins>+      ```
</ins><span class="cx"> 
</span><del>-      async = function(callback, binding) {
-        queue.push([callback, binding]);
-        element.setAttribute('drainQueue', 'drainQueue');
-      };
-    } else {
-      async = function(callback, binding) {
-        setTimeout(function() {
-          callback.call(binding);
-        }, 1);
-      };
</del><ins>+      @method allSettled
+      @for RSVP
+      @param {Array} promises
+      @param {String} label - optional string that describes the promise.
+      Useful for tooling.
+      @return {Promise} promise that is fulfilled with an array of the settled
+      states of the constituent promises.
+      @static
+    */
+
+    __exports__[&quot;default&quot;] = function allSettled(entries, label) {
+      return new Promise(function(resolve, reject) {
+        if (!isArray(entries)) {
+          throw new TypeError('You must pass an array to allSettled.');
+        }
+
+        var remaining = entries.length;
+        var entry;
+
+        if (remaining === 0) {
+          resolve([]);
+          return;
+        }
+
+        var results = new Array(remaining);
+
+        function fulfilledResolver(index) {
+          return function(value) {
+            resolveAll(index, fulfilled(value));
+          };
+        }
+
+        function rejectedResolver(index) {
+          return function(reason) {
+            resolveAll(index, rejected(reason));
+          };
+        }
+
+        function resolveAll(index, value) {
+          results[index] = value;
+          if (--remaining === 0) {
+            resolve(results);
+          }
+        }
+
+        for (var index = 0; index &lt; entries.length; index++) {
+          entry = entries[index];
+
+          if (isNonThenable(entry)) {
+            resolveAll(index, fulfilled(entry));
+          } else {
+            Promise.cast(entry).then(fulfilledResolver(index), rejectedResolver(index));
+          }
+        }
+      }, label);
+    };
+
+    function fulfilled(value) {
+      return { state: 'fulfilled', value: value };
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    var Event = function(type, options) {
-      this.type = type;
</del><ins>+    function rejected(reason) {
+      return { state: 'rejected', reason: reason };
+    }
+  });
+define(&quot;rsvp/config&quot;, 
+  [&quot;./events&quot;,&quot;exports&quot;],
+  function(__dependency1__, __exports__) {
+    &quot;use strict&quot;;
+    var EventTarget = __dependency1__[&quot;default&quot;];
</ins><span class="cx"> 
</span><del>-      for (var option in options) {
-        if (!options.hasOwnProperty(option)) { continue; }
</del><ins>+    var config = {
+      instrument: false
+    };
</ins><span class="cx"> 
</span><del>-        this[option] = options[option];
</del><ins>+    EventTarget.mixin(config);
+
+    function configure(name, value) {
+      if (name === 'onerror') {
+        // handle for legacy users that expect the actual
+        // error to be passed to their function added via
+        // `RSVP.configure('onerror', someFunctionHere);`
+        config.on('error', value);
+        return;
</ins><span class="cx">       }
</span><ins>+
+      if (arguments.length === 2) {
+        config[name] = value;
+      } else {
+        return config[name];
+      }
+    }
+
+    __exports__.config = config;
+    __exports__.configure = configure;
+  });
+define(&quot;rsvp/defer&quot;, 
+  [&quot;./promise&quot;,&quot;exports&quot;],
+  function(__dependency1__, __exports__) {
+    &quot;use strict&quot;;
+    var Promise = __dependency1__[&quot;default&quot;];
+
+    /**
+      `RSVP.defer` returns an object similar to jQuery's `$.Deferred`.
+      `RSVP.defer` should be used when porting over code reliant on `$.Deferred`'s
+      interface. New code should use the `RSVP.Promise` constructor instead.
+
+      The object returned from `RSVP.defer` is a plain object with three properties:
+
+      * promise - an `RSVP.Promise`.
+      * reject - a function that causes the `promise` property on this object to
+        become rejected
+      * resolve - a function that causes the `promise` property on this object to
+        become fulfilled.
+
+      Example:
+
+       ```javascript
+       var deferred = RSVP.defer();
+
+       deferred.resolve(&quot;Success!&quot;);
+
+       defered.promise.then(function(value){
+         // value here is &quot;Success!&quot;
+       });
+       ```
+
+      @method defer
+      @for RSVP
+      @param {String} label optional string for labeling the promise.
+      Useful for tooling.
+      @return {Object}
+     */
+
+    __exports__[&quot;default&quot;] = function defer(label) {
+      var deferred = { };
+
+      deferred.promise = new Promise(function(resolve, reject) {
+        deferred.resolve = resolve;
+        deferred.reject = reject;
+      }, label);
+
+      return deferred;
</ins><span class="cx">     };
</span><del>-
</del><ins>+  });
+define(&quot;rsvp/events&quot;, 
+  [&quot;exports&quot;],
+  function(__exports__) {
+    &quot;use strict&quot;;
</ins><span class="cx">     var indexOf = function(callbacks, callback) {
</span><span class="cx">       for (var i=0, l=callbacks.length; i&lt;l; i++) {
</span><del>-        if (callbacks[i][0] === callback) { return i; }
</del><ins>+        if (callbacks[i] === callback) { return i; }
</ins><span class="cx">       }
</span><span class="cx"> 
</span><span class="cx">       return -1;
</span><span class="lines">@@ -5834,231 +8212,1964 @@
</span><span class="cx">       return callbacks;
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    var EventTarget = {
</del><ins>+    /**
+      @class RSVP.EventTarget
+    */
+    __exports__[&quot;default&quot;] = {
+
+      /**
+        `RSVP.EventTarget.mixin` extends an object with EventTarget methods. For
+        Example:
+
+        ```javascript
+        var object = {};
+
+        RSVP.EventTarget.mixin(object);
+
+        object.on(&quot;finished&quot;, function(event) {
+          // handle event
+        });
+
+        object.trigger(&quot;finished&quot;, { detail: value });
+        ```
+
+        `EventTarget.mixin` also works with prototypes:
+
+        ```javascript
+        var Person = function() {};
+        RSVP.EventTarget.mixin(Person.prototype);
+
+        var yehuda = new Person();
+        var tom = new Person();
+
+        yehuda.on(&quot;poke&quot;, function(event) {
+          console.log(&quot;Yehuda says OW&quot;);
+        });
+
+        tom.on(&quot;poke&quot;, function(event) {
+          console.log(&quot;Tom says OW&quot;);
+        });
+
+        yehuda.trigger(&quot;poke&quot;);
+        tom.trigger(&quot;poke&quot;);
+        ```
+
+        @method mixin
+        @param {Object} object object to extend with EventTarget methods
+        @private
+      */
</ins><span class="cx">       mixin: function(object) {
</span><span class="cx">         object.on = this.on;
</span><span class="cx">         object.off = this.off;
</span><span class="cx">         object.trigger = this.trigger;
</span><ins>+        object._promiseCallbacks = undefined;
</ins><span class="cx">         return object;
</span><span class="cx">       },
</span><span class="cx"> 
</span><del>-      on: function(eventNames, callback, binding) {
-        var allCallbacks = callbacksFor(this), callbacks, eventName;
-        eventNames = eventNames.split(/\s+/);
-        binding = binding || this;
</del><ins>+      /**
+        Registers a callback to be executed when `eventName` is triggered
</ins><span class="cx"> 
</span><del>-        while (eventName = eventNames.shift()) {
-          callbacks = allCallbacks[eventName];
</del><ins>+        ```javascript
+        object.on('event', function(eventInfo){
+          // handle the event
+        });
</ins><span class="cx"> 
</span><del>-          if (!callbacks) {
-            callbacks = allCallbacks[eventName] = [];
-          }
</del><ins>+        object.trigger('event');
+        ```
</ins><span class="cx"> 
</span><del>-          if (indexOf(callbacks, callback) === -1) {
-            callbacks.push([callback, binding]);
-          }
</del><ins>+        @method on
+        @param {String} eventName name of the event to listen for
+        @param {Function} callback function to be called when the event is triggered.
+        @private
+      */
+      on: function(eventName, callback) {
+        var allCallbacks = callbacksFor(this), callbacks;
+
+        callbacks = allCallbacks[eventName];
+
+        if (!callbacks) {
+          callbacks = allCallbacks[eventName] = [];
</ins><span class="cx">         }
</span><ins>+
+        if (indexOf(callbacks, callback) === -1) {
+          callbacks.push(callback);
+        }
</ins><span class="cx">       },
</span><span class="cx"> 
</span><del>-      off: function(eventNames, callback) {
-        var allCallbacks = callbacksFor(this), callbacks, eventName, index;
-        eventNames = eventNames.split(/\s+/);
</del><ins>+      /**
+        You can use `off` to stop firing a particular callback for an event:
</ins><span class="cx"> 
</span><del>-        while (eventName = eventNames.shift()) {
-          if (!callback) {
-            allCallbacks[eventName] = [];
-            continue;
-          }
</del><ins>+        ```javascript
+        function doStuff() { // do stuff! }
+        object.on('stuff', doStuff);
</ins><span class="cx"> 
</span><del>-          callbacks = allCallbacks[eventName];
</del><ins>+        object.trigger('stuff'); // doStuff will be called
</ins><span class="cx"> 
</span><del>-          index = indexOf(callbacks, callback);
</del><ins>+        // Unregister ONLY the doStuff callback
+        object.off('stuff', doStuff);
+        object.trigger('stuff'); // doStuff will NOT be called
+        ```
</ins><span class="cx"> 
</span><del>-          if (index !== -1) { callbacks.splice(index, 1); }
</del><ins>+        If you don't pass a `callback` argument to `off`, ALL callbacks for the
+        event will not be executed when the event fires. For example:
+
+        ```javascript
+        var callback1 = function(){};
+        var callback2 = function(){};
+
+        object.on('stuff', callback1);
+        object.on('stuff', callback2);
+
+        object.trigger('stuff'); // callback1 and callback2 will be executed.
+
+        object.off('stuff');
+        object.trigger('stuff'); // callback1 and callback2 will not be executed!
+        ```
+
+        @method off
+        @param {String} eventName event to stop listening to
+        @param {Function} callback optional argument. If given, only the function
+        given will be removed from the event's callback queue. If no `callback`
+        argument is given, all callbacks will be removed from the event's callback
+        queue.
+        @private
+
+      */
+      off: function(eventName, callback) {
+        var allCallbacks = callbacksFor(this), callbacks, index;
+
+        if (!callback) {
+          allCallbacks[eventName] = [];
+          return;
</ins><span class="cx">         }
</span><ins>+
+        callbacks = allCallbacks[eventName];
+
+        index = indexOf(callbacks, callback);
+
+        if (index !== -1) { callbacks.splice(index, 1); }
</ins><span class="cx">       },
</span><span class="cx"> 
</span><ins>+      /**
+        Use `trigger` to fire custom events. For example:
+
+        ```javascript
+        object.on('foo', function(){
+          console.log('foo event happened!');
+        });
+        object.trigger('foo');
+        // 'foo event happened!' logged to the console
+        ```
+
+        You can also pass a value as a second argument to `trigger` that will be
+        passed as an argument to all event listeners for the event:
+
+        ```javascript
+        object.on('foo', function(value){
+          console.log(value.name);
+        });
+
+        object.trigger('foo', { name: 'bar' });
+        // 'bar' logged to the console
+        ```
+
+        @method trigger
+        @param {String} eventName name of the event to be triggered
+        @param {Any} options optional value to be passed to any event handlers for
+        the given `eventName`
+        @private
+      */
</ins><span class="cx">       trigger: function(eventName, options) {
</span><span class="cx">         var allCallbacks = callbacksFor(this),
</span><del>-            callbacks, callbackTuple, callback, binding, event;
</del><ins>+            callbacks, callbackTuple, callback, binding;
</ins><span class="cx"> 
</span><span class="cx">         if (callbacks = allCallbacks[eventName]) {
</span><span class="cx">           // Don't cache the callbacks.length since it may grow
</span><span class="cx">           for (var i=0; i&lt;callbacks.length; i++) {
</span><del>-            callbackTuple = callbacks[i];
-            callback = callbackTuple[0];
-            binding = callbackTuple[1];
</del><ins>+            callback = callbacks[i];
</ins><span class="cx"> 
</span><del>-            if (typeof options !== 'object') {
-              options = { detail: options };
</del><ins>+            callback(options);
+          }
+        }
+      }
+    };
+  });
+define(&quot;rsvp/filter&quot;, 
+  [&quot;./all&quot;,&quot;./map&quot;,&quot;./utils&quot;,&quot;exports&quot;],
+  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
+    &quot;use strict&quot;;
+    var all = __dependency1__[&quot;default&quot;];
+    var map = __dependency2__[&quot;default&quot;];
+    var isFunction = __dependency3__.isFunction;
+    var isArray = __dependency3__.isArray;
+
+    /**
+     `RSVP.filter` is similar to JavaScript's native `filter` method, except that it
+      waits for all promises to become fulfilled before running the `filterFn` on
+      each item in given to `promises`. `RSVP.filter` returns a promise that will
+      become fulfilled with the result of running `filterFn` on the values the
+      promises become fulfilled with.
+
+      For example:
+
+      ```javascript
+
+      var promise1 = RSVP.resolve(1);
+      var promise2 = RSVP.resolve(2);
+      var promise3 = RSVP.resolve(3);
+
+      var filterFn = function(item){
+        return item &gt; 1;
+      };
+
+      RSVP.filter(promises, filterFn).then(function(result){
+        // result is [ 2, 3 ]
+      });
+      ```
+
+      If any of the `promises` given to `RSVP.filter` are rejected, the first promise
+      that is rejected will be given as an argument to the returned promise's
+      rejection handler. For example:
+
+      ```javascript
+      var promise1 = RSVP.resolve(1);
+      var promise2 = RSVP.reject(new Error(&quot;2&quot;));
+      var promise3 = RSVP.reject(new Error(&quot;3&quot;));
+      var promises = [ promise1, promise2, promise3 ];
+
+      var filterFn = function(item){
+        return item &gt; 1;
+      };
+
+      RSVP.filter(promises, filterFn).then(function(array){
+        // Code here never runs because there are rejected promises!
+      }, function(reason) {
+        // reason.message === &quot;2&quot;
+      });
+      ```
+
+      `RSVP.filter` will also wait for any promises returned from `filterFn`.
+      For instance, you may want to fetch a list of users then return a subset
+      of those users based on some asynchronous operation:
+
+      ```javascript
+
+      var alice = { name: 'alice' };
+      var bob   = { name: 'bob' };
+      var users = [ alice, bob ];
+
+      var promises = users.map(function(user){
+        return RSVP.resolve(user);
+      });
+
+      var filterFn = function(user){
+        // Here, Alice has permissions to create a blog post, but Bob does not.
+        return getPrivilegesForUser(user).then(function(privs){
+          return privs.can_create_blog_post === true;
+        });
+      };
+      RSVP.filter(promises, filterFn).then(function(users){
+        // true, because the server told us only Alice can create a blog post.
+        users.length === 1;
+        // false, because Alice is the only user present in `users`
+        users[0] === bob;
+      });
+      ```
+
+      @method filter
+      @for RSVP
+      @param {Array} promises
+      @param {Function} filterFn - function to be called on each resolved value to
+      filter the final results.
+      @param {String} label optional string describing the promise. Useful for
+      tooling.
+      @return {Promise}
+    */
+    function filter(promises, filterFn, label) {
+      return all(promises, label).then(function(values){
+        if (!isArray(promises)) {
+          throw new TypeError('You must pass an array to filter.');
+        }
+
+        if (!isFunction(filterFn)){
+          throw new TypeError(&quot;You must pass a function to filter's second argument.&quot;);
+        }
+
+        return map(promises, filterFn, label).then(function(filterResults){
+           var i,
+               valuesLen = values.length,
+               filtered = [];
+
+           for (i = 0; i &lt; valuesLen; i++){
+             if(filterResults[i]) filtered.push(values[i]);
+           }
+           return filtered;
+        });
+      });
+    }
+
+    __exports__[&quot;default&quot;] = filter;
+  });
+define(&quot;rsvp/hash&quot;, 
+  [&quot;./promise&quot;,&quot;./utils&quot;,&quot;exports&quot;],
+  function(__dependency1__, __dependency2__, __exports__) {
+    &quot;use strict&quot;;
+    var Promise = __dependency1__[&quot;default&quot;];
+    var isNonThenable = __dependency2__.isNonThenable;
+    var keysOf = __dependency2__.keysOf;
+
+    /**
+      `RSVP.hash` is similar to `RSVP.all`, but takes an object instead of an array
+      for its `promises` argument.
+
+      Returns a promise that is fulfilled when all the given promises have been
+      fulfilled, or rejected if any of them become rejected. The returned promise
+      is fulfilled with a hash that has the same key names as the `promises` object
+      argument. If any of the values in the object are not promises, they will
+      simply be copied over to the fulfilled object.
+
+      Example:
+
+      ```javascript
+      var promises = {
+        myPromise: RSVP.resolve(1),
+        yourPromise: RSVP.resolve(2),
+        theirPromise: RSVP.resolve(3),
+        notAPromise: 4
+      };
+
+      RSVP.hash(promises).then(function(hash){
+        // hash here is an object that looks like:
+        // {
+        //   myPromise: 1,
+        //   yourPromise: 2,
+        //   theirPromise: 3,
+        //   notAPromise: 4
+        // }
+      });
+      ````
+
+      If any of the `promises` given to `RSVP.hash` are rejected, the first promise
+      that is rejected will be given as the reason to the rejection handler.
+
+      Example:
+
+      ```javascript
+      var promises = {
+        myPromise: RSVP.resolve(1),
+        rejectedPromise: RSVP.reject(new Error(&quot;rejectedPromise&quot;)),
+        anotherRejectedPromise: RSVP.reject(new Error(&quot;anotherRejectedPromise&quot;)),
+      };
+
+      RSVP.hash(promises).then(function(hash){
+        // Code here never runs because there are rejected promises!
+      }, function(reason) {
+        // reason.message === &quot;rejectedPromise&quot;
+      });
+      ```
+
+      An important note: `RSVP.hash` is intended for plain JavaScript objects that
+      are just a set of keys and values. `RSVP.hash` will NOT preserve prototype
+      chains.
+
+      Example:
+
+      ```javascript
+      function MyConstructor(){
+        this.example = RSVP.resolve(&quot;Example&quot;);
+      }
+
+      MyConstructor.prototype = {
+        protoProperty: RSVP.resolve(&quot;Proto Property&quot;)
+      };
+
+      var myObject = new MyConstructor();
+
+      RSVP.hash(myObject).then(function(hash){
+        // protoProperty will not be present, instead you will just have an
+        // object that looks like:
+        // {
+        //   example: &quot;Example&quot;
+        // }
+        //
+        // hash.hasOwnProperty('protoProperty'); // false
+        // 'undefined' === typeof hash.protoProperty
+      });
+      ```
+
+      @method hash
+      @for RSVP
+      @param {Object} promises
+      @param {String} label optional string that describes the promise.
+      Useful for tooling.
+      @return {Promise} promise that is fulfilled when all properties of `promises`
+      have been fulfilled, or rejected if any of them become rejected.
+      @static
+    */
+    __exports__[&quot;default&quot;] = function hash(object, label) {
+      return new Promise(function(resolve, reject){
+        var results = {};
+        var keys = keysOf(object);
+        var remaining = keys.length;
+        var entry, property;
+
+        if (remaining === 0) {
+          resolve(results);
+          return;
+        }
+
+       function fulfilledTo(property) {
+          return function(value) {
+            results[property] = value;
+            if (--remaining === 0) {
+              resolve(results);
</ins><span class="cx">             }
</span><ins>+          };
+        }
</ins><span class="cx"> 
</span><del>-            event = new Event(eventName, options);
-            callback.call(binding, event);
</del><ins>+        function onRejection(reason) {
+          remaining = 0;
+          reject(reason);
+        }
+
+        for (var i = 0; i &lt; keys.length; i++) {
+          property = keys[i];
+          entry = object[property];
+
+          if (isNonThenable(entry)) {
+            results[property] = entry;
+            if (--remaining === 0) {
+              resolve(results);
+            }
+          } else {
+            Promise.cast(entry).then(fulfilledTo(property), onRejection);
</ins><span class="cx">           }
</span><span class="cx">         }
</span><ins>+      });
+    };
+  });
+define(&quot;rsvp/instrument&quot;, 
+  [&quot;./config&quot;,&quot;./utils&quot;,&quot;exports&quot;],
+  function(__dependency1__, __dependency2__, __exports__) {
+    &quot;use strict&quot;;
+    var config = __dependency1__.config;
+    var now = __dependency2__.now;
+
+    __exports__[&quot;default&quot;] = function instrument(eventName, promise, child) {
+      // instrumentation should not disrupt normal usage.
+      try {
+        config.trigger(eventName, {
+          guid: promise._guidKey + promise._id,
+          eventName: eventName,
+          detail: promise._detail,
+          childGuid: child &amp;&amp; promise._guidKey + child._id,
+          label: promise._label,
+          timeStamp: now(),
+          stack: new Error(promise._label).stack
+        });
+      } catch(error) {
+        setTimeout(function(){
+          throw error;
+        }, 0);
</ins><span class="cx">       }
</span><span class="cx">     };
</span><ins>+  });
+define(&quot;rsvp/map&quot;, 
+  [&quot;./promise&quot;,&quot;./all&quot;,&quot;./utils&quot;,&quot;exports&quot;],
+  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
+    &quot;use strict&quot;;
+    var Promise = __dependency1__[&quot;default&quot;];
+    var all = __dependency2__[&quot;default&quot;];
+    var isArray = __dependency3__.isArray;
+    var isFunction = __dependency3__.isFunction;
</ins><span class="cx"> 
</span><del>-    var Promise = function() {
-      this.on('promise:resolved', function(event) {
-        this.trigger('success', { detail: event.detail });
-      }, this);
</del><ins>+    /**
+     `RSVP.map` is similar to JavaScript's native `map` method, except that it
+      waits for all promises to become fulfilled before running the `mapFn` on
+      each item in given to `promises`. `RSVP.map` returns a promise that will
+      become fulfilled with the result of running `mapFn` on the values the promises
+      become fulfilled with.
</ins><span class="cx"> 
</span><del>-      this.on('promise:failed', function(event) {
-        this.trigger('error', { detail: event.detail });
-      }, this);
</del><ins>+      For example:
+
+      ```javascript
+
+      var promise1 = RSVP.resolve(1);
+      var promise2 = RSVP.resolve(2);
+      var promise3 = RSVP.resolve(3);
+      var promises = [ promise1, promise2, promise3 ];
+
+      var mapFn = function(item){
+        return item + 1;
+      };
+
+      RSVP.map(promises, mapFn).then(function(result){
+        // result is [ 2, 3, 4 ]
+      });
+      ```
+
+      If any of the `promises` given to `RSVP.map` are rejected, the first promise
+      that is rejected will be given as an argument to the returned promise's
+      rejection handler. For example:
+
+      ```javascript
+      var promise1 = RSVP.resolve(1);
+      var promise2 = RSVP.reject(new Error(&quot;2&quot;));
+      var promise3 = RSVP.reject(new Error(&quot;3&quot;));
+      var promises = [ promise1, promise2, promise3 ];
+
+      var mapFn = function(item){
+        return item + 1;
+      };
+
+      RSVP.map(promises, mapFn).then(function(array){
+        // Code here never runs because there are rejected promises!
+      }, function(reason) {
+        // reason.message === &quot;2&quot;
+      });
+      ```
+
+      `RSVP.map` will also wait if a promise is returned from `mapFn`. For example,
+      say you want to get all comments from a set of blog posts, but you need
+      the blog posts first becuase they contain a url to those comments.
+
+      ```javscript
+
+      var mapFn = function(blogPost){
+        // getComments does some ajax and returns an RSVP.Promise that is fulfilled
+        // with some comments data
+        return getComments(blogPost.comments_url);
+      };
+
+      // getBlogPosts does some ajax and returns an RSVP.Promise that is fulfilled
+      // with some blog post data
+      RSVP.map(getBlogPosts(), mapFn).then(function(comments){
+        // comments is the result of asking the server for the comments
+        // of all blog posts returned from getBlogPosts()
+      });
+      ```
+
+      @method map
+      @for RSVP
+      @param {Array} promises
+      @param {Function} mapFn function to be called on each fulfilled promise.
+      @param {String} label optional string for labeling the promise.
+      Useful for tooling.
+      @return {Promise} promise that is fulfilled with the result of calling
+      `mapFn` on each fulfilled promise or value when they become fulfilled.
+       The promise will be rejected if any of the given `promises` become rejected.
+      @static
+    */
+    __exports__[&quot;default&quot;] = function map(promises, mapFn, label) {
+      return all(promises, label).then(function(results){
+        if (!isArray(promises)) {
+          throw new TypeError('You must pass an array to map.');
+        }
+
+        if (!isFunction(mapFn)){
+          throw new TypeError(&quot;You must pass a function to map's second argument.&quot;);
+        }
+
+
+        var resultLen = results.length,
+            mappedResults = [],
+            i;
+
+        for (i = 0; i &lt; resultLen; i++){
+          mappedResults.push(mapFn(results[i]));
+        }
+
+        return all(mappedResults, label);
+      });
</ins><span class="cx">     };
</span><ins>+  });
+define(&quot;rsvp/node&quot;, 
+  [&quot;./promise&quot;,&quot;exports&quot;],
+  function(__dependency1__, __exports__) {
+    &quot;use strict&quot;;
+    var Promise = __dependency1__[&quot;default&quot;];
</ins><span class="cx"> 
</span><del>-    var noop = function() {};
</del><ins>+    var slice = Array.prototype.slice;
</ins><span class="cx"> 
</span><del>-    var invokeCallback = function(type, promise, callback, event) {
-      var hasCallback = typeof callback === 'function',
</del><ins>+    function makeNodeCallbackFor(resolve, reject) {
+      return function (error, value) {
+        if (error) {
+          reject(error);
+        } else if (arguments.length &gt; 2) {
+          resolve(slice.call(arguments, 1));
+        } else {
+          resolve(value);
+        }
+      };
+    }
+
+    /**
+      `RSVP.denodeify` takes a &quot;node-style&quot; function and returns a function that
+      will return an `RSVP.Promise`. You can use `denodeify` in Node.js or the
+      browser when you'd prefer to use promises over using callbacks. For example,
+      `denodeify` transforms the following:
+
+      ```javascript
+      var fs = require('fs');
+
+      fs.readFile('myfile.txt', function(err, data){
+        if (err) return handleError(err);
+        handleData(data);
+      });
+      ```
+
+      into:
+
+      ```javascript
+      var fs = require('fs');
+
+      var readFile = RSVP.denodeify(fs.readFile);
+
+      readFile('myfile.txt').then(handleData, handleError);
+      ```
+
+      Using `denodeify` makes it easier to compose asynchronous operations instead
+      of using callbacks. For example, instead of:
+
+      ```javascript
+      var fs = require('fs');
+      var log = require('some-async-logger');
+
+      fs.readFile('myfile.txt', function(err, data){
+        if (err) return handleError(err);
+        fs.writeFile('myfile2.txt', data, function(err){
+          if (err) throw err;
+          log('success', function(err) {
+            if (err) throw err;
+          });
+        });
+      });
+      ```
+
+      You can chain the operations together using `then` from the returned promise:
+
+      ```javascript
+      var fs = require('fs');
+      var denodeify = RSVP.denodeify;
+      var readFile = denodeify(fs.readFile);
+      var writeFile = denodeify(fs.writeFile);
+      var log = denodeify(require('some-async-logger'));
+
+      readFile('myfile.txt').then(function(data){
+        return writeFile('myfile2.txt', data);
+      }).then(function(){
+        return log('SUCCESS');
+      }).then(function(){
+        // success handler
+      }, function(reason){
+        // rejection handler
+      });
+      ```
+
+      @method denodeify
+      @for RSVP
+      @param {Function} nodeFunc a &quot;node-style&quot; function that takes a callback as
+      its last argument. The callback expects an error to be passed as its first
+      argument (if an error occurred, otherwise null), and the value from the
+      operation as its second argument (&quot;function(err, value){ }&quot;).
+      @param {Any} binding optional argument for binding the &quot;this&quot; value when
+      calling the `nodeFunc` function.
+      @return {Function} a function that wraps `nodeFunc` to return an
+      `RSVP.Promise`
+      @static
+    */
+    __exports__[&quot;default&quot;] = function denodeify(nodeFunc, binding) {
+      return function()  {
+        var nodeArgs = slice.call(arguments), resolve, reject;
+        var thisArg = this || binding;
+
+        return new Promise(function(resolve, reject) {
+          Promise.all(nodeArgs).then(function(nodeArgs) {
+            try {
+              nodeArgs.push(makeNodeCallbackFor(resolve, reject));
+              nodeFunc.apply(thisArg, nodeArgs);
+            } catch(e) {
+              reject(e);
+            }
+          });
+        });
+      };
+    };
+  });
+define(&quot;rsvp/promise&quot;, 
+  [&quot;./config&quot;,&quot;./events&quot;,&quot;./instrument&quot;,&quot;./utils&quot;,&quot;./promise/cast&quot;,&quot;./promise/all&quot;,&quot;./promise/race&quot;,&quot;./promise/resolve&quot;,&quot;./promise/reject&quot;,&quot;exports&quot;],
+  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) {
+    &quot;use strict&quot;;
+    var config = __dependency1__.config;
+    var EventTarget = __dependency2__[&quot;default&quot;];
+    var instrument = __dependency3__[&quot;default&quot;];
+    var objectOrFunction = __dependency4__.objectOrFunction;
+    var isFunction = __dependency4__.isFunction;
+    var now = __dependency4__.now;
+    var cast = __dependency5__[&quot;default&quot;];
+    var all = __dependency6__[&quot;default&quot;];
+    var race = __dependency7__[&quot;default&quot;];
+    var Resolve = __dependency8__[&quot;default&quot;];
+    var Reject = __dependency9__[&quot;default&quot;];
+
+    var guidKey = 'rsvp_' + now() + '-';
+    var counter = 0;
+
+    function noop() {}
+
+    __exports__[&quot;default&quot;] = Promise;
+
+
+    /**
+      Promise objects represent the eventual result of an asynchronous operation. The
+      primary way of interacting with a promise is through its `then` method, which
+      registers callbacks to receive either a promise’s eventual value or the reason
+      why the promise cannot be fulfilled.
+
+      Terminology
+      -----------
+
+      - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
+      - `thenable` is an object or function that defines a `then` method.
+      - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
+      - `exception` is a value that is thrown using the throw statement.
+      - `reason` is a value that indicates why a promise was rejected.
+      - `settled` the final resting state of a promise, fulfilled or rejected.
+
+      A promise can be in one of three states: pending, fulfilled, or rejected.
+
+      Promises that are fulfilled have a fulfillment value and are in the fulfilled
+      state.  Promises that are rejected have a rejection reason and are in the
+      rejected state.  A fulfillment value is never a thenable.  Similarly, a
+      rejection reason is never a thenable.
+
+      Promises can also be said to *resolve* a value.  If this value is also a
+      promise, then the original promise's settled state will match the value's
+      settled state.  So a promise that *resolves* a promise that rejects will
+      itself reject, and a promise that *resolves* a promise that fulfills will
+      itself fulfill.
+
+
+      Basic Usage:
+      ------------
+
+      ```js
+      var promise = new Promise(function(resolve, reject) {
+        // on success
+        resolve(value);
+
+        // on failure
+        reject(reason);
+      });
+
+      promise.then(function(value) {
+        // on fulfillment
+      }, function(reason) {
+        // on rejection
+      });
+      ```
+
+      Advanced Usage:
+      ---------------
+
+      Promises shine when abstracting away asynchronous interactions such as
+      `XMLHttpRequest`s.
+
+      ```js
+      function getJSON(url) {
+        return new Promise(function(resolve, reject){
+          var xhr = new XMLHttpRequest();
+
+          xhr.open('GET', url);
+          xhr.onreadystatechange = handler;
+          xhr.responseType = 'json';
+          xhr.setRequestHeader('Accept', 'application/json');
+          xhr.send();
+
+          function handler() {
+            if (this.readyState === this.DONE) {
+              if (this.status === 200) {
+                resolve(this.response);
+              } else {
+                reject(new Error(&quot;getJSON: `&quot; + url + &quot;` failed with status: [&quot; + this.status + &quot;]&quot;);
+              }
+            }
+          };
+        });
+      }
+
+      getJSON('/posts.json').then(function(json) {
+        // on fulfillment
+      }, function(reason) {
+        // on rejection
+      });
+      ```
+
+      Unlike callbacks, promises are great composable primitives.
+
+      ```js
+      Promise.all([
+        getJSON('/posts'),
+        getJSON('/comments')
+      ]).then(function(values){
+        values[0] // =&gt; postsJSON
+        values[1] // =&gt; commentsJSON
+
+        return values;
+      });
+      ```
+
+      @class RSVP.Promise
+      @param {function}
+      @param {String} label optional string for labeling the promise.
+      Useful for tooling.
+      @constructor
+    */
+    function Promise(resolver, label) {
+      if (!isFunction(resolver)) {
+        throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
+      }
+
+      if (!(this instanceof Promise)) {
+        throw new TypeError(&quot;Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.&quot;);
+      }
+
+      this._id = counter++;
+      this._label = label;
+      this._subscribers = [];
+
+      if (config.instrument) {
+        instrument('created', this);
+      }
+
+      if (noop !== resolver) {
+        invokeResolver(resolver, this);
+      }
+    }
+
+    function invokeResolver(resolver, promise) {
+      function resolvePromise(value) {
+        resolve(promise, value);
+      }
+
+      function rejectPromise(reason) {
+        reject(promise, reason);
+      }
+
+      try {
+        resolver(resolvePromise, rejectPromise);
+      } catch(e) {
+        rejectPromise(e);
+      }
+    }
+
+    Promise.cast = cast;
+    Promise.all = all;
+    Promise.race = race;
+    Promise.resolve = Resolve;
+    Promise.reject = Reject;
+
+    var PENDING   = void 0;
+    var SEALED    = 0;
+    var FULFILLED = 1;
+    var REJECTED  = 2;
+
+    function subscribe(parent, child, onFulfillment, onRejection) {
+      var subscribers = parent._subscribers;
+      var length = subscribers.length;
+
+      subscribers[length] = child;
+      subscribers[length + FULFILLED] = onFulfillment;
+      subscribers[length + REJECTED]  = onRejection;
+    }
+
+    function publish(promise, settled) {
+      var child, callback, subscribers = promise._subscribers, detail = promise._detail;
+
+      if (config.instrument) {
+        instrument(settled === FULFILLED ? 'fulfilled' : 'rejected', promise);
+      }
+
+      for (var i = 0; i &lt; subscribers.length; i += 3) {
+        child = subscribers[i];
+        callback = subscribers[i + settled];
+
+        invokeCallback(settled, child, callback, detail);
+      }
+
+      promise._subscribers = null;
+    }
+
+    Promise.prototype = {
+      constructor: Promise,
+
+      _id: undefined,
+      _guidKey: guidKey,
+      _label: undefined,
+
+      _state: undefined,
+      _detail: undefined,
+      _subscribers: undefined,
+
+      _onerror: function (reason) {
+        config.trigger('error', reason);
+      },
+
+    /**
+      The primary way of interacting with a promise is through its `then` method,
+      which registers callbacks to receive either a promise's eventual value or the
+      reason why the promise cannot be fulfilled.
+
+      ```js
+      findUser().then(function(user){
+        // user is available
+      }, function(reason){
+        // user is unavailable, and you are given the reason why
+      });
+      ```
+
+      Chaining
+      --------
+
+      The return value of `then` is itself a promise.  This second, &quot;downstream&quot;
+      promise is resolved with the return value of the first promise's fulfillment
+      or rejection handler, or rejected if the handler throws an exception.
+
+      ```js
+      findUser().then(function (user) {
+        return user.name;
+      }, function (reason) {
+        return &quot;default name&quot;;
+      }).then(function (userName) {
+        // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
+        // will be `&quot;default name&quot;`
+      });
+
+      findUser().then(function (user) {
+        throw new Error(&quot;Found user, but still unhappy&quot;);
+      }, function (reason) {
+        throw new Error(&quot;`findUser` rejected and we're unhappy&quot;);
+      }).then(function (value) {
+        // never reached
+      }, function (reason) {
+        // if `findUser` fulfilled, `reason` will be &quot;Found user, but still unhappy&quot;.
+        // If `findUser` rejected, `reason` will be &quot;`findUser` rejected and we're unhappy&quot;.
+      });
+      ```
+      If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
+
+      ```js
+      findUser().then(function (user) {
+        throw new PedagogicalException(&quot;Upstream error&quot;);
+      }).then(function (value) {
+        // never reached
+      }).then(function (value) {
+        // never reached
+      }, function (reason) {
+        // The `PedgagocialException` is propagated all the way down to here
+      });
+      ```
+
+      Assimilation
+      ------------
+
+      Sometimes the value you want to propagate to a downstream promise can only be
+      retrieved asynchronously. This can be achieved by returning a promise in the
+      fulfillment or rejection handler. The downstream promise will then be pending
+      until the returned promise is settled. This is called *assimilation*.
+
+      ```js
+      findUser().then(function (user) {
+        return findCommentsByAuthor(user);
+      }).then(function (comments) {
+        // The user's comments are now available
+      });
+      ```
+
+      If the assimliated promise rejects, then the downstream promise will also reject.
+
+      ```js
+      findUser().then(function (user) {
+        return findCommentsByAuthor(user);
+      }).then(function (comments) {
+        // If `findCommentsByAuthor` fulfills, we'll have the value here
+      }, function (reason) {
+        // If `findCommentsByAuthor` rejects, we'll have the reason here
+      });
+      ```
+
+      Simple Example
+      --------------
+
+      Synchronous Example
+
+      ```javascript
+      var result;
+
+      try {
+        result = findResult();
+        // success
+      } catch(reason) {
+        // failure
+      }
+      ```
+
+      Errback Example
+
+      ```js
+      findResult(function(result, err){
+        if (err) {
+          // failure
+        } else {
+          // success
+        }
+      });
+      ```
+
+      Promise Example;
+
+      ```javascript
+      findResult().then(function(result){
+        // success
+      }, function(reason){
+        // failure
+      });
+      ```
+
+      Advanced Example
+      --------------
+
+      Synchronous Example
+
+      ```javascript
+      var author, books;
+
+      try {
+        author = findAuthor();
+        books  = findBooksByAuthor(author);
+        // success
+      } catch(reason) {
+        // failure
+      }
+      ```
+
+      Errback Example
+
+      ```js
+
+      function foundBooks(books) {
+
+      }
+
+      function failure(reason) {
+
+      }
+
+      findAuthor(function(author, err){
+        if (err) {
+          failure(err);
+          // failure
+        } else {
+          try {
+            findBoooksByAuthor(author, function(books, err) {
+              if (err) {
+                failure(err);
+              } else {
+                try {
+                  foundBooks(books);
+                } catch(reason) {
+                  failure(reason);
+                }
+              }
+            });
+          } catch(error) {
+            failure(err);
+          }
+          // success
+        }
+      });
+      ```
+
+      Promise Example;
+
+      ```javascript
+      findAuthor().
+        then(findBooksByAuthor).
+        then(function(books){
+          // found books
+      }).catch(function(reason){
+        // something went wrong
+      });
+      ```
+
+      @method then
+      @param {Function} onFulfilled
+      @param {Function} onRejected
+      @param {String} label optional string for labeling the promise.
+      Useful for tooling.
+      @return {Promise}
+    */
+      then: function(onFulfillment, onRejection, label) {
+        var promise = this;
+        this._onerror = null;
+
+        var thenPromise = new this.constructor(noop, label);
+
+        if (this._state) {
+          var callbacks = arguments;
+          config.async(function invokePromiseCallback() {
+            invokeCallback(promise._state, thenPromise, callbacks[promise._state - 1], promise._detail);
+          });
+        } else {
+          subscribe(this, thenPromise, onFulfillment, onRejection);
+        }
+
+        if (config.instrument) {
+          instrument('chained', promise, thenPromise);
+        }
+
+        return thenPromise;
+      },
+
+    /**
+      `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
+      as the catch block of a try/catch statement.
+
+      ```js
+      function findAuthor(){
+        throw new Error(&quot;couldn't find that author&quot;);
+      }
+
+      // synchronous
+      try {
+        findAuthor();
+      } catch(reason) {
+        // something went wrong
+      }
+
+      // async with promises
+      findAuthor().catch(function(reason){
+        // something went wrong
+      });
+      ```
+
+      @method catch
+      @param {Function} onRejection
+      @param {String} label optional string for labeling the promise.
+      Useful for tooling.
+      @return {Promise}
+    */
+      'catch': function(onRejection, label) {
+        return this.then(null, onRejection, label);
+      },
+
+    /**
+      `finally` will be invoked regardless of the promise's fate just as native
+      try/catch/finally behaves
+
+      Synchronous example:
+
+      ```js
+      findAuthor() {
+        if (Math.random() &gt; 0.5) {
+          throw new Error();
+        }
+        return new Author();
+      }
+
+      try {
+        return findAuthor(); // succeed or fail
+      } catch(error) {
+        return findOtherAuther();
+      } finally {
+        // always runs
+        // doesn't affect the return value
+      }
+      ```
+
+      Asynchronous example:
+
+      ```js
+      findAuthor().catch(function(reason){
+        return findOtherAuther();
+      }).finally(function(){
+        // author was either found, or not
+      });
+      ```
+
+      @method finally
+      @param {Function} callback
+      @param {String} label optional string for labeling the promise.
+      Useful for tooling.
+      @return {Promise}
+    */
+      'finally': function(callback, label) {
+        var constructor = this.constructor;
+
+        return this.then(function(value) {
+          return constructor.cast(callback()).then(function(){
+            return value;
+          });
+        }, function(reason) {
+          return constructor.cast(callback()).then(function(){
+            throw reason;
+          });
+        }, label);
+      }
+    };
+
+    function invokeCallback(settled, promise, callback, detail) {
+      var hasCallback = isFunction(callback),
</ins><span class="cx">           value, error, succeeded, failed;
</span><span class="cx"> 
</span><span class="cx">       if (hasCallback) {
</span><span class="cx">         try {
</span><del>-          value = callback(event.detail);
</del><ins>+          value = callback(detail);
</ins><span class="cx">           succeeded = true;
</span><span class="cx">         } catch(e) {
</span><span class="cx">           failed = true;
</span><span class="cx">           error = e;
</span><span class="cx">         }
</span><span class="cx">       } else {
</span><del>-        value = event.detail;
</del><ins>+        value = detail;
</ins><span class="cx">         succeeded = true;
</span><span class="cx">       }
</span><span class="cx"> 
</span><del>-      if (value &amp;&amp; typeof value.then === 'function') {
-        value.then(function(value) {
-          promise.resolve(value);
-        }, function(error) {
-          promise.reject(error);
-        });
</del><ins>+      if (handleThenable(promise, value)) {
+        return;
</ins><span class="cx">       } else if (hasCallback &amp;&amp; succeeded) {
</span><del>-        promise.resolve(value);
</del><ins>+        resolve(promise, value);
</ins><span class="cx">       } else if (failed) {
</span><del>-        promise.reject(error);
-      } else {
-        promise[type](value);
</del><ins>+        reject(promise, error);
+      } else if (settled === FULFILLED) {
+        resolve(promise, value);
+      } else if (settled === REJECTED) {
+        reject(promise, value);
</ins><span class="cx">       }
</span><del>-    };
</del><ins>+    }
</ins><span class="cx"> 
</span><del>-    Promise.prototype = {
-      then: function(done, fail) {
-        var thenPromise = new Promise();
</del><ins>+    function handleThenable(promise, value) {
+      var then = null,
+      resolved;
</ins><span class="cx"> 
</span><del>-        if (this.isResolved) {
-          RSVP.async(function() {
-            invokeCallback('resolve', thenPromise, done, { detail: this.resolvedValue });
-          }, this);
</del><ins>+      try {
+        if (promise === value) {
+          throw new TypeError(&quot;A promises callback cannot return that same promise.&quot;);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (this.isRejected) {
-          RSVP.async(function() {
-            invokeCallback('reject', thenPromise, fail, { detail: this.rejectedValue });
-          }, this);
</del><ins>+        if (objectOrFunction(value)) {
+          then = value.then;
+
+          if (isFunction(then)) {
+            then.call(value, function(val) {
+              if (resolved) { return true; }
+              resolved = true;
+
+              if (value !== val) {
+                resolve(promise, val);
+              } else {
+                fulfill(promise, val);
+              }
+            }, function(val) {
+              if (resolved) { return true; }
+              resolved = true;
+
+              reject(promise, val);
+            }, 'derived from: ' + (promise._label || ' unknown promise'));
+
+            return true;
+          }
</ins><span class="cx">         }
</span><ins>+      } catch (error) {
+        if (resolved) { return true; }
+        reject(promise, error);
+        return true;
+      }
</ins><span class="cx"> 
</span><del>-        this.on('promise:resolved', function(event) {
-          invokeCallback('resolve', thenPromise, done, event);
-        });
</del><ins>+      return false;
+    }
</ins><span class="cx"> 
</span><del>-        this.on('promise:failed', function(event) {
-          invokeCallback('reject', thenPromise, fail, event);
-        });
</del><ins>+    function resolve(promise, value) {
+      if (promise === value) {
+        fulfill(promise, value);
+      } else if (!handleThenable(promise, value)) {
+        fulfill(promise, value);
+      }
+    }
</ins><span class="cx"> 
</span><del>-        return thenPromise;
-      },
</del><ins>+    function fulfill(promise, value) {
+      if (promise._state !== PENDING) { return; }
+      promise._state = SEALED;
+      promise._detail = value;
</ins><span class="cx"> 
</span><del>-      resolve: function(value) {
-        resolve(this, value);
</del><ins>+      config.async(publishFulfillment, promise);
+    }
</ins><span class="cx"> 
</span><del>-        this.resolve = noop;
-        this.reject = noop;
-      },
</del><ins>+    function reject(promise, reason) {
+      if (promise._state !== PENDING) { return; }
+      promise._state = SEALED;
+      promise._detail = reason;
</ins><span class="cx"> 
</span><del>-      reject: function(value) {
-        reject(this, value);
</del><ins>+      config.async(publishRejection, promise);
+    }
</ins><span class="cx"> 
</span><del>-        this.resolve = noop;
-        this.reject = noop;
</del><ins>+    function publishFulfillment(promise) {
+      publish(promise, promise._state = FULFILLED);
+    }
+
+    function publishRejection(promise) {
+      if (promise._onerror) {
+        promise._onerror(promise._detail);
</ins><span class="cx">       }
</span><ins>+
+      publish(promise, promise._state = REJECTED);
+    }
+  });
+define(&quot;rsvp/promise/all&quot;, 
+  [&quot;../utils&quot;,&quot;exports&quot;],
+  function(__dependency1__, __exports__) {
+    &quot;use strict&quot;;
+    var isArray = __dependency1__.isArray;
+    var isNonThenable = __dependency1__.isNonThenable;
+
+    /**
+      `RSVP.Promise.all` accepts an array of promises, and returns a new promise which
+      is fulfilled with an array of fulfillment values for the passed promises, or
+      rejected with the reason of the first passed promise to be rejected. It casts all
+      elements of the passed iterable to promises as it runs this algorithm.
+
+      Example:
+
+      ```javascript
+      var promise1 = RSVP.resolve(1);
+      var promise2 = RSVP.resolve(2);
+      var promise3 = RSVP.resolve(3);
+      var promises = [ promise1, promise2, promise3 ];
+
+      RSVP.Promise.all(promises).then(function(array){
+        // The array here would be [ 1, 2, 3 ];
+      });
+      ```
+
+      If any of the `promises` given to `RSVP.all` are rejected, the first promise
+      that is rejected will be given as an argument to the returned promises's
+      rejection handler. For example:
+
+      Example:
+
+      ```javascript
+      var promise1 = RSVP.resolve(1);
+      var promise2 = RSVP.reject(new Error(&quot;2&quot;));
+      var promise3 = RSVP.reject(new Error(&quot;3&quot;));
+      var promises = [ promise1, promise2, promise3 ];
+
+      RSVP.Promise.all(promises).then(function(array){
+        // Code here never runs because there are rejected promises!
+      }, function(error) {
+        // error.message === &quot;2&quot;
+      });
+      ```
+
+      @method all
+      @for RSVP.Promise
+      @param {Array} entries array of promises
+      @param {String} label optional string for labeling the promise.
+      Useful for tooling.
+      @return {Promise} promise that is fulfilled when all `promises` have been
+      fulfilled, or rejected if any of them become rejected.
+      @static
+    */
+    __exports__[&quot;default&quot;] = function all(entries, label) {
+
+      /*jshint validthis:true */
+      var Constructor = this;
+
+      return new Constructor(function(resolve, reject) {
+        if (!isArray(entries)) {
+          throw new TypeError('You must pass an array to all.');
+        }
+
+        var remaining = entries.length;
+        var results = new Array(remaining);
+        var entry, pending = true;
+
+        if (remaining === 0) {
+          resolve(results);
+          return;
+        }
+
+        function fulfillmentAt(index) {
+          return function(value) {
+            results[index] = value;
+            if (--remaining === 0) {
+              resolve(results);
+            }
+          };
+        }
+
+        function onRejection(reason) {
+          remaining = 0;
+          reject(reason);
+        }
+
+        for (var index = 0; index &lt; entries.length; index++) {
+          entry = entries[index];
+          if (isNonThenable(entry)) {
+            results[index] = entry;
+            if (--remaining === 0) {
+              resolve(results);
+            }
+          } else {
+            Constructor.cast(entry).then(fulfillmentAt(index), onRejection);
+          }
+        }
+      }, label);
</ins><span class="cx">     };
</span><ins>+  });
+define(&quot;rsvp/promise/cast&quot;, 
+  [&quot;exports&quot;],
+  function(__exports__) {
+    &quot;use strict&quot;;
+    /**
+      `RSVP.Promise.cast` coerces its argument to a promise, or returns the
+      argument if it is already a promise which shares a constructor with the caster.
</ins><span class="cx"> 
</span><del>-    function resolve(promise, value) {
-      RSVP.async(function() {
-        promise.trigger('promise:resolved', { detail: value });
-        promise.isResolved = true;
-        promise.resolvedValue = value;
</del><ins>+      Example:
+
+      ```javascript
+      var promise = RSVP.Promise.resolve(1);
+      var casted = RSVP.Promise.cast(promise);
+
+      console.log(promise === casted); // true
+      ```
+
+      In the case of a promise whose constructor does not match, it is assimilated.
+      The resulting promise will fulfill or reject based on the outcome of the
+      promise being casted.
+
+      Example:
+
+      ```javascript
+      var thennable = $.getJSON('/api/foo');
+      var casted = RSVP.Promise.cast(thennable);
+
+      console.log(thennable === casted); // false
+      console.log(casted instanceof RSVP.Promise) // true
+
+      casted.then(function(data) {
+        // data is the value getJSON fulfills with
</ins><span class="cx">       });
</span><del>-    }
</del><ins>+      ```
</ins><span class="cx"> 
</span><del>-    function reject(promise, value) {
-      RSVP.async(function() {
-        promise.trigger('promise:failed', { detail: value });
-        promise.isRejected = true;
-        promise.rejectedValue = value;
</del><ins>+      In the case of a non-promise, a promise which will fulfill with that value is
+      returned.
+
+      Example:
+
+      ```javascript
+      var value = 1; // could be a number, boolean, string, undefined...
+      var casted = RSVP.Promise.cast(value);
+
+      console.log(value === casted); // false
+      console.log(casted instanceof RSVP.Promise) // true
+
+      casted.then(function(val) {
+        val === value // =&gt; true
</ins><span class="cx">       });
</span><del>-    }
</del><ins>+      ```
</ins><span class="cx"> 
</span><del>-    function all(promises) {
-    var i, results = [];
-    var allPromise = new Promise();
-    var remaining = promises.length;
</del><ins>+      `RSVP.Promise.cast` is similar to `RSVP.Promise.resolve`, but `RSVP.Promise.cast` differs in the
+      following ways:
</ins><span class="cx"> 
</span><del>-      if (remaining === 0) {
-        allPromise.resolve([]);
</del><ins>+      * `RSVP.Promise.cast` serves as a memory-efficient way of getting a promise, when you
+      have something that could either be a promise or a value. RSVP.resolve
+      will have the same effect but will create a new promise wrapper if the
+      argument is a promise.
+      * `RSVP.Promise.cast` is a way of casting incoming thenables or promise subclasses to
+      promises of the exact class specified, so that the resulting object's `then` is
+      ensured to have the behavior of the constructor you are calling cast on (i.e., RSVP.Promise).
+
+      @method cast
+      @param {Object} object to be casted
+      @param {String} label optional string for labeling the promise.
+      Useful for tooling.
+      @return {Promise} promise
+      @static
+    */
+
+    __exports__[&quot;default&quot;] = function cast(object, label) {
+      /*jshint validthis:true */
+      var Constructor = this;
+
+      if (object &amp;&amp; typeof object === 'object' &amp;&amp; object.constructor === Constructor) {
+        return object;
</ins><span class="cx">       }
</span><span class="cx"> 
</span><del>-    var resolver = function(index) {
-    return function(value) {
-    resolve(index, value);
</del><ins>+      return new Constructor(function(resolve) {
+        resolve(object);
+      }, label);
</ins><span class="cx">     };
</span><ins>+  });
+define(&quot;rsvp/promise/race&quot;, 
+  [&quot;../utils&quot;,&quot;exports&quot;],
+  function(__dependency1__, __exports__) {
+    &quot;use strict&quot;;
+    /* global toString */
+
+    var isArray = __dependency1__.isArray;
+    var isFunction = __dependency1__.isFunction;
+    var isNonThenable = __dependency1__.isNonThenable;
+
+    /**
+      `RSVP.Promise.race` returns a new promise which is settled in the same way as the
+      first passed promise to settle.
+
+      Example:
+
+      ```javascript
+      var promise1 = new RSVP.Promise(function(resolve, reject){
+        setTimeout(function(){
+          resolve(&quot;promise 1&quot;);
+        }, 200);
+      });
+
+      var promise2 = new RSVP.Promise(function(resolve, reject){
+        setTimeout(function(){
+          resolve(&quot;promise 2&quot;);
+        }, 100);
+      });
+
+      RSVP.Promise.race([promise1, promise2]).then(function(result){
+        // result === &quot;promise 2&quot; because it was resolved before promise1
+        // was resolved.
+      });
+      ```
+
+      `RSVP.Promise.race` is deterministic in that only the state of the first
+      settled promise matters. For example, even if other promises given to the
+      `promises` array argument are resolved, but the first settled promise has
+      become rejected before the other promises became fulfilled, the returned
+      promise will become rejected:
+
+      ```javascript
+      var promise1 = new RSVP.Promise(function(resolve, reject){
+        setTimeout(function(){
+          resolve(&quot;promise 1&quot;);
+        }, 200);
+      });
+
+      var promise2 = new RSVP.Promise(function(resolve, reject){
+        setTimeout(function(){
+          reject(new Error(&quot;promise 2&quot;));
+        }, 100);
+      });
+
+      RSVP.Promise.race([promise1, promise2]).then(function(result){
+        // Code here never runs
+      }, function(reason){
+        // reason.message === &quot;promise2&quot; because promise 2 became rejected before
+        // promise 1 became fulfilled
+      });
+      ```
+
+      An example real-world use case is implementing timeouts:
+
+      ```javascript
+      RSVP.Promise.race([ajax('foo.json'), timeout(5000)])
+      ```
+
+      @method race
+      @param {Array} promises array of promises to observe
+      @param {String} label optional string for describing the promise returned.
+      Useful for tooling.
+      @return {Promise} a promise which settles in the same way as the first passed
+      promise to settle.
+      @static
+    */
+    __exports__[&quot;default&quot;] = function race(entries, label) {
+      /*jshint validthis:true */
+      var Constructor = this, entry;
+
+      return new Constructor(function(resolve, reject) {
+        if (!isArray(entries)) {
+          throw new TypeError('You must pass an array to race.');
+        }
+
+        var pending = true;
+
+        function onFulfillment(value) { if (pending) { pending = false; resolve(value); } }
+        function onRejection(reason)  { if (pending) { pending = false; reject(reason); } }
+
+        for (var i = 0; i &lt; entries.length; i++) {
+          entry = entries[i];
+          if (isNonThenable(entry)) {
+            pending = false;
+            resolve(entry);
+            return;
+          } else {
+            Constructor.cast(entry).then(onFulfillment, onRejection);
+          }
+        }
+      }, label);
</ins><span class="cx">     };
</span><ins>+  });
+define(&quot;rsvp/promise/reject&quot;, 
+  [&quot;exports&quot;],
+  function(__exports__) {
+    &quot;use strict&quot;;
+    /**
+      `RSVP.Promise.reject` returns a promise rejected with the passed `reason`.
+      It is shorthand for the following:
</ins><span class="cx"> 
</span><del>-    var resolve = function(index, value) {
-    results[index] = value;
-    if (--remaining === 0) {
-    allPromise.resolve(results);
-    }
</del><ins>+      ```javascript
+      var promise = new RSVP.Promise(function(resolve, reject){
+        reject(new Error('WHOOPS'));
+      });
+
+      promise.then(function(value){
+        // Code here doesn't run because the promise is rejected!
+      }, function(reason){
+        // reason.message === 'WHOOPS'
+      });
+      ```
+
+      Instead of writing the above, your code now simply becomes the following:
+
+      ```javascript
+      var promise = RSVP.Promise.reject(new Error('WHOOPS'));
+
+      promise.then(function(value){
+        // Code here doesn't run because the promise is rejected!
+      }, function(reason){
+        // reason.message === 'WHOOPS'
+      });
+      ```
+
+      @method reject
+      @param {Any} reason value that the returned promise will be rejected with.
+      @param {String} label optional string for identifying the returned promise.
+      Useful for tooling.
+      @return {Promise} a promise rejected with the given `reason`.
+      @static
+    */
+    __exports__[&quot;default&quot;] = function reject(reason, label) {
+      /*jshint validthis:true */
+      var Constructor = this;
+
+      return new Constructor(function (resolve, reject) {
+        reject(reason);
+      }, label);
</ins><span class="cx">     };
</span><ins>+  });
+define(&quot;rsvp/promise/resolve&quot;, 
+  [&quot;exports&quot;],
+  function(__exports__) {
+    &quot;use strict&quot;;
+    /**
+      `RSVP.Promise.resolve` returns a promise that will become resolved with the
+      passed `value`. It is shorthand for the following:
</ins><span class="cx"> 
</span><del>-    var reject = function(error) {
-    allPromise.reject(error);
</del><ins>+      ```javascript
+      var promise = new RSVP.Promise(function(resolve, reject){
+        resolve(1);
+      });
+
+      promise.then(function(value){
+        // value === 1
+      });
+      ```
+
+      Instead of writing the above, your code now simply becomes the following:
+
+      ```javascript
+      var promise = RSVP.Promise.resolve(1);
+
+      promise.then(function(value){
+        // value === 1
+      });
+      ```
+
+      @method resolve
+      @param {Any} value value that the returned promise will be resolved with
+      @param {String} label optional string for identifying the returned promise.
+      Useful for tooling.
+      @return {Promise} a promise that will become fulfilled with the given
+      `value`
+      @static
+    */
+    __exports__[&quot;default&quot;] = function resolve(value, label) {
+      /*jshint validthis:true */
+      var Constructor = this;
+
+      return new Constructor(function(resolve, reject) {
+        resolve(value);
+      }, label);
</ins><span class="cx">     };
</span><ins>+  });
+define(&quot;rsvp/race&quot;, 
+  [&quot;./promise&quot;,&quot;exports&quot;],
+  function(__dependency1__, __exports__) {
+    &quot;use strict&quot;;
+    var Promise = __dependency1__[&quot;default&quot;];
</ins><span class="cx"> 
</span><del>-    for (i = 0; i &lt; remaining; i++) {
-    promises[i].then(resolver(i), reject);
</del><ins>+    /**
+      This is a convenient alias for `RSVP.Promise.race`.
+
+      @method race
+      @param {Array} array Array of promises.
+      @param {String} label An optional label. This is useful
+      for tooling.
+      @static
+    */
+    __exports__[&quot;default&quot;] = function race(array, label) {
+      return Promise.race(array, label);
+    };
+  });
+define(&quot;rsvp/reject&quot;, 
+  [&quot;./promise&quot;,&quot;exports&quot;],
+  function(__dependency1__, __exports__) {
+    &quot;use strict&quot;;
+    var Promise = __dependency1__[&quot;default&quot;];
+
+    /**
+      This is a convenient alias for `RSVP.Promise.reject`.
+
+      @method reject
+      @for RSVP
+      @param {Any} reason value that the returned promise will be rejected with.
+      @param {String} label optional string for identifying the returned promise.
+      Useful for tooling.
+      @return {Promise} a promise rejected with the given `reason`.
+      @static
+    */
+    __exports__[&quot;default&quot;] = function reject(reason, label) {
+      return Promise.reject(reason, label);
+    };
+  });
+define(&quot;rsvp/resolve&quot;, 
+  [&quot;./promise&quot;,&quot;exports&quot;],
+  function(__dependency1__, __exports__) {
+    &quot;use strict&quot;;
+    var Promise = __dependency1__[&quot;default&quot;];
+
+    /**
+      This is a convenient alias for `RSVP.Promise.resolve`.
+
+      @method resolve
+      @for RSVP
+      @param {Any} value value that the returned promise will be resolved with
+      @param {String} label optional string for identifying the returned promise.
+      Useful for tooling.
+      @return {Promise} a promise that will become fulfilled with the given
+      `value`
+      @static
+    */
+    __exports__[&quot;default&quot;] = function resolve(value, label) {
+      return Promise.resolve(value, label);
+    };
+  });
+define(&quot;rsvp/rethrow&quot;, 
+  [&quot;exports&quot;],
+  function(__exports__) {
+    &quot;use strict&quot;;
+    /**
+      `RSVP.rethrow` will rethrow an error on the next turn of the JavaScript event
+      loop in order to aid debugging.
+
+      Promises A+ specifies that any exceptions that occur with a promise must be
+      caught by the promises implementation and bubbled to the last handler. For
+      this reason, it is recommended that you always specify a second rejection
+      handler function to `then`. However, `RSVP.rethrow` will throw the exception
+      outside of the promise, so it bubbles up to your console if in the browser,
+      or domain/cause uncaught exception in Node. `rethrow` will also throw the
+      error again so the error can be handled by the promise per the spec.
+
+      ```javascript
+      function throws(){
+        throw new Error('Whoops!');
+      }
+
+      var promise = new RSVP.Promise(function(resolve, reject){
+        throws();
+      });
+
+      promise.catch(RSVP.rethrow).then(function(){
+        // Code here doesn't run because the promise became rejected due to an
+        // error!
+      }, function (err){
+        // handle the error here
+      });
+      ```
+
+      The 'Whoops' error will be thrown on the next turn of the event loop
+      and you can watch for it in your console. You can also handle it using a
+      rejection handler given to `.then` or `.catch` on the returned promise.
+
+      @method rethrow
+      @for RSVP
+      @param {Error} reason reason the promise became rejected.
+      @throws Error
+      @static
+    */
+    __exports__[&quot;default&quot;] = function rethrow(reason) {
+      setTimeout(function() {
+        throw reason;
+      });
+      throw reason;
+    };
+  });
+define(&quot;rsvp/utils&quot;, 
+  [&quot;exports&quot;],
+  function(__exports__) {
+    &quot;use strict&quot;;
+    function objectOrFunction(x) {
+      return typeof x === &quot;function&quot; || (typeof x === &quot;object&quot; &amp;&amp; x !== null);
</ins><span class="cx">     }
</span><del>-    return allPromise;
</del><ins>+
+    __exports__.objectOrFunction = objectOrFunction;function isFunction(x) {
+      return typeof x === &quot;function&quot;;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    EventTarget.mixin(Promise.prototype);
</del><ins>+    __exports__.isFunction = isFunction;function isNonThenable(x) {
+      return !objectOrFunction(x);
+    }
</ins><span class="cx"> 
</span><del>-    RSVP = { async: async, Promise: Promise, Event: Event, EventTarget: EventTarget, all: all, raiseOnUncaughtExceptions: true };
-    return RSVP;
</del><ins>+    __exports__.isNonThenable = isNonThenable;function isArray(x) {
+      return Object.prototype.toString.call(x) === &quot;[object Array]&quot;;
+    }
+
+    __exports__.isArray = isArray;// Date.now is not available in browsers &lt; IE9
+    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now#Compatibility
+    var now = Date.now || function() { return new Date().getTime(); };
+    __exports__.now = now;
+    var keysOf = Object.keys || function(object) {
+      var result = [];
+
+      for (var prop in object) {
+        result.push(prop);
+      }
+
+      return result;
+    };
+    __exports__.keysOf = keysOf;
</ins><span class="cx">   });
</span><ins>+define(&quot;rsvp&quot;, 
+  [&quot;./rsvp/promise&quot;,&quot;./rsvp/events&quot;,&quot;./rsvp/node&quot;,&quot;./rsvp/all&quot;,&quot;./rsvp/all_settled&quot;,&quot;./rsvp/race&quot;,&quot;./rsvp/hash&quot;,&quot;./rsvp/rethrow&quot;,&quot;./rsvp/defer&quot;,&quot;./rsvp/config&quot;,&quot;./rsvp/map&quot;,&quot;./rsvp/resolve&quot;,&quot;./rsvp/reject&quot;,&quot;./rsvp/filter&quot;,&quot;exports&quot;],
+  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __exports__) {
+    &quot;use strict&quot;;
+    var Promise = __dependency1__[&quot;default&quot;];
+    var EventTarget = __dependency2__[&quot;default&quot;];
+    var denodeify = __dependency3__[&quot;default&quot;];
+    var all = __dependency4__[&quot;default&quot;];
+    var allSettled = __dependency5__[&quot;default&quot;];
+    var race = __dependency6__[&quot;default&quot;];
+    var hash = __dependency7__[&quot;default&quot;];
+    var rethrow = __dependency8__[&quot;default&quot;];
+    var defer = __dependency9__[&quot;default&quot;];
+    var config = __dependency10__.config;
+    var configure = __dependency10__.configure;
+    var map = __dependency11__[&quot;default&quot;];
+    var resolve = __dependency12__[&quot;default&quot;];
+    var reject = __dependency13__[&quot;default&quot;];
+    var filter = __dependency14__[&quot;default&quot;];
</ins><span class="cx"> 
</span><ins>+    function async(callback, arg) {
+      config.async(callback, arg);
+    }
+
+    function on() {
+      config.on.apply(config, arguments);
+    }
+
+    function off() {
+      config.off.apply(config, arguments);
+    }
+
+    // Set up instrumentation through `window.__PROMISE_INTRUMENTATION__`
+    if (typeof window !== 'undefined' &amp;&amp; typeof window.__PROMISE_INSTRUMENTATION__ === 'object') {
+      var callbacks = window.__PROMISE_INSTRUMENTATION__;
+      configure('instrument', true);
+      for (var eventName in callbacks) {
+        if (callbacks.hasOwnProperty(eventName)) {
+          on(eventName, callbacks[eventName]);
+        }
+      }
+    }
+
+    __exports__.Promise = Promise;
+    __exports__.EventTarget = EventTarget;
+    __exports__.all = all;
+    __exports__.allSettled = allSettled;
+    __exports__.race = race;
+    __exports__.hash = hash;
+    __exports__.rethrow = rethrow;
+    __exports__.defer = defer;
+    __exports__.denodeify = denodeify;
+    __exports__.configure = configure;
+    __exports__.on = on;
+    __exports__.off = off;
+    __exports__.resolve = resolve;
+    __exports__.reject = reject;
+    __exports__.async = async;
+    __exports__.map = map;
+    __exports__.filter = filter;
+  });
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><ins>+/**
+Public api for the container is still in flux.
+The public api, specified on the application namespace should be considered the stable api.
+// @module container
+  @private
+*/
+
+/*
+ Flag to enable/disable model factory injections (disabled by default)
+ If model factory injections are enabled, models should not be
+ accessed globally (only through `container.lookupFactory('model:modelName'))`);
+*/
+Ember.MODEL_FACTORY_INJECTIONS = false || !!Ember.ENV.MODEL_FACTORY_INJECTIONS;
+
</ins><span class="cx"> define(&quot;container&quot;,
</span><span class="cx">   [],
</span><span class="cx">   function() {
</span><span class="cx"> 
</span><del>-    var objectCreate = Object.create || function(parent) {
-      function F() {}
-      F.prototype = parent;
-      return new F();
-    };
-
</del><ins>+    // A safe and simple inheriting object.
</ins><span class="cx">     function InheritingDict(parent) {
</span><span class="cx">       this.parent = parent;
</span><span class="cx">       this.dict = {};
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     InheritingDict.prototype = {
</span><ins>+
+      /**
+        @property parent
+        @type InheritingDict
+        @default null
+      */
+
+      parent: null,
+
+      /**
+        Object used to store the current nodes data.
+
+        @property dict
+        @type Object
+        @default Object
+      */
+      dict: null,
+
+      /**
+        Retrieve the value given a key, if the value is present at the current
+        level use it, otherwise walk up the parent hierarchy and try again. If
+        no matching key is found, return undefined.
+
+        @method get
+        @param {String} key
+        @return {any}
+      */
</ins><span class="cx">       get: function(key) {
</span><span class="cx">         var dict = this.dict;
</span><span class="cx"> 
</span><span class="lines">@@ -6071,10 +10182,36 @@
</span><span class="cx">         }
</span><span class="cx">       },
</span><span class="cx"> 
</span><ins>+      /**
+        Set the given value for the given key, at the current level.
+
+        @method set
+        @param {String} key
+        @param {Any} value
+      */
</ins><span class="cx">       set: function(key, value) {
</span><span class="cx">         this.dict[key] = value;
</span><span class="cx">       },
</span><span class="cx"> 
</span><ins>+      /**
+        Delete the given key
+
+        @method remove
+        @param {String} key
+      */
+      remove: function(key) {
+        delete this.dict[key];
+      },
+
+      /**
+        Check for the existence of given a key, if the key is present at the current
+        level return true, otherwise walk up the parent hierarchy and try again. If
+        no matching key is found, return false.
+
+        @method has
+        @param {String} key
+        @return {Boolean}
+      */
</ins><span class="cx">       has: function(key) {
</span><span class="cx">         var dict = this.dict;
</span><span class="cx"> 
</span><span class="lines">@@ -6089,6 +10226,13 @@
</span><span class="cx">         return false;
</span><span class="cx">       },
</span><span class="cx"> 
</span><ins>+      /**
+        Iterate and invoke a callback for each local key-value pair.
+
+        @method eachLocal
+        @param {Function} callback
+        @param {Object} binding
+      */
</ins><span class="cx">       eachLocal: function(callback, binding) {
</span><span class="cx">         var dict = this.dict;
</span><span class="cx"> 
</span><span class="lines">@@ -6100,96 +10244,469 @@
</span><span class="cx">       }
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+
+    // A lightweight container that helps to assemble and decouple components.
+    // Public api for the container is still in flux.
+    // The public api, specified on the application namespace should be considered the stable api.
</ins><span class="cx">     function Container(parent) {
</span><span class="cx">       this.parent = parent;
</span><span class="cx">       this.children = [];
</span><span class="cx"> 
</span><span class="cx">       this.resolver = parent &amp;&amp; parent.resolver || function() {};
</span><ins>+
</ins><span class="cx">       this.registry = new InheritingDict(parent &amp;&amp; parent.registry);
</span><span class="cx">       this.cache = new InheritingDict(parent &amp;&amp; parent.cache);
</span><ins>+      this.factoryCache = new InheritingDict(parent &amp;&amp; parent.cache);
</ins><span class="cx">       this.typeInjections = new InheritingDict(parent &amp;&amp; parent.typeInjections);
</span><span class="cx">       this.injections = {};
</span><ins>+
+      this.factoryTypeInjections = new InheritingDict(parent &amp;&amp; parent.factoryTypeInjections);
+      this.factoryInjections = {};
+
</ins><span class="cx">       this._options = new InheritingDict(parent &amp;&amp; parent._options);
</span><span class="cx">       this._typeOptions = new InheritingDict(parent &amp;&amp; parent._typeOptions);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     Container.prototype = {
</span><ins>+
+      /**
+        @property parent
+        @type Container
+        @default null
+      */
+      parent: null,
+
+      /**
+        @property children
+        @type Array
+        @default []
+      */
+      children: null,
+
+      /**
+        @property resolver
+        @type function
+      */
+      resolver: null,
+
+      /**
+        @property registry
+        @type InheritingDict
+      */
+      registry: null,
+
+      /**
+        @property cache
+        @type InheritingDict
+      */
+      cache: null,
+
+      /**
+        @property typeInjections
+        @type InheritingDict
+      */
+      typeInjections: null,
+
+      /**
+        @property injections
+        @type Object
+        @default {}
+      */
+      injections: null,
+
+      /**
+        @private
+
+        @property _options
+        @type InheritingDict
+        @default null
+      */
+      _options: null,
+
+      /**
+        @private
+
+        @property _typeOptions
+        @type InheritingDict
+      */
+      _typeOptions: null,
+
+      /**
+        Returns a new child of the current container. These children are configured
+        to correctly inherit from the current container.
+
+        @method child
+        @return {Container}
+      */
</ins><span class="cx">       child: function() {
</span><span class="cx">         var container = new Container(this);
</span><span class="cx">         this.children.push(container);
</span><span class="cx">         return container;
</span><span class="cx">       },
</span><span class="cx"> 
</span><ins>+      /**
+        Sets a key-value pair on the current container. If a parent container,
+        has the same key, once set on a child, the parent and child will diverge
+        as expected.
+
+        @method set
+        @param {Object} object
+        @param {String} key
+        @param {any} value
+      */
</ins><span class="cx">       set: function(object, key, value) {
</span><span class="cx">         object[key] = value;
</span><span class="cx">       },
</span><span class="cx"> 
</span><del>-      register: function(type, name, factory, options) {
-        var fullName;
</del><ins>+      /**
+        Registers a factory for later injection.
</ins><span class="cx"> 
</span><ins>+        Example:
</ins><span class="cx"> 
</span><del>-        if (type.indexOf(':') !== -1){
-          options = factory;
-          factory = name;
-          fullName = type;
-        } else {
-          Ember.deprecate('register(&quot;'+type +'&quot;, &quot;'+ name+'&quot;) is now deprecated in-favour of register(&quot;'+type+':'+name+'&quot;);', true);
-          fullName = type + &quot;:&quot; + name;
</del><ins>+        ```javascript
+        var container = new Container();
+
+        container.register('model:user', Person, {singleton: false });
+        container.register('fruit:favorite', Orange);
+        container.register('communication:main', Email, {singleton: false});
+        ```
+
+        @method register
+        @param {String} fullName
+        @param {Function} factory
+        @param {Object} options
+      */
+      register: function(fullName, factory, options) {
+        if (fullName.indexOf(':') === -1) {
+          throw new TypeError(&quot;malformed fullName, expected: `type:name` got: &quot; + fullName + &quot;&quot;);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        this.registry.set(fullName, factory);
-        this._options.set(fullName, options || {});
</del><ins>+        if (factory === undefined) {
+          throw new TypeError('Attempting to register an unknown factory: `' + fullName + '`');
+        }
+
+        var normalizedName = this.normalize(fullName);
+
+        if (this.cache.has(normalizedName)) {
+          throw new Error('Cannot re-register: `' + fullName +'`, as it has already been looked up.');
+        }
+
+        this.registry.set(normalizedName, factory);
+        this._options.set(normalizedName, options || {});
</ins><span class="cx">       },
</span><span class="cx"> 
</span><ins>+      /**
+        Unregister a fullName
+
+        ```javascript
+        var container = new Container();
+        container.register('model:user', User);
+
+        container.lookup('model:user') instanceof User //=&gt; true
+
+        container.unregister('model:user')
+        container.lookup('model:user') === undefined //=&gt; true
+        ```
+
+        @method unregister
+        @param {String} fullName
+       */
+      unregister: function(fullName) {
+        var normalizedName = this.normalize(fullName);
+
+        this.registry.remove(normalizedName);
+        this.cache.remove(normalizedName);
+        this.factoryCache.remove(normalizedName);
+        this._options.remove(normalizedName);
+      },
+
+      /**
+        Given a fullName return the corresponding factory.
+
+        By default `resolve` will retrieve the factory from
+        its container's registry.
+
+        ```javascript
+        var container = new Container();
+        container.register('api:twitter', Twitter);
+
+        container.resolve('api:twitter') // =&gt; Twitter
+        ```
+
+        Optionally the container can be provided with a custom resolver.
+        If provided, `resolve` will first provide the custom resolver
+        the oppertunity to resolve the fullName, otherwise it will fallback
+        to the registry.
+
+        ```javascript
+        var container = new Container();
+        container.resolver = function(fullName) {
+          // lookup via the module system of choice
+        };
+
+        // the twitter factory is added to the module system
+        container.resolve('api:twitter') // =&gt; Twitter
+        ```
+
+        @method resolve
+        @param {String} fullName
+        @return {Function} fullName's factory
+      */
</ins><span class="cx">       resolve: function(fullName) {
</span><span class="cx">         return this.resolver(fullName) || this.registry.get(fullName);
</span><span class="cx">       },
</span><span class="cx"> 
</span><del>-      lookup: function(fullName) {
-        if (this.cache.has(fullName)) {
</del><ins>+      /**
+        A hook that can be used to describe how the resolver will
+        attempt to find the factory.
+
+        For example, the default Ember `.describe` returns the full
+        class name (including namespace) where Ember's resolver expects
+        to find the `fullName`.
+
+        @method describe
+        @param {String} fullName
+        @return {string} described fullName
+      */
+      describe: function(fullName) {
+        return fullName;
+      },
+
+      /**
+        A hook to enable custom fullName normalization behaviour
+
+        @method normalize
+        @param {String} fullName
+        @return {string} normalized fullName
+      */
+      normalize: function(fullName) {
+        return fullName;
+      },
+
+      /**
+        @method makeToString
+
+        @param {any} factory
+        @param {string} fullName
+        @return {function} toString function
+      */
+      makeToString: function(factory, fullName) {
+        return factory.toString();
+      },
+
+      /**
+        Given a fullName return a corresponding instance.
+
+        The default behaviour is for lookup to return a singleton instance.
+        The singleton is scoped to the container, allowing multiple containers
+        to all have their own locally scoped singletons.
+
+        ```javascript
+        var container = new Container();
+        container.register('api:twitter', Twitter);
+
+        var twitter = container.lookup('api:twitter');
+
+        twitter instanceof Twitter; // =&gt; true
+
+        // by default the container will return singletons
+        var twitter2 = container.lookup('api:twitter');
+        twitter instanceof Twitter; // =&gt; true
+
+        twitter === twitter2; //=&gt; true
+        ```
+
+        If singletons are not wanted an optional flag can be provided at lookup.
+
+        ```javascript
+        var container = new Container();
+        container.register('api:twitter', Twitter);
+
+        var twitter = container.lookup('api:twitter', { singleton: false });
+        var twitter2 = container.lookup('api:twitter', { singleton: false });
+
+        twitter === twitter2; //=&gt; false
+        ```
+
+        @method lookup
+        @param {String} fullName
+        @param {Object} options
+        @return {any}
+      */
+      lookup: function(fullName, options) {
+        fullName = this.normalize(fullName);
+
+        options = options || {};
+
+        if (this.cache.has(fullName) &amp;&amp; options.singleton !== false) {
</ins><span class="cx">           return this.cache.get(fullName);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         var value = instantiate(this, fullName);
</span><span class="cx"> 
</span><del>-        if (!value) { return; }
</del><ins>+        if (value === undefined) { return; }
</ins><span class="cx"> 
</span><del>-        if (isSingleton(this, fullName)) {
</del><ins>+        if (isSingleton(this, fullName) &amp;&amp; options.singleton !== false) {
</ins><span class="cx">           this.cache.set(fullName, value);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         return value;
</span><span class="cx">       },
</span><span class="cx"> 
</span><ins>+      /**
+        Given a fullName return the corresponding factory.
+
+        @method lookupFactory
+        @param {String} fullName
+        @return {any}
+      */
+      lookupFactory: function(fullName) {
+        return factoryFor(this, fullName);
+      },
+
+      /**
+        Given a fullName check if the container is aware of its factory
+        or singleton instance.
+
+        @method has
+        @param {String} fullName
+        @return {Boolean}
+      */
</ins><span class="cx">       has: function(fullName) {
</span><span class="cx">         if (this.cache.has(fullName)) {
</span><span class="cx">           return true;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        return !!factoryFor(this, fullName);
</del><ins>+        return !!this.resolve(fullName);
</ins><span class="cx">       },
</span><span class="cx"> 
</span><ins>+      /**
+        Allow registering options for all factories of a type.
+
+        ```javascript
+        var container = new Container();
+
+        // if all of type `connection` must not be singletons
+        container.optionsForType('connection', { singleton: false });
+
+        container.register('connection:twitter', TwitterConnection);
+        container.register('connection:facebook', FacebookConnection);
+
+        var twitter = container.lookup('connection:twitter');
+        var twitter2 = container.lookup('connection:twitter');
+
+        twitter === twitter2; // =&gt; false
+
+        var facebook = container.lookup('connection:facebook');
+        var facebook2 = container.lookup('connection:facebook');
+
+        facebook === facebook2; // =&gt; false
+        ```
+
+        @method optionsForType
+        @param {String} type
+        @param {Object} options
+      */
</ins><span class="cx">       optionsForType: function(type, options) {
</span><span class="cx">         if (this.parent) { illegalChildOperation('optionsForType'); }
</span><span class="cx"> 
</span><span class="cx">         this._typeOptions.set(type, options);
</span><span class="cx">       },
</span><span class="cx"> 
</span><ins>+      /**
+        @method options
+        @param {String} type
+        @param {Object} options
+      */
</ins><span class="cx">       options: function(type, options) {
</span><span class="cx">         this.optionsForType(type, options);
</span><span class="cx">       },
</span><span class="cx"> 
</span><ins>+      /**
+        Used only via `injection`.
+
+        Provides a specialized form of injection, specifically enabling
+        all objects of one type to be injected with a reference to another
+        object.
+
+        For example, provided each object of type `controller` needed a `router`.
+        one would do the following:
+
+        ```javascript
+        var container = new Container();
+
+        container.register('router:main', Router);
+        container.register('controller:user', UserController);
+        container.register('controller:post', PostController);
+
+        container.typeInjection('controller', 'router', 'router:main');
+
+        var user = container.lookup('controller:user');
+        var post = container.lookup('controller:post');
+
+        user.router instanceof Router; //=&gt; true
+        post.router instanceof Router; //=&gt; true
+
+        // both controllers share the same router
+        user.router === post.router; //=&gt; true
+        ```
+
+        @private
+        @method typeInjection
+        @param {String} type
+        @param {String} property
+        @param {String} fullName
+      */
</ins><span class="cx">       typeInjection: function(type, property, fullName) {
</span><span class="cx">         if (this.parent) { illegalChildOperation('typeInjection'); }
</span><span class="cx"> 
</span><del>-        var injections = this.typeInjections.get(type);
-        if (!injections) {
-          injections = [];
-          this.typeInjections.set(type, injections);
-        }
-        injections.push({ property: property, fullName: fullName });
</del><ins>+        addTypeInjection(this.typeInjections, type, property, fullName);
</ins><span class="cx">       },
</span><span class="cx"> 
</span><ins>+      /**
+        Defines injection rules.
+
+        These rules are used to inject dependencies onto objects when they
+        are instantiated.
+
+        Two forms of injections are possible:
+
+        * Injecting one fullName on another fullName
+        * Injecting one fullName on a type
+
+        Example:
+
+        ```javascript
+        var container = new Container();
+
+        container.register('source:main', Source);
+        container.register('model:user', User);
+        container.register('model:post', Post);
+
+        // injecting one fullName on another fullName
+        // eg. each user model gets a post model
+        container.injection('model:user', 'post', 'model:post');
+
+        // injecting one fullName on another type
+        container.injection('model', 'source', 'source:main');
+
+        var user = container.lookup('model:user');
+        var post = container.lookup('model:post');
+
+        user.source instanceof Source; //=&gt; true
+        post.source instanceof Source; //=&gt; true
+
+        user.post instanceof Post; //=&gt; true
+
+        // and both models share the same source
+        user.source === post.source; //=&gt; true
+        ```
+
+        @method injection
+        @param {String} factoryName
+        @param {String} property
+        @param {String} injectionName
+      */
</ins><span class="cx">       injection: function(factoryName, property, injectionName) {
</span><span class="cx">         if (this.parent) { illegalChildOperation('injection'); }
</span><span class="cx"> 
</span><span class="lines">@@ -6197,12 +10714,111 @@
</span><span class="cx">           return this.typeInjection(factoryName, property, injectionName);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        var injections = this.injections[factoryName] = this.injections[factoryName] || [];
-        injections.push({ property: property, fullName: injectionName });
</del><ins>+        addInjection(this.injections, factoryName, property, injectionName);
</ins><span class="cx">       },
</span><span class="cx"> 
</span><ins>+
+      /**
+        Used only via `factoryInjection`.
+
+        Provides a specialized form of injection, specifically enabling
+        all factory of one type to be injected with a reference to another
+        object.
+
+        For example, provided each factory of type `model` needed a `store`.
+        one would do the following:
+
+        ```javascript
+        var container = new Container();
+
+        container.register('store:main', SomeStore);
+
+        container.factoryTypeInjection('model', 'store', 'store:main');
+
+        var store = container.lookup('store:main');
+        var UserFactory = container.lookupFactory('model:user');
+
+        UserFactory.store instanceof SomeStore; //=&gt; true
+        ```
+
+        @private
+        @method factoryTypeInjection
+        @param {String} type
+        @param {String} property
+        @param {String} fullName
+      */
+      factoryTypeInjection: function(type, property, fullName) {
+        if (this.parent) { illegalChildOperation('factoryTypeInjection'); }
+
+        addTypeInjection(this.factoryTypeInjections, type, property, fullName);
+      },
+
+      /**
+        Defines factory injection rules.
+
+        Similar to regular injection rules, but are run against factories, via
+        `Container#lookupFactory`.
+
+        These rules are used to inject objects onto factories when they
+        are looked up.
+
+        Two forms of injections are possible:
+
+      * Injecting one fullName on another fullName
+      * Injecting one fullName on a type
+
+        Example:
+
+        ```javascript
+        var container = new Container();
+
+        container.register('store:main', Store);
+        container.register('store:secondary', OtherStore);
+        container.register('model:user', User);
+        container.register('model:post', Post);
+
+        // injecting one fullName on another type
+        container.factoryInjection('model', 'store', 'store:main');
+
+        // injecting one fullName on another fullName
+        container.factoryInjection('model:post', 'secondaryStore', 'store:secondary');
+
+        var UserFactory = container.lookupFactory('model:user');
+        var PostFactory = container.lookupFactory('model:post');
+        var store = container.lookup('store:main');
+
+        UserFactory.store instanceof Store; //=&gt; true
+        UserFactory.secondaryStore instanceof OtherStore; //=&gt; false
+
+        PostFactory.store instanceof Store; //=&gt; true
+        PostFactory.secondaryStore instanceof OtherStore; //=&gt; true
+
+        // and both models share the same source instance
+        UserFactory.store === PostFactory.store; //=&gt; true
+        ```
+
+        @method factoryInjection
+        @param {String} factoryName
+        @param {String} property
+        @param {String} injectionName
+      */
+      factoryInjection: function(factoryName, property, injectionName) {
+        if (this.parent) { illegalChildOperation('injection'); }
+
+        if (factoryName.indexOf(':') === -1) {
+          return this.factoryTypeInjection(factoryName, property, injectionName);
+        }
+
+        addInjection(this.factoryInjections, factoryName, property, injectionName);
+      },
+
+      /**
+        A depth first traversal, destroying the container, its descendant containers and all
+        their managed objects.
+
+        @method destroy
+      */
</ins><span class="cx">       destroy: function() {
</span><del>-        this.isDestroyed = true;
</del><span class="cx"> 
</span><span class="cx">         for (var i=0, l=this.children.length; i&lt;l; i++) {
</span><span class="cx">           this.children[i].destroy();
</span><span class="lines">@@ -6211,17 +10827,16 @@
</span><span class="cx">         this.children = [];
</span><span class="cx"> 
</span><span class="cx">         eachDestroyable(this, function(item) {
</span><del>-          item.isDestroying = true;
-        });
-
-        eachDestroyable(this, function(item) {
</del><span class="cx">           item.destroy();
</span><span class="cx">         });
</span><span class="cx"> 
</span><del>-        delete this.parent;
</del><ins>+        this.parent = undefined;
</ins><span class="cx">         this.isDestroyed = true;
</span><span class="cx">       },
</span><span class="cx"> 
</span><ins>+      /**
+        @method reset
+      */
</ins><span class="cx">       reset: function() {
</span><span class="cx">         for (var i=0, l=this.children.length; i&lt;l; i++) {
</span><span class="cx">           resetCache(this.children[i]);
</span><span class="lines">@@ -6250,7 +10865,12 @@
</span><span class="cx">       for (var i=0, l=injections.length; i&lt;l; i++) {
</span><span class="cx">         injection = injections[i];
</span><span class="cx">         lookup = container.lookup(injection.fullName);
</span><del>-        hash[injection.property] = lookup;
</del><ins>+
+        if (lookup !== undefined) {
+          hash[injection.property] = lookup;
+        } else {
+          throw new Error('Attempting to inject an unknown injection: `' + injection.fullName + '`');
+        }
</ins><span class="cx">       }
</span><span class="cx"> 
</span><span class="cx">       return hash;
</span><span class="lines">@@ -6272,32 +10892,84 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     function factoryFor(container, fullName) {
</span><del>-      return container.resolve(fullName);
</del><ins>+      var name = container.normalize(fullName);
+      var factory = container.resolve(name);
+      var injectedFactory;
+      var cache = container.factoryCache;
+      var type = fullName.split(&quot;:&quot;)[0];
+
+      if (factory === undefined) { return; }
+
+      if (cache.has(fullName)) {
+        return cache.get(fullName);
+      }
+
+      if (!factory || typeof factory.extend !== 'function' || (!Ember.MODEL_FACTORY_INJECTIONS &amp;&amp; type === 'model')) {
+        // TODO: think about a 'safe' merge style extension
+        // for now just fallback to create time injection
+        return factory;
+      } else {
+
+        var injections        = injectionsFor(container, fullName);
+        var factoryInjections = factoryInjectionsFor(container, fullName);
+
+        factoryInjections._toString = container.makeToString(factory, fullName);
+
+        injectedFactory = factory.extend(injections);
+        injectedFactory.reopenClass(factoryInjections);
+
+        cache.set(fullName, injectedFactory);
+
+        return injectedFactory;
+      }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    function injectionsFor(container ,fullName) {
+      var splitName = fullName.split(&quot;:&quot;),
+        type = splitName[0],
+        injections = [];
+
+      injections = injections.concat(container.typeInjections.get(type) || []);
+      injections = injections.concat(container.injections[fullName] || []);
+
+      injections = buildInjections(container, injections);
+      injections._debugContainerKey = fullName;
+      injections.container = container;
+
+      return injections;
+    }
+
+    function factoryInjectionsFor(container, fullName) {
+      var splitName = fullName.split(&quot;:&quot;),
+        type = splitName[0],
+        factoryInjections = [];
+
+      factoryInjections = factoryInjections.concat(container.factoryTypeInjections.get(type) || []);
+      factoryInjections = factoryInjections.concat(container.factoryInjections[fullName] || []);
+
+      factoryInjections = buildInjections(container, factoryInjections);
+      factoryInjections._debugContainerKey = fullName;
+
+      return factoryInjections;
+    }
+
</ins><span class="cx">     function instantiate(container, fullName) {
</span><span class="cx">       var factory = factoryFor(container, fullName);
</span><span class="cx"> 
</span><del>-      var splitName = fullName.split(&quot;:&quot;),
-          type = splitName[0], name = splitName[1],
-          value;
-
</del><span class="cx">       if (option(container, fullName, 'instantiate') === false) {
</span><span class="cx">         return factory;
</span><span class="cx">       }
</span><span class="cx"> 
</span><span class="cx">       if (factory) {
</span><del>-        var injections = [];
-        injections = injections.concat(container.typeInjections.get(type) || []);
-        injections = injections.concat(container.injections[fullName] || []);
-
-        var hash = buildInjections(container, injections);
-        hash.container = container;
-        hash._debugContainerKey = fullName;
-
-        value = factory.create(hash);
-
-        return value;
</del><ins>+        if (typeof factory.extend === 'function') {
+          // assume the factory was extendable and is already injected
+          return factory.create();
+        } else {
+          // assume the factory was extendable
+          // to create time injections
+          // TODO: support new'ing for instantiation and merge injections for pure JS Functions
+          return factory.create(injectionsFor(container, fullName));
+        }
</ins><span class="cx">       }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -6316,6 +10988,25 @@
</span><span class="cx">       container.cache.dict = {};
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    function addTypeInjection(rules, type, property, fullName) {
+      var injections = rules.get(type);
+
+      if (!injections) {
+        injections = [];
+        rules.set(type, injections);
+      }
+
+      injections.push({
+        property: property,
+        fullName: fullName
+      });
+    }
+
+    function addInjection(rules, factoryName, property, injectionName) {
+      var injections = rules[factoryName] = rules[factoryName] || [];
+      injections.push({ property: property, fullName: injectionName });
+    }
+
</ins><span class="cx">     return Container;
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -6330,131 +11021,7 @@
</span><span class="cx"> 
</span><span class="cx"> var indexOf = Ember.EnumerableUtils.indexOf;
</span><span class="cx"> 
</span><del>-// ........................................
-// TYPING &amp; ARRAY MESSAGING
-//
-
-var TYPE_MAP = {};
-var t = &quot;Boolean Number String Function Array Date RegExp Object&quot;.split(&quot; &quot;);
-Ember.ArrayPolyfills.forEach.call(t, function(name) {
-  TYPE_MAP[ &quot;[object &quot; + name + &quot;]&quot; ] = name.toLowerCase();
-});
-
-var toString = Object.prototype.toString;
-
</del><span class="cx"> /**
</span><del>-  Returns a consistent type for the passed item.
-
-  Use this instead of the built-in `typeof` to get the type of an item.
-  It will return the same result across all browsers and includes a bit
-  more detail. Here is what will be returned:
-
-      | Return Value  | Meaning                                              |
-      |---------------|------------------------------------------------------|
-      | 'string'      | String primitive                                     |
-      | 'number'      | Number primitive                                     |
-      | 'boolean'     | Boolean primitive                                    |
-      | 'null'        | Null value                                           |
-      | 'undefined'   | Undefined value                                      |
-      | 'function'    | A function                                           |
-      | 'array'       | An instance of Array                                 |
-      | 'class'       | A Ember class (created using Ember.Object.extend())  |
-      | 'instance'    | A Ember object instance                              |
-      | 'error'       | An instance of the Error object                      |
-      | 'object'      | A JavaScript object not inheriting from Ember.Object |
-
-  Examples:
-
-  ```javascript
-  Ember.typeOf();                       // 'undefined'
-  Ember.typeOf(null);                   // 'null'
-  Ember.typeOf(undefined);              // 'undefined'
-  Ember.typeOf('michael');              // 'string'
-  Ember.typeOf(101);                    // 'number'
-  Ember.typeOf(true);                   // 'boolean'
-  Ember.typeOf(Ember.makeArray);        // 'function'
-  Ember.typeOf([1,2,90]);               // 'array'
-  Ember.typeOf(Ember.Object.extend());  // 'class'
-  Ember.typeOf(Ember.Object.create());  // 'instance'
-  Ember.typeOf(new Error('teamocil'));  // 'error'
-
-  // &quot;normal&quot; JavaScript object
-  Ember.typeOf({a: 'b'});              // 'object'
-  ```
-
-  @method typeOf
-  @for Ember
-  @param item {Object} the item to check
-  @return {String} the type
-*/
-Ember.typeOf = function(item) {
-  var ret;
-
-  ret = (item === null || item === undefined) ? String(item) : TYPE_MAP[toString.call(item)] || 'object';
-
-  if (ret === 'function') {
-    if (Ember.Object &amp;&amp; Ember.Object.detect(item)) ret = 'class';
-  } else if (ret === 'object') {
-    if (item instanceof Error) ret = 'error';
-    else if (Ember.Object &amp;&amp; item instanceof Ember.Object) ret = 'instance';
-    else ret = 'object';
-  }
-
-  return ret;
-};
-
-/**
-  Returns true if the passed value is null or undefined. This avoids errors
-  from JSLint complaining about use of ==, which can be technically
-  confusing.
-
-  ```javascript
-  Ember.isNone();              // true
-  Ember.isNone(null);          // true
-  Ember.isNone(undefined);     // true
-  Ember.isNone('');            // false
-  Ember.isNone([]);            // false
-  Ember.isNone(function(){});  // false
-  ```
-
-  @method isNone
-  @for Ember
-  @param {Object} obj Value to test
-  @return {Boolean}
-*/
-Ember.isNone = function(obj) {
-  return obj === null || obj === undefined;
-};
-Ember.none = Ember.deprecateFunc(&quot;Ember.none is deprecated. Please use Ember.isNone instead.&quot;, Ember.isNone);
-
-/**
-  Verifies that a value is `null` or an empty string, empty array,
-  or empty function.
-
-  Constrains the rules on `Ember.isNone` by returning false for empty
-  string and empty arrays.
-
-  ```javascript
-  Ember.isEmpty();                // true
-  Ember.isEmpty(null);            // true
-  Ember.isEmpty(undefined);       // true
-  Ember.isEmpty('');              // true
-  Ember.isEmpty([]);              // true
-  Ember.isEmpty('Adam Hawkins');  // false
-  Ember.isEmpty([0,1,2]);         // false
-  ```
-
-  @method isEmpty
-  @for Ember
-  @param {Object} obj Value to test
-  @return {Boolean}
-*/
-Ember.isEmpty = function(obj) {
-  return obj === null || obj === undefined || (obj.length === 0 &amp;&amp; typeof obj !== 'function') || (typeof obj === 'object' &amp;&amp; Ember.get(obj, 'length') === 0);
-};
-Ember.empty = Ember.deprecateFunc(&quot;Ember.empty is deprecated. Please use Ember.isEmpty instead.&quot;, Ember.isEmpty) ;
-
-/**
</del><span class="cx">  This will compare two javascript values of possibly different types.
</span><span class="cx">  It will tell you which one is greater than the other by returning:
</span><span class="cx"> 
</span><span class="lines">@@ -6618,7 +11185,7 @@
</span><span class="cx"> 
</span><span class="cx">   @method copy
</span><span class="cx">   @for Ember
</span><del>-  @param {Object} object The object to clone
</del><ins>+  @param {Object} obj The object to clone
</ins><span class="cx">   @param {Boolean} deep If true, a deep copy of the object is made
</span><span class="cx">   @return {Object} The cloned object
</span><span class="cx"> */
</span><span class="lines">@@ -6642,7 +11209,11 @@
</span><span class="cx">   @return {String} A description of the object
</span><span class="cx"> */
</span><span class="cx"> Ember.inspect = function(obj) {
</span><del>-  if (typeof obj !== 'object' || obj === null) {
</del><ins>+  var type = Ember.typeOf(obj);
+  if (type === 'array') {
+    return '[' + obj + ']';
+  }
+  if (type !== 'object') {
</ins><span class="cx">     return obj + '';
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -6708,41 +11279,44 @@
</span><span class="cx"> */
</span><span class="cx"> Ember.keys = Object.keys;
</span><span class="cx"> 
</span><del>-if (!Ember.keys) {
</del><ins>+if (!Ember.keys || Ember.create.isSimulated) {
+  var prototypeProperties = [
+    'constructor',
+    'hasOwnProperty',
+    'isPrototypeOf',
+    'propertyIsEnumerable',
+    'valueOf',
+    'toLocaleString',
+    'toString'
+  ],
+  pushPropertyName = function(obj, array, key) {
+    // Prevents browsers that don't respect non-enumerability from
+    // copying internal Ember properties
+    if (key.substring(0,2) === '__') return;
+    if (key === '_super') return;
+    if (indexOf(array, key) &gt;= 0) return;
+    if (!obj.hasOwnProperty(key)) return;
+
+    array.push(key);
+  };
+
</ins><span class="cx">   Ember.keys = function(obj) {
</span><del>-    var ret = [];
-    for(var key in obj) {
-      if (obj.hasOwnProperty(key)) { ret.push(key); }
</del><ins>+    var ret = [], key;
+    for (key in obj) {
+      pushPropertyName(obj, ret, key);
</ins><span class="cx">     }
</span><ins>+
+    // IE8 doesn't enumerate property that named the same as prototype properties.
+    for (var i = 0, l = prototypeProperties.length; i &lt; l; i++) {
+      key = prototypeProperties[i];
+
+      pushPropertyName(obj, ret, key);
+    }
+
</ins><span class="cx">     return ret;
</span><span class="cx">   };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// ..........................................................
-// ERROR
-//
-
-var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
-
-/**
-  A subclass of the JavaScript Error object for use in Ember.
-
-  @class Error
-  @namespace Ember
-  @extends Error
-  @constructor
-*/
-Ember.Error = function() {
-  var tmp = Error.prototype.constructor.apply(this, arguments);
-
-  // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
-  for (var idx = 0; idx &lt; errorProps.length; idx++) {
-    this[errorProps[idx]] = tmp[errorProps[idx]];
-  }
-};
-
-Ember.Error.prototype = Ember.create(Error.prototype);
-
</del><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -6755,7 +11329,7 @@
</span><span class="cx"> 
</span><span class="cx"> var STRING_DASHERIZE_REGEXP = (/[ _]/g);
</span><span class="cx"> var STRING_DASHERIZE_CACHE = {};
</span><del>-var STRING_DECAMELIZE_REGEXP = (/([a-z])([A-Z])/g);
</del><ins>+var STRING_DECAMELIZE_REGEXP = (/([a-z\d])([A-Z])/g);
</ins><span class="cx"> var STRING_CAMELIZE_REGEXP = (/(\-|_|\.|\s)+(.)?/g);
</span><span class="cx"> var STRING_UNDERSCORE_REGEXP_1 = (/([a-z\d])([A-Z]+)/g);
</span><span class="cx"> var STRING_UNDERSCORE_REGEXP_2 = (/\-|\s+/g);
</span><span class="lines">@@ -6798,16 +11372,17 @@
</span><span class="cx">     ```
</span><span class="cx"> 
</span><span class="cx">     @method fmt
</span><del>-    @param {Object...} [args]
</del><ins>+    @param {String} str The string to format
+    @param {Array} formats An array of parameters to interpolate into string.
</ins><span class="cx">     @return {String} formatted string
</span><span class="cx">   */
</span><span class="cx">   fmt: function(str, formats) {
</span><span class="cx">     // first, replace any ORDERED replacements.
</span><span class="cx">     var idx  = 0; // the current index for non-numerical replacements
</span><span class="cx">     return str.replace(/%@([0-9]+)?/g, function(s, argIndex) {
</span><del>-      argIndex = (argIndex) ? parseInt(argIndex,0) - 1 : idx++ ;
</del><ins>+      argIndex = (argIndex) ? parseInt(argIndex, 10) - 1 : idx++;
</ins><span class="cx">       s = formats[argIndex];
</span><del>-      return ((s === null) ? '(null)' : (s === undefined) ? '' : s).toString();
</del><ins>+      return (s === null) ? '(null)' : (s === undefined) ? '' : Ember.inspect(s);
</ins><span class="cx">     }) ;
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="lines">@@ -6880,7 +11455,7 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Replaces underscores or spaces with dashes.
</del><ins>+    Replaces underscores, spaces, or camelCase with dashes.
</ins><span class="cx"> 
</span><span class="cx">     ```javascript
</span><span class="cx">     'innerHTML'.dasherize();          // 'inner-html'
</span><span class="lines">@@ -6895,10 +11470,11 @@
</span><span class="cx">   */
</span><span class="cx">   dasherize: function(str) {
</span><span class="cx">     var cache = STRING_DASHERIZE_CACHE,
</span><del>-        ret   = cache[str];
</del><ins>+        hit   = cache.hasOwnProperty(str),
+        ret;
</ins><span class="cx"> 
</span><del>-    if (ret) {
-      return ret;
</del><ins>+    if (hit) {
+      return cache[str];
</ins><span class="cx">     } else {
</span><span class="cx">       ret = Ember.String.decamelize(str).replace(STRING_DASHERIZE_REGEXP,'-');
</span><span class="cx">       cache[str] = ret;
</span><span class="lines">@@ -6908,13 +11484,14 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Returns the lowerCaseCamel form of a string.
</del><ins>+    Returns the lowerCamelCase form of a string.
</ins><span class="cx"> 
</span><span class="cx">     ```javascript
</span><span class="cx">     'innerHTML'.camelize();          // 'innerHTML'
</span><span class="cx">     'action_name'.camelize();        // 'actionName'
</span><span class="cx">     'css-class-name'.camelize();     // 'cssClassName'
</span><span class="cx">     'my favorite items'.camelize();  // 'myFavoriteItems'
</span><ins>+    'My Favorite Items'.camelize();  // 'myFavoriteItems'
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><span class="cx">     @method camelize
</span><span class="lines">@@ -6924,6 +11501,8 @@
</span><span class="cx">   camelize: function(str) {
</span><span class="cx">     return str.replace(STRING_CAMELIZE_REGEXP, function(match, separator, chr) {
</span><span class="cx">       return chr ? chr.toUpperCase() : '';
</span><ins>+    }).replace(/^([A-Z])/, function(match, separator, chr) {
+      return match.toLowerCase();
</ins><span class="cx">     });
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="lines">@@ -6935,7 +11514,7 @@
</span><span class="cx">     'action_name'.classify();        // 'ActionName'
</span><span class="cx">     'css-class-name'.classify();     // 'CssClassName'
</span><span class="cx">     'my favorite items'.classify();  // 'MyFavoriteItems'
</span><del>-    ``` 
</del><ins>+    ```
</ins><span class="cx"> 
</span><span class="cx">     @method classify
</span><span class="cx">     @param {String} str the string to classify
</span><span class="lines">@@ -6976,21 +11555,24 @@
</span><span class="cx">   /**
</span><span class="cx">     Returns the Capitalized form of a string
</span><span class="cx"> 
</span><del>-       'innerHTML'.capitalize()         =&gt; 'InnerHTML'
-       'action_name'.capitalize()       =&gt; 'Action_name'
-       'css-class-name'.capitalize()    =&gt; 'Css-class-name'
-       'my favorite items'.capitalize() =&gt; 'My favorite items'
</del><ins>+    ```javascript
+    'innerHTML'.capitalize()         // 'InnerHTML'
+    'action_name'.capitalize()       // 'Action_name'
+    'css-class-name'.capitalize()    // 'Css-class-name'
+    'my favorite items'.capitalize() // 'My favorite items'
+    ```
</ins><span class="cx"> 
</span><span class="cx">     @method capitalize
</span><del>-    @param {String} str
-    @return {String}
</del><ins>+    @param {String} str The string to capitalize.
+    @return {String} The capitalized string.
</ins><span class="cx">   */
</span><span class="cx">   capitalize: function(str) {
</span><span class="cx">     return str.charAt(0).toUpperCase() + str.substr(1);
</span><span class="cx">   }
</span><del>-
</del><span class="cx"> };
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -7013,10 +11595,11 @@
</span><span class="cx">     capitalize = Ember.String.capitalize,
</span><span class="cx">     classify = Ember.String.classify;
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    See {{#crossLink &quot;Ember.String/fmt&quot;}}{{/crossLink}}
</del><ins>+    See [Ember.String.fmt](/api/classes/Ember.String.html#method_fmt).
</ins><span class="cx"> 
</span><span class="cx">     @method fmt
</span><span class="cx">     @for String
</span><span class="lines">@@ -7026,7 +11609,7 @@
</span><span class="cx">   };
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    See {{#crossLink &quot;Ember.String/w&quot;}}{{/crossLink}}
</del><ins>+    See [Ember.String.w](/api/classes/Ember.String.html#method_w).
</ins><span class="cx"> 
</span><span class="cx">     @method w
</span><span class="cx">     @for String
</span><span class="lines">@@ -7036,7 +11619,7 @@
</span><span class="cx">   };
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    See {{#crossLink &quot;Ember.String/loc&quot;}}{{/crossLink}}
</del><ins>+    See [Ember.String.loc](/api/classes/Ember.String.html#method_loc).
</ins><span class="cx"> 
</span><span class="cx">     @method loc
</span><span class="cx">     @for String
</span><span class="lines">@@ -7046,7 +11629,7 @@
</span><span class="cx">   };
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    See {{#crossLink &quot;Ember.String/camelize&quot;}}{{/crossLink}}
</del><ins>+    See [Ember.String.camelize](/api/classes/Ember.String.html#method_camelize).
</ins><span class="cx"> 
</span><span class="cx">     @method camelize
</span><span class="cx">     @for String
</span><span class="lines">@@ -7056,7 +11639,7 @@
</span><span class="cx">   };
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    See {{#crossLink &quot;Ember.String/decamelize&quot;}}{{/crossLink}}
</del><ins>+    See [Ember.String.decamelize](/api/classes/Ember.String.html#method_decamelize).
</ins><span class="cx"> 
</span><span class="cx">     @method decamelize
</span><span class="cx">     @for String
</span><span class="lines">@@ -7066,7 +11649,7 @@
</span><span class="cx">   };
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    See {{#crossLink &quot;Ember.String/dasherize&quot;}}{{/crossLink}}
</del><ins>+    See [Ember.String.dasherize](/api/classes/Ember.String.html#method_dasherize).
</ins><span class="cx"> 
</span><span class="cx">     @method dasherize
</span><span class="cx">     @for String
</span><span class="lines">@@ -7076,7 +11659,7 @@
</span><span class="cx">   };
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    See {{#crossLink &quot;Ember.String/underscore&quot;}}{{/crossLink}}
</del><ins>+    See [Ember.String.underscore](/api/classes/Ember.String.html#method_underscore).
</ins><span class="cx"> 
</span><span class="cx">     @method underscore
</span><span class="cx">     @for String
</span><span class="lines">@@ -7086,7 +11669,7 @@
</span><span class="cx">   };
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    See {{#crossLink &quot;Ember.String/classify&quot;}}{{/crossLink}}
</del><ins>+    See [Ember.String.classify](/api/classes/Ember.String.html#method_classify).
</ins><span class="cx"> 
</span><span class="cx">     @method classify
</span><span class="cx">     @for String
</span><span class="lines">@@ -7096,7 +11679,7 @@
</span><span class="cx">   };
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    See {{#crossLink &quot;Ember.String/capitalize&quot;}}{{/crossLink}}
</del><ins>+    See [Ember.String.capitalize](/api/classes/Ember.String.html#method_capitalize).
</ins><span class="cx"> 
</span><span class="cx">     @method capitalize
</span><span class="cx">     @for String
</span><span class="lines">@@ -7105,6 +11688,7 @@
</span><span class="cx">     return capitalize(this);
</span><span class="cx">   };
</span><span class="cx"> 
</span><ins>+  
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -7118,134 +11702,1269 @@
</span><span class="cx"> @submodule ember-runtime
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var a_slice = Array.prototype.slice;
</del><ins>+var get = Ember.get,
+    set = Ember.set,
+    slice = Array.prototype.slice,
+    getProperties = Ember.getProperties;
</ins><span class="cx"> 
</span><del>-if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Function) {
</del><ins>+/**
+  ## Overview
</ins><span class="cx"> 
</span><ins>+  This mixin provides properties and property observing functionality, core
+  features of the Ember object model.
+
+  Properties and observers allow one object to observe changes to a
+  property on another object. This is one of the fundamental ways that
+  models, controllers and views communicate with each other in an Ember
+  application.
+
+  Any object that has this mixin applied can be used in observer
+  operations. That includes `Ember.Object` and most objects you will
+  interact with as you write your Ember application.
+
+  Note that you will not generally apply this mixin to classes yourself,
+  but you will use the features provided by this module frequently, so it
+  is important to understand how to use it.
+
+  ## Using `get()` and `set()`
+
+  Because of Ember's support for bindings and observers, you will always
+  access properties using the get method, and set properties using the
+  set method. This allows the observing objects to be notified and
+  computed properties to be handled properly.
+
+  More documentation about `get` and `set` are below.
+
+  ## Observing Property Changes
+
+  You typically observe property changes simply by adding the `observes`
+  call to the end of your method declarations in classes that you write.
+  For example:
+
+  ```javascript
+  Ember.Object.extend({
+    valueObserver: function() {
+      // Executes whenever the &quot;value&quot; property changes
+    }.observes('value')
+  });
+  ```
+
+  Although this is the most common way to add an observer, this capability
+  is actually built into the `Ember.Object` class on top of two methods
+  defined in this mixin: `addObserver` and `removeObserver`. You can use
+  these two methods to add and remove observers yourself if you need to
+  do so at runtime.
+
+  To add an observer for a property, call:
+
+  ```javascript
+  object.addObserver('propertyKey', targetObject, targetAction)
+  ```
+
+  This will call the `targetAction` method on the `targetObject` whenever
+  the value of the `propertyKey` changes.
+
+  Note that if `propertyKey` is a computed property, the observer will be
+  called when any of the property dependencies are changed, even if the
+  resulting value of the computed property is unchanged. This is necessary
+  because computed properties are not computed until `get` is called.
+
+  @class Observable
+  @namespace Ember
+*/
+Ember.Observable = Ember.Mixin.create({
+
</ins><span class="cx">   /**
</span><del>-    The `property` extension of Javascript's Function prototype is available
-    when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is
-    `true`, which is the default.
</del><ins>+    Retrieves the value of a property from the object.
</ins><span class="cx"> 
</span><del>-    Computed properties allow you to treat a function like a property:
</del><ins>+    This method is usually similar to using `object[keyName]` or `object.keyName`,
+    however it supports both computed properties and the unknownProperty
+    handler.
</ins><span class="cx"> 
</span><ins>+    Because `get` unifies the syntax for accessing all these kinds
+    of properties, it can make many refactorings easier, such as replacing a
+    simple property with a computed property, or vice versa.
+
+    ### Computed Properties
+
+    Computed properties are methods defined with the `property` modifier
+    declared at the end, such as:
+
</ins><span class="cx">     ```javascript
</span><del>-    MyApp.president = Ember.Object.create({
-      firstName: &quot;Barack&quot;,
-      lastName: &quot;Obama&quot;,
</del><ins>+    fullName: function() {
+      return this.get('firstName') + ' ' + this.get('lastName');
+    }.property('firstName', 'lastName')
+    ```
</ins><span class="cx"> 
</span><del>-      fullName: function() {
-        return this.get('firstName') + ' ' + this.get('lastName');
</del><ins>+    When you call `get` on a computed property, the function will be
+    called and the return value will be returned instead of the function
+    itself.
</ins><span class="cx"> 
</span><del>-        // Call this flag to mark the function as a property
-      }.property()
</del><ins>+    ### Unknown Properties
+
+    Likewise, if you try to call `get` on a property whose value is
+    `undefined`, the `unknownProperty()` method will be called on the object.
+    If this method returns any value other than `undefined`, it will be returned
+    instead. This allows you to implement &quot;virtual&quot; properties that are
+    not defined upfront.
+
+    @method get
+    @param {String} keyName The property to retrieve
+    @return {Object} The property value or undefined.
+  */
+  get: function(keyName) {
+    return get(this, keyName);
+  },
+
+  /**
+    To get multiple properties at once, call `getProperties`
+    with a list of strings or an array:
+
+    ```javascript
+    record.getProperties('firstName', 'lastName', 'zipCode');  // { firstName: 'John', lastName: 'Doe', zipCode: '10011' }
+    ```
+
+    is equivalent to:
+
+    ```javascript
+    record.getProperties(['firstName', 'lastName', 'zipCode']);  // { firstName: 'John', lastName: 'Doe', zipCode: '10011' }
+    ```
+
+    @method getProperties
+    @param {String...|Array} list of keys to get
+    @return {Hash}
+  */
+  getProperties: function() {
+    return getProperties.apply(null, [this].concat(slice.call(arguments)));
+  },
+
+  /**
+    Sets the provided key or path to the value.
+
+    This method is generally very similar to calling `object[key] = value` or
+    `object.key = value`, except that it provides support for computed
+    properties, the `setUnknownProperty()` method and property observers.
+
+    ### Computed Properties
+
+    If you try to set a value on a key that has a computed property handler
+    defined (see the `get()` method for an example), then `set()` will call
+    that method, passing both the value and key instead of simply changing
+    the value itself. This is useful for those times when you need to
+    implement a property that is composed of one or more member
+    properties.
+
+    ### Unknown Properties
+
+    If you try to set a value on a key that is undefined in the target
+    object, then the `setUnknownProperty()` handler will be called instead. This
+    gives you an opportunity to implement complex &quot;virtual&quot; properties that
+    are not predefined on the object. If `setUnknownProperty()` returns
+    undefined, then `set()` will simply set the value on the object.
+
+    ### Property Observers
+
+    In addition to changing the property, `set()` will also register a property
+    change with the object. Unless you have placed this call inside of a
+    `beginPropertyChanges()` and `endPropertyChanges(),` any &quot;local&quot; observers
+    (i.e. observer methods declared on the same object), will be called
+    immediately. Any &quot;remote&quot; observers (i.e. observer methods declared on
+    another object) will be placed in a queue and called at a later time in a
+    coalesced manner.
+
+    ### Chaining
+
+    In addition to property changes, `set()` returns the value of the object
+    itself so you can do chaining like this:
+
+    ```javascript
+    record.set('firstName', 'Charles').set('lastName', 'Jolley');
+    ```
+
+    @method set
+    @param {String} keyName The property to set
+    @param {Object} value The value to set or `null`.
+    @return {Ember.Observable}
+  */
+  set: function(keyName, value) {
+    set(this, keyName, value);
+    return this;
+  },
+
+
+  /**
+    Sets a list of properties at once. These properties are set inside
+    a single `beginPropertyChanges` and `endPropertyChanges` batch, so
+    observers will be buffered.
+
+    ```javascript
+    record.setProperties({ firstName: 'Charles', lastName: 'Jolley' });
+    ```
+
+    @method setProperties
+    @param {Hash} hash the hash of keys and values to set
+    @return {Ember.Observable}
+  */
+  setProperties: function(hash) {
+    return Ember.setProperties(this, hash);
+  },
+
+  /**
+    Begins a grouping of property changes.
+
+    You can use this method to group property changes so that notifications
+    will not be sent until the changes are finished. If you plan to make a
+    large number of changes to an object at one time, you should call this
+    method at the beginning of the changes to begin deferring change
+    notifications. When you are done making changes, call
+    `endPropertyChanges()` to deliver the deferred change notifications and end
+    deferring.
+
+    @method beginPropertyChanges
+    @return {Ember.Observable}
+  */
+  beginPropertyChanges: function() {
+    Ember.beginPropertyChanges();
+    return this;
+  },
+
+  /**
+    Ends a grouping of property changes.
+
+    You can use this method to group property changes so that notifications
+    will not be sent until the changes are finished. If you plan to make a
+    large number of changes to an object at one time, you should call
+    `beginPropertyChanges()` at the beginning of the changes to defer change
+    notifications. When you are done making changes, call this method to
+    deliver the deferred change notifications and end deferring.
+
+    @method endPropertyChanges
+    @return {Ember.Observable}
+  */
+  endPropertyChanges: function() {
+    Ember.endPropertyChanges();
+    return this;
+  },
+
+  /**
+    Notify the observer system that a property is about to change.
+
+    Sometimes you need to change a value directly or indirectly without
+    actually calling `get()` or `set()` on it. In this case, you can use this
+    method and `propertyDidChange()` instead. Calling these two methods
+    together will notify all observers that the property has potentially
+    changed value.
+
+    Note that you must always call `propertyWillChange` and `propertyDidChange`
+    as a pair. If you do not, it may get the property change groups out of
+    order and cause notifications to be delivered more often than you would
+    like.
+
+    @method propertyWillChange
+    @param {String} keyName The property key that is about to change.
+    @return {Ember.Observable}
+  */
+  propertyWillChange: function(keyName) {
+    Ember.propertyWillChange(this, keyName);
+    return this;
+  },
+
+  /**
+    Notify the observer system that a property has just changed.
+
+    Sometimes you need to change a value directly or indirectly without
+    actually calling `get()` or `set()` on it. In this case, you can use this
+    method and `propertyWillChange()` instead. Calling these two methods
+    together will notify all observers that the property has potentially
+    changed value.
+
+    Note that you must always call `propertyWillChange` and `propertyDidChange`
+    as a pair. If you do not, it may get the property change groups out of
+    order and cause notifications to be delivered more often than you would
+    like.
+
+    @method propertyDidChange
+    @param {String} keyName The property key that has just changed.
+    @return {Ember.Observable}
+  */
+  propertyDidChange: function(keyName) {
+    Ember.propertyDidChange(this, keyName);
+    return this;
+  },
+
+  /**
+    Convenience method to call `propertyWillChange` and `propertyDidChange` in
+    succession.
+
+    @method notifyPropertyChange
+    @param {String} keyName The property key to be notified about.
+    @return {Ember.Observable}
+  */
+  notifyPropertyChange: function(keyName) {
+    this.propertyWillChange(keyName);
+    this.propertyDidChange(keyName);
+    return this;
+  },
+
+  addBeforeObserver: function(key, target, method) {
+    Ember.addBeforeObserver(this, key, target, method);
+  },
+
+  /**
+    Adds an observer on a property.
+
+    This is the core method used to register an observer for a property.
+
+    Once you call this method, any time the key's value is set, your observer
+    will be notified. Note that the observers are triggered any time the
+    value is set, regardless of whether it has actually changed. Your
+    observer should be prepared to handle that.
+
+    You can also pass an optional context parameter to this method. The
+    context will be passed to your observer method whenever it is triggered.
+    Note that if you add the same target/method pair on a key multiple times
+    with different context parameters, your observer will only be called once
+    with the last context you passed.
+
+    ### Observer Methods
+
+    Observer methods you pass should generally have the following signature if
+    you do not pass a `context` parameter:
+
+    ```javascript
+    fooDidChange: function(sender, key, value, rev) { };
+    ```
+
+    The sender is the object that changed. The key is the property that
+    changes. The value property is currently reserved and unused. The rev
+    is the last property revision of the object when it changed, which you can
+    use to detect if the key value has really changed or not.
+
+    If you pass a `context` parameter, the context will be passed before the
+    revision like so:
+
+    ```javascript
+    fooDidChange: function(sender, key, value, context, rev) { };
+    ```
+
+    Usually you will not need the value, context or revision parameters at
+    the end. In this case, it is common to write observer methods that take
+    only a sender and key value as parameters or, if you aren't interested in
+    any of these values, to write an observer that has no parameters at all.
+
+    @method addObserver
+    @param {String} key The key to observer
+    @param {Object} target The target object to invoke
+    @param {String|Function} method The method to invoke.
+    @return {Ember.Object} self
+  */
+  addObserver: function(key, target, method) {
+    Ember.addObserver(this, key, target, method);
+  },
+
+  /**
+    Remove an observer you have previously registered on this object. Pass
+    the same key, target, and method you passed to `addObserver()` and your
+    target will no longer receive notifications.
+
+    @method removeObserver
+    @param {String} key The key to observer
+    @param {Object} target The target object to invoke
+    @param {String|Function} method The method to invoke.
+    @return {Ember.Observable} receiver
+  */
+  removeObserver: function(key, target, method) {
+    Ember.removeObserver(this, key, target, method);
+  },
+
+  /**
+    Returns `true` if the object currently has observers registered for a
+    particular key. You can use this method to potentially defer performing
+    an expensive action until someone begins observing a particular property
+    on the object.
+
+    @method hasObserverFor
+    @param {String} key Key to check
+    @return {Boolean}
+  */
+  hasObserverFor: function(key) {
+    return Ember.hasListeners(this, key+':change');
+  },
+
+  /**
+    Retrieves the value of a property, or a default value in the case that the
+    property returns `undefined`.
+
+    ```javascript
+    person.getWithDefault('lastName', 'Doe');
+    ```
+
+    @method getWithDefault
+    @param {String} keyName The name of the property to retrieve
+    @param {Object} defaultValue The value to return if the property value is undefined
+    @return {Object} The property value or the defaultValue.
+  */
+  getWithDefault: function(keyName, defaultValue) {
+    return Ember.getWithDefault(this, keyName, defaultValue);
+  },
+
+  /**
+    Set the value of a property to the current value plus some amount.
+
+    ```javascript
+    person.incrementProperty('age');
+    team.incrementProperty('score', 2);
+    ```
+
+    @method incrementProperty
+    @param {String} keyName The name of the property to increment
+    @param {Number} increment The amount to increment by. Defaults to 1
+    @return {Number} The new property value
+  */
+  incrementProperty: function(keyName, increment) {
+    if (Ember.isNone(increment)) { increment = 1; }
+    Ember.assert(&quot;Must pass a numeric value to incrementProperty&quot;, (!isNaN(parseFloat(increment)) &amp;&amp; isFinite(increment)));
+    set(this, keyName, (get(this, keyName) || 0) + increment);
+    return get(this, keyName);
+  },
+
+  /**
+    Set the value of a property to the current value minus some amount.
+
+    ```javascript
+    player.decrementProperty('lives');
+    orc.decrementProperty('health', 5);
+    ```
+
+    @method decrementProperty
+    @param {String} keyName The name of the property to decrement
+    @param {Number} decrement The amount to decrement by. Defaults to 1
+    @return {Number} The new property value
+  */
+  decrementProperty: function(keyName, decrement) {
+    if (Ember.isNone(decrement)) { decrement = 1; }
+    Ember.assert(&quot;Must pass a numeric value to decrementProperty&quot;, (!isNaN(parseFloat(decrement)) &amp;&amp; isFinite(decrement)));
+    set(this, keyName, (get(this, keyName) || 0) - decrement);
+    return get(this, keyName);
+  },
+
+  /**
+    Set the value of a boolean property to the opposite of it's
+    current value.
+
+    ```javascript
+    starship.toggleProperty('warpDriveEngaged');
+    ```
+
+    @method toggleProperty
+    @param {String} keyName The name of the property to toggle
+    @return {Object} The new property value
+  */
+  toggleProperty: function(keyName) {
+    set(this, keyName, !get(this, keyName));
+    return get(this, keyName);
+  },
+
+  /**
+    Returns the cached value of a computed property, if it exists.
+    This allows you to inspect the value of a computed property
+    without accidentally invoking it if it is intended to be
+    generated lazily.
+
+    @method cacheFor
+    @param {String} keyName
+    @return {Object} The cached value of the computed property, if any
+  */
+  cacheFor: function(keyName) {
+    return Ember.cacheFor(this, keyName);
+  },
+
+  // intended for debugging purposes
+  observersForKey: function(keyName) {
+    return Ember.observersFor(this, keyName);
+  }
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember
+  @submodule ember-runtime
+*/
+
+
+// NOTE: this object should never be included directly. Instead use `Ember.Object`.
+// We only define this separately so that `Ember.Set` can depend on it.
+
+
+var set = Ember.set, get = Ember.get,
+    o_create = Ember.create,
+    o_defineProperty = Ember.platform.defineProperty,
+    GUID_KEY = Ember.GUID_KEY,
+    guidFor = Ember.guidFor,
+    generateGuid = Ember.generateGuid,
+    meta = Ember.meta,
+    rewatch = Ember.rewatch,
+    finishChains = Ember.finishChains,
+    sendEvent = Ember.sendEvent,
+    destroy = Ember.destroy,
+    schedule = Ember.run.schedule,
+    Mixin = Ember.Mixin,
+    applyMixin = Mixin._apply,
+    finishPartial = Mixin.finishPartial,
+    reopen = Mixin.prototype.reopen,
+    MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER,
+    indexOf = Ember.EnumerableUtils.indexOf;
+
+var undefinedDescriptor = {
+  configurable: true,
+  writable: true,
+  enumerable: false,
+  value: undefined
+};
+
+function makeCtor() {
+
+  // Note: avoid accessing any properties on the object since it makes the
+  // method a lot faster. This is glue code so we want it to be as fast as
+  // possible.
+
+  var wasApplied = false, initMixins, initProperties;
+
+  var Class = function() {
+    if (!wasApplied) {
+      Class.proto(); // prepare prototype...
+    }
+    o_defineProperty(this, GUID_KEY, undefinedDescriptor);
+    o_defineProperty(this, '_super', undefinedDescriptor);
+    var m = meta(this), proto = m.proto;
+    m.proto = this;
+    if (initMixins) {
+      // capture locally so we can clear the closed over variable
+      var mixins = initMixins;
+      initMixins = null;
+      this.reopen.apply(this, mixins);
+    }
+    if (initProperties) {
+      // capture locally so we can clear the closed over variable
+      var props = initProperties;
+      initProperties = null;
+
+      var concatenatedProperties = this.concatenatedProperties;
+
+      for (var i = 0, l = props.length; i &lt; l; i++) {
+        var properties = props[i];
+
+        Ember.assert(&quot;Ember.Object.create no longer supports mixing in other definitions, use createWithMixins instead.&quot;, !(properties instanceof Ember.Mixin));
+
+        if (typeof properties !== 'object' &amp;&amp; properties !== undefined) {
+          throw new Ember.Error(&quot;Ember.Object.create only accepts objects.&quot;);
+        }
+
+        if (!properties) { continue; }
+
+        var keyNames = Ember.keys(properties);
+
+        for (var j = 0, ll = keyNames.length; j &lt; ll; j++) {
+          var keyName = keyNames[j];
+          if (!properties.hasOwnProperty(keyName)) { continue; }
+
+          var value = properties[keyName],
+              IS_BINDING = Ember.IS_BINDING;
+
+          if (IS_BINDING.test(keyName)) {
+            var bindings = m.bindings;
+            if (!bindings) {
+              bindings = m.bindings = {};
+            } else if (!m.hasOwnProperty('bindings')) {
+              bindings = m.bindings = o_create(m.bindings);
+            }
+            bindings[keyName] = value;
+          }
+
+          var desc = m.descs[keyName];
+
+          Ember.assert(&quot;Ember.Object.create no longer supports defining computed properties.&quot;, !(value instanceof Ember.ComputedProperty));
+          Ember.assert(&quot;Ember.Object.create no longer supports defining methods that call _super.&quot;, !(typeof value === 'function' &amp;&amp; value.toString().indexOf('._super') !== -1));
+          Ember.assert(&quot;`actions` must be provided at extend time, not at create &quot; +
+                       &quot;time, when Ember.ActionHandler is used (i.e. views, &quot; +
+                       &quot;controllers &amp; routes).&quot;, !((keyName === 'actions') &amp;&amp; Ember.ActionHandler.detect(this)));
+
+          if (concatenatedProperties &amp;&amp; indexOf(concatenatedProperties, keyName) &gt;= 0) {
+            var baseValue = this[keyName];
+
+            if (baseValue) {
+              if ('function' === typeof baseValue.concat) {
+                value = baseValue.concat(value);
+              } else {
+                value = Ember.makeArray(baseValue).concat(value);
+              }
+            } else {
+              value = Ember.makeArray(value);
+            }
+          }
+
+          if (desc) {
+            desc.set(this, keyName, value);
+          } else {
+            if (typeof this.setUnknownProperty === 'function' &amp;&amp; !(keyName in this)) {
+              this.setUnknownProperty(keyName, value);
+            } else if (MANDATORY_SETTER) {
+              Ember.defineProperty(this, keyName, null, value); // setup mandatory setter
+            } else {
+              this[keyName] = value;
+            }
+          }
+        }
+      }
+    }
+    finishPartial(this, m);
+    this.init.apply(this, arguments);
+    m.proto = proto;
+    finishChains(this);
+    sendEvent(this, &quot;init&quot;);
+  };
+
+  Class.toString = Mixin.prototype.toString;
+  Class.willReopen = function() {
+    if (wasApplied) {
+      Class.PrototypeMixin = Mixin.create(Class.PrototypeMixin);
+    }
+
+    wasApplied = false;
+  };
+  Class._initMixins = function(args) { initMixins = args; };
+  Class._initProperties = function(args) { initProperties = args; };
+
+  Class.proto = function() {
+    var superclass = Class.superclass;
+    if (superclass) { superclass.proto(); }
+
+    if (!wasApplied) {
+      wasApplied = true;
+      Class.PrototypeMixin.applyPartial(Class.prototype);
+      rewatch(Class.prototype);
+    }
+
+    return this.prototype;
+  };
+
+  return Class;
+
+}
+
+/**
+  @class CoreObject
+  @namespace Ember
+*/
+var CoreObject = makeCtor();
+CoreObject.toString = function() { return &quot;Ember.CoreObject&quot;; };
+
+CoreObject.PrototypeMixin = Mixin.create({
+  reopen: function() {
+    applyMixin(this, arguments, true);
+    return this;
+  },
+
+  /**
+    An overridable method called when objects are instantiated. By default,
+    does nothing unless it is overridden during class definition.
+
+    Example:
+
+    ```javascript
+    App.Person = Ember.Object.extend({
+      init: function() {
+        alert('Name is ' + this.get('name'));
+      }
</ins><span class="cx">     });
</span><span class="cx"> 
</span><del>-    MyApp.president.get('fullName');    // &quot;Barack Obama&quot;
</del><ins>+    var steve = App.Person.create({
+      name: &quot;Steve&quot;
+    });
+
+    // alerts 'Name is Steve'.
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    Treating a function like a property is useful because they can work with
-    bindings, just like any other property.
</del><ins>+    NOTE: If you do override `init` for a framework class like `Ember.View` or
+    `Ember.ArrayController`, be sure to call `this._super()` in your
+    `init` declaration! If you don't, Ember may not have an opportunity to
+    do important setup work, and you'll see strange behavior in your
+    application.
</ins><span class="cx"> 
</span><del>-    Many computed properties have dependencies on other properties. For
-    example, in the above example, the `fullName` property depends on
-    `firstName` and `lastName` to determine its value. You can tell Ember
-    about these dependencies like this:
</del><ins>+    @method init
+  */
+  init: function() {},
</ins><span class="cx"> 
</span><ins>+  /**
+    Defines the properties that will be concatenated from the superclass
+    (instead of overridden).
+
+    By default, when you extend an Ember class a property defined in
+    the subclass overrides a property with the same name that is defined
+    in the superclass. However, there are some cases where it is preferable
+    to build up a property's value by combining the superclass' property
+    value with the subclass' value. An example of this in use within Ember
+    is the `classNames` property of `Ember.View`.
+
+    Here is some sample code showing the difference between a concatenated
+    property and a normal one:
+
</ins><span class="cx">     ```javascript
</span><del>-    MyApp.president = Ember.Object.create({
-      firstName: &quot;Barack&quot;,
-      lastName: &quot;Obama&quot;,
</del><ins>+    App.BarView = Ember.View.extend({
+      someNonConcatenatedProperty: ['bar'],
+      classNames: ['bar']
+    });
</ins><span class="cx"> 
</span><del>-      fullName: function() {
-        return this.get('firstName') + ' ' + this.get('lastName');
</del><ins>+    App.FooBarView = App.BarView.extend({
+      someNonConcatenatedProperty: ['foo'],
+      classNames: ['foo'],
+    });
</ins><span class="cx"> 
</span><del>-        // Tell Ember.js that this computed property depends on firstName
-        // and lastName
-      }.property('firstName', 'lastName')
</del><ins>+    var fooBarView = App.FooBarView.create();
+    fooBarView.get('someNonConcatenatedProperty'); // ['foo']
+    fooBarView.get('classNames'); // ['ember-view', 'bar', 'foo']
+    ```
+
+    This behavior extends to object creation as well. Continuing the
+    above example:
+
+    ```javascript
+    var view = App.FooBarView.create({
+      someNonConcatenatedProperty: ['baz'],
+      classNames: ['baz']
+    })
+    view.get('someNonConcatenatedProperty'); // ['baz']
+    view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
+    ```
+    Adding a single property that is not an array will just add it in the array:
+
+    ```javascript
+    var view = App.FooBarView.create({
+      classNames: 'baz'
+    })
+    view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
+    ```
+
+    Using the `concatenatedProperties` property, we can tell to Ember that mix
+    the content of the properties.
+
+    In `Ember.View` the `classNameBindings` and `attributeBindings` properties
+    are also concatenated, in addition to `classNames`.
+
+    This feature is available for you to use throughout the Ember object model,
+    although typical app developers are likely to use it infrequently. Since
+    it changes expectations about behavior of properties, you should properly
+    document its usage in each individual concatenated property (to not
+    mislead your users to think they can override the property in a subclass).
+
+    @property concatenatedProperties
+    @type Array
+    @default null
+  */
+  concatenatedProperties: null,
+
+  /**
+    Destroyed object property flag.
+
+    if this property is `true` the observers and bindings were already
+    removed by the effect of calling the `destroy()` method.
+
+    @property isDestroyed
+    @default false
+  */
+  isDestroyed: false,
+
+  /**
+    Destruction scheduled flag. The `destroy()` method has been called.
+
+    The object stays intact until the end of the run loop at which point
+    the `isDestroyed` flag is set.
+
+    @property isDestroying
+    @default false
+  */
+  isDestroying: false,
+
+  /**
+    Destroys an object by setting the `isDestroyed` flag and removing its
+    metadata, which effectively destroys observers and bindings.
+
+    If you try to set a property on a destroyed object, an exception will be
+    raised.
+
+    Note that destruction is scheduled for the end of the run loop and does not
+    happen immediately.  It will set an isDestroying flag immediately.
+
+    @method destroy
+    @return {Ember.Object} receiver
+  */
+  destroy: function() {
+    if (this.isDestroying) { return; }
+    this.isDestroying = true;
+
+    schedule('actions', this, this.willDestroy);
+    schedule('destroy', this, this._scheduledDestroy);
+    return this;
+  },
+
+  /**
+    Override to implement teardown.
+
+    @method willDestroy
+   */
+  willDestroy: Ember.K,
+
+  /**
+    Invoked by the run loop to actually destroy the object. This is
+    scheduled for execution by the `destroy` method.
+
+    @private
+    @method _scheduledDestroy
+  */
+  _scheduledDestroy: function() {
+    if (this.isDestroyed) { return; }
+    destroy(this);
+    this.isDestroyed = true;
+  },
+
+  bind: function(to, from) {
+    if (!(from instanceof Ember.Binding)) { from = Ember.Binding.from(from); }
+    from.to(to).connect(this);
+    return from;
+  },
+
+  /**
+    Returns a string representation which attempts to provide more information
+    than Javascript's `toString` typically does, in a generic way for all Ember
+    objects.
+
+    ```javascript
+    App.Person = Em.Object.extend()
+    person = App.Person.create()
+    person.toString() //=&gt; &quot;&lt;App.Person:ember1024&gt;&quot;
+    ```
+
+    If the object's class is not defined on an Ember namespace, it will
+    indicate it is a subclass of the registered superclass:
+
+   ```javascript
+    Student = App.Person.extend()
+    student = Student.create()
+    student.toString() //=&gt; &quot;&lt;(subclass of App.Person):ember1025&gt;&quot;
+    ```
+
+    If the method `toStringExtension` is defined, its return value will be
+    included in the output.
+
+    ```javascript
+    App.Teacher = App.Person.extend({
+      toStringExtension: function() {
+        return this.get('fullName');
+      }
</ins><span class="cx">     });
</span><ins>+    teacher = App.Teacher.create()
+    teacher.toString(); //=&gt; &quot;&lt;App.Teacher:ember1026:Tom Dale&gt;&quot;
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    Make sure you list these dependencies so Ember knows when to update
-    bindings that connect to a computed property. Changing a dependency
-    will not immediately trigger an update of the computed property, but
-    will instead clear the cache so that it is updated when the next `get`
-    is called on the property.
</del><ins>+    @method toString
+    @return {String} string representation
+  */
+  toString: function toString() {
+    var hasToStringExtension = typeof this.toStringExtension === 'function',
+        extension = hasToStringExtension ? &quot;:&quot; + this.toStringExtension() : '';
+    var ret = '&lt;'+this.constructor.toString()+':'+guidFor(this)+extension+'&gt;';
+    this.toString = makeToString(ret);
+    return ret;
+  }
+});
</ins><span class="cx"> 
</span><del>-    See {{#crossLink &quot;Ember.ComputedProperty&quot;}}{{/crossLink}},
-      {{#crossLink &quot;Ember/computed&quot;}}{{/crossLink}}
</del><ins>+CoreObject.PrototypeMixin.ownerConstructor = CoreObject;
</ins><span class="cx"> 
</span><del>-    @method property
-    @for Function
</del><ins>+function makeToString(ret) {
+  return function() { return ret; };
+}
+
+if (Ember.config.overridePrototypeMixin) {
+  Ember.config.overridePrototypeMixin(CoreObject.PrototypeMixin);
+}
+
+CoreObject.__super__ = null;
+
+var ClassMixin = Mixin.create({
+
+  ClassMixin: Ember.required(),
+
+  PrototypeMixin: Ember.required(),
+
+  isClass: true,
+
+  isMethod: false,
+
+  /**
+    Creates a new subclass.
+
+    ```javascript
+    App.Person = Ember.Object.extend({
+      say: function(thing) {
+        alert(thing);
+       }
+    });
+    ```
+
+    This defines a new subclass of Ember.Object: `App.Person`. It contains one method: `say()`.
+
+    You can also create a subclass from any existing class by calling its `extend()`  method. For example, you might want to create a subclass of Ember's built-in `Ember.View` class:
+
+    ```javascript
+    App.PersonView = Ember.View.extend({
+      tagName: 'li',
+      classNameBindings: ['isAdministrator']
+    });
+    ```
+
+    When defining a subclass, you can override methods but still access the implementation of your parent class by calling the special `_super()` method:
+
+    ```javascript
+    App.Person = Ember.Object.extend({
+      say: function(thing) {
+        var name = this.get('name');
+        alert(name + ' says: ' + thing);
+      }
+    });
+
+    App.Soldier = App.Person.extend({
+      say: function(thing) {
+        this._super(thing + &quot;, sir!&quot;);
+      },
+      march: function(numberOfHours) {
+        alert(this.get('name') + ' marches for ' + numberOfHours + ' hours.')
+      }
+    });
+
+    var yehuda = App.Soldier.create({
+      name: &quot;Yehuda Katz&quot;
+    });
+
+    yehuda.say(&quot;Yes&quot;);  // alerts &quot;Yehuda Katz says: Yes, sir!&quot;
+    ```
+
+    The `create()` on line #17 creates an *instance* of the `App.Soldier` class. The `extend()` on line #8 creates a *subclass* of `App.Person`. Any instance of the `App.Person` class will *not* have the `march()` method.
+
+    You can also pass `Ember.Mixin` classes to add additional properties to the subclass.
+
+    ```javascript
+    App.Person = Ember.Object.extend({
+      say: function(thing) {
+        alert(this.get('name') + ' says: ' + thing);
+      }
+    });
+
+    App.SingingMixin = Ember.Mixin.create({
+      sing: function(thing){
+        alert(this.get('name') + ' sings: la la la ' + thing);
+      }
+    });
+
+    App.BroadwayStar = App.Person.extend(App.SingingMixin, {
+      dance: function() {
+        alert(this.get('name') + ' dances: tap tap tap tap ');
+      }
+    });
+    ```
+
+    The `App.BroadwayStar` class contains three methods: `say()`, `sing()`, and `dance()`.
+
+    @method extend
+    @static
+
+    @param {Ember.Mixin} [mixins]* One or more Ember.Mixin classes
+    @param {Object} [arguments]* Object containing values to use within the new class
</ins><span class="cx">   */
</span><del>-  Function.prototype.property = function() {
-    var ret = Ember.computed(this);
-    return ret.property.apply(ret, arguments);
-  };
</del><ins>+  extend: function() {
+    var Class = makeCtor(), proto;
+    Class.ClassMixin = Mixin.create(this.ClassMixin);
+    Class.PrototypeMixin = Mixin.create(this.PrototypeMixin);
</ins><span class="cx"> 
</span><ins>+    Class.ClassMixin.ownerConstructor = Class;
+    Class.PrototypeMixin.ownerConstructor = Class;
+
+    reopen.apply(Class.PrototypeMixin, arguments);
+
+    Class.superclass = this;
+    Class.__super__  = this.prototype;
+
+    proto = Class.prototype = o_create(this.prototype);
+    proto.constructor = Class;
+    generateGuid(proto);
+    meta(proto).proto = proto; // this will disable observers on prototype
+
+    Class.ClassMixin.apply(Class);
+    return Class;
+  },
+
</ins><span class="cx">   /**
</span><del>-    The `observes` extension of Javascript's Function prototype is available
-    when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is
-    true, which is the default.
</del><ins>+    Equivalent to doing `extend(arguments).create()`.
+    If possible use the normal `create` method instead.
</ins><span class="cx"> 
</span><del>-    You can observe property changes simply by adding the `observes`
-    call to the end of your method declarations in classes that you write.
-    For example:
</del><ins>+    @method createWithMixins
+    @static
+    @param [arguments]*
+  */
+  createWithMixins: function() {
+    var C = this;
+    if (arguments.length&gt;0) { this._initMixins(arguments); }
+    return new C();
+  },
</ins><span class="cx"> 
</span><ins>+  /**
+    Creates an instance of a class. Accepts either no arguments, or an object
+    containing values to initialize the newly instantiated object with.
+
</ins><span class="cx">     ```javascript
</span><del>-    Ember.Object.create({
-      valueObserver: function() {
-        // Executes whenever the &quot;value&quot; property changes
-      }.observes('value')
</del><ins>+    App.Person = Ember.Object.extend({
+      helloWorld: function() {
+        alert(&quot;Hi, my name is &quot; + this.get('name'));
+      }
</ins><span class="cx">     });
</span><ins>+
+    var tom = App.Person.create({
+      name: 'Tom Dale'
+    });
+
+    tom.helloWorld(); // alerts &quot;Hi, my name is Tom Dale&quot;.
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    See {{#crossLink &quot;Ember.Observable/observes&quot;}}{{/crossLink}}
</del><ins>+    `create` will call the `init` function if defined during
+    `Ember.AnyObject.extend`
</ins><span class="cx"> 
</span><del>-    @method observes
-    @for Function
</del><ins>+    If no arguments are passed to `create`, it will not set values to the new
+    instance during initialization:
+
+    ```javascript
+    var noName = App.Person.create();
+    noName.helloWorld(); // alerts undefined
+    ```
+
+    NOTE: For performance reasons, you cannot declare methods or computed
+    properties during `create`. You should instead declare methods and computed
+    properties when using `extend` or use the `createWithMixins` shorthand.
+
+    @method create
+    @static
+    @param [arguments]*
</ins><span class="cx">   */
</span><del>-  Function.prototype.observes = function() {
-    this.__ember_observes__ = a_slice.call(arguments);
</del><ins>+  create: function() {
+    var C = this;
+    if (arguments.length&gt;0) { this._initProperties(arguments); }
+    return new C();
+  },
+
+  /**
+    Augments a constructor's prototype with additional
+    properties and functions:
+
+    ```javascript
+    MyObject = Ember.Object.extend({
+      name: 'an object'
+    });
+
+    o = MyObject.create();
+    o.get('name'); // 'an object'
+
+    MyObject.reopen({
+      say: function(msg){
+        console.log(msg);
+      }
+    })
+
+    o2 = MyObject.create();
+    o2.say(&quot;hello&quot;); // logs &quot;hello&quot;
+
+    o.say(&quot;goodbye&quot;); // logs &quot;goodbye&quot;
+    ```
+
+    To add functions and properties to the constructor itself,
+    see `reopenClass`
+
+    @method reopen
+  */
+  reopen: function() {
+    this.willReopen();
+    reopen.apply(this.PrototypeMixin, arguments);
</ins><span class="cx">     return this;
</span><del>-  };
</del><ins>+  },
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    The `observesBefore` extension of Javascript's Function prototype is
-    available when `Ember.EXTEND_PROTOTYPES` or
-    `Ember.EXTEND_PROTOTYPES.Function` is true, which is the default.
</del><ins>+    Augments a constructor's own properties and functions:
</ins><span class="cx"> 
</span><del>-    You can get notified when a property changes is about to happen by
-    by adding the `observesBefore` call to the end of your method
-    declarations in classes that you write. For example:
</del><ins>+    ```javascript
+    MyObject = Ember.Object.extend({
+      name: 'an object'
+    });
</ins><span class="cx"> 
</span><ins>+    MyObject.reopenClass({
+      canBuild: false
+    });
+
+    MyObject.canBuild; // false
+    o = MyObject.create();
+    ```
+
+    In other words, this creates static properties and functions for the class. These are only available on the class
+    and not on any instance of that class.
+
</ins><span class="cx">     ```javascript
</span><del>-    Ember.Object.create({
-      valueObserver: function() {
-        // Executes whenever the &quot;value&quot; property is about to change
-      }.observesBefore('value')
</del><ins>+    App.Person = Ember.Object.extend({
+      name : &quot;&quot;,
+      sayHello : function(){
+        alert(&quot;Hello. My name is &quot; + this.get('name'));
+      }
</ins><span class="cx">     });
</span><ins>+
+    App.Person.reopenClass({
+      species : &quot;Homo sapiens&quot;,
+      createPerson: function(newPersonsName){
+        return App.Person.create({
+          name:newPersonsName
+        });
+      }
+    });
+
+    var tom = App.Person.create({
+      name : &quot;Tom Dale&quot;
+    });
+    var yehuda = App.Person.createPerson(&quot;Yehuda Katz&quot;);
+
+    tom.sayHello(); // &quot;Hello. My name is Tom Dale&quot;
+    yehuda.sayHello(); // &quot;Hello. My name is Yehuda Katz&quot;
+    alert(App.Person.species); // &quot;Homo sapiens&quot;
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    See {{#crossLink &quot;Ember.Observable/observesBefore&quot;}}{{/crossLink}}
</del><ins>+    Note that `species` and `createPerson` are *not* valid on the `tom` and `yehuda`
+    variables. They are only valid on `App.Person`.
</ins><span class="cx"> 
</span><del>-    @method observesBefore
-    @for Function
</del><ins>+    To add functions and properties to instances of
+    a constructor by extending the constructor's prototype
+    see `reopen`
+
+    @method reopenClass
</ins><span class="cx">   */
</span><del>-  Function.prototype.observesBefore = function() {
-    this.__ember_observesBefore__ = a_slice.call(arguments);
</del><ins>+  reopenClass: function() {
+    reopen.apply(this.ClassMixin, arguments);
+    applyMixin(this, arguments, false);
</ins><span class="cx">     return this;
</span><del>-  };
</del><ins>+  },
</ins><span class="cx"> 
</span><ins>+  detect: function(obj) {
+    if ('function' !== typeof obj) { return false; }
+    while(obj) {
+      if (obj===this) { return true; }
+      obj = obj.superclass;
+    }
+    return false;
+  },
+
+  detectInstance: function(obj) {
+    return obj instanceof this;
+  },
+
+  /**
+    In some cases, you may want to annotate computed properties with additional
+    metadata about how they function or what values they operate on. For
+    example, computed property functions may close over variables that are then
+    no longer available for introspection.
+
+    You can pass a hash of these values to a computed property like this:
+
+    ```javascript
+    person: function() {
+      var personId = this.get('personId');
+      return App.Person.create({ id: personId });
+    }.property().meta({ type: App.Person })
+    ```
+
+    Once you've done this, you can retrieve the values saved to the computed
+    property from your class like this:
+
+    ```javascript
+    MyClass.metaForProperty('person');
+    ```
+
+    This will return the original hash that was passed to `meta()`.
+
+    @method metaForProperty
+    @param key {String} property name
+  */
+  metaForProperty: function(key) {
+    var desc = meta(this.proto(), false).descs[key];
+
+    Ember.assert(&quot;metaForProperty() could not find a computed property with key '&quot;+key+&quot;'.&quot;, !!desc &amp;&amp; desc instanceof Ember.ComputedProperty);
+    return desc._meta || {};
+  },
+
+  /**
+    Iterate over each computed property for the class, passing its name
+    and any associated metadata (see `metaForProperty`) to the callback.
+
+    @method eachComputedProperty
+    @param {Function} callback
+    @param {Object} binding
+  */
+  eachComputedProperty: function(callback, binding) {
+    var proto = this.proto(),
+        descs = meta(proto).descs,
+        empty = {},
+        property;
+
+    for (var name in descs) {
+      property = descs[name];
+
+      if (property instanceof Ember.ComputedProperty) {
+        callback.call(binding || this, name, property._meta || empty);
+      }
+    }
+  }
+
+});
+
+ClassMixin.ownerConstructor = CoreObject;
+
+if (Ember.config.overrideClassMixin) {
+  Ember.config.overrideClassMixin(ClassMixin);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+CoreObject.ClassMixin = ClassMixin;
+ClassMixin.apply(CoreObject);
</ins><span class="cx"> 
</span><ins>+Ember.CoreObject = CoreObject;
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><ins>+/**
+@module ember
+@submodule ember-runtime
+*/
</ins><span class="cx"> 
</span><ins>+/**
+  `Ember.Object` is the main base class for all Ember objects. It is a subclass
+  of `Ember.CoreObject` with the `Ember.Observable` mixin applied. For details,
+  see the documentation for each of these.
+
+  @class Object
+  @namespace Ember
+  @extends Ember.CoreObject
+  @uses Ember.Observable
+*/
+Ember.Object = Ember.CoreObject.extend(Ember.Observable);
+Ember.Object.toString = function() { return &quot;Ember.Object&quot;; };
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -7256,6 +12975,366 @@
</span><span class="cx"> @submodule ember-runtime
</span><span class="cx"> */
</span><span class="cx"> 
</span><ins>+var get = Ember.get, indexOf = Ember.ArrayPolyfills.indexOf;
+
+/**
+  A Namespace is an object usually used to contain other objects or methods
+  such as an application or framework. Create a namespace anytime you want
+  to define one of these new containers.
+
+  # Example Usage
+
+  ```javascript
+  MyFramework = Ember.Namespace.create({
+    VERSION: '1.0.0'
+  });
+  ```
+
+  @class Namespace
+  @namespace Ember
+  @extends Ember.Object
+*/
+var Namespace = Ember.Namespace = Ember.Object.extend({
+  isNamespace: true,
+
+  init: function() {
+    Ember.Namespace.NAMESPACES.push(this);
+    Ember.Namespace.PROCESSED = false;
+  },
+
+  toString: function() {
+    var name = get(this, 'name');
+    if (name) { return name; }
+
+    findNamespaces();
+    return this[Ember.GUID_KEY+'_name'];
+  },
+
+  nameClasses: function() {
+    processNamespace([this.toString()], this, {});
+  },
+
+  destroy: function() {
+    var namespaces = Ember.Namespace.NAMESPACES;
+    Ember.lookup[this.toString()] = undefined;
+    namespaces.splice(indexOf.call(namespaces, this), 1);
+    this._super();
+  }
+});
+
+Namespace.reopenClass({
+  NAMESPACES: [Ember],
+  NAMESPACES_BY_ID: {},
+  PROCESSED: false,
+  processAll: processAllNamespaces,
+  byName: function(name) {
+    if (!Ember.BOOTED) {
+      processAllNamespaces();
+    }
+
+    return NAMESPACES_BY_ID[name];
+  }
+});
+
+var NAMESPACES_BY_ID = Namespace.NAMESPACES_BY_ID;
+
+var hasOwnProp = ({}).hasOwnProperty,
+    guidFor = Ember.guidFor;
+
+function processNamespace(paths, root, seen) {
+  var idx = paths.length;
+
+  NAMESPACES_BY_ID[paths.join('.')] = root;
+
+  // Loop over all of the keys in the namespace, looking for classes
+  for(var key in root) {
+    if (!hasOwnProp.call(root, key)) { continue; }
+    var obj = root[key];
+
+    // If we are processing the `Ember` namespace, for example, the
+    // `paths` will start with `[&quot;Ember&quot;]`. Every iteration through
+    // the loop will update the **second** element of this list with
+    // the key, so processing `Ember.View` will make the Array
+    // `['Ember', 'View']`.
+    paths[idx] = key;
+
+    // If we have found an unprocessed class
+    if (obj &amp;&amp; obj.toString === classToString) {
+      // Replace the class' `toString` with the dot-separated path
+      // and set its `NAME_KEY`
+      obj.toString = makeToString(paths.join('.'));
+      obj[NAME_KEY] = paths.join('.');
+
+    // Support nested namespaces
+    } else if (obj &amp;&amp; obj.isNamespace) {
+      // Skip aliased namespaces
+      if (seen[guidFor(obj)]) { continue; }
+      seen[guidFor(obj)] = true;
+
+      // Process the child namespace
+      processNamespace(paths, obj, seen);
+    }
+  }
+
+  paths.length = idx; // cut out last item
+}
+
+function findNamespaces() {
+  var Namespace = Ember.Namespace, lookup = Ember.lookup, obj, isNamespace;
+
+  if (Namespace.PROCESSED) { return; }
+
+  for (var prop in lookup) {
+    // These don't raise exceptions but can cause warnings
+    if (prop === &quot;parent&quot; || prop === &quot;top&quot; || prop === &quot;frameElement&quot; || prop === &quot;webkitStorageInfo&quot;) { continue; }
+
+    //  get(window.globalStorage, 'isNamespace') would try to read the storage for domain isNamespace and cause exception in Firefox.
+    // globalStorage is a storage obsoleted by the WhatWG storage specification. See https://developer.mozilla.org/en/DOM/Storage#globalStorage
+    if (prop === &quot;globalStorage&quot; &amp;&amp; lookup.StorageList &amp;&amp; lookup.globalStorage instanceof lookup.StorageList) { continue; }
+    // Unfortunately, some versions of IE don't support window.hasOwnProperty
+    if (lookup.hasOwnProperty &amp;&amp; !lookup.hasOwnProperty(prop)) { continue; }
+
+    // At times we are not allowed to access certain properties for security reasons.
+    // There are also times where even if we can access them, we are not allowed to access their properties.
+    try {
+      obj = Ember.lookup[prop];
+      isNamespace = obj &amp;&amp; obj.isNamespace;
+    } catch (e) {
+      continue;
+    }
+
+    if (isNamespace) {
+      Ember.deprecate(&quot;Namespaces should not begin with lowercase.&quot;, /^[A-Z]/.test(prop));
+      obj[NAME_KEY] = prop;
+    }
+  }
+}
+
+var NAME_KEY = Ember.NAME_KEY = Ember.GUID_KEY + '_name';
+
+function superClassString(mixin) {
+  var superclass = mixin.superclass;
+  if (superclass) {
+    if (superclass[NAME_KEY]) { return superclass[NAME_KEY]; }
+    else { return superClassString(superclass); }
+  } else {
+    return;
+  }
+}
+
+function classToString() {
+  if (!Ember.BOOTED &amp;&amp; !this[NAME_KEY]) {
+    processAllNamespaces();
+  }
+
+  var ret;
+
+  if (this[NAME_KEY]) {
+    ret = this[NAME_KEY];
+  } else if (this._toString) {
+    ret = this._toString; 
+  } else {
+    var str = superClassString(this);
+    if (str) {
+      ret = &quot;(subclass of &quot; + str + &quot;)&quot;;
+    } else {
+      ret = &quot;(unknown mixin)&quot;;
+    }
+    this.toString = makeToString(ret);
+  }
+
+  return ret;
+}
+
+function processAllNamespaces() {
+  var unprocessedNamespaces = !Namespace.PROCESSED,
+      unprocessedMixins = Ember.anyUnprocessedMixins;
+
+  if (unprocessedNamespaces) {
+    findNamespaces();
+    Namespace.PROCESSED = true;
+  }
+
+  if (unprocessedNamespaces || unprocessedMixins) {
+    var namespaces = Namespace.NAMESPACES, namespace;
+    for (var i=0, l=namespaces.length; i&lt;l; i++) {
+      namespace = namespaces[i];
+      processNamespace([namespace.toString()], namespace, {});
+    }
+
+    Ember.anyUnprocessedMixins = false;
+  }
+}
+
+function makeToString(ret) {
+  return function() { return ret; };
+}
+
+Ember.Mixin.prototype.toString = classToString;
+
+})();
+
+
+
+(function() {
+/**
+@module ember
+@submodule ember-runtime
+*/
+
+var get = Ember.get,
+    set = Ember.set,
+    fmt = Ember.String.fmt,
+    addBeforeObserver = Ember.addBeforeObserver,
+    addObserver = Ember.addObserver,
+    removeBeforeObserver = Ember.removeBeforeObserver,
+    removeObserver = Ember.removeObserver,
+    propertyWillChange = Ember.propertyWillChange,
+    propertyDidChange = Ember.propertyDidChange,
+    meta = Ember.meta,
+    defineProperty = Ember.defineProperty;
+
+function contentPropertyWillChange(content, contentKey) {
+  var key = contentKey.slice(8); // remove &quot;content.&quot;
+  if (key in this) { return; }  // if shadowed in proxy
+  propertyWillChange(this, key);
+}
+
+function contentPropertyDidChange(content, contentKey) {
+  var key = contentKey.slice(8); // remove &quot;content.&quot;
+  if (key in this) { return; } // if shadowed in proxy
+  propertyDidChange(this, key);
+}
+
+/**
+  `Ember.ObjectProxy` forwards all properties not defined by the proxy itself
+  to a proxied `content` object.
+
+  ```javascript
+  object = Ember.Object.create({
+    name: 'Foo'
+  });
+
+  proxy = Ember.ObjectProxy.create({
+    content: object
+  });
+
+  // Access and change existing properties
+  proxy.get('name')          // 'Foo'
+  proxy.set('name', 'Bar');
+  object.get('name')         // 'Bar'
+
+  // Create new 'description' property on `object`
+  proxy.set('description', 'Foo is a whizboo baz');
+  object.get('description')  // 'Foo is a whizboo baz'
+  ```
+
+  While `content` is unset, setting a property to be delegated will throw an
+  Error.
+
+  ```javascript
+  proxy = Ember.ObjectProxy.create({
+    content: null,
+    flag: null
+  });
+  proxy.set('flag', true);
+  proxy.get('flag');         // true
+  proxy.get('foo');          // undefined
+  proxy.set('foo', 'data');  // throws Error
+  ```
+
+  Delegated properties can be bound to and will change when content is updated.
+
+  Computed properties on the proxy itself can depend on delegated properties.
+
+  ```javascript
+  ProxyWithComputedProperty = Ember.ObjectProxy.extend({
+    fullName: function () {
+      var firstName = this.get('firstName'),
+          lastName = this.get('lastName');
+      if (firstName &amp;&amp; lastName) {
+        return firstName + ' ' + lastName;
+      }
+      return firstName || lastName;
+    }.property('firstName', 'lastName')
+  });
+
+  proxy = ProxyWithComputedProperty.create();
+
+  proxy.get('fullName');  // undefined
+  proxy.set('content', {
+    firstName: 'Tom', lastName: 'Dale'
+  }); // triggers property change for fullName on proxy
+
+  proxy.get('fullName');  // 'Tom Dale'
+  ```
+
+  @class ObjectProxy
+  @namespace Ember
+  @extends Ember.Object
+*/
+Ember.ObjectProxy = Ember.Object.extend({
+  /**
+    The object whose properties will be forwarded.
+
+    @property content
+    @type Ember.Object
+    @default null
+  */
+  content: null,
+  _contentDidChange: Ember.observer('content', function() {
+    Ember.assert(&quot;Can't set ObjectProxy's content to itself&quot;, this.get('content') !== this);
+  }),
+
+  isTruthy: Ember.computed.bool('content'),
+
+  _debugContainerKey: null,
+
+  willWatchProperty: function (key) {
+    var contentKey = 'content.' + key;
+    addBeforeObserver(this, contentKey, null, contentPropertyWillChange);
+    addObserver(this, contentKey, null, contentPropertyDidChange);
+  },
+
+  didUnwatchProperty: function (key) {
+    var contentKey = 'content.' + key;
+    removeBeforeObserver(this, contentKey, null, contentPropertyWillChange);
+    removeObserver(this, contentKey, null, contentPropertyDidChange);
+  },
+
+  unknownProperty: function (key) {
+    var content = get(this, 'content');
+    if (content) {
+      return get(content, key);
+    }
+  },
+
+  setUnknownProperty: function (key, value) {
+    var m = meta(this);
+    if (m.proto === this) {
+      // if marked as prototype then just defineProperty
+      // rather than delegate
+      defineProperty(this, key, null, value);
+      return value;
+    }
+
+    var content = get(this, 'content');
+    Ember.assert(fmt(&quot;Cannot delegate set('%@', %@) to the 'content' property of object proxy %@: its 'content' is undefined.&quot;, [key, value, this]), content);
+    return set(content, key, value);
+  }
+
+});
+
+})();
+
+
+
+(function() {
+/**
+@module ember
+@submodule ember-runtime
+*/
+
</ins><span class="cx"> // ..........................................................
</span><span class="cx"> // HELPERS
</span><span class="cx"> //
</span><span class="lines">@@ -7304,7 +13383,7 @@
</span><span class="cx">      with an `Ember.Object` subclass, you should be sure to change the length
</span><span class="cx">      property using `set().`
</span><span class="cx"> 
</span><del>-  2. If you must implement `nextObject().` See documentation.
</del><ins>+  2. You must implement `nextObject().` See documentation.
</ins><span class="cx"> 
</span><span class="cx">   Once you have these two methods implement, apply the `Ember.Enumerable` mixin
</span><span class="cx">   to your class and you will be able to enumerate the contents of your object
</span><span class="lines">@@ -7320,15 +13399,10 @@
</span><span class="cx"> 
</span><span class="cx">   @class Enumerable
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Mixin
</del><span class="cx">   @since Ember 0.9
</span><span class="cx"> */
</span><del>-Ember.Enumerable = Ember.Mixin.create(
-  /** @scope Ember.Enumerable.prototype */ {
</del><ins>+Ember.Enumerable = Ember.Mixin.create({
</ins><span class="cx"> 
</span><del>-  // compatibility
-  isEnumerable: true,
-
</del><span class="cx">   /**
</span><span class="cx">     Implement this method to make your class enumerable.
</span><span class="cx"> 
</span><span class="lines">@@ -7357,7 +13431,7 @@
</span><span class="cx"> 
</span><span class="cx">     @method nextObject
</span><span class="cx">     @param {Number} index the current index of the iteration
</span><del>-    @param {Object} previousObject the value returned by the last call to 
</del><ins>+    @param {Object} previousObject the value returned by the last call to
</ins><span class="cx">       `nextObject`.
</span><span class="cx">     @param {Object} context a context object you can use to maintain state.
</span><span class="cx">     @return {Object} the next object in the iteration or undefined
</span><span class="lines">@@ -7376,10 +13450,10 @@
</span><span class="cx"> 
</span><span class="cx">     ```javascript
</span><span class="cx">     var arr = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;];
</span><del>-    arr.firstObject();  // &quot;a&quot;
</del><ins>+    arr.get('firstObject');  // &quot;a&quot;
</ins><span class="cx"> 
</span><span class="cx">     var arr = [];
</span><del>-    arr.firstObject();  // undefined
</del><ins>+    arr.get('firstObject');  // undefined
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><span class="cx">     @property firstObject
</span><span class="lines">@@ -7402,10 +13476,10 @@
</span><span class="cx"> 
</span><span class="cx">     ```javascript
</span><span class="cx">     var arr = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;];
</span><del>-    arr.lastObject();  // &quot;c&quot;
</del><ins>+    arr.get('lastObject');  // &quot;c&quot;
</ins><span class="cx"> 
</span><span class="cx">     var arr = [];
</span><del>-    arr.lastObject();  // undefined
</del><ins>+    arr.get('lastObject');  // undefined
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><span class="cx">     @property lastObject
</span><span class="lines">@@ -7484,14 +13558,14 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Alias for `mapProperty`
</del><ins>+    Alias for `mapBy`
</ins><span class="cx"> 
</span><span class="cx">     @method getEach
</span><span class="cx">     @param {String} key name of the property
</span><span class="cx">     @return {Array} The mapped array.
</span><span class="cx">   */
</span><span class="cx">   getEach: function(key) {
</span><del>-    return this.mapProperty(key);
</del><ins>+    return this.mapBy(key);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -7538,7 +13612,7 @@
</span><span class="cx">     @return {Array} The mapped array.
</span><span class="cx">   */
</span><span class="cx">   map: function(callback, target) {
</span><del>-    var ret = [];
</del><ins>+    var ret = Ember.A();
</ins><span class="cx">     this.forEach(function(x, idx, i) {
</span><span class="cx">       ret[idx] = callback.call(target, x, idx,i);
</span><span class="cx">     });
</span><span class="lines">@@ -7549,17 +13623,29 @@
</span><span class="cx">     Similar to map, this specialized function returns the value of the named
</span><span class="cx">     property on all items in the enumeration.
</span><span class="cx"> 
</span><del>-    @method mapProperty
</del><ins>+    @method mapBy
</ins><span class="cx">     @param {String} key name of the property
</span><span class="cx">     @return {Array} The mapped array.
</span><span class="cx">   */
</span><del>-  mapProperty: function(key) {
</del><ins>+  mapBy: function(key) {
</ins><span class="cx">     return this.map(function(next) {
</span><span class="cx">       return get(next, key);
</span><span class="cx">     });
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+    Similar to map, this specialized function returns the value of the named
+    property on all items in the enumeration.
+
+    @method mapProperty
+    @param {String} key name of the property
+    @return {Array} The mapped array.
+    @deprecated Use `mapBy` instead
+  */
+
+  mapProperty: Ember.aliasMethod('mapBy'),
+
+  /**
</ins><span class="cx">     Returns an array with all of the items in the enumeration that the passed
</span><span class="cx">     function returns true for. This method corresponds to `filter()` defined in
</span><span class="cx">     JavaScript 1.6.
</span><span class="lines">@@ -7588,7 +13674,7 @@
</span><span class="cx">     @return {Array} A filtered array.
</span><span class="cx">   */
</span><span class="cx">   filter: function(callback, target) {
</span><del>-    var ret = [];
</del><ins>+    var ret = Ember.A();
</ins><span class="cx">     this.forEach(function(x, idx, i) {
</span><span class="cx">       if (callback.call(target, x, idx, i)) ret.push(x);
</span><span class="cx">     });
</span><span class="lines">@@ -7602,7 +13688,9 @@
</span><span class="cx">     The callback method you provide should have the following signature (all
</span><span class="cx">     parameters are optional):
</span><span class="cx"> 
</span><del>-          function(item, index, enumerable);
</del><ins>+    ```javascript
+    function(item, index, enumerable);
+    ```
</ins><span class="cx"> 
</span><span class="cx">     - *item* is the current item in the iteration.
</span><span class="cx">     - *index* is the current index in the iteration
</span><span class="lines">@@ -7630,26 +13718,39 @@
</span><span class="cx">     can pass an optional second argument with the target value. Otherwise
</span><span class="cx">     this will match any property that evaluates to `true`.
</span><span class="cx"> 
</span><del>-    @method filterProperty
</del><ins>+    @method filterBy
</ins><span class="cx">     @param {String} key the property to test
</span><span class="cx">     @param {String} [value] optional value to test against.
</span><span class="cx">     @return {Array} filtered array
</span><span class="cx">   */
</span><del>-  filterProperty: function(key, value) {
</del><ins>+  filterBy: function(key, value) {
</ins><span class="cx">     return this.filter(iter.apply(this, arguments));
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+    Returns an array with just the items with the matched property. You
+    can pass an optional second argument with the target value. Otherwise
+    this will match any property that evaluates to `true`.
+
+    @method filterProperty
+    @param {String} key the property to test
+    @param {String} [value] optional value to test against.
+    @return {Array} filtered array
+    @deprecated Use `filterBy` instead
+  */
+  filterProperty: Ember.aliasMethod('filterBy'),
+
+  /**
</ins><span class="cx">     Returns an array with the items that do not have truthy values for
</span><span class="cx">     key.  You can pass an optional second argument with the target value.  Otherwise
</span><span class="cx">     this will match any property that evaluates to false.
</span><span class="cx"> 
</span><del>-    @method rejectProperty
</del><ins>+    @method rejectBy
</ins><span class="cx">     @param {String} key the property to test
</span><span class="cx">     @param {String} [value] optional value to test against.
</span><span class="cx">     @return {Array} rejected array
</span><span class="cx">   */
</span><del>-  rejectProperty: function(key, value) {
</del><ins>+  rejectBy: function(key, value) {
</ins><span class="cx">     var exactValue = function(item) { return get(item, key) === value; },
</span><span class="cx">         hasValue = function(item) { return !!get(item, key); },
</span><span class="cx">         use = (arguments.length === 2 ? exactValue : hasValue);
</span><span class="lines">@@ -7658,6 +13759,19 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+    Returns an array with the items that do not have truthy values for
+    key.  You can pass an optional second argument with the target value.  Otherwise
+    this will match any property that evaluates to false.
+
+    @method rejectProperty
+    @param {String} key the property to test
+    @param {String} [value] optional value to test against.
+    @return {Array} rejected array
+    @deprecated Use `rejectBy` instead
+  */
+  rejectProperty: Ember.aliasMethod('rejectBy'),
+
+  /**
</ins><span class="cx">     Returns the first item in the array for which the callback returns true.
</span><span class="cx">     This method works similar to the `filter()` method defined in JavaScript 1.6
</span><span class="cx">     except that it will stop working on the array once a match is found.
</span><span class="lines">@@ -7708,16 +13822,31 @@
</span><span class="cx"> 
</span><span class="cx">     This method works much like the more generic `find()` method.
</span><span class="cx"> 
</span><del>-    @method findProperty
</del><ins>+    @method findBy
</ins><span class="cx">     @param {String} key the property to test
</span><span class="cx">     @param {String} [value] optional value to test against.
</span><span class="cx">     @return {Object} found item or `undefined`
</span><span class="cx">   */
</span><del>-  findProperty: function(key, value) {
</del><ins>+  findBy: function(key, value) {
</ins><span class="cx">     return this.find(iter.apply(this, arguments));
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+    Returns the first item with a property matching the passed value. You
+    can pass an optional second argument with the target value. Otherwise
+    this will match any property that evaluates to `true`.
+
+    This method works much like the more generic `find()` method.
+
+    @method findProperty
+    @param {String} key the property to test
+    @param {String} [value] optional value to test against.
+    @return {Object} found item or `undefined`
+    @deprecated Use `findBy` instead
+  */
+  findProperty: Ember.aliasMethod('findBy'),
+
+  /**
</ins><span class="cx">     Returns `true` if the passed function returns true for every item in the
</span><span class="cx">     enumeration. This corresponds with the `every()` method in JavaScript 1.6.
</span><span class="cx"> 
</span><span class="lines">@@ -7756,19 +13885,36 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+    @method everyBy
+    @param {String} key the property to test
+    @param {String} [value] optional value to test against.
+    @deprecated Use `isEvery` instead
+    @return {Boolean}
+  */
+  everyBy: Ember.aliasMethod('isEvery'),
+
+  /**
+    @method everyProperty
+    @param {String} key the property to test
+    @param {String} [value] optional value to test against.
+    @deprecated Use `isEvery` instead
+    @return {Boolean}
+  */
+  everyProperty: Ember.aliasMethod('isEvery'),
+
+  /**
</ins><span class="cx">     Returns `true` if the passed property resolves to `true` for all items in
</span><span class="cx">     the enumerable. This method is often simpler/faster than using a callback.
</span><span class="cx"> 
</span><del>-    @method everyProperty
</del><ins>+    @method isEvery
</ins><span class="cx">     @param {String} key the property to test
</span><span class="cx">     @param {String} [value] optional value to test against.
</span><span class="cx">     @return {Boolean}
</span><span class="cx">   */
</span><del>-  everyProperty: function(key, value) {
</del><ins>+  isEvery: function(key, value) {
</ins><span class="cx">     return this.every(iter.apply(this, arguments));
</span><span class="cx">   },
</span><span class="cx"> 
</span><del>-
</del><span class="cx">   /**
</span><span class="cx">     Returns `true` if the passed function returns true for any item in the
</span><span class="cx">     enumeration. This corresponds with the `some()` method in JavaScript 1.6.
</span><span class="lines">@@ -7794,34 +13940,90 @@
</span><span class="cx">     Usage Example:
</span><span class="cx"> 
</span><span class="cx">     ```javascript
</span><del>-    if (people.some(isManager)) { Paychecks.addBiggerBonus(); }
</del><ins>+    if (people.any(isManager)) { Paychecks.addBiggerBonus(); }
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    @method some
</del><ins>+    @method any
</ins><span class="cx">     @param {Function} callback The callback to execute
</span><span class="cx">     @param {Object} [target] The target object to use
</span><del>-    @return {Array} A filtered array.
</del><ins>+    @return {Boolean} `true` if the passed function returns `true` for any item
</ins><span class="cx">   */
</span><del>-  some: function(callback, target) {
-    return !!this.find(function(x, idx, i) {
</del><ins>+  any: function(callback, target) {
+    var found = this.find(function(x, idx, i) {
</ins><span class="cx">       return !!callback.call(target, x, idx, i);
</span><span class="cx">     });
</span><ins>+
+    return typeof found !== 'undefined';
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+    Returns `true` if the passed function returns true for any item in the
+    enumeration. This corresponds with the `some()` method in JavaScript 1.6.
+
+    The callback method you provide should have the following signature (all
+    parameters are optional):
+
+    ```javascript
+    function(item, index, enumerable);
+    ```
+
+    - `item` is the current item in the iteration.
+    - `index` is the current index in the iteration.
+    - `enumerable` is the enumerable object itself.
+
+    It should return the `true` to include the item in the results, `false`
+    otherwise.
+
+    Note that in addition to a callback, you can also pass an optional target
+    object that will be set as `this` on the context. This is a good way
+    to give your iterator function access to the current object.
+
+    Usage Example:
+
+    ```javascript
+    if (people.some(isManager)) { Paychecks.addBiggerBonus(); }
+    ```
+
+    @method some
+    @param {Function} callback The callback to execute
+    @param {Object} [target] The target object to use
+    @return {Boolean} `true` if the passed function returns `true` for any item
+    @deprecated Use `any` instead
+  */
+  some: Ember.aliasMethod('any'),
+
+  /**
</ins><span class="cx">     Returns `true` if the passed property resolves to `true` for any item in
</span><span class="cx">     the enumerable. This method is often simpler/faster than using a callback.
</span><span class="cx"> 
</span><del>-    @method someProperty
</del><ins>+    @method isAny
</ins><span class="cx">     @param {String} key the property to test
</span><span class="cx">     @param {String} [value] optional value to test against.
</span><del>-    @return {Boolean} `true`
</del><ins>+    @return {Boolean} `true` if the passed function returns `true` for any item
</ins><span class="cx">   */
</span><del>-  someProperty: function(key, value) {
-    return this.some(iter.apply(this, arguments));
</del><ins>+  isAny: function(key, value) {
+    return this.any(iter.apply(this, arguments));
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+    @method anyBy
+    @param {String} key the property to test
+    @param {String} [value] optional value to test against.
+    @return {Boolean} `true` if the passed function returns `true` for any item
+    @deprecated Use `isAny` instead
+  */
+  anyBy: Ember.aliasMethod('isAny'),
+
+  /**
+    @method someProperty
+    @param {String} key the property to test
+    @param {String} [value] optional value to test against.
+    @return {Boolean} `true` if the passed function returns `true` for any item
+    @deprecated Use `isAny` instead
+  */
+  someProperty: Ember.aliasMethod('isAny'),
+
+  /**
</ins><span class="cx">     This will combine the values of the enumerator into a single value. It
</span><span class="cx">     is a useful way to collect a summary value from an enumeration. This
</span><span class="cx">     corresponds to the `reduce()` method defined in JavaScript 1.8.
</span><span class="lines">@@ -7877,7 +14079,7 @@
</span><span class="cx">     @return {Array} return values from calling invoke.
</span><span class="cx">   */
</span><span class="cx">   invoke: function(methodName) {
</span><del>-    var args, ret = [];
</del><ins>+    var args, ret = Ember.A();
</ins><span class="cx">     if (arguments.length&gt;1) args = a_slice.call(arguments, 1);
</span><span class="cx"> 
</span><span class="cx">     this.forEach(function(x, idx) {
</span><span class="lines">@@ -7898,23 +14100,25 @@
</span><span class="cx">     @return {Array} the enumerable as an array.
</span><span class="cx">   */
</span><span class="cx">   toArray: function() {
</span><del>-    var ret = [];
</del><ins>+    var ret = Ember.A();
</ins><span class="cx">     this.forEach(function(o, idx) { ret[idx] = o; });
</span><span class="cx">     return ret ;
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Returns a copy of the array with all null elements removed.
</del><ins>+    Returns a copy of the array with all null and undefined elements removed.
</ins><span class="cx"> 
</span><span class="cx">     ```javascript
</span><del>-    var arr = [&quot;a&quot;, null, &quot;c&quot;, null];
</del><ins>+    var arr = [&quot;a&quot;, null, &quot;c&quot;, undefined];
</ins><span class="cx">     arr.compact();  // [&quot;a&quot;, &quot;c&quot;]
</span><span class="cx">     ```
</span><span class="cx"> 
</span><span class="cx">     @method compact
</span><del>-    @return {Array} the array without null elements.
</del><ins>+    @return {Array} the array without null and undefined elements.
</ins><span class="cx">   */
</span><del>-  compact: function() { return this.without(null); },
</del><ins>+  compact: function() {
+    return this.filter(function(value) { return value != null; });
+  },
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     Returns a new enumerable that excludes the passed value. The default
</span><span class="lines">@@ -7932,7 +14136,7 @@
</span><span class="cx">   */
</span><span class="cx">   without: function(value) {
</span><span class="cx">     if (!this.contains(value)) return this; // nothing to do
</span><del>-    var ret = [] ;
</del><ins>+    var ret = Ember.A();
</ins><span class="cx">     this.forEach(function(k) {
</span><span class="cx">       if (k !== value) ret[ret.length] = k;
</span><span class="cx">     }) ;
</span><span class="lines">@@ -7952,8 +14156,8 @@
</span><span class="cx">     @return {Ember.Enumerable}
</span><span class="cx">   */
</span><span class="cx">   uniq: function() {
</span><del>-    var ret = [];
-    this.forEach(function(k){
</del><ins>+    var ret = Ember.A();
+    this.forEach(function(k) {
</ins><span class="cx">       if (a_indexOf(ret, k)&lt;0) ret.push(k);
</span><span class="cx">     });
</span><span class="cx">     return ret;
</span><span class="lines">@@ -7969,6 +14173,7 @@
</span><span class="cx"> 
</span><span class="cx">     @property []
</span><span class="cx">     @type Ember.Array
</span><ins>+    @return this
</ins><span class="cx">   */
</span><span class="cx">   '[]': Ember.computed(function(key, value) {
</span><span class="cx">     return this;
</span><span class="lines">@@ -7983,8 +14188,9 @@
</span><span class="cx">     mixin.
</span><span class="cx"> 
</span><span class="cx">     @method addEnumerableObserver
</span><del>-    @param target {Object}
-    @param opts {Hash}
</del><ins>+    @param {Object} target
+    @param {Hash} [opts]
+    @return this
</ins><span class="cx">   */
</span><span class="cx">   addEnumerableObserver: function(target, opts) {
</span><span class="cx">     var willChange = (opts &amp;&amp; opts.willChange) || 'enumerableWillChange',
</span><span class="lines">@@ -8002,8 +14208,9 @@
</span><span class="cx">     Removes a registered enumerable observer.
</span><span class="cx"> 
</span><span class="cx">     @method removeEnumerableObserver
</span><del>-    @param target {Object}
-    @param [opts] {Hash}
</del><ins>+    @param {Object} target
+    @param {Hash} [opts]
+    @return this
</ins><span class="cx">   */
</span><span class="cx">   removeEnumerableObserver: function(target, opts) {
</span><span class="cx">     var willChange = (opts &amp;&amp; opts.willChange) || 'enumerableWillChange',
</span><span class="lines">@@ -8082,7 +14289,7 @@
</span><span class="cx">     @chainable
</span><span class="cx">   */
</span><span class="cx">   enumerableContentDidChange: function(removing, adding) {
</span><del>-    var notify = this.propertyDidChange, removeCnt, addCnt, hasDelta;
</del><ins>+    var removeCnt, addCnt, hasDelta;
</ins><span class="cx"> 
</span><span class="cx">     if ('number' === typeof removing) removeCnt = removing;
</span><span class="cx">     else if (removing) removeCnt = get(removing, 'length');
</span><span class="lines">@@ -8102,10 +14309,34 @@
</span><span class="cx">     Ember.propertyDidChange(this, '[]');
</span><span class="cx"> 
</span><span class="cx">     return this ;
</span><ins>+  },
+
+  /**
+    Converts the enumerable into an array and sorts by the keys
+    specified in the argument.
+
+    You may provide multiple arguments to sort by multiple properties.
+
+    @method sortBy
+    @param {String} property name(s) to sort on
+    @return {Array} The sorted array.
+    */
+  sortBy: function() {
+    var sortKeys = arguments;
+    return this.toArray().sort(function(a, b){
+      for(var i = 0; i &lt; sortKeys.length; i++) {
+        var key = sortKeys[i],
+        propA = get(a, key),
+        propB = get(b, key);
+        // return 1 or -1 else continue to the next sortKey
+        var compareValue = Ember.compare(propA, propB);
+        if (compareValue) { return compareValue; }
+      }
+      return 0;
+    });
</ins><span class="cx">   }
</span><ins>+});
</ins><span class="cx"> 
</span><del>-}) ;
-
</del><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -8120,10 +14351,8 @@
</span><span class="cx"> // HELPERS
</span><span class="cx"> //
</span><span class="cx"> 
</span><del>-var get = Ember.get, set = Ember.set, meta = Ember.meta, map = Ember.EnumerableUtils.map, cacheFor = Ember.cacheFor;
</del><ins>+var get = Ember.get, set = Ember.set, isNone = Ember.isNone, map = Ember.EnumerableUtils.map, cacheFor = Ember.cacheFor;
</ins><span class="cx"> 
</span><del>-function none(obj) { return obj===null || obj===undefined; }
-
</del><span class="cx"> // ..........................................................
</span><span class="cx"> // ARRAY
</span><span class="cx"> //
</span><span class="lines">@@ -8145,7 +14374,7 @@
</span><span class="cx"> 
</span><span class="cx">   You can use the methods defined in this module to access and modify array
</span><span class="cx">   contents in a KVO-friendly way. You can also be notified whenever the
</span><del>-  membership if an array changes by changing the syntax of the property to
</del><ins>+  membership of an array changes by changing the syntax of the property to
</ins><span class="cx">   `.observes('*myProperty.[]')`.
</span><span class="cx"> 
</span><span class="cx">   To support `Ember.Array` in your own class, you must override two
</span><span class="lines">@@ -8156,15 +14385,11 @@
</span><span class="cx"> 
</span><span class="cx">   @class Array
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Mixin
</del><span class="cx">   @uses Ember.Enumerable
</span><span class="cx">   @since Ember 0.9.0
</span><span class="cx"> */
</span><del>-Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.prototype */ {
</del><ins>+Ember.Array = Ember.Mixin.create(Ember.Enumerable, {
</ins><span class="cx"> 
</span><del>-  // compatibility
-  isSCArray: true,
-
</del><span class="cx">   /**
</span><span class="cx">     Your array must support the `length` property. Your replace methods should
</span><span class="cx">     set this property whenever it changes.
</span><span class="lines">@@ -8193,6 +14418,7 @@
</span><span class="cx"> 
</span><span class="cx">     @method objectAt
</span><span class="cx">     @param {Number} idx The index of the item to return.
</span><ins>+    @return {*} item at index or undefined
</ins><span class="cx">   */
</span><span class="cx">   objectAt: function(idx) {
</span><span class="cx">     if ((idx &lt; 0) || (idx&gt;=get(this, 'length'))) return undefined ;
</span><span class="lines">@@ -8210,10 +14436,11 @@
</span><span class="cx"> 
</span><span class="cx">     @method objectsAt
</span><span class="cx">     @param {Array} indexes An array of indexes of items to return.
</span><ins>+    @return {Array}
</ins><span class="cx">    */
</span><span class="cx">   objectsAt: function(indexes) {
</span><span class="cx">     var self = this;
</span><del>-    return map(indexes, function(idx){ return self.objectAt(idx); });
</del><ins>+    return map(indexes, function(idx) { return self.objectAt(idx); });
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   // overrides Ember.Enumerable version
</span><span class="lines">@@ -8229,6 +14456,7 @@
</span><span class="cx">     This property overrides the default property defined in `Ember.Enumerable`.
</span><span class="cx"> 
</span><span class="cx">     @property []
</span><ins>+    @return this
</ins><span class="cx">   */
</span><span class="cx">   '[]': Ember.computed(function(key, value) {
</span><span class="cx">     if (value !== undefined) this.replace(0, get(this, 'length'), value) ;
</span><span class="lines">@@ -8244,7 +14472,7 @@
</span><span class="cx">   }),
</span><span class="cx"> 
</span><span class="cx">   // optimized version from Enumerable
</span><del>-  contains: function(obj){
</del><ins>+  contains: function(obj) {
</ins><span class="cx">     return this.indexOf(obj) &gt;= 0;
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="lines">@@ -8262,15 +14490,19 @@
</span><span class="cx">     ```
</span><span class="cx"> 
</span><span class="cx">     @method slice
</span><del>-    @param beginIndex {Integer} (Optional) index to begin slicing from.
-    @param endIndex {Integer} (Optional) index to end the slice at.
</del><ins>+    @param {Integer} beginIndex (Optional) index to begin slicing from.
+    @param {Integer} endIndex (Optional) index to end the slice at.
</ins><span class="cx">     @return {Array} New array with specified slice
</span><span class="cx">   */
</span><span class="cx">   slice: function(beginIndex, endIndex) {
</span><del>-    var ret = [];
</del><ins>+    var ret = Ember.A();
</ins><span class="cx">     var length = get(this, 'length') ;
</span><del>-    if (none(beginIndex)) beginIndex = 0 ;
-    if (none(endIndex) || (endIndex &gt; length)) endIndex = length ;
</del><ins>+    if (isNone(beginIndex)) beginIndex = 0 ;
+    if (isNone(endIndex) || (endIndex &gt; length)) endIndex = length ;
+
+    if (beginIndex &lt; 0) beginIndex = length + beginIndex;
+    if (endIndex &lt; 0) endIndex = length + endIndex;
+
</ins><span class="cx">     while(beginIndex &lt; endIndex) {
</span><span class="cx">       ret[ret.length] = this.objectAt(beginIndex++) ;
</span><span class="cx">     }
</span><span class="lines">@@ -8305,7 +14537,7 @@
</span><span class="cx">     if (startAt &lt; 0) startAt += len;
</span><span class="cx"> 
</span><span class="cx">     for(idx=startAt;idx&lt;len;idx++) {
</span><del>-      if (this.objectAt(idx, true) === object) return idx ;
</del><ins>+      if (this.objectAt(idx) === object) return idx ;
</ins><span class="cx">     }
</span><span class="cx">     return -1;
</span><span class="cx">   },
</span><span class="lines">@@ -8351,15 +14583,15 @@
</span><span class="cx">     Adds an array observer to the receiving array. The array observer object
</span><span class="cx">     normally must implement two methods:
</span><span class="cx"> 
</span><del>-    * `arrayWillChange(start, removeCount, addCount)` - This method will be
</del><ins>+    * `arrayWillChange(observedObj, start, removeCount, addCount)` - This method will be
</ins><span class="cx">       called just before the array is modified.
</span><del>-    * `arrayDidChange(start, removeCount, addCount)` - This method will be
</del><ins>+    * `arrayDidChange(observedObj, start, removeCount, addCount)` - This method will be
</ins><span class="cx">       called just after the array is modified.
</span><span class="cx"> 
</span><del>-    Both callbacks will be passed the starting index of the change as well a
-    a count of the items to be removed and added. You can use these callbacks
-    to optionally inspect the array during the change, clear caches, or do
-    any other bookkeeping necessary.
</del><ins>+    Both callbacks will be passed the observed object, starting index of the
+    change as well a a count of the items to be removed and added. You can use
+    these callbacks to optionally inspect the array during the change, clear
+    caches, or do any other bookkeeping necessary.
</ins><span class="cx"> 
</span><span class="cx">     In addition to passing a target, you can also include an options hash
</span><span class="cx">     which you can use to override the method names that will be invoked on the
</span><span class="lines">@@ -8368,7 +14600,7 @@
</span><span class="cx">     @method addArrayObserver
</span><span class="cx">     @param {Object} target The observer object.
</span><span class="cx">     @param {Hash} opts Optional hash of configuration options including
</span><del>-      `willChange`, `didChange`, and a `context` option.
</del><ins>+      `willChange` and `didChange` option.
</ins><span class="cx">     @return {Ember.Array} receiver
</span><span class="cx">   */
</span><span class="cx">   addArrayObserver: function(target, opts) {
</span><span class="lines">@@ -8390,6 +14622,8 @@
</span><span class="cx"> 
</span><span class="cx">     @method removeArrayObserver
</span><span class="cx">     @param {Object} target The object observing the array.
</span><ins>+    @param {Hash} opts Optional hash of configuration options including
+      `willChange` and `didChange` option.
</ins><span class="cx">     @return {Ember.Array} receiver
</span><span class="cx">   */
</span><span class="cx">   removeArrayObserver: function(target, opts) {
</span><span class="lines">@@ -8422,9 +14656,9 @@
</span><span class="cx"> 
</span><span class="cx">     @method arrayContentWillChange
</span><span class="cx">     @param {Number} startIdx The starting index in the array that will change.
</span><del>-    @param {Number} removeAmt The number of items that will be removed. If you 
</del><ins>+    @param {Number} removeAmt The number of items that will be removed. If you
</ins><span class="cx">       pass `null` assumes 0
</span><del>-    @param {Number} addAmt The number of items that will be added  If you 
</del><ins>+    @param {Number} addAmt The number of items that will be added. If you
</ins><span class="cx">       pass `null` assumes 0.
</span><span class="cx">     @return {Ember.Array} receiver
</span><span class="cx">   */
</span><span class="lines">@@ -8458,6 +14692,20 @@
</span><span class="cx">     return this;
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    If you are implementing an object that supports `Ember.Array`, call this
+    method just after the array content changes to notify any observers and
+    invalidate any related properties. Pass the starting index of the change
+    as well as a delta of the amounts to change.
+
+    @method arrayContentDidChange
+    @param {Number} startIdx The starting index in the array that did change.
+    @param {Number} removeAmt The number of items that were removed. If you
+      pass `null` assumes 0
+    @param {Number} addAmt The number of items that were added. If you
+      pass `null` assumes 0.
+    @return {Ember.Array} receiver
+  */
</ins><span class="cx">   arrayContentDidChange: function(startIdx, removeAmt, addAmt) {
</span><span class="cx"> 
</span><span class="cx">     // if no args are passed assume everything changes
</span><span class="lines">@@ -8506,6 +14754,9 @@
</span><span class="cx">     return an enumerable that maps automatically to the named key on the
</span><span class="cx">     member objects.
</span><span class="cx"> 
</span><ins>+    If you merely want to watch for any items being added or removed to the array,
+    use the `[]` property instead of `@each`.
+
</ins><span class="cx">     @property @each
</span><span class="cx">   */
</span><span class="cx">   '@each': Ember.computed(function() {
</span><span class="lines">@@ -8520,13 +14771,1982 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><ins>+var e_get = Ember.get,
+    set = Ember.set,
+    guidFor = Ember.guidFor,
+    metaFor = Ember.meta,
+    propertyWillChange = Ember.propertyWillChange,
+    propertyDidChange = Ember.propertyDidChange,
+    addBeforeObserver = Ember.addBeforeObserver,
+    removeBeforeObserver = Ember.removeBeforeObserver,
+    addObserver = Ember.addObserver,
+    removeObserver = Ember.removeObserver,
+    ComputedProperty = Ember.ComputedProperty,
+    a_slice = [].slice,
+    o_create = Ember.create,
+    forEach = Ember.EnumerableUtils.forEach,
+    // Here we explicitly don't allow `@each.foo`; it would require some special
+    // testing, but there's no particular reason why it should be disallowed.
+    eachPropertyPattern = /^(.*)\.@each\.(.*)/,
+    doubleEachPropertyPattern = /(.*\.@each){2,}/,
+    arrayBracketPattern = /\.\[\]$/;
+
+
+function get(obj, key) {
+  if (key === '@this') {
+    return obj;
+  }
+
+  return e_get(obj, key);
+}
+
+/*
+  Tracks changes to dependent arrays, as well as to properties of items in
+  dependent arrays.
+
+  @class DependentArraysObserver
+*/
+function DependentArraysObserver(callbacks, cp, instanceMeta, context, propertyName, sugarMeta) {
+  // user specified callbacks for `addedItem` and `removedItem`
+  this.callbacks = callbacks;
+
+  // the computed property: remember these are shared across instances
+  this.cp = cp;
+
+  // the ReduceComputedPropertyInstanceMeta this DependentArraysObserver is
+  // associated with
+  this.instanceMeta = instanceMeta;
+
+  // A map of array guids to dependentKeys, for the given context.  We track
+  // this because we want to set up the computed property potentially before the
+  // dependent array even exists, but when the array observer fires, we lack
+  // enough context to know what to update: we can recover that context by
+  // getting the dependentKey.
+  this.dependentKeysByGuid = {};
+
+  // a map of dependent array guids -&gt; Ember.TrackedArray instances.  We use
+  // this to lazily recompute indexes for item property observers.
+  this.trackedArraysByGuid = {};
+
+  // We suspend observers to ignore replacements from `reset` when totally
+  // recomputing.  Unfortunately we cannot properly suspend the observers
+  // because we only have the key; instead we make the observers no-ops
+  this.suspended = false;
+
+  // This is used to coalesce item changes from property observers.
+  this.changedItems = {};
+}
+
+function ItemPropertyObserverContext (dependentArray, index, trackedArray) {
+  Ember.assert(&quot;Internal error: trackedArray is null or undefined&quot;, trackedArray);
+
+  this.dependentArray = dependentArray;
+  this.index = index;
+  this.item = dependentArray.objectAt(index);
+  this.trackedArray = trackedArray;
+  this.beforeObserver = null;
+  this.observer = null;
+
+  this.destroyed = false;
+}
+
+DependentArraysObserver.prototype = {
+  setValue: function (newValue) {
+    this.instanceMeta.setValue(newValue, true);
+  },
+  getValue: function () {
+    return this.instanceMeta.getValue();
+  },
+
+  setupObservers: function (dependentArray, dependentKey) {
+    Ember.assert(&quot;dependent array must be an `Ember.Array`&quot;, Ember.Array.detect(dependentArray));
+
+    this.dependentKeysByGuid[guidFor(dependentArray)] = dependentKey;
+
+    dependentArray.addArrayObserver(this, {
+      willChange: 'dependentArrayWillChange',
+      didChange: 'dependentArrayDidChange'
+    });
+
+    if (this.cp._itemPropertyKeys[dependentKey]) {
+      this.setupPropertyObservers(dependentKey, this.cp._itemPropertyKeys[dependentKey]);
+    }
+  },
+
+  teardownObservers: function (dependentArray, dependentKey) {
+    var itemPropertyKeys = this.cp._itemPropertyKeys[dependentKey] || [];
+
+    delete this.dependentKeysByGuid[guidFor(dependentArray)];
+
+    this.teardownPropertyObservers(dependentKey, itemPropertyKeys);
+
+    dependentArray.removeArrayObserver(this, {
+      willChange: 'dependentArrayWillChange',
+      didChange: 'dependentArrayDidChange'
+    });
+  },
+
+  suspendArrayObservers: function (callback, binding) {
+    var oldSuspended = this.suspended;
+    this.suspended = true;
+    callback.call(binding);
+    this.suspended = oldSuspended;
+  },
+
+  setupPropertyObservers: function (dependentKey, itemPropertyKeys) {
+    var dependentArray = get(this.instanceMeta.context, dependentKey),
+        length = get(dependentArray, 'length'),
+        observerContexts = new Array(length);
+
+    this.resetTransformations(dependentKey, observerContexts);
+
+    forEach(dependentArray, function (item, index) {
+      var observerContext = this.createPropertyObserverContext(dependentArray, index, this.trackedArraysByGuid[dependentKey]);
+      observerContexts[index] = observerContext;
+
+      forEach(itemPropertyKeys, function (propertyKey) {
+        addBeforeObserver(item, propertyKey, this, observerContext.beforeObserver);
+        addObserver(item, propertyKey, this, observerContext.observer);
+      }, this);
+    }, this);
+  },
+
+  teardownPropertyObservers: function (dependentKey, itemPropertyKeys) {
+    var dependentArrayObserver = this,
+        trackedArray = this.trackedArraysByGuid[dependentKey],
+        beforeObserver,
+        observer,
+        item;
+
+    if (!trackedArray) { return; }
+
+    trackedArray.apply(function (observerContexts, offset, operation) {
+      if (operation === Ember.TrackedArray.DELETE) { return; }
+
+      forEach(observerContexts, function (observerContext) {
+        observerContext.destroyed = true;
+        beforeObserver = observerContext.beforeObserver;
+        observer = observerContext.observer;
+        item = observerContext.item;
+
+        forEach(itemPropertyKeys, function (propertyKey) {
+          removeBeforeObserver(item, propertyKey, dependentArrayObserver, beforeObserver);
+          removeObserver(item, propertyKey, dependentArrayObserver, observer);
+        });
+      });
+    });
+  },
+
+  createPropertyObserverContext: function (dependentArray, index, trackedArray) {
+    var observerContext = new ItemPropertyObserverContext(dependentArray, index, trackedArray);
+
+    this.createPropertyObserver(observerContext);
+
+    return observerContext;
+  },
+
+  createPropertyObserver: function (observerContext) {
+    var dependentArrayObserver = this;
+
+    observerContext.beforeObserver = function (obj, keyName) {
+      return dependentArrayObserver.itemPropertyWillChange(obj, keyName, observerContext.dependentArray, observerContext);
+    };
+    observerContext.observer = function (obj, keyName) {
+      return dependentArrayObserver.itemPropertyDidChange(obj, keyName, observerContext.dependentArray, observerContext);
+    };
+  },
+
+  resetTransformations: function (dependentKey, observerContexts) {
+    this.trackedArraysByGuid[dependentKey] = new Ember.TrackedArray(observerContexts);
+  },
+
+  trackAdd: function (dependentKey, index, newItems) {
+    var trackedArray = this.trackedArraysByGuid[dependentKey];
+    if (trackedArray) {
+      trackedArray.addItems(index, newItems);
+    }
+  },
+
+  trackRemove: function (dependentKey, index, removedCount) {
+    var trackedArray = this.trackedArraysByGuid[dependentKey];
+
+    if (trackedArray) {
+      return trackedArray.removeItems(index, removedCount);
+    }
+
+    return [];
+  },
+
+  updateIndexes: function (trackedArray, array) {
+    var length = get(array, 'length');
+    // OPTIMIZE: we could stop updating once we hit the object whose observer
+    // fired; ie partially apply the transformations
+    trackedArray.apply(function (observerContexts, offset, operation) {
+      // we don't even have observer contexts for removed items, even if we did,
+      // they no longer have any index in the array
+      if (operation === Ember.TrackedArray.DELETE) { return; }
+      if (operation === Ember.TrackedArray.RETAIN &amp;&amp; observerContexts.length === length &amp;&amp; offset === 0) {
+        // If we update many items we don't want to walk the array each time: we
+        // only need to update the indexes at most once per run loop.
+        return;
+      }
+
+      forEach(observerContexts, function (context, index) {
+        context.index = index + offset;
+      });
+    });
+  },
+
+  dependentArrayWillChange: function (dependentArray, index, removedCount, addedCount) {
+    if (this.suspended) { return; }
+
+    var removedItem = this.callbacks.removedItem,
+        changeMeta,
+        guid = guidFor(dependentArray),
+        dependentKey = this.dependentKeysByGuid[guid],
+        itemPropertyKeys = this.cp._itemPropertyKeys[dependentKey] || [],
+        length = get(dependentArray, 'length'),
+        normalizedIndex = normalizeIndex(index, length, 0),
+        normalizedRemoveCount = normalizeRemoveCount(normalizedIndex, length, removedCount),
+        item,
+        itemIndex,
+        sliceIndex,
+        observerContexts;
+
+    observerContexts = this.trackRemove(dependentKey, normalizedIndex, normalizedRemoveCount);
+
+    function removeObservers(propertyKey) {
+      observerContexts[sliceIndex].destroyed = true;
+      removeBeforeObserver(item, propertyKey, this, observerContexts[sliceIndex].beforeObserver);
+      removeObserver(item, propertyKey, this, observerContexts[sliceIndex].observer);
+    }
+
+    for (sliceIndex = normalizedRemoveCount - 1; sliceIndex &gt;= 0; --sliceIndex) {
+      itemIndex = normalizedIndex + sliceIndex;
+      if (itemIndex &gt;= length) { break; }
+
+      item = dependentArray.objectAt(itemIndex);
+
+      forEach(itemPropertyKeys, removeObservers, this);
+
+      changeMeta = createChangeMeta(dependentArray, item, itemIndex, this.instanceMeta.propertyName, this.cp);
+      this.setValue( removedItem.call(
+        this.instanceMeta.context, this.getValue(), item, changeMeta, this.instanceMeta.sugarMeta));
+    }
+  },
+
+  dependentArrayDidChange: function (dependentArray, index, removedCount, addedCount) {
+    if (this.suspended) { return; }
+
+    var addedItem = this.callbacks.addedItem,
+        guid = guidFor(dependentArray),
+        dependentKey = this.dependentKeysByGuid[guid],
+        observerContexts = new Array(addedCount),
+        itemPropertyKeys = this.cp._itemPropertyKeys[dependentKey],
+        length = get(dependentArray, 'length'),
+        normalizedIndex = normalizeIndex(index, length, addedCount),
+        changeMeta,
+        observerContext;
+
+    forEach(dependentArray.slice(normalizedIndex, normalizedIndex + addedCount), function (item, sliceIndex) {
+      if (itemPropertyKeys) {
+        observerContext =
+          observerContexts[sliceIndex] =
+          this.createPropertyObserverContext(dependentArray, normalizedIndex + sliceIndex, this.trackedArraysByGuid[dependentKey]);
+        forEach(itemPropertyKeys, function (propertyKey) {
+          addBeforeObserver(item, propertyKey, this, observerContext.beforeObserver);
+          addObserver(item, propertyKey, this, observerContext.observer);
+        }, this);
+      }
+
+      changeMeta = createChangeMeta(dependentArray, item, normalizedIndex + sliceIndex, this.instanceMeta.propertyName, this.cp);
+      this.setValue( addedItem.call(
+        this.instanceMeta.context, this.getValue(), item, changeMeta, this.instanceMeta.sugarMeta));
+    }, this);
+
+    this.trackAdd(dependentKey, normalizedIndex, observerContexts);
+  },
+
+  itemPropertyWillChange: function (obj, keyName, array, observerContext) {
+    var guid = guidFor(obj);
+
+    if (!this.changedItems[guid]) {
+      this.changedItems[guid] = {
+        array:            array,
+        observerContext:  observerContext,
+        obj:              obj,
+        previousValues:   {}
+      };
+    }
+
+    this.changedItems[guid].previousValues[keyName] = get(obj, keyName);
+  },
+
+  itemPropertyDidChange: function(obj, keyName, array, observerContext) {
+    this.flushChanges();
+  },
+
+  flushChanges: function() {
+    var changedItems = this.changedItems, key, c, changeMeta;
+
+    for (key in changedItems) {
+      c = changedItems[key];
+      if (c.observerContext.destroyed) { continue; }
+
+      this.updateIndexes(c.observerContext.trackedArray, c.observerContext.dependentArray);
+
+      changeMeta = createChangeMeta(c.array, c.obj, c.observerContext.index, this.instanceMeta.propertyName, this.cp, c.previousValues);
+      this.setValue(
+        this.callbacks.removedItem.call(this.instanceMeta.context, this.getValue(), c.obj, changeMeta, this.instanceMeta.sugarMeta));
+      this.setValue(
+        this.callbacks.addedItem.call(this.instanceMeta.context, this.getValue(), c.obj, changeMeta, this.instanceMeta.sugarMeta));
+    }
+    this.changedItems = {};
+  }
+};
+
+function normalizeIndex(index, length, newItemsOffset) {
+  if (index &lt; 0) {
+    return Math.max(0, length + index);
+  } else if (index &lt; length) {
+    return index;
+  } else /* index &gt; length */ {
+    return Math.min(length - newItemsOffset, index);
+  }
+}
+
+function normalizeRemoveCount(index, length, removedCount) {
+  return Math.min(removedCount, length - index);
+}
+
+function createChangeMeta(dependentArray, item, index, propertyName, property, previousValues) {
+  var meta = {
+    arrayChanged: dependentArray,
+    index: index,
+    item: item,
+    propertyName: propertyName,
+    property: property
+  };
+
+  if (previousValues) {
+    // previous values only available for item property changes
+    meta.previousValues = previousValues;
+  }
+
+  return meta;
+}
+
+function addItems (dependentArray, callbacks, cp, propertyName, meta) {
+  forEach(dependentArray, function (item, index) {
+    meta.setValue( callbacks.addedItem.call(
+      this, meta.getValue(), item, createChangeMeta(dependentArray, item, index, propertyName, cp), meta.sugarMeta));
+  }, this);
+}
+
+function reset(cp, propertyName) {
+  var callbacks = cp._callbacks(),
+      meta;
+
+  if (cp._hasInstanceMeta(this, propertyName)) {
+    meta = cp._instanceMeta(this, propertyName);
+    meta.setValue(cp.resetValue(meta.getValue()));
+  } else {
+    meta = cp._instanceMeta(this, propertyName);
+  }
+
+  if (cp.options.initialize) {
+    cp.options.initialize.call(this, meta.getValue(), { property: cp, propertyName: propertyName }, meta.sugarMeta);
+  }
+}
+
+function partiallyRecomputeFor(obj, dependentKey) {
+  if (arrayBracketPattern.test(dependentKey)) {
+    return false;
+  }
+
+  var value = get(obj, dependentKey);
+  return Ember.Array.detect(value);
+}
+
+function ReduceComputedPropertyInstanceMeta(context, propertyName, initialValue) {
+  this.context = context;
+  this.propertyName = propertyName;
+  this.cache = metaFor(context).cache;
+
+  this.dependentArrays = {};
+  this.sugarMeta = {};
+
+  this.initialValue = initialValue;
+}
+
+ReduceComputedPropertyInstanceMeta.prototype = {
+  getValue: function () {
+    if (this.propertyName in this.cache) {
+      return this.cache[this.propertyName];
+    } else {
+      return this.initialValue;
+    }
+  },
+
+  setValue: function(newValue, triggerObservers) {
+    // This lets sugars force a recomputation, handy for very simple
+    // implementations of eg max.
+    if (newValue !== undefined) {
+      var fireObservers = triggerObservers &amp;&amp; (newValue !== this.cache[this.propertyName]);
+
+      if (fireObservers) {
+        propertyWillChange(this.context, this.propertyName);
+      }
+
+      this.cache[this.propertyName] = newValue;
+
+      if (fireObservers) {
+        propertyDidChange(this.context, this.propertyName);
+      }
+    } else {
+      delete this.cache[this.propertyName];
+    }
+  }
+};
+
</ins><span class="cx"> /**
</span><ins>+  A computed property whose dependent keys are arrays and which is updated with
+  &quot;one at a time&quot; semantics.
+
+  @class ReduceComputedProperty
+  @namespace Ember
+  @extends Ember.ComputedProperty
+  @constructor
+*/
+function ReduceComputedProperty(options) {
+  var cp = this;
+
+  this.options = options;
+  this._instanceMetas = {};
+
+  this._dependentKeys = null;
+  // A map of dependentKey -&gt; [itemProperty, ...] that tracks what properties of
+  // items in the array we must track to update this property.
+  this._itemPropertyKeys = {};
+  this._previousItemPropertyKeys = {};
+
+  this.readOnly();
+  this.cacheable();
+
+  this.recomputeOnce = function(propertyName) {
+    // What we really want to do is coalesce by &lt;cp, propertyName&gt;.
+    // We need a form of `scheduleOnce` that accepts an arbitrary token to
+    // coalesce by, in addition to the target and method.
+    Ember.run.once(this, recompute, propertyName);
+  };
+  var recompute = function(propertyName) {
+    var dependentKeys = cp._dependentKeys,
+        meta = cp._instanceMeta(this, propertyName),
+        callbacks = cp._callbacks();
+
+    reset.call(this, cp, propertyName);
+
+    meta.dependentArraysObserver.suspendArrayObservers(function () {
+      forEach(cp._dependentKeys, function (dependentKey) {
+        if (!partiallyRecomputeFor(this, dependentKey)) { return; }
+
+        var dependentArray = get(this, dependentKey),
+            previousDependentArray = meta.dependentArrays[dependentKey];
+
+        if (dependentArray === previousDependentArray) {
+          // The array may be the same, but our item property keys may have
+          // changed, so we set them up again.  We can't easily tell if they've
+          // changed: the array may be the same object, but with different
+          // contents.
+          if (cp._previousItemPropertyKeys[dependentKey]) {
+            delete cp._previousItemPropertyKeys[dependentKey];
+            meta.dependentArraysObserver.setupPropertyObservers(dependentKey, cp._itemPropertyKeys[dependentKey]);
+          }
+        } else {
+          meta.dependentArrays[dependentKey] = dependentArray;
+
+          if (previousDependentArray) {
+            meta.dependentArraysObserver.teardownObservers(previousDependentArray, dependentKey);
+          }
+
+          if (dependentArray) {
+            meta.dependentArraysObserver.setupObservers(dependentArray, dependentKey);
+          }
+        }
+      }, this);
+    }, this);
+
+    forEach(cp._dependentKeys, function(dependentKey) {
+      if (!partiallyRecomputeFor(this, dependentKey)) { return; }
+
+      var dependentArray = get(this, dependentKey);
+      if (dependentArray) {
+        addItems.call(this, dependentArray, callbacks, cp, propertyName, meta);
+      }
+    }, this);
+  };
+
+  this.func = function (propertyName) {
+    Ember.assert(&quot;Computed reduce values require at least one dependent key&quot;, cp._dependentKeys);
+
+    recompute.call(this, propertyName);
+
+    return cp._instanceMeta(this, propertyName).getValue();
+  };
+}
+
+Ember.ReduceComputedProperty = ReduceComputedProperty;
+ReduceComputedProperty.prototype = o_create(ComputedProperty.prototype);
+
+function defaultCallback(computedValue) {
+  return computedValue;
+}
+
+ReduceComputedProperty.prototype._callbacks = function () {
+  if (!this.callbacks) {
+    var options = this.options;
+    this.callbacks = {
+      removedItem: options.removedItem || defaultCallback,
+      addedItem: options.addedItem || defaultCallback
+    };
+  }
+  return this.callbacks;
+};
+
+ReduceComputedProperty.prototype._hasInstanceMeta = function (context, propertyName) {
+  var guid = guidFor(context),
+      key = guid + ':' + propertyName;
+
+  return !!this._instanceMetas[key];
+};
+
+ReduceComputedProperty.prototype._instanceMeta = function (context, propertyName) {
+  var guid = guidFor(context),
+      key = guid + ':' + propertyName,
+      meta = this._instanceMetas[key];
+
+  if (!meta) {
+    meta = this._instanceMetas[key] = new ReduceComputedPropertyInstanceMeta(context, propertyName, this.initialValue());
+    meta.dependentArraysObserver = new DependentArraysObserver(this._callbacks(), this, meta, context, propertyName, meta.sugarMeta);
+  }
+
+  return meta;
+};
+
+ReduceComputedProperty.prototype.initialValue = function () {
+  if (typeof this.options.initialValue === 'function') {
+    return this.options.initialValue();
+  }
+  else {
+    return this.options.initialValue;
+  }
+};
+
+ReduceComputedProperty.prototype.resetValue = function (value) {
+  return this.initialValue();
+};
+
+ReduceComputedProperty.prototype.itemPropertyKey = function (dependentArrayKey, itemPropertyKey) {
+  this._itemPropertyKeys[dependentArrayKey] = this._itemPropertyKeys[dependentArrayKey] || [];
+  this._itemPropertyKeys[dependentArrayKey].push(itemPropertyKey);
+};
+
+ReduceComputedProperty.prototype.clearItemPropertyKeys = function (dependentArrayKey) {
+  if (this._itemPropertyKeys[dependentArrayKey]) {
+    this._previousItemPropertyKeys[dependentArrayKey] = this._itemPropertyKeys[dependentArrayKey];
+    this._itemPropertyKeys[dependentArrayKey] = [];
+  }
+};
+
+ReduceComputedProperty.prototype.property = function () {
+  var cp = this,
+      args = a_slice.call(arguments),
+      propertyArgs = new Ember.Set(),
+      match,
+      dependentArrayKey,
+      itemPropertyKey;
+
+  forEach(a_slice.call(arguments), function (dependentKey) {
+    if (doubleEachPropertyPattern.test(dependentKey)) {
+      throw new Ember.Error(&quot;Nested @each properties not supported: &quot; + dependentKey);
+    } else if (match = eachPropertyPattern.exec(dependentKey)) {
+      dependentArrayKey = match[1];
+
+      
+        itemPropertyKey = match[2];
+        cp.itemPropertyKey(dependentArrayKey, itemPropertyKey);
+      
+      propertyArgs.add(dependentArrayKey);
+    } else {
+      propertyArgs.add(dependentKey);
+    }
+  });
+
+  return ComputedProperty.prototype.property.apply(this, propertyArgs.toArray());
+
+};
+
+/**
+  Creates a computed property which operates on dependent arrays and
+  is updated with &quot;one at a time&quot; semantics. When items are added or
+  removed from the dependent array(s) a reduce computed only operates
+  on the change instead of re-evaluating the entire array.
+
+  If there are more than one arguments the first arguments are
+  considered to be dependent property keys. The last argument is
+  required to be an options object. The options object can have the
+  following four properties:
+
+  `initialValue` - A value or function that will be used as the initial
+  value for the computed. If this property is a function the result of calling
+  the function will be used as the initial value. This property is required.
+
+  `initialize` - An optional initialize function. Typically this will be used
+  to set up state on the instanceMeta object.
+
+  `removedItem` - A function that is called each time an element is removed
+  from the array.
+
+  `addedItem` - A function that is called each time an element is added to
+  the array.
+
+
+  The `initialize` function has the following signature:
+
+  ```javascript
+   function (initialValue, changeMeta, instanceMeta)
+  ```
+
+  `initialValue` - The value of the `initialValue` property from the
+  options object.
+
+  `changeMeta` - An object which contains meta information about the
+  computed. It contains the following properties:
+
+     - `property` the computed property
+     - `propertyName` the name of the property on the object
+
+  `instanceMeta` - An object that can be used to store meta
+  information needed for calculating your computed. For example a
+  unique computed might use this to store the number of times a given
+  element is found in the dependent array.
+
+
+  The `removedItem` and `addedItem` functions both have the following signature:
+
+  ```javascript
+  function (accumulatedValue, item, changeMeta, instanceMeta)
+  ```
+
+  `accumulatedValue` - The value returned from the last time
+  `removedItem` or `addedItem` was called or `initialValue`.
+
+  `item` - the element added or removed from the array
+
+  `changeMeta` - An object which contains meta information about the
+  change. It contains the following properties:
+
+    - `property` the computed property
+    - `propertyName` the name of the property on the object
+    - `index` the index of the added or removed item
+    - `item` the added or removed item: this is exactly the same as
+      the second arg
+    - `arrayChanged` the array that triggered the change. Can be
+      useful when depending on multiple arrays.
+
+  For property changes triggered on an item property change (when
+  depKey is something like `someArray.@each.someProperty`),
+  `changeMeta` will also contain the following property:
+
+    - `previousValues` an object whose keys are the properties that changed on
+    the item, and whose values are the item's previous values.
+
+  `previousValues` is important Ember coalesces item property changes via
+  Ember.run.once. This means that by the time removedItem gets called, item has
+  the new values, but you may need the previous value (eg for sorting &amp;
+  filtering).
+
+  `instanceMeta` - An object that can be used to store meta
+  information needed for calculating your computed. For example a
+  unique computed might use this to store the number of times a given
+  element is found in the dependent array.
+
+  The `removedItem` and `addedItem` functions should return the accumulated
+  value. It is acceptable to not return anything (ie return undefined)
+  to invalidate the computation. This is generally not a good idea for
+  arrayComputed but it's used in eg max and min.
+
+  Note that observers will be fired if either of these functions return a value
+  that differs from the accumulated value.  When returning an object that
+  mutates in response to array changes, for example an array that maps
+  everything from some other array (see `Ember.computed.map`), it is usually
+  important that the *same* array be returned to avoid accidentally triggering observers.
+
+  Example
+
+  ```javascript
+  Ember.computed.max = function (dependentKey) {
+    return Ember.reduceComputed.call(null, dependentKey, {
+      initialValue: -Infinity,
+
+      addedItem: function (accumulatedValue, item, changeMeta, instanceMeta) {
+        return Math.max(accumulatedValue, item);
+      },
+
+      removedItem: function (accumulatedValue, item, changeMeta, instanceMeta) {
+        if (item &lt; accumulatedValue) {
+          return accumulatedValue;
+        }
+      }
+    });
+  };
+  ```
+
+  Dependent keys may refer to `@this` to observe changes to the object itself,
+  which must be array-like, rather than a property of the object.  This is
+  mostly useful for array proxies, to ensure objects are retrieved via
+  `objectAtContent`.  This is how you could sort items by properties defined on an item controller.
+
+  Example
+
+  ```javascript
+  App.PeopleController = Ember.ArrayController.extend({
+    itemController: 'person',
+
+    sortedPeople: Ember.computed.sort('@this.@each.reversedName', function(personA, personB) {
+      // `reversedName` isn't defined on Person, but we have access to it via
+      // the item controller App.PersonController.  If we'd used
+      // `content.@each.reversedName` above, we would be getting the objects
+      // directly and not have access to `reversedName`.
+      //
+      var reversedNameA = get(personA, 'reversedName'),
+          reversedNameB = get(personB, 'reversedName');
+
+      return Ember.compare(reversedNameA, reversedNameB);
+    })
+  });
+
+  App.PersonController = Ember.ObjectController.extend({
+    reversedName: function () {
+      return reverse(get(this, 'name'));
+    }.property('name')
+  })
+  ```
+
+  Dependent keys whose values are not arrays are treated as regular
+  dependencies: when they change, the computed property is completely
+  recalculated.  It is sometimes useful to have dependent arrays with similar
+  semantics.  Dependent keys which end in `.[]` do not use &quot;one at a time&quot;
+  semantics.  When an item is added or removed from such a dependency, the
+  computed property is completely recomputed.
+
+  Example
+
+  ```javascript
+  Ember.Object.extend({
+    // When `string` is changed, `computed` is completely recomputed.
+    string: 'a string',
+
+    // When an item is added to `array`, `addedItem` is called.
+    array: [],
+
+    // When an item is added to `anotherArray`, `computed` is completely
+    // recomputed.
+    anotherArray: [],
+
+    computed: Ember.reduceComputed('string', 'array', 'anotherArray.[]', {
+      addedItem: addedItemCallback,
+      removedItem: removedItemCallback
+    })
+  });
+  ```
+
+  @method reduceComputed
+  @for Ember
+  @param {String} [dependentKeys*]
+  @param {Object} options
+  @return {Ember.ComputedProperty}
+*/
+Ember.reduceComputed = function (options) {
+  var args;
+
+  if (arguments.length &gt; 1) {
+    args = a_slice.call(arguments, 0, -1);
+    options = a_slice.call(arguments, -1)[0];
+  }
+
+  if (typeof options !== &quot;object&quot;) {
+    throw new Ember.Error(&quot;Reduce Computed Property declared without an options hash&quot;);
+  }
+
+  if (!('initialValue' in options)) {
+    throw new Ember.Error(&quot;Reduce Computed Property declared without an initial value&quot;);
+  }
+
+  var cp = new ReduceComputedProperty(options);
+
+  if (args) {
+    cp.property.apply(cp, args);
+  }
+
+  return cp;
+};
+
+})();
+
+
+
+(function() {
+var ReduceComputedProperty = Ember.ReduceComputedProperty,
+    a_slice = [].slice,
+    o_create = Ember.create,
+    forEach = Ember.EnumerableUtils.forEach;
+
+function ArrayComputedProperty() {
+  var cp = this;
+
+  ReduceComputedProperty.apply(this, arguments);
+
+  this.func = (function(reduceFunc) {
+    return function (propertyName) {
+      if (!cp._hasInstanceMeta(this, propertyName)) {
+        // When we recompute an array computed property, we need already
+        // retrieved arrays to be updated; we can't simply empty the cache and
+        // hope the array is re-retrieved.
+        forEach(cp._dependentKeys, function(dependentKey) {
+          Ember.addObserver(this, dependentKey, function() {
+            cp.recomputeOnce.call(this, propertyName);
+          });
+        }, this);
+      }
+
+      return reduceFunc.apply(this, arguments);
+    };
+  })(this.func);
+
+  return this;
+}
+Ember.ArrayComputedProperty = ArrayComputedProperty;
+ArrayComputedProperty.prototype = o_create(ReduceComputedProperty.prototype);
+ArrayComputedProperty.prototype.initialValue = function () {
+  return Ember.A();
+};
+ArrayComputedProperty.prototype.resetValue = function (array) {
+  array.clear();
+  return array;
+};
+
+// This is a stopgap to keep the reference counts correct with lazy CPs.
+ArrayComputedProperty.prototype.didChange = function (obj, keyName) {
+  return;
+};
+
+/**
+  Creates a computed property which operates on dependent arrays and
+  is updated with &quot;one at a time&quot; semantics. When items are added or
+  removed from the dependent array(s) an array computed only operates
+  on the change instead of re-evaluating the entire array. This should
+  return an array, if you'd like to use &quot;one at a time&quot; semantics and
+  compute some value other then an array look at
+  `Ember.reduceComputed`.
+
+  If there are more than one arguments the first arguments are
+  considered to be dependent property keys. The last argument is
+  required to be an options object. The options object can have the
+  following three properties.
+
+  `initialize` - An optional initialize function. Typically this will be used
+  to set up state on the instanceMeta object.
+
+  `removedItem` - A function that is called each time an element is
+  removed from the array.
+
+  `addedItem` - A function that is called each time an element is
+  added to the array.
+
+
+  The `initialize` function has the following signature:
+
+  ```javascript
+   function (array, changeMeta, instanceMeta)
+  ```
+
+  `array` - The initial value of the arrayComputed, an empty array.
+
+  `changeMeta` - An object which contains meta information about the
+  computed. It contains the following properties:
+
+     - `property` the computed property
+     - `propertyName` the name of the property on the object
+
+  `instanceMeta` - An object that can be used to store meta
+  information needed for calculating your computed. For example a
+  unique computed might use this to store the number of times a given
+  element is found in the dependent array.
+
+
+  The `removedItem` and `addedItem` functions both have the following signature:
+
+  ```javascript
+  function (accumulatedValue, item, changeMeta, instanceMeta)
+  ```
+
+  `accumulatedValue` - The value returned from the last time
+  `removedItem` or `addedItem` was called or an empty array.
+
+  `item` - the element added or removed from the array
+
+  `changeMeta` - An object which contains meta information about the
+  change. It contains the following properties:
+
+    - `property` the computed property
+    - `propertyName` the name of the property on the object
+    - `index` the index of the added or removed item
+    - `item` the added or removed item: this is exactly the same as
+      the second arg
+    - `arrayChanged` the array that triggered the change. Can be
+      useful when depending on multiple arrays.
+
+  For property changes triggered on an item property change (when
+  depKey is something like `someArray.@each.someProperty`),
+  `changeMeta` will also contain the following property:
+
+    - `previousValues` an object whose keys are the properties that changed on
+    the item, and whose values are the item's previous values.
+
+  `previousValues` is important Ember coalesces item property changes via
+  Ember.run.once. This means that by the time removedItem gets called, item has
+  the new values, but you may need the previous value (eg for sorting &amp;
+  filtering).
+
+  `instanceMeta` - An object that can be used to store meta
+  information needed for calculating your computed. For example a
+  unique computed might use this to store the number of times a given
+  element is found in the dependent array.
+
+  The `removedItem` and `addedItem` functions should return the accumulated
+  value. It is acceptable to not return anything (ie return undefined)
+  to invalidate the computation. This is generally not a good idea for
+  arrayComputed but it's used in eg max and min.
+
+  Example
+
+  ```javascript
+  Ember.computed.map = function(dependentKey, callback) {
+    var options = {
+      addedItem: function(array, item, changeMeta, instanceMeta) {
+        var mapped = callback(item);
+        array.insertAt(changeMeta.index, mapped);
+        return array;
+      },
+      removedItem: function(array, item, changeMeta, instanceMeta) {
+        array.removeAt(changeMeta.index, 1);
+        return array;
+      }
+    };
+
+    return Ember.arrayComputed(dependentKey, options);
+  };
+  ```
+
+  @method arrayComputed
+  @for Ember
+  @param {String} [dependentKeys*]
+  @param {Object} options
+  @return {Ember.ComputedProperty}
+*/
+Ember.arrayComputed = function (options) {
+  var args;
+
+  if (arguments.length &gt; 1) {
+    args = a_slice.call(arguments, 0, -1);
+    options = a_slice.call(arguments, -1)[0];
+  }
+
+  if (typeof options !== &quot;object&quot;) {
+    throw new Ember.Error(&quot;Array Computed Property declared without an options hash&quot;);
+  }
+
+  var cp = new ArrayComputedProperty(options);
+
+  if (args) {
+    cp.property.apply(cp, args);
+  }
+
+  return cp;
+};
+
+})();
+
+
+
+(function() {
+/**
</ins><span class="cx"> @module ember
</span><span class="cx"> @submodule ember-runtime
</span><span class="cx"> */
</span><span class="cx"> 
</span><ins>+var get = Ember.get,
+    set = Ember.set,
+    guidFor = Ember.guidFor,
+    merge = Ember.merge,
+    a_slice = [].slice,
+    forEach = Ember.EnumerableUtils.forEach,
+    map = Ember.EnumerableUtils.map,
+    SearchProxy;
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+  A computed property that calculates the maximum value in the
+  dependent array. This will return `-Infinity` when the dependent
+  array is empty.
+
+  ```javascript
+  App.Person = Ember.Object.extend({
+    childAges: Ember.computed.mapBy('children', 'age'),
+    maxChildAge: Ember.computed.max('childAges')
+  });
+
+  var lordByron = App.Person.create({children: []});
+  lordByron.get('maxChildAge'); // -Infinity
+  lordByron.get('children').pushObject({
+    name: 'Augusta Ada Byron', age: 7
+  });
+  lordByron.get('maxChildAge'); // 7
+  lordByron.get('children').pushObjects([{
+    name: 'Allegra Byron',
+    age: 5
+  }, {
+    name: 'Elizabeth Medora Leigh',
+    age: 8
+  }]);
+  lordByron.get('maxChildAge'); // 8
+  ```
+
+  @method computed.max
+  @for Ember
+  @param {String} dependentKey
+  @return {Ember.ComputedProperty} computes the largest value in the dependentKey's array
+*/
+Ember.computed.max = function (dependentKey) {
+  return Ember.reduceComputed.call(null, dependentKey, {
+    initialValue: -Infinity,
+
+    addedItem: function (accumulatedValue, item, changeMeta, instanceMeta) {
+      return Math.max(accumulatedValue, item);
+    },
+
+    removedItem: function (accumulatedValue, item, changeMeta, instanceMeta) {
+      if (item &lt; accumulatedValue) {
+        return accumulatedValue;
+      }
+    }
+  });
+};
+
+/**
+  A computed property that calculates the minimum value in the
+  dependent array. This will return `Infinity` when the dependent
+  array is empty.
+
+  ```javascript
+  App.Person = Ember.Object.extend({
+    childAges: Ember.computed.mapBy('children', 'age'),
+    minChildAge: Ember.computed.min('childAges')
+  });
+
+  var lordByron = App.Person.create({children: []});
+  lordByron.get('minChildAge'); // Infinity
+  lordByron.get('children').pushObject({
+    name: 'Augusta Ada Byron', age: 7
+  });
+  lordByron.get('minChildAge'); // 7
+  lordByron.get('children').pushObjects([{
+    name: 'Allegra Byron',
+    age: 5
+  }, {
+    name: 'Elizabeth Medora Leigh',
+    age: 8
+  }]);
+  lordByron.get('minChildAge'); // 5
+  ```
+
+  @method computed.min
+  @for Ember
+  @param {String} dependentKey
+  @return {Ember.ComputedProperty} computes the smallest value in the dependentKey's array
+*/
+Ember.computed.min = function (dependentKey) {
+  return Ember.reduceComputed.call(null, dependentKey, {
+    initialValue: Infinity,
+
+    addedItem: function (accumulatedValue, item, changeMeta, instanceMeta) {
+      return Math.min(accumulatedValue, item);
+    },
+
+    removedItem: function (accumulatedValue, item, changeMeta, instanceMeta) {
+      if (item &gt; accumulatedValue) {
+        return accumulatedValue;
+      }
+    }
+  });
+};
+
+/**
+  Returns an array mapped via the callback
+
+  The callback method you provide should have the following signature.
+  `item` is the current item in the iteration.
+
+  ```javascript
+  function(item);
+  ```
+
+  Example
+
+  ```javascript
+  App.Hamster = Ember.Object.extend({
+    excitingChores: Ember.computed.map('chores', function(chore) {
+      return chore.toUpperCase() + '!';
+    })
+  });
+
+  var hamster = App.Hamster.create({
+    chores: ['clean', 'write more unit tests']
+  });
+  hamster.get('excitingChores'); // ['CLEAN!', 'WRITE MORE UNIT TESTS!']
+  ```
+
+  @method computed.map
+  @for Ember
+  @param {String} dependentKey
+  @param {Function} callback
+  @return {Ember.ComputedProperty} an array mapped via the callback
+*/
+Ember.computed.map = function(dependentKey, callback) {
+  var options = {
+    addedItem: function(array, item, changeMeta, instanceMeta) {
+      var mapped = callback.call(this, item);
+      array.insertAt(changeMeta.index, mapped);
+      return array;
+    },
+    removedItem: function(array, item, changeMeta, instanceMeta) {
+      array.removeAt(changeMeta.index, 1);
+      return array;
+    }
+  };
+
+  return Ember.arrayComputed(dependentKey, options);
+};
+
+/**
+  Returns an array mapped to the specified key.
+
+  ```javascript
+  App.Person = Ember.Object.extend({
+    childAges: Ember.computed.mapBy('children', 'age')
+  });
+
+  var lordByron = App.Person.create({children: []});
+  lordByron.get('childAges'); // []
+  lordByron.get('children').pushObject({name: 'Augusta Ada Byron', age: 7});
+  lordByron.get('childAges'); // [7]
+  lordByron.get('children').pushObjects([{
+    name: 'Allegra Byron',
+    age: 5
+  }, {
+    name: 'Elizabeth Medora Leigh',
+    age: 8
+  }]);
+  lordByron.get('childAges'); // [7, 5, 8]
+  ```
+
+  @method computed.mapBy
+  @for Ember
+  @param {String} dependentKey
+  @param {String} propertyKey
+  @return {Ember.ComputedProperty} an array mapped to the specified key
+*/
+Ember.computed.mapBy = function(dependentKey, propertyKey) {
+  var callback = function(item) { return get(item, propertyKey); };
+  return Ember.computed.map(dependentKey + '.@each.' + propertyKey, callback);
+};
+
+/**
+  @method computed.mapProperty
+  @for Ember
+  @deprecated Use `Ember.computed.mapBy` instead
+  @param dependentKey
+  @param propertyKey
+*/
+Ember.computed.mapProperty = Ember.computed.mapBy;
+
+/**
+  Filters the array by the callback.
+
+  The callback method you provide should have the following signature.
+  `item` is the current item in the iteration.
+
+  ```javascript
+  function(item);
+  ```
+
+  ```javascript
+  App.Hamster = Ember.Object.extend({
+    remainingChores: Ember.computed.filter('chores', function(chore) {
+      return !chore.done;
+    })
+  });
+
+  var hamster = App.Hamster.create({chores: [
+    {name: 'cook', done: true},
+    {name: 'clean', done: true},
+    {name: 'write more unit tests', done: false}
+  ]});
+  hamster.get('remainingChores'); // [{name: 'write more unit tests', done: false}]
+  ```
+
+  @method computed.filter
+  @for Ember
+  @param {String} dependentKey
+  @param {Function} callback
+  @return {Ember.ComputedProperty} the filtered array
+*/
+Ember.computed.filter = function(dependentKey, callback) {
+  var options = {
+    initialize: function (array, changeMeta, instanceMeta) {
+      instanceMeta.filteredArrayIndexes = new Ember.SubArray();
+    },
+
+    addedItem: function(array, item, changeMeta, instanceMeta) {
+      var match = !!callback.call(this, item),
+          filterIndex = instanceMeta.filteredArrayIndexes.addItem(changeMeta.index, match);
+
+      if (match) {
+        array.insertAt(filterIndex, item);
+      }
+
+      return array;
+    },
+
+    removedItem: function(array, item, changeMeta, instanceMeta) {
+      var filterIndex = instanceMeta.filteredArrayIndexes.removeItem(changeMeta.index);
+
+      if (filterIndex &gt; -1) {
+        array.removeAt(filterIndex);
+      }
+
+      return array;
+    }
+  };
+
+  return Ember.arrayComputed(dependentKey, options);
+};
+
+/**
+  Filters the array by the property and value
+
+  ```javascript
+  App.Hamster = Ember.Object.extend({
+    remainingChores: Ember.computed.filterBy('chores', 'done', false)
+  });
+
+  var hamster = App.Hamster.create({chores: [
+    {name: 'cook', done: true},
+    {name: 'clean', done: true},
+    {name: 'write more unit tests', done: false}
+  ]});
+  hamster.get('remainingChores'); // [{name: 'write more unit tests', done: false}]
+  ```
+
+  @method computed.filterBy
+  @for Ember
+  @param {String} dependentKey
+  @param {String} propertyKey
+  @param {String} value
+  @return {Ember.ComputedProperty} the filtered array
+*/
+Ember.computed.filterBy = function(dependentKey, propertyKey, value) {
+  var callback;
+
+  if (arguments.length === 2) {
+    callback = function(item) {
+      return get(item, propertyKey);
+    };
+  } else {
+    callback = function(item) {
+      return get(item, propertyKey) === value;
+    };
+  }
+
+  return Ember.computed.filter(dependentKey + '.@each.' + propertyKey, callback);
+};
+
+/**
+  @method computed.filterProperty
+  @for Ember
+  @param dependentKey
+  @param propertyKey
+  @param value
+  @deprecated Use `Ember.computed.filterBy` instead
+*/
+Ember.computed.filterProperty = Ember.computed.filterBy;
+
+/**
+  A computed property which returns a new array with all the unique
+  elements from one or more dependent arrays.
+
+  Example
+
+  ```javascript
+  App.Hamster = Ember.Object.extend({
+    uniqueFruits: Ember.computed.uniq('fruits')
+  });
+
+  var hamster = App.Hamster.create({fruits: [
+    'banana',
+    'grape',
+    'kale',
+    'banana'
+  ]});
+  hamster.get('uniqueFruits'); // ['banana', 'grape', 'kale']
+  ```
+
+  @method computed.uniq
+  @for Ember
+  @param {String} propertyKey*
+  @return {Ember.ComputedProperty} computes a new array with all the
+  unique elements from the dependent array
+*/
+Ember.computed.uniq = function() {
+  var args = a_slice.call(arguments);
+  args.push({
+    initialize: function(array, changeMeta, instanceMeta) {
+      instanceMeta.itemCounts = {};
+    },
+
+    addedItem: function(array, item, changeMeta, instanceMeta) {
+      var guid = guidFor(item);
+
+      if (!instanceMeta.itemCounts[guid]) {
+        instanceMeta.itemCounts[guid] = 1;
+      } else {
+        ++instanceMeta.itemCounts[guid];
+      }
+      array.addObject(item);
+      return array;
+    },
+    removedItem: function(array, item, _, instanceMeta) {
+      var guid = guidFor(item),
+          itemCounts = instanceMeta.itemCounts;
+
+      if (--itemCounts[guid] === 0) {
+        array.removeObject(item);
+      }
+      return array;
+    }
+  });
+  return Ember.arrayComputed.apply(null, args);
+};
+
+/**
+  Alias for [Ember.computed.uniq](/api/#method_computed_uniq).
+
+  @method computed.union
+  @for Ember
+  @param {String} propertyKey*
+  @return {Ember.ComputedProperty} computes a new array with all the
+  unique elements from the dependent array
+*/
+Ember.computed.union = Ember.computed.uniq;
+
+/**
+  A computed property which returns a new array with all the duplicated
+  elements from two or more dependeny arrays.
+
+  Example
+
+  ```javascript
+  var obj = Ember.Object.createWithMixins({
+    adaFriends: ['Charles Babbage', 'John Hobhouse', 'William King', 'Mary Somerville'],
+    charlesFriends: ['William King', 'Mary Somerville', 'Ada Lovelace', 'George Peacock'],
+    friendsInCommon: Ember.computed.intersect('adaFriends', 'charlesFriends')
+  });
+
+  obj.get('friendsInCommon'); // ['William King', 'Mary Somerville']
+  ```
+
+  @method computed.intersect
+  @for Ember
+  @param {String} propertyKey*
+  @return {Ember.ComputedProperty} computes a new array with all the
+  duplicated elements from the dependent arrays
+*/
+Ember.computed.intersect = function () {
+  var getDependentKeyGuids = function (changeMeta) {
+    return map(changeMeta.property._dependentKeys, function (dependentKey) {
+      return guidFor(dependentKey);
+    });
+  };
+
+  var args = a_slice.call(arguments);
+  args.push({
+    initialize: function (array, changeMeta, instanceMeta) {
+      instanceMeta.itemCounts = {};
+    },
+
+    addedItem: function(array, item, changeMeta, instanceMeta) {
+      var itemGuid = guidFor(item),
+          dependentGuids = getDependentKeyGuids(changeMeta),
+          dependentGuid = guidFor(changeMeta.arrayChanged),
+          numberOfDependentArrays = changeMeta.property._dependentKeys.length,
+          itemCounts = instanceMeta.itemCounts;
+
+      if (!itemCounts[itemGuid]) { itemCounts[itemGuid] = {}; }
+      if (itemCounts[itemGuid][dependentGuid] === undefined) { itemCounts[itemGuid][dependentGuid] = 0; }
+
+      if (++itemCounts[itemGuid][dependentGuid] === 1 &amp;&amp;
+          numberOfDependentArrays === Ember.keys(itemCounts[itemGuid]).length) {
+
+        array.addObject(item);
+      }
+      return array;
+    },
+    removedItem: function(array, item, changeMeta, instanceMeta) {
+      var itemGuid = guidFor(item),
+          dependentGuids = getDependentKeyGuids(changeMeta),
+          dependentGuid = guidFor(changeMeta.arrayChanged),
+          numberOfDependentArrays = changeMeta.property._dependentKeys.length,
+          numberOfArraysItemAppearsIn,
+          itemCounts = instanceMeta.itemCounts;
+
+      if (itemCounts[itemGuid][dependentGuid] === undefined) { itemCounts[itemGuid][dependentGuid] = 0; }
+      if (--itemCounts[itemGuid][dependentGuid] === 0) {
+        delete itemCounts[itemGuid][dependentGuid];
+        numberOfArraysItemAppearsIn = Ember.keys(itemCounts[itemGuid]).length;
+
+        if (numberOfArraysItemAppearsIn === 0) {
+          delete itemCounts[itemGuid];
+        }
+        array.removeObject(item);
+      }
+      return array;
+    }
+  });
+  return Ember.arrayComputed.apply(null, args);
+};
+
+/**
+  A computed property which returns a new array with all the
+  properties from the first dependent array that are not in the second
+  dependent array.
+
+  Example
+
+  ```javascript
+  App.Hamster = Ember.Object.extend({
+    likes: ['banana', 'grape', 'kale'],
+    wants: Ember.computed.setDiff('likes', 'fruits')
+  });
+
+  var hamster = App.Hamster.create({fruits: [
+    'grape',
+    'kale',
+  ]});
+  hamster.get('wants'); // ['banana']
+  ```
+
+  @method computed.setDiff
+  @for Ember
+  @param {String} setAProperty
+  @param {String} setBProperty
+  @return {Ember.ComputedProperty} computes a new array with all the
+  items from the first dependent array that are not in the second
+  dependent array
+*/
+Ember.computed.setDiff = function (setAProperty, setBProperty) {
+  if (arguments.length !== 2) {
+    throw new Ember.Error(&quot;setDiff requires exactly two dependent arrays.&quot;);
+  }
+  return Ember.arrayComputed.call(null, setAProperty, setBProperty, {
+    addedItem: function (array, item, changeMeta, instanceMeta) {
+      var setA = get(this, setAProperty),
+          setB = get(this, setBProperty);
+
+      if (changeMeta.arrayChanged === setA) {
+        if (!setB.contains(item)) {
+          array.addObject(item);
+        }
+      } else {
+        array.removeObject(item);
+      }
+      return array;
+    },
+
+    removedItem: function (array, item, changeMeta, instanceMeta) {
+      var setA = get(this, setAProperty),
+          setB = get(this, setBProperty);
+
+      if (changeMeta.arrayChanged === setB) {
+        if (setA.contains(item)) {
+          array.addObject(item);
+        }
+      } else {
+        array.removeObject(item);
+      }
+      return array;
+    }
+  });
+};
+
+function binarySearch(array, item, low, high) {
+  var mid, midItem, res, guidMid, guidItem;
+
+  if (arguments.length &lt; 4) { high = get(array, 'length'); }
+  if (arguments.length &lt; 3) { low = 0; }
+
+  if (low === high) {
+    return low;
+  }
+
+  mid = low + Math.floor((high - low) / 2);
+  midItem = array.objectAt(mid);
+
+  guidMid = _guidFor(midItem);
+  guidItem = _guidFor(item);
+
+  if (guidMid === guidItem) {
+    return mid;
+  }
+
+  res = this.order(midItem, item);
+  if (res === 0) {
+    res = guidMid &lt; guidItem ? -1 : 1;
+  }
+
+
+  if (res &lt; 0) {
+    return this.binarySearch(array, item, mid+1, high);
+  } else if (res &gt; 0) {
+    return this.binarySearch(array, item, low, mid);
+  }
+
+  return mid;
+
+  function _guidFor(item) {
+    if (SearchProxy.detectInstance(item)) {
+      return guidFor(get(item, 'content'));
+    }
+    return guidFor(item);
+  }
+}
+
+
+SearchProxy = Ember.ObjectProxy.extend();
+
+/**
+  A computed property which returns a new array with all the
+  properties from the first dependent array sorted based on a property
+  or sort function.
+
+  The callback method you provide should have the following signature:
+
+  ```javascript
+  function(itemA, itemB);
+  ```
+
+  - `itemA` the first item to compare.
+  - `itemB` the second item to compare.
+
+  This function should return `-1` when `itemA` should come before
+  `itemB`. It should return `1` when `itemA` should come after
+  `itemB`. If the `itemA` and `itemB` are equal this function should return `0`.
+
+  Example
+
+  ```javascript
+  var ToDoList = Ember.Object.extend({
+    todosSorting: ['name'],
+    sortedTodos: Ember.computed.sort('todos', 'todosSorting'),
+    priorityTodos: Ember.computed.sort('todos', function(a, b){
+      if (a.priority &gt; b.priority) {
+        return 1;
+      } else if (a.priority &lt; b.priority) {
+        return -1;
+      }
+      return 0;
+    }),
+  });
+  var todoList = ToDoList.create({todos: [
+    {name: 'Unit Test', priority: 2},
+    {name: 'Documentation', priority: 3},
+    {name: 'Release', priority: 1}
+  ]});
+
+  todoList.get('sortedTodos'); // [{name:'Documentation', priority:3}, {name:'Release', priority:1}, {name:'Unit Test', priority:2}]
+  todoList.get('priorityTodos'); // [{name:'Release', priority:1}, {name:'Unit Test', priority:2}, {name:'Documentation', priority:3}]
+  ```
+
+  @method computed.sort
+  @for Ember
+  @param {String} dependentKey
+  @param {String or Function} sortDefinition a dependent key to an
+  array of sort properties or a function to use when sorting
+  @return {Ember.ComputedProperty} computes a new sorted array based
+  on the sort property array or callback function
+*/
+Ember.computed.sort = function (itemsKey, sortDefinition) {
+  Ember.assert(&quot;Ember.computed.sort requires two arguments: an array key to sort and either a sort properties key or sort function&quot;, arguments.length === 2);
+
+  var initFn, sortPropertiesKey;
+
+  if (typeof sortDefinition === 'function') {
+    initFn = function (array, changeMeta, instanceMeta) {
+      instanceMeta.order = sortDefinition;
+      instanceMeta.binarySearch = binarySearch;
+    };
+  } else {
+    sortPropertiesKey = sortDefinition;
+    initFn = function (array, changeMeta, instanceMeta) {
+      function setupSortProperties() {
+        var sortPropertyDefinitions = get(this, sortPropertiesKey),
+            sortProperty,
+            sortProperties = instanceMeta.sortProperties = [],
+            sortPropertyAscending = instanceMeta.sortPropertyAscending = {},
+            idx,
+            asc;
+
+        Ember.assert(&quot;Cannot sort: '&quot; + sortPropertiesKey + &quot;' is not an array.&quot;, Ember.isArray(sortPropertyDefinitions));
+
+        changeMeta.property.clearItemPropertyKeys(itemsKey);
+
+        forEach(sortPropertyDefinitions, function (sortPropertyDefinition) {
+          if ((idx = sortPropertyDefinition.indexOf(':')) !== -1) {
+            sortProperty = sortPropertyDefinition.substring(0, idx);
+            asc = sortPropertyDefinition.substring(idx+1).toLowerCase() !== 'desc';
+          } else {
+            sortProperty = sortPropertyDefinition;
+            asc = true;
+          }
+
+          sortProperties.push(sortProperty);
+          sortPropertyAscending[sortProperty] = asc;
+          changeMeta.property.itemPropertyKey(itemsKey, sortProperty);
+        });
+
+        sortPropertyDefinitions.addObserver('@each', this, updateSortPropertiesOnce);
+      }
+
+      function updateSortPropertiesOnce() {
+        Ember.run.once(this, updateSortProperties, changeMeta.propertyName);
+      }
+
+      function updateSortProperties(propertyName) {
+        setupSortProperties.call(this);
+        changeMeta.property.recomputeOnce.call(this, propertyName);
+      }
+
+      Ember.addObserver(this, sortPropertiesKey, updateSortPropertiesOnce);
+
+      setupSortProperties.call(this);
+
+
+      instanceMeta.order = function (itemA, itemB) {
+        var sortProperty, result, asc;
+        for (var i = 0; i &lt; this.sortProperties.length; ++i) {
+          sortProperty = this.sortProperties[i];
+          result = Ember.compare(get(itemA, sortProperty), get(itemB, sortProperty));
+
+          if (result !== 0) {
+            asc = this.sortPropertyAscending[sortProperty];
+            return asc ? result : (-1 * result);
+          }
+        }
+
+        return 0;
+      };
+
+      instanceMeta.binarySearch = binarySearch;
+    };
+  }
+
+  return Ember.arrayComputed.call(null, itemsKey, {
+    initialize: initFn,
+
+    addedItem: function (array, item, changeMeta, instanceMeta) {
+      var index = instanceMeta.binarySearch(array, item);
+      array.insertAt(index, item);
+      return array;
+    },
+
+    removedItem: function (array, item, changeMeta, instanceMeta) {
+      var proxyProperties, index, searchItem;
+
+      if (changeMeta.previousValues) {
+        proxyProperties = merge({ content: item }, changeMeta.previousValues);
+
+        searchItem = SearchProxy.create(proxyProperties);
+      } else {
+        searchItem = item;
+      }
+
+      index = instanceMeta.binarySearch(array, searchItem);
+      array.removeAt(index);
+      return array;
+    }
+  });
+};
+
+})();
+
+
+
+(function() {
+Ember.RSVP = requireModule('rsvp');
+
+Ember.RSVP.onerrorDefault = function(error) {
+  if (error instanceof Error) {
+    if (Ember.testing) {
+      if (Ember.Test &amp;&amp; Ember.Test.adapter) {
+        Ember.Test.adapter.exception(error);
+      } else {
+        throw error;
+      }
+    } else {
+      Ember.Logger.error(error.stack);
+      Ember.assert(error, false);
+    }
+  }
+};
+
+Ember.RSVP.on('error', Ember.RSVP.onerrorDefault);
+
+})();
+
+
+
+(function() {
+/**
+@module ember
+@submodule ember-runtime
+*/
+
+var a_slice = Array.prototype.slice;
+
+
+if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Function) {
+
+  /**
+    The `property` extension of Javascript's Function prototype is available
+    when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is
+    `true`, which is the default.
+
+    Computed properties allow you to treat a function like a property:
+
+    ```javascript
+    MyApp.President = Ember.Object.extend({
+      firstName: '',
+      lastName:  '',
+
+      fullName: function() {
+        return this.get('firstName') + ' ' + this.get('lastName');
+
+        // Call this flag to mark the function as a property
+      }.property()
+    });
+
+    var president = MyApp.President.create({
+      firstName: &quot;Barack&quot;,
+      lastName: &quot;Obama&quot;
+    });
+
+    president.get('fullName');    // &quot;Barack Obama&quot;
+    ```
+
+    Treating a function like a property is useful because they can work with
+    bindings, just like any other property.
+
+    Many computed properties have dependencies on other properties. For
+    example, in the above example, the `fullName` property depends on
+    `firstName` and `lastName` to determine its value. You can tell Ember
+    about these dependencies like this:
+
+    ```javascript
+    MyApp.President = Ember.Object.extend({
+      firstName: '',
+      lastName:  '',
+
+      fullName: function() {
+        return this.get('firstName') + ' ' + this.get('lastName');
+
+        // Tell Ember.js that this computed property depends on firstName
+        // and lastName
+      }.property('firstName', 'lastName')
+    });
+    ```
+
+    Make sure you list these dependencies so Ember knows when to update
+    bindings that connect to a computed property. Changing a dependency
+    will not immediately trigger an update of the computed property, but
+    will instead clear the cache so that it is updated when the next `get`
+    is called on the property.
+
+    See [Ember.ComputedProperty](/api/classes/Ember.ComputedProperty.html), [Ember.computed](/api/#method_computed).
+
+    @method property
+    @for Function
+  */
+  Function.prototype.property = function() {
+    var ret = Ember.computed(this);
+    // ComputedProperty.prototype.property expands properties; no need for us to
+    // do so here.
+    return ret.property.apply(ret, arguments);
+  };
+
+  /**
+    The `observes` extension of Javascript's Function prototype is available
+    when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is
+    true, which is the default.
+
+    You can observe property changes simply by adding the `observes`
+    call to the end of your method declarations in classes that you write.
+    For example:
+
+    ```javascript
+    Ember.Object.extend({
+      valueObserver: function() {
+        // Executes whenever the &quot;value&quot; property changes
+      }.observes('value')
+    });
+    ```
+
+    In the future this method may become asynchronous. If you want to ensure
+    synchronous behavior, use `observesImmediately`.
+
+    See `Ember.observer`.
+
+    @method observes
+    @for Function
+  */
+  Function.prototype.observes = function() {
+    
+      this.__ember_observes__ = a_slice.call(arguments);
+    
+
+    return this;
+  };
+
+  /**
+    The `observesImmediately` extension of Javascript's Function prototype is
+    available when `Ember.EXTEND_PROTOTYPES` or
+    `Ember.EXTEND_PROTOTYPES.Function` is true, which is the default.
+
+    You can observe property changes simply by adding the `observesImmediately`
+    call to the end of your method declarations in classes that you write.
+    For example:
+
+    ```javascript
+    Ember.Object.extend({
+      valueObserver: function() {
+        // Executes immediately after the &quot;value&quot; property changes
+      }.observesImmediately('value')
+    });
+    ```
+
+    In the future, `observes` may become asynchronous. In this event,
+    `observesImmediately` will maintain the synchronous behavior.
+
+    See `Ember.immediateObserver`.
+
+    @method observesImmediately
+    @for Function
+  */
+  Function.prototype.observesImmediately = function() {
+    for (var i=0, l=arguments.length; i&lt;l; i++) {
+      var arg = arguments[i];
+      Ember.assert(&quot;Immediate observers must observe internal properties only, not properties on other objects.&quot;, arg.indexOf('.') === -1);
+    }
+
+    // observes handles property expansion
+    return this.observes.apply(this, arguments);
+  };
+
+  /**
+    The `observesBefore` extension of Javascript's Function prototype is
+    available when `Ember.EXTEND_PROTOTYPES` or
+    `Ember.EXTEND_PROTOTYPES.Function` is true, which is the default.
+
+    You can get notified when a property change is about to happen by
+    by adding the `observesBefore` call to the end of your method
+    declarations in classes that you write. For example:
+
+    ```javascript
+    Ember.Object.extend({
+      valueObserver: function() {
+        // Executes whenever the &quot;value&quot; property is about to change
+      }.observesBefore('value')
+    });
+    ```
+
+    See `Ember.beforeObserver`.
+
+    @method observesBefore
+    @for Function
+  */
+  Function.prototype.observesBefore = function() {
+    
+      this.__ember_observesBefore__ = a_slice.call(arguments);
+    
+
+    return this;
+  };
+
+  /**
+    The `on` extension of Javascript's Function prototype is available
+    when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is
+    true, which is the default.
+
+    You can listen for events simply by adding the `on` call to the end of
+    your method declarations in classes or mixins that you write. For example:
+
+    ```javascript
+    Ember.Mixin.create({
+      doSomethingWithElement: function() {
+        // Executes whenever the &quot;didInsertElement&quot; event fires
+      }.on('didInsertElement')
+    });
+    ```
+
+    See `Ember.on`.
+
+    @method on
+    @for Function
+  */
+  Function.prototype.on = function() {
+    var events = a_slice.call(arguments);
+    this.__ember_listens__ = events;
+    return this;
+  };
+}
+
+
+})();
+
+
+
+(function() {
+
+})();
+
+
+
+(function() {
+/**
+@module ember
+@submodule ember-runtime
+*/
+
+
+/**
</ins><span class="cx">   Implements some standard methods for comparing objects. Add this mixin to
</span><span class="cx">   any class you create that can compare its instances.
</span><span class="cx"> 
</span><span class="lines">@@ -8534,21 +16754,11 @@
</span><span class="cx"> 
</span><span class="cx">   @class Comparable
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Mixin
</del><span class="cx">   @since Ember 0.9
</span><span class="cx"> */
</span><del>-Ember.Comparable = Ember.Mixin.create( /** @scope Ember.Comparable.prototype */{
</del><ins>+Ember.Comparable = Ember.Mixin.create({
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    walk like a duck. Indicates that the object can be compared.
-
-    @property isComparable
-    @type Boolean
-    @default true
-  */
-  isComparable: true,
-
-  /**
</del><span class="cx">     Override to return the result of the comparison of the two parameters. The
</span><span class="cx">     compare method should return:
</span><span class="cx"> 
</span><span class="lines">@@ -8595,18 +16805,16 @@
</span><span class="cx"> 
</span><span class="cx">   @class Copyable
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Mixin
</del><span class="cx">   @since Ember 0.9
</span><span class="cx"> */
</span><del>-Ember.Copyable = Ember.Mixin.create(
-/** @scope Ember.Copyable.prototype */ {
</del><ins>+Ember.Copyable = Ember.Mixin.create({
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     Override to return a copy of the receiver. Default implementation raises
</span><span class="cx">     an exception.
</span><span class="cx"> 
</span><span class="cx">     @method copy
</span><del>-    @param deep {Boolean} if `true`, a deep copy of the object should be made
</del><ins>+    @param {Boolean} deep if `true`, a deep copy of the object should be made
</ins><span class="cx">     @return {Object} copy of receiver
</span><span class="cx">   */
</span><span class="cx">   copy: Ember.required(Function),
</span><span class="lines">@@ -8629,7 +16837,7 @@
</span><span class="cx">     if (Ember.Freezable &amp;&amp; Ember.Freezable.detect(this)) {
</span><span class="cx">       return get(this, 'isFrozen') ? this : this.copy().freeze();
</span><span class="cx">     } else {
</span><del>-      throw new Error(Ember.String.fmt(&quot;%@ does not support freezing&quot;, [this]));
</del><ins>+      throw new Ember.Error(Ember.String.fmt(&quot;%@ does not support freezing&quot;, [this]));
</ins><span class="cx">     }
</span><span class="cx">   }
</span><span class="cx"> });
</span><span class="lines">@@ -8687,7 +16895,7 @@
</span><span class="cx"> 
</span><span class="cx">   });
</span><span class="cx"> 
</span><del>-  c = Context.create({ firstName: &quot;John&quot;, lastName: &quot;Doe&quot; });
</del><ins>+  c = Contact.create({ firstName: &quot;John&quot;, lastName: &quot;Doe&quot; });
</ins><span class="cx">   c.swapNames();  // returns c
</span><span class="cx">   c.freeze();
</span><span class="cx">   c.swapNames();  // EXCEPTION
</span><span class="lines">@@ -8701,11 +16909,9 @@
</span><span class="cx"> 
</span><span class="cx">   @class Freezable
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Mixin
</del><span class="cx">   @since Ember 0.9
</span><span class="cx"> */
</span><del>-Ember.Freezable = Ember.Mixin.create(
-/** @scope Ember.Freezable.prototype */ {
</del><ins>+Ember.Freezable = Ember.Mixin.create({
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     Set to `true` when the object is frozen. Use this property to detect
</span><span class="lines">@@ -8758,7 +16964,7 @@
</span><span class="cx"> 
</span><span class="cx">   To add an object to an enumerable, use the `addObject()` method. This
</span><span class="cx">   method will only add the object to the enumerable if the object is not
</span><del>-  already present and the object if of a type supported by the enumerable.
</del><ins>+  already present and is of a type supported by the enumerable.
</ins><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="cx">   set.addObject(contact);
</span><span class="lines">@@ -8766,8 +16972,8 @@
</span><span class="cx"> 
</span><span class="cx">   ## Removing Objects
</span><span class="cx"> 
</span><del>-  To remove an object form an enumerable, use the `removeObject()` method. This
-  will only remove the object if it is already in the enumerable, otherwise
</del><ins>+  To remove an object from an enumerable, use the `removeObject()` method. This
+  will only remove the object if it is present in the enumerable, otherwise
</ins><span class="cx">   this method has no effect.
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="lines">@@ -8782,11 +16988,9 @@
</span><span class="cx"> 
</span><span class="cx">   @class MutableEnumerable
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Mixin
</del><span class="cx">   @uses Ember.Enumerable
</span><span class="cx"> */
</span><del>-Ember.MutableEnumerable = Ember.Mixin.create(Ember.Enumerable,
-  /** @scope Ember.MutableEnumerable.prototype */ {
</del><ins>+Ember.MutableEnumerable = Ember.Mixin.create(Ember.Enumerable, {
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     __Required.__ You must implement this method to apply this mixin.
</span><span class="lines">@@ -8795,7 +16999,7 @@
</span><span class="cx">     already present in the collection. If the object is present, this method
</span><span class="cx">     has no effect.
</span><span class="cx"> 
</span><del>-    If the passed object is of a type not supported by the receiver
</del><ins>+    If the passed object is of a type not supported by the receiver,
</ins><span class="cx">     then this method should raise an exception.
</span><span class="cx"> 
</span><span class="cx">     @method addObject
</span><span class="lines">@@ -8822,10 +17026,10 @@
</span><span class="cx">     __Required.__ You must implement this method to apply this mixin.
</span><span class="cx"> 
</span><span class="cx">     Attempts to remove the passed object from the receiver collection if the
</span><del>-    object is in present in the collection. If the object is not present,
</del><ins>+    object is present in the collection. If the object is not present,
</ins><span class="cx">     this method has no effect.
</span><span class="cx"> 
</span><del>-    If the passed object is of a type not supported by the receiver
</del><ins>+    If the passed object is of a type not supported by the receiver,
</ins><span class="cx">     then this method should raise an exception.
</span><span class="cx"> 
</span><span class="cx">     @method removeObject
</span><span class="lines">@@ -8836,7 +17040,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Removes each objects in the passed enumerable from the receiver.
</del><ins>+    Removes each object in the passed enumerable from the receiver.
</ins><span class="cx"> 
</span><span class="cx">     @method removeObjects
</span><span class="cx">     @param {Ember.Enumerable} objects the objects to remove
</span><span class="lines">@@ -8871,7 +17075,7 @@
</span><span class="cx"> // HELPERS
</span><span class="cx"> //
</span><span class="cx"> 
</span><del>-var get = Ember.get, set = Ember.set, forEach = Ember.EnumerableUtils.forEach;
</del><ins>+var get = Ember.get, set = Ember.set;
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><span class="cx">   This mixin defines the API for modifying array-like objects. These methods
</span><span class="lines">@@ -8883,12 +17087,10 @@
</span><span class="cx"> 
</span><span class="cx">   @class MutableArray
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Mixin
</del><span class="cx">   @uses Ember.Array
</span><span class="cx">   @uses Ember.MutableEnumerable
</span><span class="cx"> */
</span><del>-Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,
-  /** @scope Ember.MutableArray.prototype */ {
</del><ins>+Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable, {
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     __Required.__ You must implement this method to apply this mixin.
</span><span class="lines">@@ -8898,11 +17100,11 @@
</span><span class="cx">     passed array. You should also call `this.enumerableContentDidChange()`
</span><span class="cx"> 
</span><span class="cx">     @method replace
</span><del>-    @param {Number} idx Starting index in the array to replace. If 
</del><ins>+    @param {Number} idx Starting index in the array to replace. If
</ins><span class="cx">       idx &gt;= length, then append to the end of the array.
</span><del>-    @param {Number} amt Number of elements that should be removed from 
</del><ins>+    @param {Number} amt Number of elements that should be removed from
</ins><span class="cx">       the array, starting at *idx*.
</span><del>-    @param {Array} objects An array of zero or more objects that should be 
</del><ins>+    @param {Array} objects An array of zero or more objects that should be
</ins><span class="cx">       inserted into the array at *idx*
</span><span class="cx">   */
</span><span class="cx">   replace: Ember.required(),
</span><span class="lines">@@ -8941,9 +17143,10 @@
</span><span class="cx">     @method insertAt
</span><span class="cx">     @param {Number} idx index of insert the object at.
</span><span class="cx">     @param {Object} object object to insert
</span><ins>+    @return this
</ins><span class="cx">   */
</span><span class="cx">   insertAt: function(idx, object) {
</span><del>-    if (idx &gt; get(this, 'length')) throw new Error(OUT_OF_RANGE_EXCEPTION) ;
</del><ins>+    if (idx &gt; get(this, 'length')) throw new Ember.Error(OUT_OF_RANGE_EXCEPTION) ;
</ins><span class="cx">     this.replace(idx, 0, [object]) ;
</span><span class="cx">     return this ;
</span><span class="cx">   },
</span><span class="lines">@@ -8953,7 +17156,7 @@
</span><span class="cx">     method. You can pass either a single index, or a start and a length.
</span><span class="cx"> 
</span><span class="cx">     If you pass a start and length that is beyond the
</span><del>-    length this method will throw an `Ember.OUT_OF_RANGE_EXCEPTION`
</del><ins>+    length this method will throw an `OUT_OF_RANGE_EXCEPTION`.
</ins><span class="cx"> 
</span><span class="cx">     ```javascript
</span><span class="cx">     var colors = [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;, &quot;yellow&quot;, &quot;orange&quot;];
</span><span class="lines">@@ -8971,7 +17174,7 @@
</span><span class="cx">     if ('number' === typeof start) {
</span><span class="cx"> 
</span><span class="cx">       if ((start &lt; 0) || (start &gt;= get(this, 'length'))) {
</span><del>-        throw new Error(OUT_OF_RANGE_EXCEPTION);
</del><ins>+        throw new Ember.Error(OUT_OF_RANGE_EXCEPTION);
</ins><span class="cx">       }
</span><span class="cx"> 
</span><span class="cx">       // fast case
</span><span class="lines">@@ -8987,17 +17190,18 @@
</span><span class="cx">     is KVO-compliant.
</span><span class="cx"> 
</span><span class="cx">     ```javascript
</span><del>-    var colors = [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;];
-    colors.pushObject(&quot;black&quot;);               // [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;, &quot;black&quot;]
-    colors.pushObject([&quot;yellow&quot;, &quot;orange&quot;]);  // [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;, &quot;black&quot;, [&quot;yellow&quot;, &quot;orange&quot;]]
</del><ins>+    var colors = [&quot;red&quot;, &quot;green&quot;];
+    colors.pushObject(&quot;black&quot;);     // [&quot;red&quot;, &quot;green&quot;, &quot;black&quot;]
+    colors.pushObject([&quot;yellow&quot;]);  // [&quot;red&quot;, &quot;green&quot;, [&quot;yellow&quot;]]
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><span class="cx">     @method pushObject
</span><del>-    @param {anything} obj object to push
</del><ins>+    @param {*} obj object to push
+    @return The same obj passed as param
</ins><span class="cx">   */
</span><span class="cx">   pushObject: function(obj) {
</span><span class="cx">     this.insertAt(get(this, 'length'), obj) ;
</span><del>-    return obj ;
</del><ins>+    return obj;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -9005,9 +17209,8 @@
</span><span class="cx">     notifying observers of the change until all objects are added.
</span><span class="cx"> 
</span><span class="cx">     ```javascript
</span><del>-    var colors = [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;];
-    colors.pushObjects(&quot;black&quot;);               // [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;, &quot;black&quot;]
-    colors.pushObjects([&quot;yellow&quot;, &quot;orange&quot;]);  // [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;, &quot;black&quot;, &quot;yellow&quot;, &quot;orange&quot;]
</del><ins>+    var colors = [&quot;red&quot;];
+    colors.pushObjects([&quot;yellow&quot;, &quot;orange&quot;]);  // [&quot;red&quot;, &quot;yellow&quot;, &quot;orange&quot;]
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><span class="cx">     @method pushObjects
</span><span class="lines">@@ -9015,6 +17218,9 @@
</span><span class="cx">     @return {Ember.Array} receiver
</span><span class="cx">   */
</span><span class="cx">   pushObjects: function(objects) {
</span><ins>+    if (!(Ember.Enumerable.detect(objects) || Ember.isArray(objects))) {
+      throw new TypeError(&quot;Must pass Ember.Enumerable to Ember.MutableArray#pushObjects&quot;);
+    }
</ins><span class="cx">     this.replace(get(this, 'length'), 0, objects);
</span><span class="cx">     return this;
</span><span class="cx">   },
</span><span class="lines">@@ -9066,13 +17272,14 @@
</span><span class="cx">     KVO-compliant.
</span><span class="cx"> 
</span><span class="cx">     ```javascript
</span><del>-    var colors = [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;];
-    colors.unshiftObject(&quot;yellow&quot;);             // [&quot;yellow&quot;, &quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]
-    colors.unshiftObject([&quot;black&quot;, &quot;white&quot;]);   // [[&quot;black&quot;, &quot;white&quot;], &quot;yellow&quot;, &quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]
</del><ins>+    var colors = [&quot;red&quot;];
+    colors.unshiftObject(&quot;yellow&quot;);    // [&quot;yellow&quot;, &quot;red&quot;]
+    colors.unshiftObject([&quot;black&quot;]);   // [[&quot;black&quot;], &quot;yellow&quot;, &quot;red&quot;]
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><span class="cx">     @method unshiftObject
</span><del>-    @param {anything} obj object to unshift
</del><ins>+    @param {*} obj object to unshift
+    @return The same obj passed as param
</ins><span class="cx">   */
</span><span class="cx">   unshiftObject: function(obj) {
</span><span class="cx">     this.insertAt(0, obj) ;
</span><span class="lines">@@ -9084,9 +17291,9 @@
</span><span class="cx">     observers until all objects have been added.
</span><span class="cx"> 
</span><span class="cx">     ```javascript
</span><del>-    var colors = [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;];
-    colors.unshiftObjects([&quot;black&quot;, &quot;white&quot;]);   // [&quot;black&quot;, &quot;white&quot;, &quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]
-    colors.unshiftObjects(&quot;yellow&quot;);             // Type Error: 'undefined' is not a function
</del><ins>+    var colors = [&quot;red&quot;];
+    colors.unshiftObjects([&quot;black&quot;, &quot;white&quot;]);   // [&quot;black&quot;, &quot;white&quot;, &quot;red&quot;]
+    colors.unshiftObjects(&quot;yellow&quot;); // Type Error: 'undefined' is not a function
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><span class="cx">     @method unshiftObjects
</span><span class="lines">@@ -9156,7 +17363,6 @@
</span><span class="cx"> 
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -9167,563 +17373,130 @@
</span><span class="cx"> @submodule ember-runtime
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var get = Ember.get, set = Ember.set, defineProperty = Ember.defineProperty;
</del><ins>+var get = Ember.get, set = Ember.set;
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  ## Overview
</del><ins>+`Ember.TargetActionSupport` is a mixin that can be included in a class
+to add a `triggerAction` method with semantics similar to the Handlebars
+`{{action}}` helper. In normal Ember usage, the `{{action}}` helper is
+usually the best choice. This mixin is most often useful when you are
+doing more complex event handling in View objects.
</ins><span class="cx"> 
</span><del>-  This mixin provides properties and property observing functionality, core
-  features of the Ember object model.
</del><ins>+See also `Ember.ViewTargetActionSupport`, which has
+view-aware defaults for target and actionContext.
</ins><span class="cx"> 
</span><del>-  Properties and observers allow one object to observe changes to a
-  property on another object. This is one of the fundamental ways that
-  models, controllers and views communicate with each other in an Ember
-  application.
</del><ins>+@class TargetActionSupport
+@namespace Ember
+@extends Ember.Mixin
+*/
+Ember.TargetActionSupport = Ember.Mixin.create({
+  target: null,
+  action: null,
+  actionContext: null,
</ins><span class="cx"> 
</span><del>-  Any object that has this mixin applied can be used in observer
-  operations. That includes `Ember.Object` and most objects you will
-  interact with as you write your Ember application.
</del><ins>+  targetObject: Ember.computed(function() {
+    var target = get(this, 'target');
</ins><span class="cx"> 
</span><del>-  Note that you will not generally apply this mixin to classes yourself,
-  but you will use the features provided by this module frequently, so it
-  is important to understand how to use it.
</del><ins>+    if (Ember.typeOf(target) === &quot;string&quot;) {
+      var value = get(this, target);
+      if (value === undefined) { value = get(Ember.lookup, target); }
+      return value;
+    } else {
+      return target;
+    }
+  }).property('target'),
</ins><span class="cx"> 
</span><del>-  ## Using `get()` and `set()`
</del><ins>+  actionContextObject: Ember.computed(function() {
+    var actionContext = get(this, 'actionContext');
</ins><span class="cx"> 
</span><del>-  Because of Ember's support for bindings and observers, you will always
-  access properties using the get method, and set properties using the
-  set method. This allows the observing objects to be notified and
-  computed properties to be handled properly.
</del><ins>+    if (Ember.typeOf(actionContext) === &quot;string&quot;) {
+      var value = get(this, actionContext);
+      if (value === undefined) { value = get(Ember.lookup, actionContext); }
+      return value;
+    } else {
+      return actionContext;
+    }
+  }).property('actionContext'),
</ins><span class="cx"> 
</span><del>-  More documentation about `get` and `set` are below.
</del><ins>+  /**
+  Send an &quot;action&quot; with an &quot;actionContext&quot; to a &quot;target&quot;. The action, actionContext
+  and target will be retrieved from properties of the object. For example:
</ins><span class="cx"> 
</span><del>-  ## Observing Property Changes
</del><ins>+  ```javascript
+  App.SaveButtonView = Ember.View.extend(Ember.TargetActionSupport, {
+    target: Ember.computed.alias('controller'),
+    action: 'save',
+    actionContext: Ember.computed.alias('context'),
+    click: function() {
+      this.triggerAction(); // Sends the `save` action, along with the current context
+                            // to the current controller
+    }
+  });
+  ```
</ins><span class="cx"> 
</span><del>-  You typically observe property changes simply by adding the `observes`
-  call to the end of your method declarations in classes that you write.
-  For example:
</del><ins>+  The `target`, `action`, and `actionContext` can be provided as properties of
+  an optional object argument to `triggerAction` as well.
</ins><span class="cx"> 
</span><span class="cx">   ```javascript
</span><del>-  Ember.Object.create({
-    valueObserver: function() {
-      // Executes whenever the &quot;value&quot; property changes
-    }.observes('value')
</del><ins>+  App.SaveButtonView = Ember.View.extend(Ember.TargetActionSupport, {
+    click: function() {
+      this.triggerAction({
+        action: 'save',
+        target: this.get('controller'),
+        actionContext: this.get('context'),
+      }); // Sends the `save` action, along with the current context
+          // to the current controller
+    }
</ins><span class="cx">   });
</span><span class="cx">   ```
</span><span class="cx"> 
</span><del>-  Although this is the most common way to add an observer, this capability
-  is actually built into the `Ember.Object` class on top of two methods
-  defined in this mixin: `addObserver` and `removeObserver`. You can use
-  these two methods to add and remove observers yourself if you need to
-  do so at runtime.
</del><ins>+  The `actionContext` defaults to the object you mixing `TargetActionSupport` into.
+  But `target` and `action` must be specified either as properties or with the argument
+  to `triggerAction`, or a combination:
</ins><span class="cx"> 
</span><del>-  To add an observer for a property, call:
-
</del><span class="cx">   ```javascript
</span><del>-  object.addObserver('propertyKey', targetObject, targetAction)
</del><ins>+  App.SaveButtonView = Ember.View.extend(Ember.TargetActionSupport, {
+    target: Ember.computed.alias('controller'),
+    click: function() {
+      this.triggerAction({
+        action: 'save'
+      }); // Sends the `save` action, along with a reference to `this`,
+          // to the current controller
+    }
+  });
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><del>-  This will call the `targetAction` method on the `targetObject` to be called
-  whenever the value of the `propertyKey` changes.
-
-  Note that if `propertyKey` is a computed property, the observer will be
-  called when any of the property dependencies are changed, even if the
-  resulting value of the computed property is unchanged. This is necessary
-  because computed properties are not computed until `get` is called.
-
-  @class Observable
-  @namespace Ember
-  @extends Ember.Mixin
-*/
-Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ {
-
-  /**
-    Retrieves the value of a property from the object.
-
-    This method is usually similar to using `object[keyName]` or `object.keyName`,
-    however it supports both computed properties and the unknownProperty
-    handler.
-
-    Because `get` unifies the syntax for accessing all these kinds
-    of properties, it can make many refactorings easier, such as replacing a
-    simple property with a computed property, or vice versa.
-
-    ### Computed Properties
-
-    Computed properties are methods defined with the `property` modifier
-    declared at the end, such as:
-
-    ```javascript
-    fullName: function() {
-      return this.getEach('firstName', 'lastName').compact().join(' ');
-    }.property('firstName', 'lastName')
-    ```
-
-    When you call `get` on a computed property, the function will be
-    called and the return value will be returned instead of the function
-    itself.
-
-    ### Unknown Properties
-
-    Likewise, if you try to call `get` on a property whose value is
-    `undefined`, the `unknownProperty()` method will be called on the object.
-    If this method returns any value other than `undefined`, it will be returned
-    instead. This allows you to implement &quot;virtual&quot; properties that are
-    not defined upfront.
-
-    @method get
-    @param {String} key The property to retrieve
-    @return {Object} The property value or undefined.
</del><ins>+  @method triggerAction
+  @param opts {Hash} (optional, with the optional keys action, target and/or actionContext)
+  @return {Boolean} true if the action was sent successfully and did not return false
</ins><span class="cx">   */
</span><del>-  get: function(keyName) {
-    return get(this, keyName);
-  },
</del><ins>+  triggerAction: function(opts) {
+    opts = opts || {};
+    var action = opts.action || get(this, 'action'),
+        target = opts.target || get(this, 'targetObject'),
+        actionContext = opts.actionContext;
</ins><span class="cx"> 
</span><del>-  /**
-    To get multiple properties at once, call `getProperties`
-    with a list of strings or an array:
</del><ins>+    function args(options, actionName) {
+      var ret = [];
+      if (actionName) { ret.push(actionName); }
</ins><span class="cx"> 
</span><del>-    ```javascript
-    record.getProperties('firstName', 'lastName', 'zipCode');  // { firstName: 'John', lastName: 'Doe', zipCode: '10011' }
-    ```
-
-    is equivalent to:
-
-    ```javascript
-    record.getProperties(['firstName', 'lastName', 'zipCode']);  // { firstName: 'John', lastName: 'Doe', zipCode: '10011' }
-    ```
-
-    @method getProperties
-    @param {String...|Array} list of keys to get
-    @return {Hash}
-  */
-  getProperties: function() {
-    var ret = {};
-    var propertyNames = arguments;
-    if (arguments.length === 1 &amp;&amp; Ember.typeOf(arguments[0]) === 'array') {
-      propertyNames = arguments[0];
</del><ins>+      return ret.concat(options);
</ins><span class="cx">     }
</span><del>-    for(var i = 0; i &lt; propertyNames.length; i++) {
-      ret[propertyNames[i]] = get(this, propertyNames[i]);
-    }
-    return ret;
-  },
</del><span class="cx"> 
</span><del>-  /**
-    Sets the provided key or path to the value.
-
-    This method is generally very similar to calling `object[key] = value` or
-    `object.key = value`, except that it provides support for computed
-    properties, the `unknownProperty()` method and property observers.
-
-    ### Computed Properties
-
-    If you try to set a value on a key that has a computed property handler
-    defined (see the `get()` method for an example), then `set()` will call
-    that method, passing both the value and key instead of simply changing
-    the value itself. This is useful for those times when you need to
-    implement a property that is composed of one or more member
-    properties.
-
-    ### Unknown Properties
-
-    If you try to set a value on a key that is undefined in the target
-    object, then the `unknownProperty()` handler will be called instead. This
-    gives you an opportunity to implement complex &quot;virtual&quot; properties that
-    are not predefined on the object. If `unknownProperty()` returns
-    undefined, then `set()` will simply set the value on the object.
-
-    ### Property Observers
-
-    In addition to changing the property, `set()` will also register a property
-    change with the object. Unless you have placed this call inside of a
-    `beginPropertyChanges()` and `endPropertyChanges(),` any &quot;local&quot; observers
-    (i.e. observer methods declared on the same object), will be called
-    immediately. Any &quot;remote&quot; observers (i.e. observer methods declared on
-    another object) will be placed in a queue and called at a later time in a
-    coalesced manner.
-
-    ### Chaining
-
-    In addition to property changes, `set()` returns the value of the object
-    itself so you can do chaining like this:
-
-    ```javascript
-    record.set('firstName', 'Charles').set('lastName', 'Jolley');
-    ```
-
-    @method set
-    @param {String} key The property to set
-    @param {Object} value The value to set or `null`.
-    @return {Ember.Observable}
-  */
-  set: function(keyName, value) {
-    set(this, keyName, value);
-    return this;
-  },
-
-  /**
-    To set multiple properties at once, call `setProperties`
-    with a Hash:
-
-    ```javascript
-    record.setProperties({ firstName: 'Charles', lastName: 'Jolley' });
-    ```
-
-    @method setProperties
-    @param {Hash} hash the hash of keys and values to set
-    @return {Ember.Observable}
-  */
-  setProperties: function(hash) {
-    return Ember.setProperties(this, hash);
-  },
-
-  /**
-    Begins a grouping of property changes.
-
-    You can use this method to group property changes so that notifications
-    will not be sent until the changes are finished. If you plan to make a
-    large number of changes to an object at one time, you should call this
-    method at the beginning of the changes to begin deferring change
-    notifications. When you are done making changes, call
-    `endPropertyChanges()` to deliver the deferred change notifications and end
-    deferring.
-
-    @method beginPropertyChanges
-    @return {Ember.Observable}
-  */
-  beginPropertyChanges: function() {
-    Ember.beginPropertyChanges();
-    return this;
-  },
-
-  /**
-    Ends a grouping of property changes.
-
-    You can use this method to group property changes so that notifications
-    will not be sent until the changes are finished. If you plan to make a
-    large number of changes to an object at one time, you should call
-    `beginPropertyChanges()` at the beginning of the changes to defer change
-    notifications. When you are done making changes, call this method to
-    deliver the deferred change notifications and end deferring.
-
-    @method endPropertyChanges
-    @return {Ember.Observable}
-  */
-  endPropertyChanges: function() {
-    Ember.endPropertyChanges();
-    return this;
-  },
-
-  /**
-    Notify the observer system that a property is about to change.
-
-    Sometimes you need to change a value directly or indirectly without
-    actually calling `get()` or `set()` on it. In this case, you can use this
-    method and `propertyDidChange()` instead. Calling these two methods
-    together will notify all observers that the property has potentially
-    changed value.
-
-    Note that you must always call `propertyWillChange` and `propertyDidChange`
-    as a pair. If you do not, it may get the property change groups out of
-    order and cause notifications to be delivered more often than you would
-    like.
-
-    @method propertyWillChange
-    @param {String} key The property key that is about to change.
-    @return {Ember.Observable}
-  */
-  propertyWillChange: function(keyName){
-    Ember.propertyWillChange(this, keyName);
-    return this;
-  },
-
-  /**
-    Notify the observer system that a property has just changed.
-
-    Sometimes you need to change a value directly or indirectly without
-    actually calling `get()` or `set()` on it. In this case, you can use this
-    method and `propertyWillChange()` instead. Calling these two methods
-    together will notify all observers that the property has potentially
-    changed value.
-
-    Note that you must always call `propertyWillChange` and `propertyDidChange`
-    as a pair. If you do not, it may get the property change groups out of
-    order and cause notifications to be delivered more often than you would
-    like.
-
-    @method propertyDidChange
-    @param {String} keyName The property key that has just changed.
-    @return {Ember.Observable}
-  */
-  propertyDidChange: function(keyName) {
-    Ember.propertyDidChange(this, keyName);
-    return this;
-  },
-
-  /**
-    Convenience method to call `propertyWillChange` and `propertyDidChange` in
-    succession.
-
-    @method notifyPropertyChange
-    @param {String} keyName The property key to be notified about.
-    @return {Ember.Observable}
-  */
-  notifyPropertyChange: function(keyName) {
-    this.propertyWillChange(keyName);
-    this.propertyDidChange(keyName);
-    return this;
-  },
-
-  addBeforeObserver: function(key, target, method) {
-    Ember.addBeforeObserver(this, key, target, method);
-  },
-
-  /**
-    Adds an observer on a property.
-
-    This is the core method used to register an observer for a property.
-
-    Once you call this method, anytime the key's value is set, your observer
-    will be notified. Note that the observers are triggered anytime the
-    value is set, regardless of whether it has actually changed. Your
-    observer should be prepared to handle that.
-
-    You can also pass an optional context parameter to this method. The
-    context will be passed to your observer method whenever it is triggered.
-    Note that if you add the same target/method pair on a key multiple times
-    with different context parameters, your observer will only be called once
-    with the last context you passed.
-
-    ### Observer Methods
-
-    Observer methods you pass should generally have the following signature if
-    you do not pass a `context` parameter:
-
-    ```javascript
-    fooDidChange: function(sender, key, value, rev) { };
-    ```
-
-    The sender is the object that changed. The key is the property that
-    changes. The value property is currently reserved and unused. The rev
-    is the last property revision of the object when it changed, which you can
-    use to detect if the key value has really changed or not.
-
-    If you pass a `context` parameter, the context will be passed before the
-    revision like so:
-
-    ```javascript
-    fooDidChange: function(sender, key, value, context, rev) { };
-    ```
-
-    Usually you will not need the value, context or revision parameters at
-    the end. In this case, it is common to write observer methods that take
-    only a sender and key value as parameters or, if you aren't interested in
-    any of these values, to write an observer that has no parameters at all.
-
-    @method addObserver
-    @param {String} key The key to observer
-    @param {Object} target The target object to invoke
-    @param {String|Function} method The method to invoke.
-    @return {Ember.Object} self
-  */
-  addObserver: function(key, target, method) {
-    Ember.addObserver(this, key, target, method);
-  },
-
-  /**
-    Remove an observer you have previously registered on this object. Pass
-    the same key, target, and method you passed to `addObserver()` and your
-    target will no longer receive notifications.
-
-    @method removeObserver
-    @param {String} key The key to observer
-    @param {Object} target The target object to invoke
-    @param {String|Function} method The method to invoke.
-    @return {Ember.Observable} receiver
-  */
-  removeObserver: function(key, target, method) {
-    Ember.removeObserver(this, key, target, method);
-  },
-
-  /**
-    Returns `true` if the object currently has observers registered for a
-    particular key. You can use this method to potentially defer performing
-    an expensive action until someone begins observing a particular property
-    on the object.
-
-    @method hasObserverFor
-    @param {String} key Key to check
-    @return {Boolean}
-  */
-  hasObserverFor: function(key) {
-    return Ember.hasListeners(this, key+':change');
-  },
-
-  /**
-    @deprecated
-    @method getPath
-    @param {String} path The property path to retrieve
-    @return {Object} The property value or undefined.
-  */
-  getPath: function(path) {
-    Ember.deprecate(&quot;getPath is deprecated since get now supports paths&quot;);
-    return this.get(path);
-  },
-
-  /**
-    @deprecated
-    @method setPath
-    @param {String} path The path to the property that will be set
-    @param {Object} value The value to set or `null`.
-    @return {Ember.Observable}
-  */
-  setPath: function(path, value) {
-    Ember.deprecate(&quot;setPath is deprecated since set now supports paths&quot;);
-    return this.set(path, value);
-  },
-
-  /**
-    Retrieves the value of a property, or a default value in the case that the
-    property returns `undefined`.
-
-    ```javascript
-    person.getWithDefault('lastName', 'Doe');
-    ```
-
-    @method getWithDefault
-    @param {String} keyName The name of the property to retrieve
-    @param {Object} defaultValue The value to return if the property value is undefined
-    @return {Object} The property value or the defaultValue.
-  */
-  getWithDefault: function(keyName, defaultValue) {
-    return Ember.getWithDefault(this, keyName, defaultValue);
-  },
-
-  /**
-    Set the value of a property to the current value plus some amount.
-
-    ```javascript
-    person.incrementProperty('age');
-    team.incrementProperty('score', 2);
-    ```
-
-    @method incrementProperty
-    @param {String} keyName The name of the property to increment
-    @param {Object} increment The amount to increment by. Defaults to 1
-    @return {Object} The new property value
-  */
-  incrementProperty: function(keyName, increment) {
-    if (!increment) { increment = 1; }
-    set(this, keyName, (get(this, keyName) || 0)+increment);
-    return get(this, keyName);
-  },
-
-  /**
-    Set the value of a property to the current value minus some amount.
-
-    ```javascript
-    player.decrementProperty('lives');
-    orc.decrementProperty('health', 5);
-    ```
-
-    @method decrementProperty
-    @param {String} keyName The name of the property to decrement
-    @param {Object} increment The amount to decrement by. Defaults to 1
-    @return {Object} The new property value
-  */
-  decrementProperty: function(keyName, increment) {
-    if (!increment) { increment = 1; }
-    set(this, keyName, (get(this, keyName) || 0)-increment);
-    return get(this, keyName);
-  },
-
-  /**
-    Set the value of a boolean property to the opposite of it's
-    current value.
-
-    ```javascript
-    starship.toggleProperty('warpDriveEnaged');
-    ```
-
-    @method toggleProperty
-    @param {String} keyName The name of the property to toggle
-    @return {Object} The new property value
-  */
-  toggleProperty: function(keyName) {
-    set(this, keyName, !get(this, keyName));
-    return get(this, keyName);
-  },
-
-  /**
-    Returns the cached value of a computed property, if it exists.
-    This allows you to inspect the value of a computed property
-    without accidentally invoking it if it is intended to be
-    generated lazily.
-
-    @method cacheFor
-    @param {String} keyName
-    @return {Object} The cached value of the computed property, if any
-  */
-  cacheFor: function(keyName) {
-    return Ember.cacheFor(this, keyName);
-  },
-
-  // intended for debugging purposes
-  observersForKey: function(keyName) {
-    return Ember.observersFor(this, keyName);
-  }
-});
-
-
-})();
-
-
-
-(function() {
-/**
-@module ember
-@submodule ember-runtime
-*/
-
-var get = Ember.get, set = Ember.set;
-
-/**
-@class TargetActionSupport
-@namespace Ember
-@extends Ember.Mixin
-*/
-Ember.TargetActionSupport = Ember.Mixin.create({
-  target: null,
-  action: null,
-
-  targetObject: Ember.computed(function() {
-    var target = get(this, 'target');
-
-    if (Ember.typeOf(target) === &quot;string&quot;) {
-      var value = get(this, target);
-      if (value === undefined) { value = get(Ember.lookup, target); }
-      return value;
-    } else {
-      return target;
</del><ins>+    if (typeof actionContext === 'undefined') {
+      actionContext = get(this, 'actionContextObject') || this;
</ins><span class="cx">     }
</span><del>-  }).property('target'),
</del><span class="cx"> 
</span><del>-  triggerAction: function() {
-    var action = get(this, 'action'),
-        target = get(this, 'targetObject');
-
</del><span class="cx">     if (target &amp;&amp; action) {
</span><span class="cx">       var ret;
</span><span class="cx"> 
</span><del>-      if (typeof target.send === 'function') {
-        ret = target.send(action, this);
</del><ins>+      if (target.send) {
+        ret = target.send.apply(target, args(actionContext, action));
</ins><span class="cx">       } else {
</span><del>-        if (typeof action === 'string') {
-          action = target[action];
-        }
-        ret = action.call(target, this);
</del><ins>+        Ember.assert(&quot;The action '&quot; + action + &quot;' did not exist on &quot; + target, typeof target[action] === 'function');
+        ret = target[action].apply(target, args(actionContext));
</ins><span class="cx">       }
</span><ins>+
</ins><span class="cx">       if (ret !== false) ret = true;
</span><span class="cx"> 
</span><span class="cx">       return ret;
</span><span class="lines">@@ -9765,9 +17538,18 @@
</span><span class="cx">   // outputs: 'Our person has greeted'
</span><span class="cx">   ```
</span><span class="cx"> 
</span><ins>+  You can also chain multiple event subscriptions:
+
+  ```javascript
+  person.on('greet', function() {
+    console.log('Our person has greeted');
+  }).one('greet', function() {
+    console.log('Offer one-time special');
+  }).off('event', this, forgetThis);
+  ```
+
</ins><span class="cx">   @class Evented
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Mixin
</del><span class="cx">  */
</span><span class="cx"> Ember.Evented = Ember.Mixin.create({
</span><span class="cx"> 
</span><span class="lines">@@ -9789,9 +17571,11 @@
</span><span class="cx">    @param {String} name The name of the event
</span><span class="cx">    @param {Object} [target] The &quot;this&quot; binding for the callback
</span><span class="cx">    @param {Function} method The callback to execute
</span><ins>+   @return this
</ins><span class="cx">   */
</span><span class="cx">   on: function(name, target, method) {
</span><span class="cx">     Ember.addListener(this, name, target, method);
</span><ins>+    return this;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -9807,6 +17591,7 @@
</span><span class="cx">     @param {String} name The name of the event
</span><span class="cx">     @param {Object} [target] The &quot;this&quot; binding for the callback
</span><span class="cx">     @param {Function} method The callback to execute
</span><ins>+    @return this
</ins><span class="cx">   */
</span><span class="cx">   one: function(name, target, method) {
</span><span class="cx">     if (!method) {
</span><span class="lines">@@ -9815,6 +17600,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     Ember.addListener(this, name, target, method, true);
</span><ins>+    return this;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -9843,21 +17629,18 @@
</span><span class="cx">     Ember.sendEvent(this, name, args);
</span><span class="cx">   },
</span><span class="cx"> 
</span><del>-  fire: function(name) {
-    Ember.deprecate(&quot;Ember.Evented#fire() has been deprecated in favor of trigger() for compatibility with jQuery. It will be removed in 1.0. Please update your code to call trigger() instead.&quot;);
-    this.trigger.apply(this, arguments);
-  },
-
</del><span class="cx">   /**
</span><del>-    Cancels subscription for give name, target, and method.
</del><ins>+    Cancels subscription for given name, target, and method.
</ins><span class="cx"> 
</span><span class="cx">     @method off
</span><span class="cx">     @param {String} name The name of the event
</span><span class="cx">     @param {Object} target The target of the subscription
</span><span class="cx">     @param {Function} method The function of the subscription
</span><ins>+    @return this
</ins><span class="cx">   */
</span><span class="cx">   off: function(name, target, method) {
</span><span class="cx">     Ember.removeListener(this, name, target, method);
</span><ins>+    return this;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -9879,8 +17662,13 @@
</span><span class="cx"> (function() {
</span><span class="cx"> var RSVP = requireModule(&quot;rsvp&quot;);
</span><span class="cx"> 
</span><del>-RSVP.async = function(callback, binding) {
-  Ember.run.schedule('actions', binding, callback);
</del><ins>+RSVP.configure('async', function(callback, promise) {
+  Ember.run.schedule('actions', promise, callback, promise);
+});
+
+RSVP.Promise.prototype.fail = function(callback, label){
+  Ember.deprecate('RSVP.Promise.fail has been renamed as RSVP.Promise.catch');
+  return this['catch'](callback, label);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><span class="lines">@@ -9888,25 +17676,36 @@
</span><span class="cx"> @submodule ember-runtime
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var get = Ember.get,
-    slice = Array.prototype.slice;
</del><ins>+var get = Ember.get;
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><span class="cx">   @class Deferred
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Mixin
</del><span class="cx">  */
</span><span class="cx"> Ember.DeferredMixin = Ember.Mixin.create({
</span><span class="cx">   /**
</span><span class="cx">     Add handlers to be called when the Deferred object is resolved or rejected.
</span><span class="cx"> 
</span><span class="cx">     @method then
</span><del>-    @param {Function} doneCallback a callback function to be called when done
-    @param {Function} failCallback a callback function to be called when failed
</del><ins>+    @param {Function} resolve a callback function to be called when done
+    @param {Function} reject  a callback function to be called when failed
</ins><span class="cx">   */
</span><del>-  then: function(doneCallback, failCallback) {
-    var promise = get(this, 'promise');
-    return promise.then.apply(promise, arguments);
</del><ins>+  then: function(resolve, reject, label) {
+    var deferred, promise, entity;
+
+    entity = this;
+    deferred = get(this, '_deferred');
+    promise = deferred.promise;
+
+    function fulfillmentHandler(fulfillment) {
+      if (fulfillment === promise) {
+        return resolve(entity);
+      } else {
+        return resolve(fulfillment);
+      }
+    }
+
+    return promise.then(resolve &amp;&amp; fulfillmentHandler, reject, label);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -9915,7 +17714,16 @@
</span><span class="cx">     @method resolve
</span><span class="cx">   */
</span><span class="cx">   resolve: function(value) {
</span><del>-    get(this, 'promise').resolve(value);
</del><ins>+    var deferred, promise;
+
+    deferred = get(this, '_deferred');
+    promise = deferred.promise;
+
+    if (value === this) {
+      deferred.resolve(promise);
+    } else {
+      deferred.resolve(value);
+    }
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -9924,11 +17732,11 @@
</span><span class="cx">     @method reject
</span><span class="cx">   */
</span><span class="cx">   reject: function(value) {
</span><del>-    get(this, 'promise').reject(value);
</del><ins>+    get(this, '_deferred').reject(value);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  promise: Ember.computed(function() {
-    return new RSVP.Promise();
</del><ins>+  _deferred: Ember.computed(function() {
+    return RSVP.defer('Ember: DeferredMixin - ' + this);
</ins><span class="cx">   })
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -9938,1224 +17746,941 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-
-})();
-
-
-
-(function() {
-Ember.Container = requireModule('container');
-Ember.Container.set = Ember.set;
-
-})();
-
-
-
-(function() {
</del><span class="cx"> /**
</span><span class="cx"> @module ember
</span><span class="cx"> @submodule ember-runtime
</span><span class="cx"> */
</span><span class="cx"> 
</span><ins>+var get = Ember.get, typeOf = Ember.typeOf;
</ins><span class="cx"> 
</span><del>-// NOTE: this object should never be included directly. Instead use Ember.
-// Ember.Object. We only define this separately so that Ember.Set can depend on it
</del><ins>+/**
+  The `Ember.ActionHandler` mixin implements support for moving an `actions`
+  property to an `_actions` property at extend time, and adding `_actions`
+  to the object's mergedProperties list.
</ins><span class="cx"> 
</span><ins>+  `Ember.ActionHandler` is used internally by Ember in  `Ember.View`,
+  `Ember.Controller`, and `Ember.Route`.
</ins><span class="cx"> 
</span><del>-var set = Ember.set, get = Ember.get,
-    o_create = Ember.create,
-    o_defineProperty = Ember.platform.defineProperty,
-    a_slice = Array.prototype.slice,
-    GUID_KEY = Ember.GUID_KEY,
-    guidFor = Ember.guidFor,
-    generateGuid = Ember.generateGuid,
-    meta = Ember.meta,
-    rewatch = Ember.rewatch,
-    finishChains = Ember.finishChains,
-    destroy = Ember.destroy,
-    schedule = Ember.run.schedule,
-    Mixin = Ember.Mixin,
-    applyMixin = Mixin._apply,
-    finishPartial = Mixin.finishPartial,
-    reopen = Mixin.prototype.reopen,
-    MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER,
-    indexOf = Ember.EnumerableUtils.indexOf;
</del><ins>+  @class ActionHandler
+  @namespace Ember
+*/
+Ember.ActionHandler = Ember.Mixin.create({
+  mergedProperties: ['_actions'],
</ins><span class="cx"> 
</span><del>-var undefinedDescriptor = {
-  configurable: true,
-  writable: true,
-  enumerable: false,
-  value: undefined
-};
</del><ins>+  /**
+    The collection of functions, keyed by name, available on this
+    `ActionHandler` as action targets.
</ins><span class="cx"> 
</span><del>-function makeCtor() {
</del><ins>+    These functions will be invoked when a matching `{{action}}` is triggered
+    from within a template and the application's current route is this route.
</ins><span class="cx"> 
</span><del>-  // Note: avoid accessing any properties on the object since it makes the
-  // method a lot faster. This is glue code so we want it to be as fast as
-  // possible.
</del><ins>+    Actions can also be invoked from other parts of your application
+    via `ActionHandler#send`.
</ins><span class="cx"> 
</span><del>-  var wasApplied = false, initMixins, initProperties;
</del><ins>+    The `actions` hash will inherit action handlers from
+    the `actions` hash defined on extended parent classes
+    or mixins rather than just replace the entire hash, e.g.:
</ins><span class="cx"> 
</span><del>-  var Class = function() {
-    if (!wasApplied) {
-      Class.proto(); // prepare prototype...
-    }
-    o_defineProperty(this, GUID_KEY, undefinedDescriptor);
-    o_defineProperty(this, '_super', undefinedDescriptor);
-    var m = meta(this);
-    m.proto = this;
-    if (initMixins) {
-      // capture locally so we can clear the closed over variable
-      var mixins = initMixins;
-      initMixins = null;
-      this.reopen.apply(this, mixins);
-    }
-    if (initProperties) {
-      // capture locally so we can clear the closed over variable
-      var props = initProperties;
-      initProperties = null;
</del><ins>+    ```js
+    App.CanDisplayBanner = Ember.Mixin.create({
+      actions: {
+        displayBanner: function(msg) {
+          // ...
+        }
+      }
+    });
</ins><span class="cx"> 
</span><del>-      var concatenatedProperties = this.concatenatedProperties;
</del><ins>+    App.WelcomeRoute = Ember.Route.extend(App.CanDisplayBanner, {
+      actions: {
+        playMusic: function() {
+          // ...
+        }
+      }
+    });
</ins><span class="cx"> 
</span><del>-      for (var i = 0, l = props.length; i &lt; l; i++) {
-        var properties = props[i];
-        for (var keyName in properties) {
-          if (!properties.hasOwnProperty(keyName)) { continue; }
</del><ins>+    // `WelcomeRoute`, when active, will be able to respond
+    // to both actions, since the actions hash is merged rather
+    // then replaced when extending mixins / parent classes.
+    this.send('displayBanner');
+    this.send('playMusic');
+    ```
</ins><span class="cx"> 
</span><del>-          var value = properties[keyName],
-              IS_BINDING = Ember.IS_BINDING;
</del><ins>+    Within a Controller, Route, View or Component's action handler,
+    the value of the `this` context is the Controller, Route, View or
+    Component object:
</ins><span class="cx"> 
</span><del>-          if (IS_BINDING.test(keyName)) {
-            var bindings = m.bindings;
-            if (!bindings) {
-              bindings = m.bindings = {};
-            } else if (!m.hasOwnProperty('bindings')) {
-              bindings = m.bindings = o_create(m.bindings);
-            }
-            bindings[keyName] = value;
-          }
</del><ins>+    ```js
+    App.SongRoute = Ember.Route.extend({
+      actions: {
+        myAction: function() {
+          this.controllerFor(&quot;song&quot;);
+          this.transitionTo(&quot;other.route&quot;);
+          ...
+        }
+      }
+    });
+    ```
</ins><span class="cx"> 
</span><del>-          var desc = m.descs[keyName];
</del><ins>+    It is also possible to call `this._super()` from within an
+    action handler if it overrides a handler defined on a parent
+    class or mixin:
</ins><span class="cx"> 
</span><del>-          Ember.assert(&quot;Ember.Object.create no longer supports defining computed properties.&quot;, !(value instanceof Ember.ComputedProperty));
-          Ember.assert(&quot;Ember.Object.create no longer supports defining methods that call _super.&quot;, !(typeof value === 'function' &amp;&amp; value.toString().indexOf('._super') !== -1));
</del><ins>+    Take for example the following routes:
</ins><span class="cx"> 
</span><del>-          if (concatenatedProperties &amp;&amp; indexOf(concatenatedProperties, keyName) &gt;= 0) {
-            var baseValue = this[keyName];
</del><ins>+    ```js
+    App.DebugRoute = Ember.Mixin.create({
+      actions: {
+        debugRouteInformation: function() {
+          console.debug(&quot;trololo&quot;);
+        }
+      }
+    });
</ins><span class="cx"> 
</span><del>-            if (baseValue) {
-              if ('function' === typeof baseValue.concat) {
-                value = baseValue.concat(value);
-              } else {
-                value = Ember.makeArray(baseValue).concat(value);
-              }
-            } else {
-              value = Ember.makeArray(value);
-            }
-          }
</del><ins>+    App.AnnoyingDebugRoute = Ember.Route.extend(App.DebugRoute, {
+      actions: {
+        debugRouteInformation: function() {
+          // also call the debugRouteInformation of mixed in App.DebugRoute
+          this._super();
</ins><span class="cx"> 
</span><del>-          if (desc) {
-            desc.set(this, keyName, value);
-          } else {
-            if (typeof this.setUnknownProperty === 'function' &amp;&amp; !(keyName in this)) {
-              this.setUnknownProperty(keyName, value);
-            } else if (MANDATORY_SETTER) {
-              Ember.defineProperty(this, keyName, null, value); // setup mandatory setter
-            } else {
-              this[keyName] = value;
-            }
-          }
</del><ins>+          // show additional annoyance
+          window.alert(...);
</ins><span class="cx">         }
</span><span class="cx">       }
</span><del>-    }
-    finishPartial(this, m);
-    delete m.proto;
-    finishChains(this);
-    this.init.apply(this, arguments);
-  };
</del><ins>+    });
+    ```
</ins><span class="cx"> 
</span><del>-  Class.toString = Mixin.prototype.toString;
-  Class.willReopen = function() {
-    if (wasApplied) {
-      Class.PrototypeMixin = Mixin.create(Class.PrototypeMixin);
-    }
</del><ins>+    ## Bubbling
</ins><span class="cx"> 
</span><del>-    wasApplied = false;
-  };
-  Class._initMixins = function(args) { initMixins = args; };
-  Class._initProperties = function(args) { initProperties = args; };
</del><ins>+    By default, an action will stop bubbling once a handler defined
+    on the `actions` hash handles it. To continue bubbling the action,
+    you must return `true` from the handler:
</ins><span class="cx"> 
</span><del>-  Class.proto = function() {
-    var superclass = Class.superclass;
-    if (superclass) { superclass.proto(); }
-
-    if (!wasApplied) {
-      wasApplied = true;
-      Class.PrototypeMixin.applyPartial(Class.prototype);
-      rewatch(Class.prototype);
-    }
-
-    return this.prototype;
-  };
-
-  return Class;
-
-}
-
-var CoreObject = makeCtor();
-CoreObject.toString = function() { return &quot;Ember.CoreObject&quot;; };
-
-CoreObject.PrototypeMixin = Mixin.create({
-  reopen: function() {
-    applyMixin(this, arguments, true);
-    return this;
-  },
-
-  isInstance: true,
-
-  init: function() {},
-
-  /**
-    Defines the properties that will be concatenated from the superclass
-    (instead of overridden).
-
-    By default, when you extend an Ember class a property defined in
-    the subclass overrides a property with the same name that is defined
-    in the superclass. However, there are some cases where it is preferable
-    to build up a property's value by combining the superclass' property
-    value with the subclass' value. An example of this in use within Ember
-    is the `classNames` property of `Ember.View`.
-
-    Here is some sample code showing the difference between a concatenated
-    property and a normal one:
-
-    ```javascript
-    App.BarView = Ember.View.extend({
-      someNonConcatenatedProperty: ['bar'],
-      classNames: ['bar']
</del><ins>+    ```js
+    App.Router.map(function() {
+      this.resource(&quot;album&quot;, function() {
+        this.route(&quot;song&quot;);
+      });
</ins><span class="cx">     });
</span><span class="cx"> 
</span><del>-    App.FooBarView = App.BarView.extend({
-      someNonConcatenatedProperty: ['foo'],
-      classNames: ['foo'],
</del><ins>+    App.AlbumRoute = Ember.Route.extend({
+      actions: {
+        startPlaying: function() {
+        }
+      }
</ins><span class="cx">     });
</span><span class="cx"> 
</span><del>-    var fooBarView = App.FooBarView.create();
-    fooBarView.get('someNonConcatenatedProperty'); // ['foo']
-    fooBarView.get('classNames'); // ['ember-view', 'bar', 'foo']
-    ```
</del><ins>+    App.AlbumSongRoute = Ember.Route.extend({
+      actions: {
+        startPlaying: function() {
+          // ...
</ins><span class="cx"> 
</span><del>-    This behavior extends to object creation as well. Continuing the
-    above example:
-
-    ```javascript
-    var view = App.FooBarView.create({
-      someNonConcatenatedProperty: ['baz'],
-      classNames: ['baz']
-    })
-    view.get('someNonConcatenatedProperty'); // ['baz']
-    view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
</del><ins>+          if (actionShouldAlsoBeTriggeredOnParentRoute) {
+            return true;
+          }
+        }
+      }
+    });
</ins><span class="cx">     ```
</span><del>-    Adding a single property that is not an array will just add it in the array:
-    
-    ```javascript
-    var view = App.FooBarView.create({
-      classNames: 'baz'
-    })
-    view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
-    ```
-    
-    Using the `concatenatedProperties` property, we can tell to Ember that mix
-    the content of the properties.
</del><span class="cx"> 
</span><del>-    In `Ember.View` the `classNameBindings` and `attributeBindings` properties
-    are also concatenated, in addition to `classNames`.
-
-    This feature is available for you to use throughout the Ember object model,
-    although typical app developers are likely to use it infrequently.
-
-    @property concatenatedProperties
-    @type Array
</del><ins>+    @property actions
+    @type Hash
</ins><span class="cx">     @default null
</span><span class="cx">   */
</span><del>-  concatenatedProperties: null,
</del><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @property isDestroyed
-    @default false
-  */
-  isDestroyed: false,
</del><ins>+    Moves `actions` to `_actions` at extend time. Note that this currently
+    modifies the mixin themselves, which is technically dubious but
+    is practically of little consequence. This may change in the future.
</ins><span class="cx"> 
</span><del>-  /**
-    @property isDestroying
-    @default false
</del><ins>+    @private
+    @method willMergeMixin
</ins><span class="cx">   */
</span><del>-  isDestroying: false,
</del><ins>+  willMergeMixin: function(props) {
+    var hashName;
</ins><span class="cx"> 
</span><del>-  /**
-    Destroys an object by setting the `isDestroyed` flag and removing its
-    metadata, which effectively destroys observers and bindings.
</del><ins>+    if (!props._actions) {
+      if (typeOf(props.actions) === 'object') {
+        hashName = 'actions';
+      } else if (typeOf(props.events) === 'object') {
+        Ember.deprecate('Action handlers contained in an `events` object are deprecated in favor of putting them in an `actions` object', false);
+        hashName = 'events';
+      }
</ins><span class="cx"> 
</span><del>-    If you try to set a property on a destroyed object, an exception will be
-    raised.
</del><ins>+      if (hashName) {
+        props._actions = Ember.merge(props._actions || {}, props[hashName]);
+      }
</ins><span class="cx"> 
</span><del>-    Note that destruction is scheduled for the end of the run loop and does not
-    happen immediately.
-
-    @method destroy
-    @return {Ember.Object} receiver
-  */
-  destroy: function() {
-    if (this._didCallDestroy) { return; }
-
-    this.isDestroying = true;
-    this._didCallDestroy = true;
-
-    if (this.willDestroy) { this.willDestroy(); }
-
-    schedule('destroy', this, this._scheduledDestroy);
-    return this;
</del><ins>+      delete props[hashName];
+    }
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  /**
-    @private
</del><ins>+  send: function(actionName) {
+    var args = [].slice.call(arguments, 1), target;
</ins><span class="cx"> 
</span><del>-    Invoked by the run loop to actually destroy the object. This is
-    scheduled for execution by the `destroy` method.
</del><ins>+    if (this._actions &amp;&amp; this._actions[actionName]) {
+      if (this._actions[actionName].apply(this, args) === true) {
+        // handler returned true, so this action will bubble
+      } else {
+        return;
+      }
+    } else if (this.deprecatedSend &amp;&amp; this.deprecatedSendHandles &amp;&amp; this.deprecatedSendHandles(actionName)) {
+      if (this.deprecatedSend.apply(this, [].slice.call(arguments)) === true) {
+        // handler return true, so this action will bubble
+      } else {
+        return;
+      }
+    }
</ins><span class="cx"> 
</span><del>-    @method _scheduledDestroy
-  */
-  _scheduledDestroy: function() {
-    destroy(this);
-    set(this, 'isDestroyed', true);
</del><ins>+    if (target = get(this, 'target')) {
+      Ember.assert(&quot;The `target` for &quot; + this + &quot; (&quot; + target + &quot;) does not have a `send` method&quot;, typeof target.send === 'function');
+      target.send.apply(target, arguments);
+    }
+  }
</ins><span class="cx"> 
</span><del>-    if (this.didDestroy) { this.didDestroy(); }
-  },
</del><ins>+});
</ins><span class="cx"> 
</span><del>-  bind: function(to, from) {
-    if (!(from instanceof Ember.Binding)) { from = Ember.Binding.from(from); }
-    from.to(to).connect(this);
-    return from;
-  },
</del><ins>+})();
</ins><span class="cx"> 
</span><del>-  /**
-    Returns a string representation which attempts to provide more information
-    than Javascript's `toString` typically does, in a generic way for all Ember
-    objects.
</del><span class="cx"> 
</span><del>-        App.Person = Em.Object.extend()
-        person = App.Person.create()
-        person.toString() //=&gt; &quot;&lt;App.Person:ember1024&gt;&quot;
</del><span class="cx"> 
</span><del>-    If the object's class is not defined on an Ember namespace, it will
-    indicate it is a subclass of the registered superclass:
</del><ins>+(function() {
+var set = Ember.set, get = Ember.get,
+    resolve = Ember.RSVP.resolve,
+    rethrow = Ember.RSVP.rethrow,
+    not = Ember.computed.not,
+    or = Ember.computed.or;
</ins><span class="cx"> 
</span><del>-        Student = App.Person.extend()
-        student = Student.create()
-        student.toString() //=&gt; &quot;&lt;(subclass of App.Person):ember1025&gt;&quot;
</del><ins>+/**
+  @module ember
+  @submodule ember-runtime
+ */
</ins><span class="cx"> 
</span><del>-    If the method `toStringExtension` is defined, its return value will be
-    included in the output.
</del><ins>+function observePromise(proxy, promise) {
+  promise.then(function(value) {
+    set(proxy, 'isFulfilled', true);
+    set(proxy, 'content', value);
+  }, function(reason) {
+    set(proxy, 'isRejected', true);
+    set(proxy, 'reason', reason);
+    // don't re-throw, as we are merely observing
+  }, &quot;Ember: PromiseProxy&quot;);
+}
</ins><span class="cx"> 
</span><del>-        App.Teacher = App.Person.extend({
-          toStringExtension: function(){
-            return this.get('fullName');
-          }
-        });
-        teacher = App.Teacher.create()
-        teacher.toString(); // #=&gt; &quot;&lt;App.Teacher:ember1026:Tom Dale&gt;&quot;
</del><ins>+/**
+  A low level mixin making ObjectProxy, ObjectController or ArrayController's promise aware.
</ins><span class="cx"> 
</span><del>-    @method toString
-    @return {String} string representation
-  */
-  toString: function toString() {
-    var hasToStringExtension = typeof this.toStringExtension === 'function',
-        extension = hasToStringExtension ? &quot;:&quot; + this.toStringExtension() : '';
-    var ret = '&lt;'+this.constructor.toString()+':'+guidFor(this)+extension+'&gt;';
-    this.toString = makeToString(ret);
-    return ret;
-  }
-});
</del><ins>+  ```javascript
+  var ObjectPromiseController = Ember.ObjectController.extend(Ember.PromiseProxyMixin);
</ins><span class="cx"> 
</span><del>-CoreObject.PrototypeMixin.ownerConstructor = CoreObject;
</del><ins>+  var controller = ObjectPromiseController.create({
+    promise: $.getJSON('/some/remote/data.json')
+  });
</ins><span class="cx"> 
</span><del>-function makeToString(ret) {
-  return function() { return ret; };
-}
</del><ins>+  controller.then(function(json){
+     // the json
+  }, function(reason) {
+     // the reason why you have no json
+  });
+  ```
</ins><span class="cx"> 
</span><del>-if (Ember.config.overridePrototypeMixin) {
-  Ember.config.overridePrototypeMixin(CoreObject.PrototypeMixin);
-}
</del><ins>+  the controller has bindable attributes which
+  track the promises life cycle
</ins><span class="cx"> 
</span><del>-CoreObject.__super__ = null;
</del><ins>+  ```javascript
+  controller.get('isPending')   //=&gt; true
+  controller.get('isSettled')  //=&gt; false
+  controller.get('isRejected')  //=&gt; false
+  controller.get('isFulfilled') //=&gt; false
+  ```
</ins><span class="cx"> 
</span><del>-var ClassMixin = Mixin.create({
</del><ins>+  When the the $.getJSON completes, and the promise is fulfilled
+  with json, the life cycle attributes will update accordingly.
</ins><span class="cx"> 
</span><del>-  ClassMixin: Ember.required(),
</del><ins>+  ```javascript
+  controller.get('isPending')   //=&gt; false
+  controller.get('isSettled')   //=&gt; true
+  controller.get('isRejected')  //=&gt; false
+  controller.get('isFulfilled') //=&gt; true
+  ```
</ins><span class="cx"> 
</span><del>-  PrototypeMixin: Ember.required(),
</del><ins>+  As the controller is an ObjectController, and the json now its content,
+  all the json properties will be available directly from the controller.
</ins><span class="cx"> 
</span><del>-  isClass: true,
</del><ins>+  ```javascript
+  // Assuming the following json:
+  {
+    firstName: 'Stefan',
+    lastName: 'Penner'
+  }
</ins><span class="cx"> 
</span><del>-  isMethod: false,
</del><ins>+  // both properties will accessible on the controller
+  controller.get('firstName') //=&gt; 'Stefan'
+  controller.get('lastName')  //=&gt; 'Penner'
+  ```
</ins><span class="cx"> 
</span><del>-  extend: function() {
-    var Class = makeCtor(), proto;
-    Class.ClassMixin = Mixin.create(this.ClassMixin);
-    Class.PrototypeMixin = Mixin.create(this.PrototypeMixin);
</del><ins>+  If the controller is backing a template, the attributes are
+  bindable from within that template
</ins><span class="cx"> 
</span><del>-    Class.ClassMixin.ownerConstructor = Class;
-    Class.PrototypeMixin.ownerConstructor = Class;
</del><ins>+  ```handlebars
+  {{#if isPending}}
+    loading...
+  {{else}}
+    firstName: {{firstName}}
+    lastName: {{lastName}}
+  {{/if}}
+  ```
+  @class Ember.PromiseProxyMixin
+*/
+Ember.PromiseProxyMixin = Ember.Mixin.create({
+  /**
+    If the proxied promise is rejected this will contain the reason
+    provided.
</ins><span class="cx"> 
</span><del>-    reopen.apply(Class.PrototypeMixin, arguments);
</del><ins>+    @property reason
+    @default null
+  */
+  reason:    null,
</ins><span class="cx"> 
</span><del>-    Class.superclass = this;
-    Class.__super__  = this.prototype;
</del><ins>+  /**
+    Once the proxied promise has settled this will become `false`.
</ins><span class="cx"> 
</span><del>-    proto = Class.prototype = o_create(this.prototype);
-    proto.constructor = Class;
-    generateGuid(proto, 'ember');
-    meta(proto).proto = proto; // this will disable observers on prototype
</del><ins>+    @property isPending
+    @default true
+  */
+  isPending:  not('isSettled').readOnly(),
</ins><span class="cx"> 
</span><del>-    Class.ClassMixin.apply(Class);
-    return Class;
-  },
</del><ins>+  /**
+    Once the proxied promise has settled this will become `true`.
</ins><span class="cx"> 
</span><del>-  createWithMixins: function() {
-    var C = this;
-    if (arguments.length&gt;0) { this._initMixins(arguments); }
-    return new C();
-  },
</del><ins>+    @property isSettled
+    @default false
+  */
+  isSettled:  or('isRejected', 'isFulfilled').readOnly(),
</ins><span class="cx"> 
</span><del>-  create: function() {
-    var C = this;
-    if (arguments.length&gt;0) { this._initProperties(arguments); }
-    return new C();
-  },
</del><ins>+  /**
+    Will become `true` if the proxied promise is rejected.
</ins><span class="cx"> 
</span><del>-  reopen: function() {
-    this.willReopen();
-    reopen.apply(this.PrototypeMixin, arguments);
-    return this;
-  },
</del><ins>+    @property isRejected
+    @default false
+  */
+  isRejected:  false,
</ins><span class="cx"> 
</span><del>-  reopenClass: function() {
-    reopen.apply(this.ClassMixin, arguments);
-    applyMixin(this, arguments, false);
-    return this;
-  },
</del><ins>+  /**
+    Will become `true` if the proxied promise is fulfilled.
</ins><span class="cx"> 
</span><del>-  detect: function(obj) {
-    if ('function' !== typeof obj) { return false; }
-    while(obj) {
-      if (obj===this) { return true; }
-      obj = obj.superclass;
-    }
-    return false;
-  },
</del><ins>+    @property isFullfilled
+    @default false
+  */
+  isFulfilled: false,
</ins><span class="cx"> 
</span><del>-  detectInstance: function(obj) {
-    return obj instanceof this;
-  },
-
</del><span class="cx">   /**
</span><del>-    In some cases, you may want to annotate computed properties with additional
-    metadata about how they function or what values they operate on. For
-    example, computed property functions may close over variables that are then
-    no longer available for introspection.
</del><ins>+    The promise whose fulfillment value is being proxied by this object.
</ins><span class="cx"> 
</span><del>-    You can pass a hash of these values to a computed property like this:
</del><ins>+    This property must be specified upon creation, and should not be
+    changed once created.
</ins><span class="cx"> 
</span><ins>+    Example:
+
</ins><span class="cx">     ```javascript
</span><del>-    person: function() {
-      var personId = this.get('personId');
-      return App.Person.create({ id: personId });
-    }.property().meta({ type: App.Person })
</del><ins>+    Ember.ObjectController.extend(Ember.PromiseProxyMixin).create({
+      promise: &lt;thenable&gt;
+    });
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    Once you've done this, you can retrieve the values saved to the computed
-    property from your class like this:
</del><ins>+    @property promise
+  */
+  promise: Ember.computed(function(key, promise) {
+    if (arguments.length === 2) {
+      promise = resolve(promise);
+      observePromise(this, promise);
+      return promise.then(); // fork the promise.
+    } else {
+      throw new Ember.Error(&quot;PromiseProxy's promise must be set&quot;);
+    }
+  }),
</ins><span class="cx"> 
</span><del>-    ```javascript
-    MyClass.metaForProperty('person');
-    ```
</del><ins>+  /**
+    An alias to the proxied promise's `then`.
</ins><span class="cx"> 
</span><del>-    This will return the original hash that was passed to `meta()`.
</del><ins>+    See RSVP.Promise.then.
</ins><span class="cx"> 
</span><del>-    @method metaForProperty
-    @param key {String} property name
</del><ins>+    @method then
+    @param {Function} callback
+    @return {RSVP.Promise}
</ins><span class="cx">   */
</span><del>-  metaForProperty: function(key) {
-    var desc = meta(this.proto(), false).descs[key];
</del><ins>+  then: promiseAlias('then'),
</ins><span class="cx"> 
</span><del>-    Ember.assert(&quot;metaForProperty() could not find a computed property with key '&quot;+key+&quot;'.&quot;, !!desc &amp;&amp; desc instanceof Ember.ComputedProperty);
-    return desc._meta || {};
-  },
-
</del><span class="cx">   /**
</span><del>-    Iterate over each computed property for the class, passing its name
-    and any associated metadata (see `metaForProperty`) to the callback.
</del><ins>+    An alias to the proxied promise's `catch`.
</ins><span class="cx"> 
</span><del>-    @method eachComputedProperty
</del><ins>+    See RSVP.Promise.catch.
+
+    @method catch
</ins><span class="cx">     @param {Function} callback
</span><del>-    @param {Object} binding
</del><ins>+    @return {RSVP.Promise}
</ins><span class="cx">   */
</span><del>-  eachComputedProperty: function(callback, binding) {
-    var proto = this.proto(),
-        descs = meta(proto).descs,
-        empty = {},
-        property;
</del><ins>+  'catch': promiseAlias('catch'),
</ins><span class="cx"> 
</span><del>-    for (var name in descs) {
-      property = descs[name];
</del><ins>+  /**
+    An alias to the proxied promise's `finally`.
</ins><span class="cx"> 
</span><del>-      if (property instanceof Ember.ComputedProperty) {
-        callback.call(binding || this, name, property._meta || empty);
-      }
-    }
-  }
</del><ins>+    See RSVP.Promise.finally.
</ins><span class="cx"> 
</span><ins>+    @method finally
+    @param {Function} callback
+    @return {RSVP.Promise}
+  */
+  'finally': promiseAlias('finally')
+
</ins><span class="cx"> });
</span><span class="cx"> 
</span><del>-ClassMixin.ownerConstructor = CoreObject;
-
-if (Ember.config.overrideClassMixin) {
-  Ember.config.overrideClassMixin(ClassMixin);
</del><ins>+function promiseAlias(name) {
+  return function () {
+    var promise = get(this, 'promise');
+    return promise[name].apply(promise, arguments);
+  };
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-CoreObject.ClassMixin = ClassMixin;
-ClassMixin.apply(CoreObject);
-
-/**
-  @class CoreObject
-  @namespace Ember
-*/
-Ember.CoreObject = CoreObject;
-
</del><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-/**
-@module ember
-@submodule ember-runtime
-*/
</del><span class="cx"> 
</span><del>-var get = Ember.get, set = Ember.set, guidFor = Ember.guidFor, none = Ember.isNone;
</del><ins>+})();
</ins><span class="cx"> 
</span><del>-/**
-  An unordered collection of objects.
</del><span class="cx"> 
</span><del>-  A Set works a bit like an array except that its items are not ordered. You
-  can create a set to efficiently test for membership for an object. You can
-  also iterate through a set just like an array, even accessing objects by
-  index, however there is no guarantee as to their order.
</del><span class="cx"> 
</span><del>-  All Sets are observable via the Enumerable Observer API - which works
-  on any enumerable object including both Sets and Arrays.
</del><ins>+(function() {
+var get = Ember.get,
+    forEach = Ember.EnumerableUtils.forEach,
+    RETAIN = 'r',
+    INSERT = 'i',
+    DELETE = 'd';
</ins><span class="cx"> 
</span><del>-  ## Creating a Set
</del><ins>+/**
+  An `Ember.TrackedArray` tracks array operations.  It's useful when you want to
+  lazily compute the indexes of items in an array after they've been shifted by
+  subsequent operations.
</ins><span class="cx"> 
</span><del>-  You can create a set like you would most objects using
-  `new Ember.Set()`. Most new sets you create will be empty, but you can
-  also initialize the set with some content by passing an array or other
-  enumerable of objects to the constructor.
-
-  Finally, you can pass in an existing set and the set will be copied. You
-  can also create a copy of a set by calling `Ember.Set#copy()`.
-
-  ```javascript
-  // creates a new empty set
-  var foundNames = new Ember.Set();
-
-  // creates a set with four names in it.
-  var names = new Ember.Set([&quot;Charles&quot;, &quot;Tom&quot;, &quot;Juan&quot;, &quot;Alex&quot;]); // :P
-
-  // creates a copy of the names set.
-  var namesCopy = new Ember.Set(names);
-
-  // same as above.
-  var anotherNamesCopy = names.copy();
-  ```
-
-  ## Adding/Removing Objects
-
-  You generally add or remove objects from a set using `add()` or
-  `remove()`. You can add any type of object including primitives such as
-  numbers, strings, and booleans.
-
-  Unlike arrays, objects can only exist one time in a set. If you call `add()`
-  on a set with the same object multiple times, the object will only be added
-  once. Likewise, calling `remove()` with the same object multiple times will
-  remove the object the first time and have no effect on future calls until
-  you add the object to the set again.
-
-  NOTE: You cannot add/remove `null` or `undefined` to a set. Any attempt to do
-  so will be ignored.
-
-  In addition to add/remove you can also call `push()`/`pop()`. Push behaves
-  just like `add()` but `pop()`, unlike `remove()` will pick an arbitrary
-  object, remove it and return it. This is a good way to use a set as a job
-  queue when you don't care which order the jobs are executed in.
-
-  ## Testing for an Object
-
-  To test for an object's presence in a set you simply call
-  `Ember.Set#contains()`.
-
-  ## Observing changes
-
-  When using `Ember.Set`, you can observe the `&quot;[]&quot;` property to be
-  alerted whenever the content changes. You can also add an enumerable
-  observer to the set to be notified of specific objects that are added and
-  removed from the set. See `Ember.Enumerable` for more information on
-  enumerables.
-
-  This is often unhelpful. If you are filtering sets of objects, for instance,
-  it is very inefficient to re-filter all of the items each time the set
-  changes. It would be better if you could just adjust the filtered set based
-  on what was changed on the original set. The same issue applies to merging
-  sets, as well.
-
-  ## Other Methods
-
-  `Ember.Set` primary implements other mixin APIs. For a complete reference
-  on the methods you will use with `Ember.Set`, please consult these mixins.
-  The most useful ones will be `Ember.Enumerable` and
-  `Ember.MutableEnumerable` which implement most of the common iterator
-  methods you are used to on Array.
-
-  Note that you can also use the `Ember.Copyable` and `Ember.Freezable`
-  APIs on `Ember.Set` as well. Once a set is frozen it can no longer be
-  modified. The benefit of this is that when you call `frozenCopy()` on it,
-  Ember will avoid making copies of the set. This allows you to write
-  code that can know with certainty when the underlying set data will or
-  will not be modified.
-
-  @class Set
</del><ins>+  @class TrackedArray
</ins><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.CoreObject
-  @uses Ember.MutableEnumerable
-  @uses Ember.Copyable
-  @uses Ember.Freezable
-  @since Ember 0.9
</del><ins>+  @param {array} [items=[]] The array to be tracked.  This is used just to get
+  the initial items for the starting state of retain:n.
</ins><span class="cx"> */
</span><del>-Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Ember.Freezable,
-  /** @scope Ember.Set.prototype */ {
</del><ins>+Ember.TrackedArray = function (items) {
+  if (arguments.length &lt; 1) { items = []; }
</ins><span class="cx"> 
</span><del>-  // ..........................................................
-  // IMPLEMENT ENUMERABLE APIS
-  //
</del><ins>+  var length = get(items, 'length');
</ins><span class="cx"> 
</span><del>-  /**
-    This property will change as the number of objects in the set changes.
</del><ins>+  if (length) {
+    this._operations = [new ArrayOperation(RETAIN, length, items)];
+  } else {
+    this._operations = [];
+  }
+};
</ins><span class="cx"> 
</span><del>-    @property length
-    @type number
-    @default 0
-  */
-  length: 0,
</del><ins>+Ember.TrackedArray.RETAIN = RETAIN;
+Ember.TrackedArray.INSERT = INSERT;
+Ember.TrackedArray.DELETE = DELETE;
</ins><span class="cx"> 
</span><ins>+Ember.TrackedArray.prototype = {
+
</ins><span class="cx">   /**
</span><del>-    Clears the set. This is useful if you want to reuse an existing set
-    without having to recreate it.
</del><ins>+    Track that `newItems` were added to the tracked array at `index`.
</ins><span class="cx"> 
</span><del>-    ```javascript
-    var colors = new Ember.Set([&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]);
-    colors.length;  // 3
-    colors.clear();
-    colors.length;  // 0
-    ```
-
-    @method clear
-    @return {Ember.Set} An empty Set
</del><ins>+    @method addItems
+    @param index
+    @param newItems
</ins><span class="cx">   */
</span><del>-  clear: function() {
-    if (this.isFrozen) { throw new Error(Ember.FROZEN_ERROR); }
</del><ins>+  addItems: function (index, newItems) {
+    var count = get(newItems, 'length');
+    if (count &lt; 1) { return; }
</ins><span class="cx"> 
</span><del>-    var len = get(this, 'length');
-    if (len === 0) { return this; }
</del><ins>+    var match = this._findArrayOperation(index),
+        arrayOperation = match.operation,
+        arrayOperationIndex = match.index,
+        arrayOperationRangeStart = match.rangeStart,
+        composeIndex,
+        splitIndex,
+        splitItems,
+        splitArrayOperation,
+        newArrayOperation;
</ins><span class="cx"> 
</span><del>-    var guid;
</del><ins>+    newArrayOperation = new ArrayOperation(INSERT, count, newItems);
</ins><span class="cx"> 
</span><del>-    this.enumerableContentWillChange(len, 0);
-    Ember.propertyWillChange(this, 'firstObject');
-    Ember.propertyWillChange(this, 'lastObject');
-
-    for (var i=0; i &lt; len; i++){
-      guid = guidFor(this[i]);
-      delete this[guid];
-      delete this[i];
</del><ins>+    if (arrayOperation) {
+      if (!match.split) {
+        // insert left of arrayOperation
+        this._operations.splice(arrayOperationIndex, 0, newArrayOperation);
+        composeIndex = arrayOperationIndex;
+      } else {
+        this._split(arrayOperationIndex, index - arrayOperationRangeStart, newArrayOperation);
+        composeIndex = arrayOperationIndex + 1;
+      }
+    } else {
+      // insert at end
+      this._operations.push(newArrayOperation);
+      composeIndex = arrayOperationIndex;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    set(this, 'length', 0);
-
-    Ember.propertyDidChange(this, 'firstObject');
-    Ember.propertyDidChange(this, 'lastObject');
-    this.enumerableContentDidChange(len, 0);
-
-    return this;
</del><ins>+    this._composeInsert(composeIndex);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Returns true if the passed object is also an enumerable that contains the
-    same objects as the receiver.
</del><ins>+    Track that `count` items were removed at `index`.
</ins><span class="cx"> 
</span><del>-    ```javascript
-    var colors = [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;],
-        same_colors = new Ember.Set(colors);
-
-    same_colors.isEqual(colors);               // true
-    same_colors.isEqual([&quot;purple&quot;, &quot;brown&quot;]);  // false
-    ```
-
-    @method isEqual
-    @param {Ember.Set} obj the other object.
-    @return {Boolean}
</del><ins>+    @method removeItems
+    @param index
+    @param count
</ins><span class="cx">   */
</span><del>-  isEqual: function(obj) {
-    // fail fast
-    if (!Ember.Enumerable.detect(obj)) return false;
</del><ins>+  removeItems: function (index, count) {
+    if (count &lt; 1) { return; }
</ins><span class="cx"> 
</span><del>-    var loc = get(this, 'length');
-    if (get(obj, 'length') !== loc) return false;
</del><ins>+    var match = this._findArrayOperation(index),
+        arrayOperation = match.operation,
+        arrayOperationIndex = match.index,
+        arrayOperationRangeStart = match.rangeStart,
+        newArrayOperation,
+        composeIndex;
</ins><span class="cx"> 
</span><del>-    while(--loc &gt;= 0) {
-      if (!obj.contains(this[loc])) return false;
</del><ins>+    newArrayOperation = new ArrayOperation(DELETE, count);
+    if (!match.split) {
+      // insert left of arrayOperation
+      this._operations.splice(arrayOperationIndex, 0, newArrayOperation);
+      composeIndex = arrayOperationIndex;
+    } else {
+      this._split(arrayOperationIndex, index - arrayOperationRangeStart, newArrayOperation);
+      composeIndex = arrayOperationIndex + 1;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return true;
</del><ins>+    return this._composeDelete(composeIndex);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Adds an object to the set. Only non-`null` objects can be added to a set
-    and those can only be added once. If the object is already in the set or
-    the passed value is null this method will have no effect.
</del><ins>+    Apply all operations, reducing them to retain:n, for `n`, the number of
+    items in the array.
</ins><span class="cx"> 
</span><del>-    This is an alias for `Ember.MutableEnumerable.addObject()`.
</del><ins>+    `callback` will be called for each operation and will be passed the following arguments:
</ins><span class="cx"> 
</span><del>-    ```javascript
-    var colors = new Ember.Set();
-    colors.add(&quot;blue&quot;);     // [&quot;blue&quot;]
-    colors.add(&quot;blue&quot;);     // [&quot;blue&quot;]
-    colors.add(&quot;red&quot;);      // [&quot;blue&quot;, &quot;red&quot;]
-    colors.add(null);       // [&quot;blue&quot;, &quot;red&quot;]
-    colors.add(undefined);  // [&quot;blue&quot;, &quot;red&quot;]
-    ```
</del><ins>+    * {array} items The items for the given operation
+    * {number} offset The computed offset of the items, ie the index in the
+    array of the first item for this operation.
+    * {string} operation The type of the operation.  One of
+    `Ember.TrackedArray.{RETAIN, DELETE, INSERT}`
</ins><span class="cx"> 
</span><del>-    @method add
-    @param {Object} obj The object to add.
-    @return {Ember.Set} The set itself.
</del><ins>+    @method apply
+    @param {function} callback
</ins><span class="cx">   */
</span><del>-  add: Ember.aliasMethod('addObject'),
</del><ins>+  apply: function (callback) {
+    var items = [],
+        offset = 0;
</ins><span class="cx"> 
</span><del>-  /**
-    Removes the object from the set if it is found. If you pass a `null` value
-    or an object that is already not in the set, this method will have no
-    effect. This is an alias for `Ember.MutableEnumerable.removeObject()`.
</del><ins>+    forEach(this._operations, function (arrayOperation) {
+      callback(arrayOperation.items, offset, arrayOperation.type);
</ins><span class="cx"> 
</span><del>-    ```javascript
-    var colors = new Ember.Set([&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]);
-    colors.remove(&quot;red&quot;);     // [&quot;blue&quot;, &quot;green&quot;]
-    colors.remove(&quot;purple&quot;);  // [&quot;blue&quot;, &quot;green&quot;]
-    colors.remove(null);      // [&quot;blue&quot;, &quot;green&quot;]
-    ```
</del><ins>+      if (arrayOperation.type !== DELETE) {
+        offset += arrayOperation.count;
+        items = items.concat(arrayOperation.items);
+      }
+    });
</ins><span class="cx"> 
</span><del>-    @method remove
-    @param {Object} obj The object to remove
-    @return {Ember.Set} The set itself.
-  */
-  remove: Ember.aliasMethod('removeObject'),
-
-  /**
-    Removes the last element from the set and returns it, or `null` if it's empty.
-
-    ```javascript
-    var colors = new Ember.Set([&quot;green&quot;, &quot;blue&quot;]);
-    colors.pop();  // &quot;blue&quot;
-    colors.pop();  // &quot;green&quot;
-    colors.pop();  // null
-    ```
-
-    @method pop
-    @return {Object} The removed object from the set or null.
-  */
-  pop: function() {
-    if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
-    var obj = this.length &gt; 0 ? this[this.length-1] : null;
-    this.remove(obj);
-    return obj;
</del><ins>+    this._operations = [new ArrayOperation(RETAIN, items.length, items)];
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Inserts the given object on to the end of the set. It returns
-    the set itself.
</del><ins>+    Return an `ArrayOperationMatch` for the operation that contains the item at `index`.
</ins><span class="cx"> 
</span><del>-    This is an alias for `Ember.MutableEnumerable.addObject()`.
</del><ins>+    @method _findArrayOperation
</ins><span class="cx"> 
</span><del>-    ```javascript
-    var colors = new Ember.Set();
-    colors.push(&quot;red&quot;);   // [&quot;red&quot;]
-    colors.push(&quot;green&quot;); // [&quot;red&quot;, &quot;green&quot;]
-    colors.push(&quot;blue&quot;);  // [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]
-    ```
-
-    @method push
-    @return {Ember.Set} The set itself.
</del><ins>+    @param {number} index the index of the item whose operation information
+    should be returned.
+    @private
</ins><span class="cx">   */
</span><del>-  push: Ember.aliasMethod('addObject'),
</del><ins>+  _findArrayOperation: function (index) {
+    var arrayOperationIndex,
+        len,
+        split = false,
+        arrayOperation,
+        arrayOperationRangeStart,
+        arrayOperationRangeEnd;
</ins><span class="cx"> 
</span><del>-  /**
-    Removes the last element from the set and returns it, or `null` if it's empty.
</del><ins>+    // OPTIMIZE: we could search these faster if we kept a balanced tree.
+    // find leftmost arrayOperation to the right of `index`
+    for (arrayOperationIndex = arrayOperationRangeStart = 0, len = this._operations.length; arrayOperationIndex &lt; len; ++arrayOperationIndex) {
+      arrayOperation = this._operations[arrayOperationIndex];
</ins><span class="cx"> 
</span><del>-    This is an alias for `Ember.Set.pop()`.
</del><ins>+      if (arrayOperation.type === DELETE) { continue; }
</ins><span class="cx"> 
</span><del>-    ```javascript
-    var colors = new Ember.Set([&quot;green&quot;, &quot;blue&quot;]);
-    colors.shift();  // &quot;blue&quot;
-    colors.shift();  // &quot;green&quot;
-    colors.shift();  // null
-    ```
</del><ins>+      arrayOperationRangeEnd = arrayOperationRangeStart + arrayOperation.count - 1;
</ins><span class="cx"> 
</span><del>-    @method shift
-    @return {Object} The removed object from the set or null.
-  */
-  shift: Ember.aliasMethod('pop'),
</del><ins>+      if (index === arrayOperationRangeStart) {
+        break;
+      } else if (index &gt; arrayOperationRangeStart &amp;&amp; index &lt;= arrayOperationRangeEnd) {
+        split = true;
+        break;
+      } else {
+        arrayOperationRangeStart = arrayOperationRangeEnd + 1;
+      }
+    }
</ins><span class="cx"> 
</span><del>-  /**
-    Inserts the given object on to the end of the set. It returns
-    the set itself.
</del><ins>+    return new ArrayOperationMatch(arrayOperation, arrayOperationIndex, split, arrayOperationRangeStart);
+  },
</ins><span class="cx"> 
</span><del>-    This is an alias of `Ember.Set.push()`
</del><ins>+  _split: function (arrayOperationIndex, splitIndex, newArrayOperation) {
+    var arrayOperation = this._operations[arrayOperationIndex],
+        splitItems = arrayOperation.items.slice(splitIndex),
+        splitArrayOperation = new ArrayOperation(arrayOperation.type, splitItems.length, splitItems);
</ins><span class="cx"> 
</span><del>-    ```javascript
-    var colors = new Ember.Set();
-    colors.unshift(&quot;red&quot;);    // [&quot;red&quot;]
-    colors.unshift(&quot;green&quot;);  // [&quot;red&quot;, &quot;green&quot;]
-    colors.unshift(&quot;blue&quot;);   // [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]
-    ```
</del><ins>+    // truncate LHS
+    arrayOperation.count = splitIndex;
+    arrayOperation.items = arrayOperation.items.slice(0, splitIndex);
</ins><span class="cx"> 
</span><del>-    @method unshift
-    @return {Ember.Set} The set itself.
-  */
-  unshift: Ember.aliasMethod('push'),
</del><ins>+    this._operations.splice(arrayOperationIndex + 1, 0, newArrayOperation, splitArrayOperation);
+  },
</ins><span class="cx"> 
</span><del>-  /**
-    Adds each object in the passed enumerable to the set.
</del><ins>+  // see SubArray for a better implementation.
+  _composeInsert: function (index) {
+    var newArrayOperation = this._operations[index],
+        leftArrayOperation = this._operations[index-1], // may be undefined
+        rightArrayOperation = this._operations[index+1], // may be undefined
+        leftOp = leftArrayOperation &amp;&amp; leftArrayOperation.type,
+        rightOp = rightArrayOperation &amp;&amp; rightArrayOperation.type;
</ins><span class="cx"> 
</span><del>-    This is an alias of `Ember.MutableEnumerable.addObjects()`
</del><ins>+    if (leftOp === INSERT) {
+        // merge left
+        leftArrayOperation.count += newArrayOperation.count;
+        leftArrayOperation.items = leftArrayOperation.items.concat(newArrayOperation.items);
</ins><span class="cx"> 
</span><del>-    ```javascript
-    var colors = new Ember.Set();
-    colors.addEach([&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]);  // [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]
-    ```
-
-    @method addEach
-    @param {Ember.Enumerable} objects the objects to add.
-    @return {Ember.Set} The set itself.
-  */
-  addEach: Ember.aliasMethod('addObjects'),
-
-  /**
-    Removes each object in the passed enumerable to the set.
-
-    This is an alias of `Ember.MutableEnumerable.removeObjects()`
-
-    ```javascript
-    var colors = new Ember.Set([&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]);
-    colors.removeEach([&quot;red&quot;, &quot;blue&quot;]);  //  [&quot;green&quot;]
-    ```
-
-    @method removeEach
-    @param {Ember.Enumerable} objects the objects to remove.
-    @return {Ember.Set} The set itself.
-  */
-  removeEach: Ember.aliasMethod('removeObjects'),
-
-  // ..........................................................
-  // PRIVATE ENUMERABLE SUPPORT
-  //
-
-  init: function(items) {
-    this._super();
-    if (items) this.addObjects(items);
</del><ins>+      if (rightOp === INSERT) {
+        // also merge right (we have split an insert with an insert)
+        leftArrayOperation.count += rightArrayOperation.count;
+        leftArrayOperation.items = leftArrayOperation.items.concat(rightArrayOperation.items);
+        this._operations.splice(index, 2);
+      } else {
+        // only merge left
+        this._operations.splice(index, 1);
+      }
+    } else if (rightOp === INSERT) {
+      // merge right
+      newArrayOperation.count += rightArrayOperation.count;
+      newArrayOperation.items = newArrayOperation.items.concat(rightArrayOperation.items);
+      this._operations.splice(index + 1, 1);
+    }
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  // implement Ember.Enumerable
-  nextObject: function(idx) {
-    return this[idx];
-  },
</del><ins>+  _composeDelete: function (index) {
+    var arrayOperation = this._operations[index],
+        deletesToGo = arrayOperation.count,
+        leftArrayOperation = this._operations[index-1], // may be undefined
+        leftOp = leftArrayOperation &amp;&amp; leftArrayOperation.type,
+        nextArrayOperation,
+        nextOp,
+        nextCount,
+        removeNewAndNextOp = false,
+        removedItems = [];
</ins><span class="cx"> 
</span><del>-  // more optimized version
-  firstObject: Ember.computed(function() {
-    return this.length &gt; 0 ? this[0] : undefined;
-  }),
</del><ins>+    if (leftOp === DELETE) {
+      arrayOperation = leftArrayOperation;
+      index -= 1;
+    }
</ins><span class="cx"> 
</span><del>-  // more optimized version
-  lastObject: Ember.computed(function() {
-    return this.length &gt; 0 ? this[this.length-1] : undefined;
-  }),
</del><ins>+    for (var i = index + 1; deletesToGo &gt; 0; ++i) {
+      nextArrayOperation = this._operations[i];
+      nextOp = nextArrayOperation.type;
+      nextCount = nextArrayOperation.count;
</ins><span class="cx"> 
</span><del>-  // implements Ember.MutableEnumerable
-  addObject: function(obj) {
-    if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
-    if (none(obj)) return this; // nothing to do
</del><ins>+      if (nextOp === DELETE) {
+        arrayOperation.count += nextCount;
+        continue;
+      }
</ins><span class="cx"> 
</span><del>-    var guid = guidFor(obj),
-        idx  = this[guid],
-        len  = get(this, 'length'),
-        added ;
</del><ins>+      if (nextCount &gt; deletesToGo) {
+        // d:2 {r,i}:5  we reduce the retain or insert, but it stays
+        removedItems = removedItems.concat(nextArrayOperation.items.splice(0, deletesToGo));
+        nextArrayOperation.count -= deletesToGo;
</ins><span class="cx"> 
</span><del>-    if (idx&gt;=0 &amp;&amp; idx&lt;len &amp;&amp; (this[idx] === obj)) return this; // added
</del><ins>+        // In the case where we truncate the last arrayOperation, we don't need to
+        // remove it; also the deletesToGo reduction is not the entirety of
+        // nextCount
+        i -= 1;
+        nextCount = deletesToGo;
</ins><span class="cx"> 
</span><del>-    added = [obj];
</del><ins>+        deletesToGo = 0;
+      } else {
+        if (nextCount === deletesToGo) {
+          // Handle edge case of d:2 i:2 in which case both operations go away
+          // during composition.
+          removeNewAndNextOp = true;
+        }
+        removedItems = removedItems.concat(nextArrayOperation.items);
+        deletesToGo -= nextCount;
+      }
</ins><span class="cx"> 
</span><del>-    this.enumerableContentWillChange(null, added);
-    Ember.propertyWillChange(this, 'lastObject');
-
-    len = get(this, 'length');
-    this[guid] = len;
-    this[len] = obj;
-    set(this, 'length', len+1);
-
-    Ember.propertyDidChange(this, 'lastObject');
-    this.enumerableContentDidChange(null, added);
-
-    return this;
-  },
-
-  // implements Ember.MutableEnumerable
-  removeObject: function(obj) {
-    if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
-    if (none(obj)) return this; // nothing to do
-
-    var guid = guidFor(obj),
-        idx  = this[guid],
-        len = get(this, 'length'),
-        isFirst = idx === 0,
-        isLast = idx === len-1,
-        last, removed;
-
-
-    if (idx&gt;=0 &amp;&amp; idx&lt;len &amp;&amp; (this[idx] === obj)) {
-      removed = [obj];
-
-      this.enumerableContentWillChange(removed, null);
-      if (isFirst) { Ember.propertyWillChange(this, 'firstObject'); }
-      if (isLast)  { Ember.propertyWillChange(this, 'lastObject'); }
-
-      // swap items - basically move the item to the end so it can be removed
-      if (idx &lt; len-1) {
-        last = this[len-1];
-        this[idx] = last;
-        this[guidFor(last)] = idx;
</del><ins>+      if (nextOp === INSERT) {
+        // d:2 i:3 will result in delete going away
+        arrayOperation.count -= nextCount;
</ins><span class="cx">       }
</span><ins>+    }
</ins><span class="cx"> 
</span><del>-      delete this[guid];
-      delete this[len-1];
-      set(this, 'length', len-1);
-
-      if (isFirst) { Ember.propertyDidChange(this, 'firstObject'); }
-      if (isLast)  { Ember.propertyDidChange(this, 'lastObject'); }
-      this.enumerableContentDidChange(removed, null);
</del><ins>+    if (arrayOperation.count &gt; 0) {
+      // compose our new delete with possibly several operations to the right of
+      // disparate types
+      this._operations.splice(index+1, i-1-index);
+    } else {
+      // The delete operation can go away; it has merely reduced some other
+      // operation, as in d:3 i:4; it may also have eliminated that operation,
+      // as in d:3 i:3.
+      this._operations.splice(index, removeNewAndNextOp ? 2 : 1);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return this;
</del><ins>+    return removedItems;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  // optimized version
-  contains: function(obj) {
-    return this[guidFor(obj)]&gt;=0;
-  },
-
-  copy: function() {
-    var C = this.constructor, ret = new C(), loc = get(this, 'length');
-    set(ret, 'length', loc);
-    while(--loc&gt;=0) {
-      ret[loc] = this[loc];
-      ret[guidFor(this[loc])] = loc;
-    }
-    return ret;
-  },
-
-  toString: function() {
-    var len = this.length, idx, array = [];
-    for(idx = 0; idx &lt; len; idx++) {
-      array[idx] = this[idx];
-    }
-    return &quot;Ember.Set&lt;%@&gt;&quot;.fmt(array.join(','));
</del><ins>+  toString: function () {
+    var str = &quot;&quot;;
+    forEach(this._operations, function (operation) {
+      str += &quot; &quot; + operation.type + &quot;:&quot; + operation.count;
+    });
+    return str.substring(1);
</ins><span class="cx">   }
</span><ins>+};
</ins><span class="cx"> 
</span><del>-});
</del><ins>+/**
+  Internal data structure to represent an array operation.
</ins><span class="cx"> 
</span><del>-})();
-
-
-
-(function() {
-/**
-@module ember
-@submodule ember-runtime
</del><ins>+  @method ArrayOperation
+  @private
+  @param {string} type The type of the operation.  One of
+  `Ember.TrackedArray.{RETAIN, INSERT, DELETE}`
+  @param {number} count The number of items in this operation.
+  @param {array} items The items of the operation, if included.  RETAIN and
+  INSERT include their items, DELETE does not.
</ins><span class="cx"> */
</span><ins>+function ArrayOperation (operation, count, items) {
+  this.type = operation; // RETAIN | INSERT | DELETE
+  this.count = count;
+  this.items = items;
+}
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  `Ember.Object` is the main base class for all Ember objects. It is a subclass
-  of `Ember.CoreObject` with the `Ember.Observable` mixin applied. For details,
-  see the documentation for each of these.
</del><ins>+  Internal data structure used to include information when looking up operations
+  by item index.
</ins><span class="cx"> 
</span><del>-  @class Object
-  @namespace Ember
-  @extends Ember.CoreObject
-  @uses Ember.Observable
</del><ins>+  @method ArrayOperationMatch
+  @private
+  @param {ArrayOperation} operation
+  @param {number} index The index of `operation` in the array of operations.
+  @param {boolean} split Whether or not the item index searched for would
+  require a split for a new operation type.
+  @param {number} rangeStart The index of the first item in the operation,
+  with respect to the tracked array.  The index of the last item can be computed
+  from `rangeStart` and `operation.count`.
</ins><span class="cx"> */
</span><del>-Ember.Object = Ember.CoreObject.extend(Ember.Observable);
-Ember.Object.toString = function() { return &quot;Ember.Object&quot;; };
</del><ins>+function ArrayOperationMatch(operation, index, split, rangeStart) {
+  this.operation = operation;
+  this.index = index;
+  this.split = split;
+  this.rangeStart = rangeStart;
+}
</ins><span class="cx"> 
</span><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-/**
-@module ember
-@submodule ember-runtime
-*/
</del><ins>+var get = Ember.get,
+    forEach = Ember.EnumerableUtils.forEach,
+    RETAIN = 'r',
+    FILTER = 'f';
</ins><span class="cx"> 
</span><del>-var get = Ember.get, indexOf = Ember.ArrayPolyfills.indexOf;
</del><ins>+function Operation (type, count) {
+  this.type = type;
+  this.count = count;
+}
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  A Namespace is an object usually used to contain other objects or methods
-  such as an application or framework. Create a namespace anytime you want
-  to define one of these new containers.
</del><ins>+  An `Ember.SubArray` tracks an array in a way similar to, but more specialized
+  than, `Ember.TrackedArray`.  It is useful for keeping track of the indexes of
+  items within a filtered array.
</ins><span class="cx"> 
</span><del>-  # Example Usage
-
-  ```javascript
-  MyFramework = Ember.Namespace.create({
-    VERSION: '1.0.0'
-  });
-  ```
-
-  @class Namespace
</del><ins>+  @class SubArray
</ins><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Object
</del><span class="cx"> */
</span><del>-var Namespace = Ember.Namespace = Ember.Object.extend({
-  isNamespace: true,
</del><ins>+Ember.SubArray = function (length) {
+  if (arguments.length &lt; 1) { length = 0; }
</ins><span class="cx"> 
</span><del>-  init: function() {
-    Ember.Namespace.NAMESPACES.push(this);
-    Ember.Namespace.PROCESSED = false;
-  },
-
-  toString: function() {
-    var name = get(this, 'name');
-    if (name) { return name; }
-
-    findNamespaces();
-    return this[Ember.GUID_KEY+'_name'];
-  },
-
-  nameClasses: function() {
-    processNamespace([this.toString()], this, {});
-  },
-
-  destroy: function() {
-    var namespaces = Ember.Namespace.NAMESPACES;
-    Ember.lookup[this.toString()] = undefined;
-    namespaces.splice(indexOf.call(namespaces, this), 1);
-    this._super();
</del><ins>+  if (length &gt; 0) {
+    this._operations = [new Operation(RETAIN, length)];
+  } else {
+    this._operations = [];
</ins><span class="cx">   }
</span><del>-});
</del><ins>+};
</ins><span class="cx"> 
</span><del>-Namespace.reopenClass({
-  NAMESPACES: [Ember],
-  NAMESPACES_BY_ID: {},
-  PROCESSED: false,
-  processAll: processAllNamespaces,
-  byName: function(name) {
-    if (!Ember.BOOTED) {
-      processAllNamespaces();
-    }
</del><ins>+Ember.SubArray.prototype = {
+  /**
+    Track that an item was added to the tracked array.
</ins><span class="cx"> 
</span><del>-    return NAMESPACES_BY_ID[name];
-  }
-});
</del><ins>+    @method addItem
</ins><span class="cx"> 
</span><del>-var NAMESPACES_BY_ID = Namespace.NAMESPACES_BY_ID;
</del><ins>+    @param {number} index The index of the item in the tracked array.
+    @param {boolean} match `true` iff the item is included in the subarray.
</ins><span class="cx"> 
</span><del>-var hasOwnProp = ({}).hasOwnProperty,
-    guidFor = Ember.guidFor;
</del><ins>+    @return {number} The index of the item in the subarray.
+  */
+  addItem: function(index, match) {
+    var returnValue = -1,
+        itemType = match ? RETAIN : FILTER,
+        self = this;
</ins><span class="cx"> 
</span><del>-function processNamespace(paths, root, seen) {
-  var idx = paths.length;
</del><ins>+    this._findOperation(index, function(operation, operationIndex, rangeStart, rangeEnd, seenInSubArray) {
+      var newOperation, splitOperation;
</ins><span class="cx"> 
</span><del>-  NAMESPACES_BY_ID[paths.join('.')] = root;
</del><ins>+      if (itemType === operation.type) {
+        ++operation.count;
+      } else if (index === rangeStart) {
+        // insert to the left of `operation`
+        self._operations.splice(operationIndex, 0, new Operation(itemType, 1));
+      } else {
+        newOperation = new Operation(itemType, 1);
+        splitOperation = new Operation(operation.type, rangeEnd - index + 1);
+        operation.count = index - rangeStart;
</ins><span class="cx"> 
</span><del>-  // Loop over all of the keys in the namespace, looking for classes
-  for(var key in root) {
-    if (!hasOwnProp.call(root, key)) { continue; }
-    var obj = root[key];
</del><ins>+        self._operations.splice(operationIndex + 1, 0, newOperation, splitOperation);
+      }
</ins><span class="cx"> 
</span><del>-    // If we are processing the `Ember` namespace, for example, the
-    // `paths` will start with `[&quot;Ember&quot;]`. Every iteration through
-    // the loop will update the **second** element of this list with
-    // the key, so processing `Ember.View` will make the Array
-    // `['Ember', 'View']`.
-    paths[idx] = key;
</del><ins>+      if (match) {
+        if (operation.type === RETAIN) {
+          returnValue = seenInSubArray + (index - rangeStart);
+        } else {
+          returnValue = seenInSubArray;
+        }
+      }
</ins><span class="cx"> 
</span><del>-    // If we have found an unprocessed class
-    if (obj &amp;&amp; obj.toString === classToString) {
-      // Replace the class' `toString` with the dot-separated path
-      // and set its `NAME_KEY`
-      obj.toString = makeToString(paths.join('.'));
-      obj[NAME_KEY] = paths.join('.');
</del><ins>+      self._composeAt(operationIndex);
+    }, function(seenInSubArray) {
+      self._operations.push(new Operation(itemType, 1));
</ins><span class="cx"> 
</span><del>-    // Support nested namespaces
-    } else if (obj &amp;&amp; obj.isNamespace) {
-      // Skip aliased namespaces
-      if (seen[guidFor(obj)]) { continue; }
-      seen[guidFor(obj)] = true;
</del><ins>+      if (match) {
+        returnValue = seenInSubArray;
+      }
</ins><span class="cx"> 
</span><del>-      // Process the child namespace
-      processNamespace(paths, obj, seen);
-    }
-  }
</del><ins>+      self._composeAt(self._operations.length-1);
+    });
</ins><span class="cx"> 
</span><del>-  paths.length = idx; // cut out last item
-}
</del><ins>+    return returnValue;
+  },
</ins><span class="cx"> 
</span><del>-function findNamespaces() {
-  var Namespace = Ember.Namespace, lookup = Ember.lookup, obj, isNamespace;
</del><ins>+  /**
+    Track that an item was removed from the tracked array.
</ins><span class="cx"> 
</span><del>-  if (Namespace.PROCESSED) { return; }
</del><ins>+    @method removeItem
</ins><span class="cx"> 
</span><del>-  for (var prop in lookup) {
-    // These don't raise exceptions but can cause warnings
-    if (prop === &quot;parent&quot; || prop === &quot;top&quot; || prop === &quot;frameElement&quot;) { continue; }
</del><ins>+    @param {number} index The index of the item in the tracked array.
</ins><span class="cx"> 
</span><del>-    //  get(window.globalStorage, 'isNamespace') would try to read the storage for domain isNamespace and cause exception in Firefox.
-    // globalStorage is a storage obsoleted by the WhatWG storage specification. See https://developer.mozilla.org/en/DOM/Storage#globalStorage
-    if (prop === &quot;globalStorage&quot; &amp;&amp; lookup.StorageList &amp;&amp; lookup.globalStorage instanceof lookup.StorageList) { continue; }
-    // Unfortunately, some versions of IE don't support window.hasOwnProperty
-    if (lookup.hasOwnProperty &amp;&amp; !lookup.hasOwnProperty(prop)) { continue; }
</del><ins>+    @return {number} The index of the item in the subarray, or `-1` if the item
+    was not in the subarray.
+  */
+  removeItem: function(index) {
+    var returnValue = -1,
+        self = this;
</ins><span class="cx"> 
</span><del>-    // At times we are not allowed to access certain properties for security reasons.
-    // There are also times where even if we can access them, we are not allowed to access their properties.
-    try {
-      obj = Ember.lookup[prop];
-      isNamespace = obj &amp;&amp; obj.isNamespace;
-    } catch (e) {
-      continue;
-    }
</del><ins>+    this._findOperation(index, function (operation, operationIndex, rangeStart, rangeEnd, seenInSubArray) {
+      if (operation.type === RETAIN) {
+        returnValue = seenInSubArray + (index - rangeStart);
+      }
</ins><span class="cx"> 
</span><del>-    if (isNamespace) {
-      Ember.deprecate(&quot;Namespaces should not begin with lowercase.&quot;, /^[A-Z]/.test(prop));
-      obj[NAME_KEY] = prop;
-    }
-  }
-}
</del><ins>+      if (operation.count &gt; 1) {
+        --operation.count;
+      } else {
+        self._operations.splice(operationIndex, 1);
+        self._composeAt(operationIndex);
+      }
+    }, function() {
+      throw new Ember.Error(&quot;Can't remove an item that has never been added.&quot;);
+    });
</ins><span class="cx"> 
</span><del>-var NAME_KEY = Ember.NAME_KEY = Ember.GUID_KEY + '_name';
</del><ins>+    return returnValue;
+  },
</ins><span class="cx"> 
</span><del>-function superClassString(mixin) {
-  var superclass = mixin.superclass;
-  if (superclass) {
-    if (superclass[NAME_KEY]) { return superclass[NAME_KEY]; }
-    else { return superClassString(superclass); }
-  } else {
-    return;
-  }
-}
</del><span class="cx"> 
</span><del>-function classToString() {
-  if (!Ember.BOOTED &amp;&amp; !this[NAME_KEY]) {
-    processAllNamespaces();
-  }
</del><ins>+  _findOperation: function (index, foundCallback, notFoundCallback) {
+    var operationIndex,
+        len,
+        operation,
+        rangeStart,
+        rangeEnd,
+        seenInSubArray = 0;
</ins><span class="cx"> 
</span><del>-  var ret;
</del><ins>+    // OPTIMIZE: change to balanced tree
+    // find leftmost operation to the right of `index`
+    for (operationIndex = rangeStart = 0, len = this._operations.length; operationIndex &lt; len; rangeStart = rangeEnd + 1, ++operationIndex) {
+      operation = this._operations[operationIndex];
+      rangeEnd = rangeStart + operation.count - 1;
</ins><span class="cx"> 
</span><del>-  if (this[NAME_KEY]) {
-    ret = this[NAME_KEY];
-  } else {
-    var str = superClassString(this);
-    if (str) {
-      ret = &quot;(subclass of &quot; + str + &quot;)&quot;;
-    } else {
-      ret = &quot;(unknown mixin)&quot;;
</del><ins>+      if (index &gt;= rangeStart &amp;&amp; index &lt;= rangeEnd) {
+        foundCallback(operation, operationIndex, rangeStart, rangeEnd, seenInSubArray);
+        return;
+      } else if (operation.type === RETAIN) {
+        seenInSubArray += operation.count;
+      }
</ins><span class="cx">     }
</span><del>-    this.toString = makeToString(ret);
-  }
</del><span class="cx"> 
</span><del>-  return ret;
-}
</del><ins>+    notFoundCallback(seenInSubArray);
+  },
</ins><span class="cx"> 
</span><del>-function processAllNamespaces() {
-  var unprocessedNamespaces = !Namespace.PROCESSED,
-      unprocessedMixins = Ember.anyUnprocessedMixins;
</del><ins>+  _composeAt: function(index) {
+    var op = this._operations[index],
+        otherOp;
</ins><span class="cx"> 
</span><del>-  if (unprocessedNamespaces) {
-    findNamespaces();
-    Namespace.PROCESSED = true;
-  }
</del><ins>+    if (!op) {
+      // Composing out of bounds is a no-op, as when removing the last operation
+      // in the list.
+      return;
+    }
</ins><span class="cx"> 
</span><del>-  if (unprocessedNamespaces || unprocessedMixins) {
-    var namespaces = Namespace.NAMESPACES, namespace;
-    for (var i=0, l=namespaces.length; i&lt;l; i++) {
-      namespace = namespaces[i];
-      processNamespace([namespace.toString()], namespace, {});
</del><ins>+    if (index &gt; 0) {
+      otherOp = this._operations[index-1];
+      if (otherOp.type === op.type) {
+        op.count += otherOp.count;
+        this._operations.splice(index-1, 1);
+        --index;
+      }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Ember.anyUnprocessedMixins = false;
</del><ins>+    if (index &lt; this._operations.length-1) {
+      otherOp = this._operations[index+1];
+      if (otherOp.type === op.type) {
+        op.count += otherOp.count;
+        this._operations.splice(index+1, 1);
+      }
+    }
+  },
+
+  toString: function () {
+    var str = &quot;&quot;;
+    forEach(this._operations, function (operation) {
+      str += &quot; &quot; + operation.type + &quot;:&quot; + operation.count;
+    });
+    return str.substring(1);
</ins><span class="cx">   }
</span><del>-}
</del><ins>+};
</ins><span class="cx"> 
</span><del>-function makeToString(ret) {
-  return function() { return ret; };
-}
-
-Ember.Mixin.prototype.toString = classToString;
-
</del><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-/**
-@module ember
-@submodule ember-runtime
-*/
</del><ins>+Ember.Container = requireModule('container');
+Ember.Container.set = Ember.set;
</ins><span class="cx"> 
</span><del>-/**
-  Defines a namespace that will contain an executable application. This is
-  very similar to a normal namespace except that it is expected to include at
-  least a 'ready' function which can be run to initialize the application.
</del><ins>+})();
</ins><span class="cx"> 
</span><del>-  Currently `Ember.Application` is very similar to `Ember.Namespace.`  However,
-  this class may be augmented by additional frameworks so it is important to
-  use this instance when building new applications.
</del><span class="cx"> 
</span><del>-  # Example Usage
</del><span class="cx"> 
</span><del>-  ```javascript
-  MyApp = Ember.Application.create({
-    VERSION: '1.0.0',
-    store: Ember.Store.create().from(Ember.fixtures)
-  });
-
-  MyApp.ready = function() {
-    //..init code goes here...
-  }
-  ```
-
-  @class Application
-  @namespace Ember
-  @extends Ember.Namespace
-*/
</del><ins>+(function() {
</ins><span class="cx"> Ember.Application = Ember.Namespace.extend();
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -11166,6 +18691,8 @@
</span><span class="cx"> @submodule ember-runtime
</span><span class="cx"> */
</span><span class="cx"> 
</span><ins>+var OUT_OF_RANGE_EXCEPTION = &quot;Index out of range&quot;;
+var EMPTY = [];
</ins><span class="cx"> 
</span><span class="cx"> var get = Ember.get, set = Ember.set;
</span><span class="cx"> 
</span><span class="lines">@@ -11207,8 +18734,7 @@
</span><span class="cx">   @extends Ember.Object
</span><span class="cx">   @uses Ember.MutableArray
</span><span class="cx"> */
</span><del>-Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,
-/** @scope Ember.ArrayProxy.prototype */ {
</del><ins>+Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray, {
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     The content array. Must be an object that implements `Ember.Array` and/or
</span><span class="lines">@@ -11262,16 +18788,15 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Invoked when the content property is about to change. Notifies observers that the
</span><span class="cx">     entire array content will change.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method _contentWillChange
</span><span class="cx">   */
</span><del>-  _contentWillChange: Ember.beforeObserver(function() {
</del><ins>+  _contentWillChange: Ember.beforeObserver('content', function() {
</ins><span class="cx">     this._teardownContent();
</span><del>-  }, 'content'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><span class="cx">   _teardownContent: function() {
</span><span class="cx">     var content = get(this, 'content');
</span><span class="lines">@@ -11288,20 +18813,19 @@
</span><span class="cx">   contentArrayDidChange: Ember.K,
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Invoked when the content property changes. Notifies observers that the
</span><span class="cx">     entire array content has changed.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method _contentDidChange
</span><span class="cx">   */
</span><del>-  _contentDidChange: Ember.observer(function() {
</del><ins>+  _contentDidChange: Ember.observer('content', function() {
</ins><span class="cx">     var content = get(this, 'content');
</span><span class="cx"> 
</span><span class="cx">     Ember.assert(&quot;Can't set ArrayProxy's content to itself&quot;, content !== this);
</span><span class="cx"> 
</span><span class="cx">     this._setupContent();
</span><del>-  }, 'content'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><span class="cx">   _setupContent: function() {
</span><span class="cx">     var content = get(this, 'content');
</span><span class="lines">@@ -11314,7 +18838,7 @@
</span><span class="cx">     }
</span><span class="cx">   },
</span><span class="cx"> 
</span><del>-  _arrangedContentWillChange: Ember.beforeObserver(function() {
</del><ins>+  _arrangedContentWillChange: Ember.beforeObserver('arrangedContent', function() {
</ins><span class="cx">     var arrangedContent = get(this, 'arrangedContent'),
</span><span class="cx">         len = arrangedContent ? get(arrangedContent, 'length') : 0;
</span><span class="cx"> 
</span><span class="lines">@@ -11322,9 +18846,9 @@
</span><span class="cx">     this.arrangedContentWillChange(this);
</span><span class="cx"> 
</span><span class="cx">     this._teardownArrangedContent(arrangedContent);
</span><del>-  }, 'arrangedContent'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><del>-  _arrangedContentDidChange: Ember.observer(function() {
</del><ins>+  _arrangedContentDidChange: Ember.observer('arrangedContent', function() {
</ins><span class="cx">     var arrangedContent = get(this, 'arrangedContent'),
</span><span class="cx">         len = arrangedContent ? get(arrangedContent, 'length') : 0;
</span><span class="cx"> 
</span><span class="lines">@@ -11334,7 +18858,7 @@
</span><span class="cx"> 
</span><span class="cx">     this.arrangedContentDidChange(this);
</span><span class="cx">     this.arrangedContentArrayDidChange(this, 0, undefined, len);
</span><del>-  }, 'arrangedContent'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><span class="cx">   _setupArrangedContent: function() {
</span><span class="cx">     var arrangedContent = get(this, 'arrangedContent');
</span><span class="lines">@@ -11371,173 +18895,119 @@
</span><span class="cx">     // No dependencies since Enumerable notifies length of change
</span><span class="cx">   }),
</span><span class="cx"> 
</span><del>-  replace: function(idx, amt, objects) {
-    Ember.assert('The content property of '+ this.constructor + ' should be set before modifying it', this.get('content'));
-    if (get(this, 'content')) this.replaceContent(idx, amt, objects);
</del><ins>+  _replace: function(idx, amt, objects) {
+    var content = get(this, 'content');
+    Ember.assert('The content property of '+ this.constructor + ' should be set before modifying it', content);
+    if (content) this.replaceContent(idx, amt, objects);
</ins><span class="cx">     return this;
</span><span class="cx">   },
</span><span class="cx"> 
</span><del>-  arrangedContentArrayWillChange: function(item, idx, removedCnt, addedCnt) {
-    this.arrayContentWillChange(idx, removedCnt, addedCnt);
</del><ins>+  replace: function() {
+    if (get(this, 'arrangedContent') === get(this, 'content')) {
+      this._replace.apply(this, arguments);
+    } else {
+      throw new Ember.Error(&quot;Using replace on an arranged ArrayProxy is not allowed.&quot;);
+    }
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  arrangedContentArrayDidChange: function(item, idx, removedCnt, addedCnt) {
-    this.arrayContentDidChange(idx, removedCnt, addedCnt);
</del><ins>+  _insertAt: function(idx, object) {
+    if (idx &gt; get(this, 'content.length')) throw new Ember.Error(OUT_OF_RANGE_EXCEPTION);
+    this._replace(idx, 0, [object]);
+    return this;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  init: function() {
-    this._super();
-    this._setupContent();
-    this._setupArrangedContent();
</del><ins>+  insertAt: function(idx, object) {
+    if (get(this, 'arrangedContent') === get(this, 'content')) {
+      return this._insertAt(idx, object);
+    } else {
+      throw new Ember.Error(&quot;Using insertAt on an arranged ArrayProxy is not allowed.&quot;);
+    }
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  willDestroy: function() {
-    this._teardownArrangedContent();
-    this._teardownContent();
-  }
-});
</del><ins>+  removeAt: function(start, len) {
+    if ('number' === typeof start) {
+      var content = get(this, 'content'),
+          arrangedContent = get(this, 'arrangedContent'),
+          indices = [], i;
</ins><span class="cx"> 
</span><ins>+      if ((start &lt; 0) || (start &gt;= get(this, 'length'))) {
+        throw new Ember.Error(OUT_OF_RANGE_EXCEPTION);
+      }
</ins><span class="cx"> 
</span><del>-})();
</del><ins>+      if (len === undefined) len = 1;
</ins><span class="cx"> 
</span><ins>+      // Get a list of indices in original content to remove
+      for (i=start; i&lt;start+len; i++) {
+        // Use arrangedContent here so we avoid confusion with objects transformed by objectAtContent
+        indices.push(content.indexOf(arrangedContent.objectAt(i)));
+      }
</ins><span class="cx"> 
</span><ins>+      // Replace in reverse order since indices will change
+      indices.sort(function(a,b) { return b - a; });
</ins><span class="cx"> 
</span><del>-(function() {
-/**
-@module ember
-@submodule ember-runtime
-*/
-
-var get = Ember.get,
-    set = Ember.set,
-    fmt = Ember.String.fmt,
-    addBeforeObserver = Ember.addBeforeObserver,
-    addObserver = Ember.addObserver,
-    removeBeforeObserver = Ember.removeBeforeObserver,
-    removeObserver = Ember.removeObserver,
-    propertyWillChange = Ember.propertyWillChange,
-    propertyDidChange = Ember.propertyDidChange;
-
-function contentPropertyWillChange(content, contentKey) {
-  var key = contentKey.slice(8); // remove &quot;content.&quot;
-  if (key in this) { return; }  // if shadowed in proxy
-  propertyWillChange(this, key);
-}
-
-function contentPropertyDidChange(content, contentKey) {
-  var key = contentKey.slice(8); // remove &quot;content.&quot;
-  if (key in this) { return; } // if shadowed in proxy
-  propertyDidChange(this, key);
-}
-
-/**
-  `Ember.ObjectProxy` forwards all properties not defined by the proxy itself
-  to a proxied `content` object.
-
-  ```javascript
-  object = Ember.Object.create({
-    name: 'Foo'
-  });
-
-  proxy = Ember.ObjectProxy.create({
-    content: object
-  });
-
-  // Access and change existing properties
-  proxy.get('name')          // 'Foo'
-  proxy.set('name', 'Bar');
-  object.get('name')         // 'Bar'
-
-  // Create new 'description' property on `object`
-  proxy.set('description', 'Foo is a whizboo baz');
-  object.get('description')  // 'Foo is a whizboo baz'
-  ```
-
-  While `content` is unset, setting a property to be delegated will throw an
-  Error.
-
-  ```javascript
-  proxy = Ember.ObjectProxy.create({
-    content: null,
-    flag: null
-  });
-  proxy.set('flag', true);
-  proxy.get('flag');         // true
-  proxy.get('foo');          // undefined
-  proxy.set('foo', 'data');  // throws Error
-  ```
-
-  Delegated properties can be bound to and will change when content is updated.
-
-  Computed properties on the proxy itself can depend on delegated properties.
-
-  ```javascript
-  ProxyWithComputedProperty = Ember.ObjectProxy.extend({
-    fullName: function () {
-      var firstName = this.get('firstName'),
-          lastName = this.get('lastName');
-      if (firstName &amp;&amp; lastName) {
-        return firstName + ' ' + lastName;
</del><ins>+      Ember.beginPropertyChanges();
+      for (i=0; i&lt;indices.length; i++) {
+        this._replace(indices[i], 1, EMPTY);
</ins><span class="cx">       }
</span><del>-      return firstName || lastName;
-    }.property('firstName', 'lastName')
-  });
</del><ins>+      Ember.endPropertyChanges();
+    }
</ins><span class="cx"> 
</span><del>-  proxy = ProxyWithComputedProperty.create();
</del><ins>+    return this ;
+  },
</ins><span class="cx"> 
</span><del>-  proxy.get('fullName');  // undefined
-  proxy.set('content', {
-    firstName: 'Tom', lastName: 'Dale'
-  }); // triggers property change for fullName on proxy
</del><ins>+  pushObject: function(obj) {
+    this._insertAt(get(this, 'content.length'), obj) ;
+    return obj ;
+  },
</ins><span class="cx"> 
</span><del>-  proxy.get('fullName');  // 'Tom Dale'
-  ```
</del><ins>+  pushObjects: function(objects) {
+    if (!(Ember.Enumerable.detect(objects) || Ember.isArray(objects))) {
+      throw new TypeError(&quot;Must pass Ember.Enumerable to Ember.MutableArray#pushObjects&quot;);
+    }
+    this._replace(get(this, 'length'), 0, objects);
+    return this;
+  },
</ins><span class="cx"> 
</span><del>-  @class ObjectProxy
-  @namespace Ember
-  @extends Ember.Object
-*/
-Ember.ObjectProxy = Ember.Object.extend(
-/** @scope Ember.ObjectProxy.prototype */ {
-  /**
-    The object whose properties will be forwarded.
</del><ins>+  setObjects: function(objects) {
+    if (objects.length === 0) return this.clear();
</ins><span class="cx"> 
</span><del>-    @property content
-    @type Ember.Object
-    @default null
-  */
-  content: null,
-  _contentDidChange: Ember.observer(function() {
-    Ember.assert(&quot;Can't set ObjectProxy's content to itself&quot;, this.get('content') !== this);
-  }, 'content'),
</del><ins>+    var len = get(this, 'length');
+    this._replace(0, len, objects);
+    return this;
+  },
</ins><span class="cx"> 
</span><del>-  isTruthy: Ember.computed.bool('content'),
</del><ins>+  unshiftObject: function(obj) {
+    this._insertAt(0, obj) ;
+    return obj ;
+  },
</ins><span class="cx"> 
</span><del>-  _debugContainerKey: null,
</del><ins>+  unshiftObjects: function(objects) {
+    this._replace(0, 0, objects);
+    return this;
+  },
</ins><span class="cx"> 
</span><del>-  willWatchProperty: function (key) {
-    var contentKey = 'content.' + key;
-    addBeforeObserver(this, contentKey, null, contentPropertyWillChange);
-    addObserver(this, contentKey, null, contentPropertyDidChange);
</del><ins>+  slice: function() {
+    var arr = this.toArray();
+    return arr.slice.apply(arr, arguments);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  didUnwatchProperty: function (key) {
-    var contentKey = 'content.' + key;
-    removeBeforeObserver(this, contentKey, null, contentPropertyWillChange);
-    removeObserver(this, contentKey, null, contentPropertyDidChange);
</del><ins>+  arrangedContentArrayWillChange: function(item, idx, removedCnt, addedCnt) {
+    this.arrayContentWillChange(idx, removedCnt, addedCnt);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  unknownProperty: function (key) {
-    var content = get(this, 'content');
-    if (content) {
-      return get(content, key);
-    }
</del><ins>+  arrangedContentArrayDidChange: function(item, idx, removedCnt, addedCnt) {
+    this.arrayContentDidChange(idx, removedCnt, addedCnt);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  setUnknownProperty: function (key, value) {
-    var content = get(this, 'content');
-    Ember.assert(fmt(&quot;Cannot delegate set('%@', %@) to the 'content' property of object proxy %@: its 'content' is undefined.&quot;, [key, value, this]), content);
-    return set(content, key, value);
</del><ins>+  init: function() {
+    this._super();
+    this._setupContent();
+    this._setupArrangedContent();
+  },
+
+  willDestroy: function() {
+    this._teardownArrangedContent();
+    this._teardownContent();
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -11553,7 +19023,8 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> var set = Ember.set, get = Ember.get, guidFor = Ember.guidFor;
</span><del>-var forEach = Ember.EnumerableUtils.forEach;
</del><ins>+var forEach = Ember.EnumerableUtils.forEach,
+    indexOf = Ember.ArrayPolyfills.indexOf;
</ins><span class="cx"> 
</span><span class="cx"> var EachArray = Ember.Object.extend(Ember.Array, {
</span><span class="cx"> 
</span><span class="lines">@@ -11585,10 +19056,11 @@
</span><span class="cx">   while(--loc&gt;=idx) {
</span><span class="cx">     var item = content.objectAt(loc);
</span><span class="cx">     if (item) {
</span><ins>+      Ember.assert('When using @each to observe the array ' + content + ', the array must return an object', Ember.typeOf(item) === 'instance' || Ember.typeOf(item) === 'object');
</ins><span class="cx">       Ember.addBeforeObserver(item, keyName, proxy, 'contentKeyWillChange');
</span><span class="cx">       Ember.addObserver(item, keyName, proxy, 'contentKeyDidChange');
</span><span class="cx"> 
</span><del>-      // keep track of the indicies each item was found at so we can map
</del><ins>+      // keep track of the index each item was found at so we can map
</ins><span class="cx">       // it back when the obj changes.
</span><span class="cx">       guid = guidFor(item);
</span><span class="cx">       if (!objects[guid]) objects[guid] = [];
</span><span class="lines">@@ -11610,7 +19082,7 @@
</span><span class="cx"> 
</span><span class="cx">       guid = guidFor(item);
</span><span class="cx">       indicies = objects[guid];
</span><del>-      indicies[indicies.indexOf(loc)] = null;
</del><ins>+      indicies[indexOf.call(indicies, loc)] = null;
</ins><span class="cx">     }
</span><span class="cx">   }
</span><span class="cx"> }
</span><span class="lines">@@ -11645,7 +19117,7 @@
</span><span class="cx"> 
</span><span class="cx">     @method unknownProperty
</span><span class="cx">     @param keyName {String}
</span><del>-    @param value {anything}
</del><ins>+    @param value {*}
</ins><span class="cx">   */
</span><span class="cx">   unknownProperty: function(keyName, value) {
</span><span class="cx">     var ret;
</span><span class="lines">@@ -11660,7 +19132,7 @@
</span><span class="cx">   // Invokes whenever the content array itself changes.
</span><span class="cx"> 
</span><span class="cx">   arrayWillChange: function(content, idx, removedCnt, addedCnt) {
</span><del>-    var keys = this._keys, key, array, lim;
</del><ins>+    var keys = this._keys, key, lim;
</ins><span class="cx"> 
</span><span class="cx">     lim = removedCnt&gt;0 ? idx+removedCnt : -1;
</span><span class="cx">     Ember.beginPropertyChanges(this);
</span><span class="lines">@@ -11668,7 +19140,7 @@
</span><span class="cx">     for(key in keys) {
</span><span class="cx">       if (!keys.hasOwnProperty(key)) { continue; }
</span><span class="cx"> 
</span><del>-      if (lim&gt;0) removeObserverForContentKey(content, key, this, idx, lim);
</del><ins>+      if (lim&gt;0) { removeObserverForContentKey(content, key, this, idx, lim); }
</ins><span class="cx"> 
</span><span class="cx">       Ember.propertyWillChange(this, key);
</span><span class="cx">     }
</span><span class="lines">@@ -11678,21 +19150,20 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   arrayDidChange: function(content, idx, removedCnt, addedCnt) {
</span><del>-    var keys = this._keys, key, array, lim;
</del><ins>+    var keys = this._keys, lim;
</ins><span class="cx"> 
</span><span class="cx">     lim = addedCnt&gt;0 ? idx+addedCnt : -1;
</span><del>-    Ember.beginPropertyChanges(this);
</del><ins>+    Ember.changeProperties(function() {
+      for(var key in keys) {
+        if (!keys.hasOwnProperty(key)) { continue; }
</ins><span class="cx"> 
</span><del>-    for(key in keys) {
-      if (!keys.hasOwnProperty(key)) { continue; }
</del><ins>+        if (lim&gt;0) { addObserverForContentKey(content, key, this, idx, lim); }
</ins><span class="cx"> 
</span><del>-      if (lim&gt;0) addObserverForContentKey(content, key, this, idx, lim);
</del><ins>+        Ember.propertyDidChange(this, key);
+      }
</ins><span class="cx"> 
</span><del>-      Ember.propertyDidChange(this, key);
-    }
-
-    Ember.propertyDidChange(this._content, '@each');
-    Ember.endPropertyChanges(this);
</del><ins>+      Ember.propertyDidChange(this._content, '@each');
+    }, this);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   // ..........................................................
</span><span class="lines">@@ -11760,7 +19231,7 @@
</span><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-var get = Ember.get, set = Ember.set;
</del><ins>+var get = Ember.get, set = Ember.set, replace = Ember.EnumerableUtils._replace;
</ins><span class="cx"> 
</span><span class="cx"> // Add Ember.Array to Array.prototype. Remove methods with native
</span><span class="cx"> // implementations and supply some more optimized versions of generic methods
</span><span class="lines">@@ -11782,7 +19253,7 @@
</span><span class="cx">   // primitive for array support.
</span><span class="cx">   replace: function(idx, amt, objects) {
</span><span class="cx"> 
</span><del>-    if (this.isFrozen) throw Ember.FROZEN_ERROR ;
</del><ins>+    if (this.isFrozen) throw Ember.FROZEN_ERROR;
</ins><span class="cx"> 
</span><span class="cx">     // if we replaced exactly the same number of items, then pass only the
</span><span class="cx">     // replaced range. Otherwise, pass the full remaining array length
</span><span class="lines">@@ -11790,15 +19261,14 @@
</span><span class="cx">     var len = objects ? get(objects, 'length') : 0;
</span><span class="cx">     this.arrayContentWillChange(idx, amt, len);
</span><span class="cx"> 
</span><del>-    if (!objects || objects.length === 0) {
-      this.splice(idx, amt) ;
</del><ins>+    if (len === 0) {
+      this.splice(idx, amt);
</ins><span class="cx">     } else {
</span><del>-      var args = [idx, amt].concat(objects) ;
-      this.splice.apply(this,args) ;
</del><ins>+      replace(this, idx, amt, objects);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     this.arrayContentDidChange(idx, amt, len);
</span><del>-    return this ;
</del><ins>+    return this;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   // If you ask for an unknown property, then try to collect the value
</span><span class="lines">@@ -11841,7 +19311,7 @@
</span><span class="cx"> 
</span><span class="cx">   copy: function(deep) {
</span><span class="cx">     if (deep) {
</span><del>-      return this.map(function(item){ return Ember.copy(item, true); });
</del><ins>+      return this.map(function(item) { return Ember.copy(item, true); });
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return this.slice();
</span><span class="lines">@@ -11861,37 +19331,64 @@
</span><span class="cx"> /**
</span><span class="cx">   The NativeArray mixin contains the properties needed to to make the native
</span><span class="cx">   Array support Ember.MutableArray and all of its dependent APIs. Unless you
</span><del>-  have `Ember.EXTEND_PROTOTYPES or `Ember.EXTEND_PROTOTYPES.Array` set to
</del><ins>+  have `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Array` set to
</ins><span class="cx">   false, this will be applied automatically. Otherwise you can apply the mixin
</span><span class="cx">   at anytime by calling `Ember.NativeArray.activate`.
</span><span class="cx"> 
</span><span class="cx">   @class NativeArray
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Mixin
</del><span class="cx">   @uses Ember.MutableArray
</span><del>-  @uses Ember.MutableEnumerable
</del><ins>+  @uses Ember.Observable
</ins><span class="cx">   @uses Ember.Copyable
</span><del>-  @uses Ember.Freezable
</del><span class="cx"> */
</span><span class="cx"> Ember.NativeArray = NativeArray;
</span><span class="cx"> 
</span><span class="cx"> /**
</span><span class="cx">   Creates an `Ember.NativeArray` from an Array like object.
</span><del>-  Does not modify the original object.
</del><ins>+  Does not modify the original object. Ember.A is not needed if
+  `Ember.EXTEND_PROTOTYPES` is `true` (the default value). However,
+  it is recommended that you use Ember.A when creating addons for
+  ember or when you can not guarantee that `Ember.EXTEND_PROTOTYPES`
+  will be `true`.
</ins><span class="cx"> 
</span><ins>+  Example
+
+  ```js
+  var Pagination = Ember.CollectionView.extend({
+    tagName: 'ul',
+    classNames: ['pagination'],
+    init: function() {
+      this._super();
+      if (!this.get('content')) {
+        this.set('content', Ember.A([]));
+      }
+    }
+  });
+  ```
+
</ins><span class="cx">   @method A
</span><span class="cx">   @for Ember
</span><span class="cx">   @return {Ember.NativeArray}
</span><span class="cx"> */
</span><del>-Ember.A = function(arr){
</del><ins>+Ember.A = function(arr) {
</ins><span class="cx">   if (arr === undefined) { arr = []; }
</span><span class="cx">   return Ember.Array.detect(arr) ? arr : Ember.NativeArray.apply(arr);
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><span class="cx">   Activates the mixin on the Array.prototype if not already applied. Calling
</span><del>-  this method more than once is safe.
</del><ins>+  this method more than once is safe. This will be called when ember is loaded
+  unless you have `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Array`
+  set to `false`.
</ins><span class="cx"> 
</span><ins>+  Example
+
+  ```js
+  if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Array) {
+    Ember.NativeArray.activate();
+  }
+  ```
+
</ins><span class="cx">   @method activate
</span><span class="cx">   @for Ember.NativeArray
</span><span class="cx">   @static
</span><span class="lines">@@ -11913,8 +19410,464 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><ins>+/**
+@module ember
+@submodule ember-runtime
+*/
+
+var get = Ember.get, set = Ember.set, guidFor = Ember.guidFor, isNone = Ember.isNone, fmt = Ember.String.fmt;
+
+/**
+  An unordered collection of objects.
+
+  A Set works a bit like an array except that its items are not ordered. You
+  can create a set to efficiently test for membership for an object. You can
+  also iterate through a set just like an array, even accessing objects by
+  index, however there is no guarantee as to their order.
+
+  All Sets are observable via the Enumerable Observer API - which works
+  on any enumerable object including both Sets and Arrays.
+
+  ## Creating a Set
+
+  You can create a set like you would most objects using
+  `new Ember.Set()`. Most new sets you create will be empty, but you can
+  also initialize the set with some content by passing an array or other
+  enumerable of objects to the constructor.
+
+  Finally, you can pass in an existing set and the set will be copied. You
+  can also create a copy of a set by calling `Ember.Set#copy()`.
+
+  ```javascript
+  // creates a new empty set
+  var foundNames = new Ember.Set();
+
+  // creates a set with four names in it.
+  var names = new Ember.Set([&quot;Charles&quot;, &quot;Tom&quot;, &quot;Juan&quot;, &quot;Alex&quot;]); // :P
+
+  // creates a copy of the names set.
+  var namesCopy = new Ember.Set(names);
+
+  // same as above.
+  var anotherNamesCopy = names.copy();
+  ```
+
+  ## Adding/Removing Objects
+
+  You generally add or remove objects from a set using `add()` or
+  `remove()`. You can add any type of object including primitives such as
+  numbers, strings, and booleans.
+
+  Unlike arrays, objects can only exist one time in a set. If you call `add()`
+  on a set with the same object multiple times, the object will only be added
+  once. Likewise, calling `remove()` with the same object multiple times will
+  remove the object the first time and have no effect on future calls until
+  you add the object to the set again.
+
+  NOTE: You cannot add/remove `null` or `undefined` to a set. Any attempt to do
+  so will be ignored.
+
+  In addition to add/remove you can also call `push()`/`pop()`. Push behaves
+  just like `add()` but `pop()`, unlike `remove()` will pick an arbitrary
+  object, remove it and return it. This is a good way to use a set as a job
+  queue when you don't care which order the jobs are executed in.
+
+  ## Testing for an Object
+
+  To test for an object's presence in a set you simply call
+  `Ember.Set#contains()`.
+
+  ## Observing changes
+
+  When using `Ember.Set`, you can observe the `&quot;[]&quot;` property to be
+  alerted whenever the content changes. You can also add an enumerable
+  observer to the set to be notified of specific objects that are added and
+  removed from the set. See [Ember.Enumerable](/api/classes/Ember.Enumerable.html)
+  for more information on enumerables.
+
+  This is often unhelpful. If you are filtering sets of objects, for instance,
+  it is very inefficient to re-filter all of the items each time the set
+  changes. It would be better if you could just adjust the filtered set based
+  on what was changed on the original set. The same issue applies to merging
+  sets, as well.
+
+  ## Other Methods
+
+  `Ember.Set` primary implements other mixin APIs. For a complete reference
+  on the methods you will use with `Ember.Set`, please consult these mixins.
+  The most useful ones will be `Ember.Enumerable` and
+  `Ember.MutableEnumerable` which implement most of the common iterator
+  methods you are used to on Array.
+
+  Note that you can also use the `Ember.Copyable` and `Ember.Freezable`
+  APIs on `Ember.Set` as well. Once a set is frozen it can no longer be
+  modified. The benefit of this is that when you call `frozenCopy()` on it,
+  Ember will avoid making copies of the set. This allows you to write
+  code that can know with certainty when the underlying set data will or
+  will not be modified.
+
+  @class Set
+  @namespace Ember
+  @extends Ember.CoreObject
+  @uses Ember.MutableEnumerable
+  @uses Ember.Copyable
+  @uses Ember.Freezable
+  @since Ember 0.9
+*/
+Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Ember.Freezable,
+  {
+
+  // ..........................................................
+  // IMPLEMENT ENUMERABLE APIS
+  //
+
+  /**
+    This property will change as the number of objects in the set changes.
+
+    @property length
+    @type number
+    @default 0
+  */
+  length: 0,
+
+  /**
+    Clears the set. This is useful if you want to reuse an existing set
+    without having to recreate it.
+
+    ```javascript
+    var colors = new Ember.Set([&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]);
+    colors.length;  // 3
+    colors.clear();
+    colors.length;  // 0
+    ```
+
+    @method clear
+    @return {Ember.Set} An empty Set
+  */
+  clear: function() {
+    if (this.isFrozen) { throw new Ember.Error(Ember.FROZEN_ERROR); }
+
+    var len = get(this, 'length');
+    if (len === 0) { return this; }
+
+    var guid;
+
+    this.enumerableContentWillChange(len, 0);
+    Ember.propertyWillChange(this, 'firstObject');
+    Ember.propertyWillChange(this, 'lastObject');
+
+    for (var i=0; i &lt; len; i++) {
+      guid = guidFor(this[i]);
+      delete this[guid];
+      delete this[i];
+    }
+
+    set(this, 'length', 0);
+
+    Ember.propertyDidChange(this, 'firstObject');
+    Ember.propertyDidChange(this, 'lastObject');
+    this.enumerableContentDidChange(len, 0);
+
+    return this;
+  },
+
+  /**
+    Returns true if the passed object is also an enumerable that contains the
+    same objects as the receiver.
+
+    ```javascript
+    var colors = [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;],
+        same_colors = new Ember.Set(colors);
+
+    same_colors.isEqual(colors);               // true
+    same_colors.isEqual([&quot;purple&quot;, &quot;brown&quot;]);  // false
+    ```
+
+    @method isEqual
+    @param {Ember.Set} obj the other object.
+    @return {Boolean}
+  */
+  isEqual: function(obj) {
+    // fail fast
+    if (!Ember.Enumerable.detect(obj)) return false;
+
+    var loc = get(this, 'length');
+    if (get(obj, 'length') !== loc) return false;
+
+    while(--loc &gt;= 0) {
+      if (!obj.contains(this[loc])) return false;
+    }
+
+    return true;
+  },
+
+  /**
+    Adds an object to the set. Only non-`null` objects can be added to a set
+    and those can only be added once. If the object is already in the set or
+    the passed value is null this method will have no effect.
+
+    This is an alias for `Ember.MutableEnumerable.addObject()`.
+
+    ```javascript
+    var colors = new Ember.Set();
+    colors.add(&quot;blue&quot;);     // [&quot;blue&quot;]
+    colors.add(&quot;blue&quot;);     // [&quot;blue&quot;]
+    colors.add(&quot;red&quot;);      // [&quot;blue&quot;, &quot;red&quot;]
+    colors.add(null);       // [&quot;blue&quot;, &quot;red&quot;]
+    colors.add(undefined);  // [&quot;blue&quot;, &quot;red&quot;]
+    ```
+
+    @method add
+    @param {Object} obj The object to add.
+    @return {Ember.Set} The set itself.
+  */
+  add: Ember.aliasMethod('addObject'),
+
+  /**
+    Removes the object from the set if it is found. If you pass a `null` value
+    or an object that is already not in the set, this method will have no
+    effect. This is an alias for `Ember.MutableEnumerable.removeObject()`.
+
+    ```javascript
+    var colors = new Ember.Set([&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]);
+    colors.remove(&quot;red&quot;);     // [&quot;blue&quot;, &quot;green&quot;]
+    colors.remove(&quot;purple&quot;);  // [&quot;blue&quot;, &quot;green&quot;]
+    colors.remove(null);      // [&quot;blue&quot;, &quot;green&quot;]
+    ```
+
+    @method remove
+    @param {Object} obj The object to remove
+    @return {Ember.Set} The set itself.
+  */
+  remove: Ember.aliasMethod('removeObject'),
+
+  /**
+    Removes the last element from the set and returns it, or `null` if it's empty.
+
+    ```javascript
+    var colors = new Ember.Set([&quot;green&quot;, &quot;blue&quot;]);
+    colors.pop();  // &quot;blue&quot;
+    colors.pop();  // &quot;green&quot;
+    colors.pop();  // null
+    ```
+
+    @method pop
+    @return {Object} The removed object from the set or null.
+  */
+  pop: function() {
+    if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
+    var obj = this.length &gt; 0 ? this[this.length-1] : null;
+    this.remove(obj);
+    return obj;
+  },
+
+  /**
+    Inserts the given object on to the end of the set. It returns
+    the set itself.
+
+    This is an alias for `Ember.MutableEnumerable.addObject()`.
+
+    ```javascript
+    var colors = new Ember.Set();
+    colors.push(&quot;red&quot;);   // [&quot;red&quot;]
+    colors.push(&quot;green&quot;); // [&quot;red&quot;, &quot;green&quot;]
+    colors.push(&quot;blue&quot;);  // [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]
+    ```
+
+    @method push
+    @return {Ember.Set} The set itself.
+  */
+  push: Ember.aliasMethod('addObject'),
+
+  /**
+    Removes the last element from the set and returns it, or `null` if it's empty.
+
+    This is an alias for `Ember.Set.pop()`.
+
+    ```javascript
+    var colors = new Ember.Set([&quot;green&quot;, &quot;blue&quot;]);
+    colors.shift();  // &quot;blue&quot;
+    colors.shift();  // &quot;green&quot;
+    colors.shift();  // null
+    ```
+
+    @method shift
+    @return {Object} The removed object from the set or null.
+  */
+  shift: Ember.aliasMethod('pop'),
+
+  /**
+    Inserts the given object on to the end of the set. It returns
+    the set itself.
+
+    This is an alias of `Ember.Set.push()`
+
+    ```javascript
+    var colors = new Ember.Set();
+    colors.unshift(&quot;red&quot;);    // [&quot;red&quot;]
+    colors.unshift(&quot;green&quot;);  // [&quot;red&quot;, &quot;green&quot;]
+    colors.unshift(&quot;blue&quot;);   // [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]
+    ```
+
+    @method unshift
+    @return {Ember.Set} The set itself.
+  */
+  unshift: Ember.aliasMethod('push'),
+
+  /**
+    Adds each object in the passed enumerable to the set.
+
+    This is an alias of `Ember.MutableEnumerable.addObjects()`
+
+    ```javascript
+    var colors = new Ember.Set();
+    colors.addEach([&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]);  // [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]
+    ```
+
+    @method addEach
+    @param {Ember.Enumerable} objects the objects to add.
+    @return {Ember.Set} The set itself.
+  */
+  addEach: Ember.aliasMethod('addObjects'),
+
+  /**
+    Removes each object in the passed enumerable to the set.
+
+    This is an alias of `Ember.MutableEnumerable.removeObjects()`
+
+    ```javascript
+    var colors = new Ember.Set([&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]);
+    colors.removeEach([&quot;red&quot;, &quot;blue&quot;]);  //  [&quot;green&quot;]
+    ```
+
+    @method removeEach
+    @param {Ember.Enumerable} objects the objects to remove.
+    @return {Ember.Set} The set itself.
+  */
+  removeEach: Ember.aliasMethod('removeObjects'),
+
+  // ..........................................................
+  // PRIVATE ENUMERABLE SUPPORT
+  //
+
+  init: function(items) {
+    this._super();
+    if (items) this.addObjects(items);
+  },
+
+  // implement Ember.Enumerable
+  nextObject: function(idx) {
+    return this[idx];
+  },
+
+  // more optimized version
+  firstObject: Ember.computed(function() {
+    return this.length &gt; 0 ? this[0] : undefined;
+  }),
+
+  // more optimized version
+  lastObject: Ember.computed(function() {
+    return this.length &gt; 0 ? this[this.length-1] : undefined;
+  }),
+
+  // implements Ember.MutableEnumerable
+  addObject: function(obj) {
+    if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
+    if (isNone(obj)) return this; // nothing to do
+
+    var guid = guidFor(obj),
+        idx  = this[guid],
+        len  = get(this, 'length'),
+        added ;
+
+    if (idx&gt;=0 &amp;&amp; idx&lt;len &amp;&amp; (this[idx] === obj)) return this; // added
+
+    added = [obj];
+
+    this.enumerableContentWillChange(null, added);
+    Ember.propertyWillChange(this, 'lastObject');
+
+    len = get(this, 'length');
+    this[guid] = len;
+    this[len] = obj;
+    set(this, 'length', len+1);
+
+    Ember.propertyDidChange(this, 'lastObject');
+    this.enumerableContentDidChange(null, added);
+
+    return this;
+  },
+
+  // implements Ember.MutableEnumerable
+  removeObject: function(obj) {
+    if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
+    if (isNone(obj)) return this; // nothing to do
+
+    var guid = guidFor(obj),
+        idx  = this[guid],
+        len = get(this, 'length'),
+        isFirst = idx === 0,
+        isLast = idx === len-1,
+        last, removed;
+
+
+    if (idx&gt;=0 &amp;&amp; idx&lt;len &amp;&amp; (this[idx] === obj)) {
+      removed = [obj];
+
+      this.enumerableContentWillChange(removed, null);
+      if (isFirst) { Ember.propertyWillChange(this, 'firstObject'); }
+      if (isLast)  { Ember.propertyWillChange(this, 'lastObject'); }
+
+      // swap items - basically move the item to the end so it can be removed
+      if (idx &lt; len-1) {
+        last = this[len-1];
+        this[idx] = last;
+        this[guidFor(last)] = idx;
+      }
+
+      delete this[guid];
+      delete this[len-1];
+      set(this, 'length', len-1);
+
+      if (isFirst) { Ember.propertyDidChange(this, 'firstObject'); }
+      if (isLast)  { Ember.propertyDidChange(this, 'lastObject'); }
+      this.enumerableContentDidChange(removed, null);
+    }
+
+    return this;
+  },
+
+  // optimized version
+  contains: function(obj) {
+    return this[guidFor(obj)]&gt;=0;
+  },
+
+  copy: function() {
+    var C = this.constructor, ret = new C(), loc = get(this, 'length');
+    set(ret, 'length', loc);
+    while(--loc&gt;=0) {
+      ret[loc] = this[loc];
+      ret[guidFor(this[loc])] = loc;
+    }
+    return ret;
+  },
+
+  toString: function() {
+    var len = this.length, idx, array = [];
+    for(idx = 0; idx &lt; len; idx++) {
+      array[idx] = this[idx];
+    }
+    return fmt(&quot;Ember.Set&lt;%@&gt;&quot;, [array.join(',')]);
+  }
+
+});
+
+})();
+
+
+
+(function() {
</ins><span class="cx"> var DeferredMixin = Ember.DeferredMixin, // mixins/deferred
</span><del>-    EmberObject = Ember.Object,          // system/object
</del><span class="cx">     get = Ember.get;
</span><span class="cx"> 
</span><span class="cx"> var Deferred = Ember.Object.extend(DeferredMixin);
</span><span class="lines">@@ -11923,7 +19876,7 @@
</span><span class="cx">   promise: function(callback, binding) {
</span><span class="cx">     var deferred = Deferred.create();
</span><span class="cx">     callback.call(binding, deferred);
</span><del>-    return get(deferred, 'promise');
</del><ins>+    return deferred;
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -11934,19 +19887,33 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><ins>+var forEach = Ember.ArrayPolyfills.forEach;
+
</ins><span class="cx"> /**
</span><del>-@module ember
-@submodule ember-runtime
</del><ins>+  @module ember
+  @submodule ember-runtime
</ins><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> var loadHooks = Ember.ENV.EMBER_LOAD_HOOKS || {};
</span><span class="cx"> var loaded = {};
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-@method onLoad
-@for Ember
-@param name {String} name of hook
-@param callback {Function} callback to be called
</del><ins>+  Detects when a specific package of Ember (e.g. 'Ember.Handlebars')
+  has fully loaded and is available for extension.
+
+  The provided `callback` will be called with the `name` passed
+  resolved from a string into the object:
+
+  ``` javascript
+  Ember.onLoad('Ember.Handlebars' function(hbars){
+    hbars.registerHelper(...);
+  });
+  ```
+
+  @method onLoad
+  @for Ember
+  @param name {String} name of hook
+  @param callback {Function} callback to be called
</ins><span class="cx"> */
</span><span class="cx"> Ember.onLoad = function(name, callback) {
</span><span class="cx">   var object;
</span><span class="lines">@@ -11960,18 +19927,19 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-@method runLoadHooks
-@for Ember
-@param name {String} name of hook
-@param object {Object} object to pass to callbacks
</del><ins>+  Called when an Ember.js package (e.g Ember.Handlebars) has finished
+  loading. Triggers any callbacks registered for this event.
+
+  @method runLoadHooks
+  @for Ember
+  @param name {String} name of hook
+  @param object {Object} object to pass to callbacks
</ins><span class="cx"> */
</span><span class="cx"> Ember.runLoadHooks = function(name, object) {
</span><del>-  var hooks;
-
</del><span class="cx">   loaded[name] = object;
</span><span class="cx"> 
</span><del>-  if (hooks = loadHooks[name]) {
-    loadHooks[name].forEach(function(callback) {
</del><ins>+  if (loadHooks[name]) {
+    forEach.call(loadHooks[name], function(callback) {
</ins><span class="cx">       callback(object);
</span><span class="cx">     });
</span><span class="cx">   }
</span><span class="lines">@@ -12000,40 +19968,19 @@
</span><span class="cx">   compose Ember's controller layer: `Ember.Controller`,
</span><span class="cx">   `Ember.ArrayController`, and `Ember.ObjectController`.
</span><span class="cx"> 
</span><del>-  Within an `Ember.Router`-managed application single shared instaces of every
-  Controller object in your application's namespace will be added to the
-  application's `Ember.Router` instance. See `Ember.Application#initialize`
-  for additional information.
-
-  ## Views
-
-  By default a controller instance will be the rendering context
-  for its associated `Ember.View.` This connection is made during calls to
-  `Ember.ControllerMixin#connectOutlet`.
-
-  Within the view's template, the `Ember.View` instance can be accessed
-  through the controller with `{{view}}`.
-
-  ## Target Forwarding
-
-  By default a controller will target your application's `Ember.Router`
-  instance. Calls to `{{action}}` within the template of a controller's view
-  are forwarded to the router. See `Ember.Handlebars.helpers.action` for
-  additional information.
-
</del><span class="cx">   @class ControllerMixin
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Mixin
</del><ins>+  @uses Ember.ActionHandler
</ins><span class="cx"> */
</span><del>-Ember.ControllerMixin = Ember.Mixin.create({
</del><ins>+Ember.ControllerMixin = Ember.Mixin.create(Ember.ActionHandler, {
</ins><span class="cx">   /* ducktype as a controller */
</span><span class="cx">   isController: true,
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    The object to which events from the view should be sent.
</del><ins>+    The object to which actions from the view should be sent.
</ins><span class="cx"> 
</span><span class="cx">     For example, when a Handlebars template uses the `{{action}}` helper,
</span><del>-    it will attempt to send the event to the view's controller's `target`.
</del><ins>+    it will attempt to send the action to the view's controller's `target`.
</ins><span class="cx"> 
</span><span class="cx">     By default, a controller's `target` is set to the router after it is
</span><span class="cx">     instantiated by `Ember.Application#initialize`.
</span><span class="lines">@@ -12045,20 +19992,22 @@
</span><span class="cx"> 
</span><span class="cx">   container: null,
</span><span class="cx"> 
</span><ins>+  parentController: null,
+
</ins><span class="cx">   store: null,
</span><span class="cx"> 
</span><span class="cx">   model: Ember.computed.alias('content'),
</span><span class="cx"> 
</span><del>-  send: function(actionName) {
-    var args = [].slice.call(arguments, 1), target;
</del><ins>+  deprecatedSendHandles: function(actionName) {
+    return !!this[actionName];
+  },
</ins><span class="cx"> 
</span><del>-    if (this[actionName]) {
-      Ember.assert(&quot;The controller &quot; + this + &quot; does not have the action &quot; + actionName, typeof this[actionName] === 'function');
-      this[actionName].apply(this, args);
-    } else if(target = get(this, 'target')) {
-      Ember.assert(&quot;The target for controller &quot; + this + &quot; (&quot; + target + &quot;) did not define a `send` method&quot;, typeof target.send === 'function');
-      target.send.apply(target, arguments);
-    }
</del><ins>+  deprecatedSend: function(actionName) {
+    var args = [].slice.call(arguments, 1);
+    Ember.assert('' + this + &quot; has the action &quot; + actionName + &quot; but it is not a function&quot;, typeof this[actionName] === 'function');
+    Ember.deprecate('Action handlers implemented directly on controllers are deprecated in favor of action handlers on an `actions` object (' + actionName + ' on ' + this + ')', false);
+    this[actionName].apply(this, args);
+    return;
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -12107,9 +20056,31 @@
</span><span class="cx">   songsController.get('firstObject');  // {trackNumber: 1, title: 'Dear Prudence'}
</span><span class="cx">   ```
</span><span class="cx"> 
</span><ins>+  If you add or remove the properties to sort by or change the sort direction the content
+  sort order will be automatically updated.
+
+  ```javascript
+  songsController.set('sortProperties', ['title']);
+  songsController.get('firstObject'); // {trackNumber: 2, title: 'Back in the U.S.S.R.'}
+
+  songsController.toggleProperty('sortAscending');
+  songsController.get('firstObject'); // {trackNumber: 4, title: 'Ob-La-Di, Ob-La-Da'}
+  ```
+
+  SortableMixin works by sorting the arrangedContent array, which is the array that
+  arrayProxy displays. Due to the fact that the underlying 'content' array is not changed, that
+  array will not display the sorted list:
+
+   ```javascript
+  songsController.get('content').get('firstObject'); // Returns the unsorted original content
+  songsController.get('firstObject'); // Returns the sorted content.
+  ``` 
+  
+  Although the sorted content can also be accessed through the arrangedContent property,
+  it is preferable to use the proxied class and not the arrangedContent array directly.
+
</ins><span class="cx">   @class SortableMixin
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Mixin
</del><span class="cx">   @uses Ember.MutableEnumerable
</span><span class="cx"> */
</span><span class="cx"> Ember.SortableMixin = Ember.Mixin.create(Ember.MutableEnumerable, {
</span><span class="lines">@@ -12117,6 +20088,9 @@
</span><span class="cx">   /**
</span><span class="cx">     Specifies which properties dictate the arrangedContent's sort order.
</span><span class="cx"> 
</span><ins>+    When specifying multiple properties the sorting will use properties
+    from the `sortProperties` array prioritized from first to last.
+
</ins><span class="cx">     @property {Array} sortProperties
</span><span class="cx">   */
</span><span class="cx">   sortProperties: null,
</span><span class="lines">@@ -12128,16 +20102,39 @@
</span><span class="cx">   */
</span><span class="cx">   sortAscending: true,
</span><span class="cx"> 
</span><ins>+  /**
+    The function used to compare two values. You can override this if you
+    want to do custom comparisons. Functions must be of the type expected by
+    Array#sort, i.e.
+      return 0 if the two parameters are equal,
+      return a negative value if the first parameter is smaller than the second or
+      return a positive value otherwise:
+
+    ```javascript
+    function(x,y) { // These are assumed to be integers
+      if (x === y)
+        return 0;
+      return x &lt; y ? -1 : 1;
+    }
+    ```
+
+    @property sortFunction
+    @type {Function}
+    @default Ember.compare
+  */
+  sortFunction: Ember.compare,
+
</ins><span class="cx">   orderBy: function(item1, item2) {
</span><span class="cx">     var result = 0,
</span><span class="cx">         sortProperties = get(this, 'sortProperties'),
</span><del>-        sortAscending = get(this, 'sortAscending');
</del><ins>+        sortAscending = get(this, 'sortAscending'),
+        sortFunction = get(this, 'sortFunction');
</ins><span class="cx"> 
</span><span class="cx">     Ember.assert(&quot;you need to define `sortProperties`&quot;, !!sortProperties);
</span><span class="cx"> 
</span><span class="cx">     forEach(sortProperties, function(propertyName) {
</span><span class="cx">       if (result === 0) {
</span><del>-        result = Ember.compare(get(item1, propertyName), get(item2, propertyName));
</del><ins>+        result = sortFunction(get(item1, propertyName), get(item2, propertyName));
</ins><span class="cx">         if ((result !== 0) &amp;&amp; !sortAscending) {
</span><span class="cx">           result = (-1) * result;
</span><span class="cx">         }
</span><span class="lines">@@ -12164,6 +20161,13 @@
</span><span class="cx"> 
</span><span class="cx">   isSorted: Ember.computed.bool('sortProperties'),
</span><span class="cx"> 
</span><ins>+  /**
+    Overrides the default arrangedContent from arrayProxy in order to sort by sortFunction.
+    Also sets up observers for each sortProperty on each item in the content Array.
+    
+    @property arrangedContent
+  */
+
</ins><span class="cx">   arrangedContent: Ember.computed('content', 'sortProperties.@each', function(key, value) {
</span><span class="cx">     var content = get(this, 'content'),
</span><span class="cx">         isSorted = get(this, 'isSorted'),
</span><span class="lines">@@ -12186,7 +20190,7 @@
</span><span class="cx">     return content;
</span><span class="cx">   }),
</span><span class="cx"> 
</span><del>-  _contentWillChange: Ember.beforeObserver(function() {
</del><ins>+  _contentWillChange: Ember.beforeObserver('content', function() {
</ins><span class="cx">     var content = get(this, 'content'),
</span><span class="cx">         sortProperties = get(this, 'sortProperties');
</span><span class="cx"> 
</span><span class="lines">@@ -12199,18 +20203,18 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     this._super();
</span><del>-  }, 'content'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><del>-  sortAscendingWillChange: Ember.beforeObserver(function() {
</del><ins>+  sortAscendingWillChange: Ember.beforeObserver('sortAscending', function() {
</ins><span class="cx">     this._lastSortAscending = get(this, 'sortAscending');
</span><del>-  }, 'sortAscending'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><del>-  sortAscendingDidChange: Ember.observer(function() {
</del><ins>+  sortAscendingDidChange: Ember.observer('sortAscending', function() {
</ins><span class="cx">     if (get(this, 'sortAscending') !== this._lastSortAscending) {
</span><span class="cx">       var arrangedContent = get(this, 'arrangedContent');
</span><span class="cx">       arrangedContent.reverseObjects();
</span><span class="cx">     }
</span><del>-  }, 'sortAscending'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><span class="cx">   contentArrayWillChange: function(array, idx, removedCount, addedCount) {
</span><span class="cx">     var isSorted = get(this, 'isSorted');
</span><span class="lines">@@ -12238,7 +20242,6 @@
</span><span class="cx"> 
</span><span class="cx">     if (isSorted) {
</span><span class="cx">       var addedObjects = array.slice(idx, idx+addedCount);
</span><del>-      var arrangedContent = get(this, 'arrangedContent');
</del><span class="cx"> 
</span><span class="cx">       forEach(addedObjects, function(item) {
</span><span class="cx">         this.insertItemSorted(item);
</span><span class="lines">@@ -12308,8 +20311,8 @@
</span><span class="cx"> @submodule ember-runtime
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var get = Ember.get, set = Ember.set, isGlobalPath = Ember.isGlobalPath,
-    forEach = Ember.EnumerableUtils.forEach, replace = Ember.EnumerableUtils.replace;
</del><ins>+var get = Ember.get, set = Ember.set, forEach = Ember.EnumerableUtils.forEach,
+    replace = Ember.EnumerableUtils.replace;
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><span class="cx">   `Ember.ArrayController` provides a way for you to publish a collection of
</span><span class="lines">@@ -12388,6 +20391,10 @@
</span><span class="cx">   });
</span><span class="cx">   ```
</span><span class="cx"> 
</span><ins>+  The itemController instances will have a `parentController` property set to
+  either the the `parentController` property of the `ArrayController`
+  or to the `ArrayController` instance itself.
+
</ins><span class="cx">   @class ArrayController
</span><span class="cx">   @namespace Ember
</span><span class="cx">   @extends Ember.ArrayProxy
</span><span class="lines">@@ -12427,9 +20434,9 @@
</span><span class="cx">     });
</span><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    @method
-    @type String
-    @default null
</del><ins>+    @method lookupItemController
+    @param {Object} object
+    @return {String}
</ins><span class="cx">   */
</span><span class="cx">   lookupItemController: function(object) {
</span><span class="cx">     return get(this, 'itemController');
</span><span class="lines">@@ -12437,7 +20444,8 @@
</span><span class="cx"> 
</span><span class="cx">   objectAtContent: function(idx) {
</span><span class="cx">     var length = get(this, 'length'),
</span><del>-        object = get(this,'arrangedContent').objectAt(idx);
</del><ins>+        arrangedContent = get(this,'arrangedContent'),
+        object = arrangedContent &amp;&amp; arrangedContent.objectAt(idx);
</ins><span class="cx"> 
</span><span class="cx">     if (idx &gt;= 0 &amp;&amp; idx &lt; length) {
</span><span class="cx">       var controllerClass = this.lookupItemController(object);
</span><span class="lines">@@ -12457,20 +20465,20 @@
</span><span class="cx"> 
</span><span class="cx">   arrangedContentDidChange: function() {
</span><span class="cx">     this._super();
</span><del>-    this._resetSubContainers();
</del><ins>+    this._resetSubControllers();
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   arrayContentDidChange: function(idx, removedCnt, addedCnt) {
</span><del>-    var subContainers = get(this, 'subContainers'),
-        subContainersToRemove = subContainers.slice(idx, idx+removedCnt);
</del><ins>+    var subControllers = get(this, '_subControllers'),
+        subControllersToRemove = subControllers.slice(idx, idx+removedCnt);
</ins><span class="cx"> 
</span><del>-    forEach(subContainersToRemove, function(subContainer) {
-      if (subContainer) { subContainer.destroy(); }
</del><ins>+    forEach(subControllersToRemove, function(subController) {
+      if (subController) { subController.destroy(); }
</ins><span class="cx">     });
</span><span class="cx"> 
</span><del>-    replace(subContainers, idx, removedCnt, new Array(addedCnt));
</del><ins>+    replace(subControllers, idx, removedCnt, new Array(addedCnt));
</ins><span class="cx"> 
</span><del>-    // The shadow array of subcontainers must be updated before we trigger
</del><ins>+    // The shadow array of subcontrollers must be updated before we trigger
</ins><span class="cx">     // observers, otherwise observers will get the wrong subcontainer when
</span><span class="cx">     // calling `objectAt`
</span><span class="cx">     this._super(idx, removedCnt, addedCnt);
</span><span class="lines">@@ -12478,43 +20486,50 @@
</span><span class="cx"> 
</span><span class="cx">   init: function() {
</span><span class="cx">     this._super();
</span><del>-    if (!this.get('content')) { this.set('content', Ember.A()); }
-    this._resetSubContainers();
</del><ins>+
+    this.set('_subControllers', Ember.A());
</ins><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  content: Ember.computed(function () {
+    return Ember.A();
+  }),
+
</ins><span class="cx">   controllerAt: function(idx, object, controllerClass) {
</span><span class="cx">     var container = get(this, 'container'),
</span><del>-        subContainers = get(this, 'subContainers'),
-        subContainer = subContainers[idx],
-        controller;
</del><ins>+        subControllers = get(this, '_subControllers'),
+        subController = subControllers[idx],
+        factory, fullName;
</ins><span class="cx"> 
</span><del>-    if (!subContainer) {
-      subContainer = subContainers[idx] = container.child();
-    }
</del><ins>+    if (subController) { return subController; }
</ins><span class="cx"> 
</span><del>-    controller = subContainer.lookup(&quot;controller:&quot; + controllerClass);
-    if (!controller) {
-      throw new Error('Could not resolve itemController: &quot;' + controllerClass + '&quot;');
</del><ins>+    fullName = &quot;controller:&quot; + controllerClass;
+
+    if (!container.has(fullName)) {
+      throw new Ember.Error('Could not resolve itemController: &quot;' + controllerClass + '&quot;');
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    controller.set('target', this);
-    controller.set('content', object);
</del><ins>+    subController = container.lookupFactory(fullName).create({
+      target: this,
+      parentController: get(this, 'parentController') || this,
+      content: object
+    });
</ins><span class="cx"> 
</span><del>-    return controller;
</del><ins>+    subControllers[idx] = subController;
+
+    return subController;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  subContainers: null,
</del><ins>+  _subControllers: null,
</ins><span class="cx"> 
</span><del>-  _resetSubContainers: function() {
-    var subContainers = get(this, 'subContainers');
-
-    if (subContainers) {
-      forEach(subContainers, function(subContainer) {
-        if (subContainer) { subContainer.destroy(); }
</del><ins>+  _resetSubControllers: function() {
+    var subControllers = get(this, '_subControllers');
+    if (subControllers) {
+      forEach(subControllers, function(subController) {
+        if (subController) { subController.destroy(); }
</ins><span class="cx">       });
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    this.set('subContainers', Ember.A());
</del><ins>+    this.set('_subControllers', Ember.A());
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -12529,12 +20544,11 @@
</span><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  `Ember.ObjectController` is part of Ember's Controller layer. A single shared
-  instance of each `Ember.ObjectController` subclass in your application's
-  namespace will be created at application initialization and be stored on your
-  application's `Ember.Router` instance.
</del><ins>+  `Ember.ObjectController` is part of Ember's Controller layer. It is intended
+  to wrap a single object, proxying unhandled attempts to `get` and `set` to the underlying
+  content object, and to forward unhandled action attempts to its `target`.
</ins><span class="cx"> 
</span><del>-  `Ember.ObjectController` derives its functionality from its superclass
</del><ins>+  `Ember.ObjectController` derives this functionality from its superclass
</ins><span class="cx">   `Ember.ObjectProxy` and the `Ember.ControllerMixin` mixin.
</span><span class="cx"> 
</span><span class="cx">   @class ObjectController
</span><span class="lines">@@ -12571,9 +20585,13 @@
</span><span class="cx"> @submodule ember-views
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var jQuery = Ember.imports.jQuery;
-Ember.assert(&quot;Ember Views require jQuery 1.8 or 1.9&quot;, jQuery &amp;&amp; (jQuery().jquery.match(/^1\.(8|9)(\.\d+)?(pre|rc\d?)?/) || Ember.ENV.FORCE_JQUERY));
</del><ins>+var jQuery = this.jQuery || (Ember.imports &amp;&amp; Ember.imports.jQuery);
+if (!jQuery &amp;&amp; typeof require === 'function') {
+  jQuery = require('jquery');
+}
</ins><span class="cx"> 
</span><ins>+Ember.assert(&quot;Ember Views require jQuery 1.7, 1.8, 1.9, 1.10, or 2.0&quot;, jQuery &amp;&amp; (jQuery().jquery.match(/^((1\.(7|8|9|10))|2.0)(\.\d+)?(pre|rc\d?)?/) || Ember.ENV.FORCE_JQUERY));
+
</ins><span class="cx"> /**
</span><span class="cx">   Alias for jQuery
</span><span class="cx"> 
</span><span class="lines">@@ -12591,16 +20609,17 @@
</span><span class="cx"> @module ember
</span><span class="cx"> @submodule ember-views
</span><span class="cx"> */
</span><ins>+if (Ember.$) {
+  // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dndevents
+  var dragEvents = Ember.String.w('dragstart drag dragenter dragleave dragover drop dragend');
</ins><span class="cx"> 
</span><del>-// http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dndevents
-var dragEvents = Ember.String.w('dragstart drag dragenter dragleave dragover drop dragend');
</del><ins>+  // Copies the `dataTransfer` property from a browser event object onto the
+  // jQuery event object for the specified events
+  Ember.EnumerableUtils.forEach(dragEvents, function(eventName) {
+    Ember.$.event.fixHooks[eventName] = { props: ['dataTransfer'] };
+  });
+}
</ins><span class="cx"> 
</span><del>-// Copies the `dataTransfer` property from a browser event object onto the
-// jQuery event object for the specified events
-Ember.EnumerableUtils.forEach(dragEvents, function(eventName) {
-  Ember.$.event.fixHooks[eventName] = { props: ['dataTransfer'] };
-});
-
</del><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -12611,12 +20630,13 @@
</span><span class="cx"> @submodule ember-views
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-/*** BEGIN METAMORPH HELPERS ***/
</del><ins>+/* BEGIN METAMORPH HELPERS */
</ins><span class="cx"> 
</span><span class="cx"> // Internet Explorer prior to 9 does not allow setting innerHTML if the first element
</span><span class="cx"> // is a &quot;zero-scope&quot; element. This problem can be worked around by making
</span><span class="cx"> // the first node an invisible text node. We, like Modernizr, use &amp;shy;
</span><del>-var needsShy = (function(){
</del><ins>+
+var needsShy = this.document &amp;&amp; (function() {
</ins><span class="cx">   var testEl = document.createElement('div');
</span><span class="cx">   testEl.innerHTML = &quot;&lt;div&gt;&lt;/div&gt;&quot;;
</span><span class="cx">   testEl.firstChild.innerHTML = &quot;&lt;script&gt;&lt;/script&gt;&quot;;
</span><span class="lines">@@ -12626,7 +20646,7 @@
</span><span class="cx"> // IE 8 (and likely earlier) likes to move whitespace preceeding
</span><span class="cx"> // a script tag to appear after it. This means that we can
</span><span class="cx"> // accidentally remove whitespace when updating a morph.
</span><del>-var movesWhitespace = (function() {
</del><ins>+var movesWhitespace = this.document &amp;&amp; (function() {
</ins><span class="cx">   var testEl = document.createElement('div');
</span><span class="cx">   testEl.innerHTML = &quot;Test: &lt;script type='text/x-placeholder'&gt;&lt;/script&gt;Value&quot;;
</span><span class="cx">   return testEl.childNodes[0].nodeValue === 'Test:' &amp;&amp;
</span><span class="lines">@@ -12683,7 +20703,7 @@
</span><span class="cx">   }
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-/*** END METAMORPH HELPERS */
</del><ins>+/* END METAMORPH HELPERS */
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> var innerHTMLTags = {};
</span><span class="lines">@@ -12712,9 +20732,11 @@
</span><span class="cx">   if (canSetInnerHTML(tagName)) {
</span><span class="cx">     setInnerHTMLWithoutFix(element, html);
</span><span class="cx">   } else {
</span><del>-    Ember.assert(&quot;Can't set innerHTML on &quot;+element.tagName+&quot; in this browser&quot;, element.outerHTML);
</del><ins>+    // Firefox versions &lt; 11 do not have support for element.outerHTML.
+    var outerHTML = element.outerHTML || new XMLSerializer().serializeToString(element);
+    Ember.assert(&quot;Can't set innerHTML on &quot;+element.tagName+&quot; in this browser&quot;, outerHTML);
</ins><span class="cx"> 
</span><del>-    var startTag = element.outerHTML.match(new RegExp(&quot;&lt;&quot;+tagName+&quot;([^&gt;]*)&gt;&quot;, 'i'))[0],
</del><ins>+    var startTag = outerHTML.match(new RegExp(&quot;&lt;&quot;+tagName+&quot;([^&gt;]*)&gt;&quot;, 'i'))[0],
</ins><span class="cx">         endTag = '&lt;/'+tagName+'&gt;';
</span><span class="cx"> 
</span><span class="cx">     var wrapper = document.createElement('div');
</span><span class="lines">@@ -12751,12 +20773,7 @@
</span><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> var get = Ember.get, set = Ember.set;
</span><del>-var indexOf = Ember.ArrayPolyfills.indexOf;
</del><span class="cx"> 
</span><del>-
-
-
-
</del><span class="cx"> var ClassSet = function() {
</span><span class="cx">   this.seen = {};
</span><span class="cx">   this.list = [];
</span><span class="lines">@@ -12775,14 +20792,71 @@
</span><span class="cx">   }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+var BAD_TAG_NAME_TEST_REGEXP = /[^a-zA-Z0-9\-]/;
+var BAD_TAG_NAME_REPLACE_REGEXP = /[^a-zA-Z0-9\-]/g;
+
+function stripTagName(tagName) {
+  if (!tagName) {
+    return tagName;
+  }
+
+  if (!BAD_TAG_NAME_TEST_REGEXP.test(tagName)) {
+    return tagName;
+  }
+
+  return tagName.replace(BAD_TAG_NAME_REPLACE_REGEXP, '');
+}
+
+var BAD_CHARS_REGEXP = /&amp;(?!\w+;)|[&lt;&gt;&quot;'`]/g;
+var POSSIBLE_CHARS_REGEXP = /[&amp;&lt;&gt;&quot;'`]/;
+
+function escapeAttribute(value) {
+  // Stolen shamelessly from Handlebars
+
+  var escape = {
+    &quot;&lt;&quot;: &quot;&amp;lt;&quot;,
+    &quot;&gt;&quot;: &quot;&amp;gt;&quot;,
+    '&quot;': &quot;&amp;quot;&quot;,
+    &quot;'&quot;: &quot;&amp;#x27;&quot;,
+    &quot;`&quot;: &quot;&amp;#x60;&quot;
+  };
+
+  var escapeChar = function(chr) {
+    return escape[chr] || &quot;&amp;amp;&quot;;
+  };
+
+  var string = value.toString();
+
+  if(!POSSIBLE_CHARS_REGEXP.test(string)) { return string; }
+  return string.replace(BAD_CHARS_REGEXP, escapeChar);
+}
+
+// IE 6/7 have bugs arond setting names on inputs during creation.
+// From http://msdn.microsoft.com/en-us/library/ie/ms536389(v=vs.85).aspx:
+// &quot;To include the NAME attribute at run time on objects created with the createElement method, use the eTag.&quot;
+var canSetNameOnInputs = (function() {
+  var div = document.createElement('div'),
+      el = document.createElement('input');
+
+  el.setAttribute('name', 'foo');
+  div.appendChild(el);
+
+  return !!div.innerHTML.match('foo');
+})();
+
</ins><span class="cx"> /**
</span><span class="cx">   `Ember.RenderBuffer` gathers information regarding the a view and generates the
</span><span class="cx">   final representation. `Ember.RenderBuffer` will generate HTML which can be pushed
</span><span class="cx">   to the DOM.
</span><span class="cx"> 
</span><ins>+   ```javascript
+   var buffer = Ember.RenderBuffer('div');
+  ```
+
</ins><span class="cx">   @class RenderBuffer
</span><span class="cx">   @namespace Ember
</span><span class="cx">   @constructor
</span><ins>+  @param {String} tagName tag name (such as 'div' or 'p') used for the buffer
</ins><span class="cx"> */
</span><span class="cx"> Ember.RenderBuffer = function(tagName) {
</span><span class="cx">   return new Ember._RenderBuffer(tagName);
</span><span class="lines">@@ -12790,22 +20864,22 @@
</span><span class="cx"> 
</span><span class="cx"> Ember._RenderBuffer = function(tagName) {
</span><span class="cx">   this.tagNames = [tagName || null];
</span><del>-  this.buffer = [];
</del><ins>+  this.buffer = &quot;&quot;;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-Ember._RenderBuffer.prototype =
-/** @scope Ember.RenderBuffer.prototype */ {
</del><ins>+Ember._RenderBuffer.prototype = {
</ins><span class="cx"> 
</span><span class="cx">   // The root view's element
</span><span class="cx">   _element: null,
</span><span class="cx"> 
</span><ins>+  _hasElement: true,
+
</ins><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     An internal set used to de-dupe class names when `addClass()` is
</span><span class="cx">     used. After each call to `addClass()`, the `classes` property
</span><span class="cx">     will be updated.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @property elementClasses
</span><span class="cx">     @type Array
</span><span class="cx">     @default []
</span><span class="lines">@@ -12914,7 +20988,7 @@
</span><span class="cx">     @chainable
</span><span class="cx">   */
</span><span class="cx">   push: function(string) {
</span><del>-    this.buffer.push(string);
</del><ins>+    this.buffer += string;
</ins><span class="cx">     return this;
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="lines">@@ -12927,7 +21001,7 @@
</span><span class="cx">   */
</span><span class="cx">   addClass: function(className) {
</span><span class="cx">     // lazily create elementClasses
</span><del>-    var elementClasses = this.elementClasses = (this.elementClasses || new ClassSet());
</del><ins>+    this.elementClasses = (this.elementClasses || new ClassSet());
</ins><span class="cx">     this.elementClasses.add(className);
</span><span class="cx">     this.classes = this.elementClasses.list;
</span><span class="cx"> 
</span><span class="lines">@@ -13032,7 +21106,7 @@
</span><span class="cx">     @chainable
</span><span class="cx">   */
</span><span class="cx">   style: function(name, value) {
</span><del>-    var style = this.elementStyle = (this.elementStyle || {});
</del><ins>+    this.elementStyle = (this.elementStyle || {});
</ins><span class="cx"> 
</span><span class="cx">     this.elementStyle[name] = value;
</span><span class="cx">     return this;
</span><span class="lines">@@ -13047,7 +21121,7 @@
</span><span class="cx">     var tagName = this.currentTagName();
</span><span class="cx">     if (!tagName) { return; }
</span><span class="cx"> 
</span><del>-    if (!this._element &amp;&amp; this.buffer.length === 0) {
</del><ins>+    if (this._hasElement &amp;&amp; !this._element &amp;&amp; this.buffer.length === 0) {
</ins><span class="cx">       this._element = this.generateElement();
</span><span class="cx">       return;
</span><span class="cx">     }
</span><span class="lines">@@ -13060,27 +21134,27 @@
</span><span class="cx">         style = this.elementStyle,
</span><span class="cx">         attr, prop;
</span><span class="cx"> 
</span><del>-    buffer.push('&lt;' + tagName);
</del><ins>+    buffer += '&lt;' + stripTagName(tagName);
</ins><span class="cx"> 
</span><span class="cx">     if (id) {
</span><del>-      buffer.push(' id=&quot;' + this._escapeAttribute(id) + '&quot;');
</del><ins>+      buffer += ' id=&quot;' + escapeAttribute(id) + '&quot;';
</ins><span class="cx">       this.elementId = null;
</span><span class="cx">     }
</span><span class="cx">     if (classes) {
</span><del>-      buffer.push(' class=&quot;' + this._escapeAttribute(classes.join(' ')) + '&quot;');
</del><ins>+      buffer += ' class=&quot;' + escapeAttribute(classes.join(' ')) + '&quot;';
</ins><span class="cx">       this.classes = null;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (style) {
</span><del>-      buffer.push(' style=&quot;');
</del><ins>+      buffer += ' style=&quot;';
</ins><span class="cx"> 
</span><span class="cx">       for (prop in style) {
</span><span class="cx">         if (style.hasOwnProperty(prop)) {
</span><del>-          buffer.push(prop + ':' + this._escapeAttribute(style[prop]) + ';');
</del><ins>+          buffer += prop + ':' + escapeAttribute(style[prop]) + ';';
</ins><span class="cx">         }
</span><span class="cx">       }
</span><span class="cx"> 
</span><del>-      buffer.push('&quot;');
</del><ins>+      buffer += '&quot;';
</ins><span class="cx"> 
</span><span class="cx">       this.elementStyle = null;
</span><span class="cx">     }
</span><span class="lines">@@ -13088,7 +21162,7 @@
</span><span class="cx">     if (attrs) {
</span><span class="cx">       for (attr in attrs) {
</span><span class="cx">         if (attrs.hasOwnProperty(attr)) {
</span><del>-          buffer.push(' ' + attr + '=&quot;' + this._escapeAttribute(attrs[attr]) + '&quot;');
</del><ins>+          buffer += ' ' + attr + '=&quot;' + escapeAttribute(attrs[attr]) + '&quot;';
</ins><span class="cx">         }
</span><span class="cx">       }
</span><span class="cx"> 
</span><span class="lines">@@ -13101,9 +21175,9 @@
</span><span class="cx">           var value = props[prop];
</span><span class="cx">           if (value || typeof(value) === 'number') {
</span><span class="cx">             if (value === true) {
</span><del>-              buffer.push(' ' + prop + '=&quot;' + prop + '&quot;');
</del><ins>+              buffer += ' ' + prop + '=&quot;' + prop + '&quot;';
</ins><span class="cx">             } else {
</span><del>-              buffer.push(' ' + prop + '=&quot;' + this._escapeAttribute(props[prop]) + '&quot;');
</del><ins>+              buffer += ' ' + prop + '=&quot;' + escapeAttribute(props[prop]) + '&quot;';
</ins><span class="cx">             }
</span><span class="cx">           }
</span><span class="cx">         }
</span><span class="lines">@@ -13112,12 +21186,13 @@
</span><span class="cx">       this.elementProperties = null;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    buffer.push('&gt;');
</del><ins>+    buffer += '&gt;';
+    this.buffer = buffer;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   pushClosingTag: function() {
</span><span class="cx">     var tagName = this.tagNames.pop();
</span><del>-    if (tagName) { this.buffer.push('&lt;/' + tagName + '&gt;'); }
</del><ins>+    if (tagName) { this.buffer += '&lt;/' + stripTagName(tagName) + '&gt;'; }
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   currentTagName: function() {
</span><span class="lines">@@ -13126,15 +21201,23 @@
</span><span class="cx"> 
</span><span class="cx">   generateElement: function() {
</span><span class="cx">     var tagName = this.tagNames.pop(), // pop since we don't need to close
</span><del>-        element = document.createElement(tagName),
-        $element = Ember.$(element),
</del><span class="cx">         id = this.elementId,
</span><span class="cx">         classes = this.classes,
</span><span class="cx">         attrs = this.elementAttributes,
</span><span class="cx">         props = this.elementProperties,
</span><span class="cx">         style = this.elementStyle,
</span><del>-        styleBuffer = '', attr, prop;
</del><ins>+        styleBuffer = '', attr, prop, tagString;
</ins><span class="cx"> 
</span><ins>+    if (attrs &amp;&amp; attrs.name &amp;&amp; !canSetNameOnInputs) {
+      // IE allows passing a tag to createElement. See note on `canSetNameOnInputs` above as well.
+      tagString = '&lt;'+stripTagName(tagName)+' name=&quot;'+escapeAttribute(attrs.name)+'&quot;&gt;';
+    } else {
+      tagString = tagName;
+    }
+
+    var element = document.createElement(tagString),
+        $element = Ember.$(element);
+
</ins><span class="cx">     if (id) {
</span><span class="cx">       $element.attr('id', id);
</span><span class="cx">       this.elementId = null;
</span><span class="lines">@@ -13201,41 +21284,21 @@
</span><span class="cx">     @return {String} The generated HTML
</span><span class="cx">   */
</span><span class="cx">   string: function() {
</span><del>-    if (this._element) {
-      return this.element().outerHTML;
</del><ins>+    if (this._hasElement &amp;&amp; this._element) {
+      // Firefox versions &lt; 11 do not have support for element.outerHTML.
+      var thisElement = this.element(), outerHTML = thisElement.outerHTML;
+      if (typeof outerHTML === 'undefined') {
+        return Ember.$('&lt;div/&gt;').append(thisElement).html();
+      }
+      return outerHTML;
</ins><span class="cx">     } else {
</span><span class="cx">       return this.innerString();
</span><span class="cx">     }
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   innerString: function() {
</span><del>-    return this.buffer.join('');
-  },
-
-  _escapeAttribute: function(value) {
-    // Stolen shamelessly from Handlebars
-
-    var escape = {
-      &quot;&lt;&quot;: &quot;&amp;lt;&quot;,
-      &quot;&gt;&quot;: &quot;&amp;gt;&quot;,
-      '&quot;': &quot;&amp;quot;&quot;,
-      &quot;'&quot;: &quot;&amp;#x27;&quot;,
-      &quot;`&quot;: &quot;&amp;#x60;&quot;
-    };
-
-    var badChars = /&amp;(?!\w+;)|[&lt;&gt;&quot;'`]/g;
-    var possible = /[&amp;&lt;&gt;&quot;'`]/;
-
-    var escapeChar = function(chr) {
-      return escape[chr] || &quot;&amp;amp;&quot;;
-    };
-
-    var string = value.toString();
-
-    if(!possible.test(string)) { return string; }
-    return string.replace(badChars, escapeChar);
</del><ins>+    return this.buffer;
</ins><span class="cx">   }
</span><del>-
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> })();
</span><span class="lines">@@ -13261,12 +21324,50 @@
</span><span class="cx">   @private
</span><span class="cx">   @extends Ember.Object
</span><span class="cx"> */
</span><del>-Ember.EventDispatcher = Ember.Object.extend(
-/** @scope Ember.EventDispatcher.prototype */{
</del><ins>+Ember.EventDispatcher = Ember.Object.extend({
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
</del><ins>+    The set of events names (and associated handler function names) to be setup
+    and dispatched by the `EventDispatcher`. Custom events can added to this list at setup
+    time, generally via the `Ember.Application.customEvents` hash. Only override this
+    default set to prevent the EventDispatcher from listening on some events all together.
</ins><span class="cx"> 
</span><ins>+    This set will be modified by `setup` to also include any events added at that time.
+
+    @property events
+    @type Object
+  */
+  events: {
+    touchstart  : 'touchStart',
+    touchmove   : 'touchMove',
+    touchend    : 'touchEnd',
+    touchcancel : 'touchCancel',
+    keydown     : 'keyDown',
+    keyup       : 'keyUp',
+    keypress    : 'keyPress',
+    mousedown   : 'mouseDown',
+    mouseup     : 'mouseUp',
+    contextmenu : 'contextMenu',
+    click       : 'click',
+    dblclick    : 'doubleClick',
+    mousemove   : 'mouseMove',
+    focusin     : 'focusIn',
+    focusout    : 'focusOut',
+    mouseenter  : 'mouseEnter',
+    mouseleave  : 'mouseLeave',
+    submit      : 'submit',
+    input       : 'input',
+    change      : 'change',
+    dragstart   : 'dragStart',
+    drag        : 'drag',
+    dragenter   : 'dragEnter',
+    dragleave   : 'dragLeave',
+    dragover    : 'dragOver',
+    drop        : 'drop',
+    dragend     : 'dragEnd'
+  },
+
+  /**
</ins><span class="cx">     The root DOM element to which event listeners should be attached. Event
</span><span class="cx">     listeners will be attached to the document unless this is overridden.
</span><span class="cx"> 
</span><span class="lines">@@ -13275,6 +21376,7 @@
</span><span class="cx">     The default body is a string since this may be evaluated before document.body
</span><span class="cx">     exists in the DOM.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @property rootElement
</span><span class="cx">     @type DOMElement
</span><span class="cx">     @default 'body'
</span><span class="lines">@@ -13282,8 +21384,6 @@
</span><span class="cx">   rootElement: 'body',
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Sets up event listeners for standard browser events.
</span><span class="cx"> 
</span><span class="cx">     This will be called after the browser sends a `DOMContentReady` event. By
</span><span class="lines">@@ -13291,44 +21391,22 @@
</span><span class="cx">     would like to register the listeners on a different element, set the event
</span><span class="cx">     dispatcher's `root` property.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method setup
</span><span class="cx">     @param addedEvents {Hash}
</span><span class="cx">   */
</span><del>-  setup: function(addedEvents) {
-    var event, events = {
-      touchstart  : 'touchStart',
-      touchmove   : 'touchMove',
-      touchend    : 'touchEnd',
-      touchcancel : 'touchCancel',
-      keydown     : 'keyDown',
-      keyup       : 'keyUp',
-      keypress    : 'keyPress',
-      mousedown   : 'mouseDown',
-      mouseup     : 'mouseUp',
-      contextmenu : 'contextMenu',
-      click       : 'click',
-      dblclick    : 'doubleClick',
-      mousemove   : 'mouseMove',
-      focusin     : 'focusIn',
-      focusout    : 'focusOut',
-      mouseenter  : 'mouseEnter',
-      mouseleave  : 'mouseLeave',
-      submit      : 'submit',
-      input       : 'input',
-      change      : 'change',
-      dragstart   : 'dragStart',
-      drag        : 'drag',
-      dragenter   : 'dragEnter',
-      dragleave   : 'dragLeave',
-      dragover    : 'dragOver',
-      drop        : 'drop',
-      dragend     : 'dragEnd'
-    };
</del><ins>+  setup: function(addedEvents, rootElement) {
+    var event, events = get(this, 'events');
</ins><span class="cx"> 
</span><span class="cx">     Ember.$.extend(events, addedEvents || {});
</span><span class="cx"> 
</span><del>-    var rootElement = Ember.$(get(this, 'rootElement'));
</del><span class="cx"> 
</span><ins>+    if (!Ember.isNone(rootElement)) {
+      set(this, 'rootElement', rootElement);
+    }
+
+    rootElement = Ember.$(get(this, 'rootElement'));
+
</ins><span class="cx">     Ember.assert(fmt('You cannot use the same root element (%@) multiple times in an Ember.Application', [rootElement.selector || rootElement[0].tagName]), !rootElement.is('.ember-application'));
</span><span class="cx">     Ember.assert('You cannot make a new Ember.Application using a root element that is a descendent of an existing Ember.Application', !rootElement.closest('.ember-application').length);
</span><span class="cx">     Ember.assert('You cannot make a new Ember.Application using a root element that is an ancestor of an existing Ember.Application', !rootElement.find('.ember-application').length);
</span><span class="lines">@@ -13345,8 +21423,6 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Registers an event listener on the document. If the given event is
</span><span class="cx">     triggered, the provided event handler will be triggered on the target view.
</span><span class="cx"> 
</span><span class="lines">@@ -13361,6 +21437,7 @@
</span><span class="cx">     setupHandler('mousedown', 'mouseDown');
</span><span class="cx">     ```
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method setupHandler
</span><span class="cx">     @param {Element} rootElement
</span><span class="cx">     @param {String} event the browser-originated event to listen to
</span><span class="lines">@@ -13369,8 +21446,8 @@
</span><span class="cx">   setupHandler: function(rootElement, event, eventName) {
</span><span class="cx">     var self = this;
</span><span class="cx"> 
</span><del>-    rootElement.delegate('.ember-view', event + '.ember', function(evt, triggeringManager) {
-      return Ember.handleErrors(function() {
</del><ins>+    rootElement.on(event + '.ember', '.ember-view', function(evt, triggeringManager) {
+      return Ember.handleErrors(function handleViewEvent() {
</ins><span class="cx">         var view = Ember.View.views[this.id],
</span><span class="cx">             result = true, manager = null;
</span><span class="cx"> 
</span><span class="lines">@@ -13388,8 +21465,8 @@
</span><span class="cx">       }, this);
</span><span class="cx">     });
</span><span class="cx"> 
</span><del>-    rootElement.delegate('[data-ember-action]', event + '.ember', function(evt) {
-      return Ember.handleErrors(function() {
</del><ins>+    rootElement.on(event + '.ember', '[data-ember-action]', function(evt) {
+      return Ember.handleErrors(function handleActionEvent() {
</ins><span class="cx">         var actionId = Ember.$(evt.currentTarget).attr('data-ember-action'),
</span><span class="cx">             action   = Ember.Handlebars.ActionHelper.registeredActions[actionId];
</span><span class="cx"> 
</span><span class="lines">@@ -13421,7 +21498,9 @@
</span><span class="cx"> 
</span><span class="cx">     var handler = object[eventName];
</span><span class="cx">     if (Ember.typeOf(handler) === 'function') {
</span><del>-      result = handler.call(object, evt, view);
</del><ins>+      result = Ember.run(function() {
+        return handler.call(object, evt, view);
+      });
</ins><span class="cx">       // Do not preventDefault in eventManagers.
</span><span class="cx">       evt.stopPropagation();
</span><span class="cx">     }
</span><span class="lines">@@ -13433,14 +21512,14 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   _bubbleEvent: function(view, evt, eventName) {
</span><del>-    return Ember.run(function() {
</del><ins>+    return Ember.run(function bubbleEvent() {
</ins><span class="cx">       return view.handleEvent(eventName, evt);
</span><span class="cx">     });
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   destroy: function() {
</span><span class="cx">     var rootElement = get(this, 'rootElement');
</span><del>-    Ember.$(rootElement).undelegate('.ember').removeClass('ember-application');
</del><ins>+    Ember.$(rootElement).off('.ember', '**').removeClass('ember-application');
</ins><span class="cx">     return this._super();
</span><span class="cx">   }
</span><span class="cx"> });
</span><span class="lines">@@ -13458,8 +21537,9 @@
</span><span class="cx"> // Add a new named queue for rendering views that happens
</span><span class="cx"> // after bindings have synced, and a queue for scheduling actions
</span><span class="cx"> // that that should occur after view rendering.
</span><del>-var queues = Ember.run.queues;
-queues.splice(Ember.$.inArray('actions', queues)+1, 0, 'render', 'afterRender');
</del><ins>+var queues = Ember.run.queues,
+    indexOf = Ember.ArrayPolyfills.indexOf;
+queues.splice(indexOf.call(queues, 'actions')+1, 0, 'render', 'afterRender');
</ins><span class="cx"> 
</span><span class="cx"> })();
</span><span class="cx"> 
</span><span class="lines">@@ -13494,9 +21574,8 @@
</span><span class="cx">     set(this, '_childContainers', {});
</span><span class="cx">   },
</span><span class="cx"> 
</span><del>-  _modelDidChange: Ember.observer(function() {
-    var containers = get(this, '_childContainers'),
-        container;
</del><ins>+  _modelDidChange: Ember.observer('model', function() {
+    var containers = get(this, '_childContainers');
</ins><span class="cx"> 
</span><span class="cx">     for (var prop in containers) {
</span><span class="cx">       if (!containers.hasOwnProperty(prop)) { continue; }
</span><span class="lines">@@ -13504,7 +21583,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     set(this, '_childContainers', {});
</span><del>-  }, 'model')
</del><ins>+  })
</ins><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> })();
</span><span class="lines">@@ -13525,18 +21604,21 @@
</span><span class="cx"> @submodule ember-views
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var get = Ember.get, set = Ember.set, addObserver = Ember.addObserver, removeObserver = Ember.removeObserver;
-var meta = Ember.meta, guidFor = Ember.guidFor, fmt = Ember.String.fmt;
-var a_slice = [].slice;
</del><ins>+var get = Ember.get, set = Ember.set;
+var guidFor = Ember.guidFor;
</ins><span class="cx"> var a_forEach = Ember.EnumerableUtils.forEach;
</span><span class="cx"> var a_addObject = Ember.EnumerableUtils.addObject;
</span><ins>+var meta = Ember.meta;
</ins><span class="cx"> 
</span><span class="cx"> var childViewsProperty = Ember.computed(function() {
</span><span class="cx">   var childViews = this._childViews, ret = Ember.A(), view = this;
</span><span class="cx"> 
</span><span class="cx">   a_forEach(childViews, function(view) {
</span><ins>+    var currentChildViews;
</ins><span class="cx">     if (view.isVirtual) {
</span><del>-      ret.pushObjects(get(view, 'childViews'));
</del><ins>+      if (currentChildViews = get(view, 'childViews')) {
+        ret.pushObjects(currentChildViews);
+      }
</ins><span class="cx">     } else {
</span><span class="cx">       ret.push(view);
</span><span class="cx">     }
</span><span class="lines">@@ -13544,10 +21626,10 @@
</span><span class="cx"> 
</span><span class="cx">   ret.replace = function (idx, removedCount, addedViews) {
</span><span class="cx">     if (view instanceof Ember.ContainerView) {
</span><del>-      Ember.deprecate(&quot;Manipulating a Ember.ContainerView through its childViews property is deprecated. Please use the ContainerView instance itself as an Ember.MutableArray.&quot;);
</del><ins>+      Ember.deprecate(&quot;Manipulating an Ember.ContainerView through its childViews property is deprecated. Please use the ContainerView instance itself as an Ember.MutableArray.&quot;);
</ins><span class="cx">       return view.replace(idx, removedCount, addedViews);
</span><span class="cx">     }
</span><del>-    throw new Error(&quot;childViews is immutable&quot;);
</del><ins>+    throw new Ember.Error(&quot;childViews is immutable&quot;);
</ins><span class="cx">   };
</span><span class="cx"> 
</span><span class="cx">   return ret;
</span><span class="lines">@@ -13566,25 +21648,29 @@
</span><span class="cx"> */
</span><span class="cx"> Ember.TEMPLATES = {};
</span><span class="cx"> 
</span><del>-Ember.CoreView = Ember.Object.extend(Ember.Evented, {
</del><ins>+/**
+  `Ember.CoreView` is an abstract class that exists to give view-like behavior
+  to both Ember's main view class `Ember.View` and other classes like
+  `Ember._SimpleMetamorphView` that don't need the fully functionaltiy of
+  `Ember.View`.
+
+  Unless you have specific needs for `CoreView`, you will use `Ember.View`
+  in your applications.
+
+  @class CoreView
+  @namespace Ember
+  @extends Ember.Object
+  @uses Ember.Evented
+  @uses Ember.ActionHandler
+*/
+
+Ember.CoreView = Ember.Object.extend(Ember.Evented, Ember.ActionHandler, {
</ins><span class="cx">   isView: true,
</span><span class="cx"> 
</span><span class="cx">   states: states,
</span><span class="cx"> 
</span><span class="cx">   init: function() {
</span><span class="cx">     this._super();
</span><del>-
-    // Register the view for event handling. This hash is used by
-    // Ember.EventDispatcher to dispatch incoming events.
-    if (!this.isVirtual) {
-      Ember.assert(&quot;Attempted to register a view with an id already in use: &quot;+this.elementId, !Ember.View.views[this.elementId]);
-      Ember.View.views[this.elementId] = this;
-    }
-
-    this.addBeforeObserver('elementId', function() {
-      throw new Error(&quot;Changing a view's elementId after creation is not allowed&quot;);
-    });
-
</del><span class="cx">     this.transitionTo('preRender');
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="lines">@@ -13614,7 +21700,7 @@
</span><span class="cx">   concreteView: Ember.computed(function() {
</span><span class="cx">     if (!this.isVirtual) { return this; }
</span><span class="cx">     else { return get(this, 'parentView'); }
</span><del>-  }).property('parentView').volatile(),
</del><ins>+  }).property('parentView'),
</ins><span class="cx"> 
</span><span class="cx">   instrumentName: 'core_view',
</span><span class="cx"> 
</span><span class="lines">@@ -13623,8 +21709,6 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Invoked by the view system when this view needs to produce an HTML
</span><span class="cx">     representation. This method will create a new render buffer, if needed,
</span><span class="cx">     then apply any default attributes, such as class names and visibility.
</span><span class="lines">@@ -13639,6 +21723,7 @@
</span><span class="cx">     @param {Ember.RenderBuffer} buffer the render buffer. If no buffer is
</span><span class="cx">       passed, a default buffer, using the current view's `tagName`, will
</span><span class="cx">       be used.
</span><ins>+    @private
</ins><span class="cx">   */
</span><span class="cx">   renderToBuffer: function(parentBuffer, bufferOperation) {
</span><span class="cx">     var name = 'render.' + this.instrumentName,
</span><span class="lines">@@ -13646,14 +21731,12 @@
</span><span class="cx"> 
</span><span class="cx">     this.instrumentDetails(details);
</span><span class="cx"> 
</span><del>-    return Ember.instrument(name, details, function() {
</del><ins>+    return Ember.instrument(name, details, function instrumentRenderToBuffer() {
</ins><span class="cx">       return this._renderToBuffer(parentBuffer, bufferOperation);
</span><span class="cx">     }, this);
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   _renderToBuffer: function(parentBuffer, bufferOperation) {
</span><del>-    Ember.run.sync();
-
</del><span class="cx">     // If this is the top-most view, start a new buffer. Otherwise,
</span><span class="cx">     // create a new buffer relative to the original using the
</span><span class="cx">     // provided buffer operation (for example, `insertAfter` will
</span><span class="lines">@@ -13675,13 +21758,12 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Override the default event firing from `Ember.Evented` to
</span><span class="cx">     also call methods with the given name.
</span><span class="cx"> 
</span><span class="cx">     @method trigger
</span><span class="cx">     @param name {String}
</span><ins>+    @private
</ins><span class="cx">   */
</span><span class="cx">   trigger: function(name) {
</span><span class="cx">     this._super.apply(this, arguments);
</span><span class="lines">@@ -13695,13 +21777,27 @@
</span><span class="cx">     }
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  deprecatedSendHandles: function(actionName) {
+    return !!this[actionName];
+  },
+
+  deprecatedSend: function(actionName) {
+    var args = [].slice.call(arguments, 1);
+    Ember.assert('' + this + &quot; has the action &quot; + actionName + &quot; but it is not a function&quot;, typeof this[actionName] === 'function');
+    Ember.deprecate('Action handlers implemented directly on views are deprecated in favor of action handlers on an `actions` object (' + actionName + ' on ' + this + ')', false);
+    this[actionName].apply(this, args);
+    return;
+  },
+
</ins><span class="cx">   has: function(name) {
</span><span class="cx">     return Ember.typeOf(this[name]) === 'function' || this._super(name);
</span><span class="cx">   },
</span><span class="cx"> 
</span><del>-  willDestroy: function() {
</del><ins>+  destroy: function() {
</ins><span class="cx">     var parent = this._parentView;
</span><span class="cx"> 
</span><ins>+    if (!this._super()) { return; }
+
</ins><span class="cx">     // destroy the element -- this will avoid each child view destroying
</span><span class="cx">     // the element over and over again...
</span><span class="cx">     if (!this.removedFromDOM) { this.destroyElement(); }
</span><span class="lines">@@ -13711,10 +21807,9 @@
</span><span class="cx">     // the DOM again.
</span><span class="cx">     if (parent) { parent.removeChild(this); }
</span><span class="cx"> 
</span><del>-    this.transitionTo('destroyed');
</del><ins>+    this.transitionTo('destroying', false);
</ins><span class="cx"> 
</span><del>-    // next remove view from global hash
-    if (!this.isVirtual) delete Ember.View.views[this.elementId];
</del><ins>+    return this;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   clearRenderedChildren: Ember.K,
</span><span class="lines">@@ -13724,6 +21819,68 @@
</span><span class="cx">   destroyElement: Ember.K
</span><span class="cx"> });
</span><span class="cx"> 
</span><ins>+var ViewCollection = Ember._ViewCollection = function(initialViews) {
+  var views = this.views = initialViews || [];
+  this.length = views.length;
+};
+
+ViewCollection.prototype = {
+  length: 0,
+
+  trigger: function(eventName) {
+    var views = this.views, view;
+    for (var i = 0, l = views.length; i &lt; l; i++) {
+      view = views[i];
+      if (view.trigger) { view.trigger(eventName); }
+    }
+  },
+
+  triggerRecursively: function(eventName) {
+    var views = this.views;
+    for (var i = 0, l = views.length; i &lt; l; i++) {
+      views[i].triggerRecursively(eventName);
+    }
+  },
+
+  invokeRecursively: function(fn) {
+    var views = this.views, view;
+
+    for (var i = 0, l = views.length; i &lt; l; i++) {
+      view = views[i];
+      fn(view);
+    }
+  },
+
+  transitionTo: function(state, children) {
+    var views = this.views;
+    for (var i = 0, l = views.length; i &lt; l; i++) {
+      views[i].transitionTo(state, children);
+    }
+  },
+
+  push: function() {
+    this.length += arguments.length;
+    var views = this.views;
+    return views.push.apply(views, arguments);
+  },
+
+  objectAt: function(idx) {
+    return this.views[idx];
+  },
+
+  forEach: function(callback) {
+    var views = this.views;
+    return a_forEach(views, callback);
+  },
+
+  clear: function() {
+    this.length = 0;
+    this.views.length = 0;
+  }
+};
+
+var EMPTY_ARRAY = [];
+
</ins><span class="cx"> /**
</span><span class="cx">   `Ember.View` is the class in Ember responsible for encapsulating templates of
</span><span class="cx">   HTML content, combining templates with data to render as sections of a page's
</span><span class="lines">@@ -13733,7 +21890,7 @@
</span><span class="cx"> 
</span><span class="cx">   The default HTML tag name used for a view's DOM representation is `div`. This
</span><span class="cx">   can be customized by setting the `tagName` property. The following view
</span><del>-class:
</del><ins>+  class:
</ins><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="cx">   ParagraphView = Ember.View.extend({
</span><span class="lines">@@ -13773,8 +21930,8 @@
</span><span class="cx">   MyView = Ember.View.extend({
</span><span class="cx">     classNameBindings: ['propertyA', 'propertyB'],
</span><span class="cx">     propertyA: 'from-a',
</span><del>-    propertyB: function(){
-      if(someLogic){ return 'from-b'; }
</del><ins>+    propertyB: function() {
+      if (someLogic) { return 'from-b'; }
</ins><span class="cx">     }.property()
</span><span class="cx">   });
</span><span class="cx">   ```
</span><span class="lines">@@ -13859,7 +22016,7 @@
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="cx">   // Applies 'enabled' class when isEnabled is true and 'disabled' when isEnabled is false
</span><del>-  Ember.View.create({
</del><ins>+  Ember.View.extend({
</ins><span class="cx">     classNameBindings: ['isEnabled:enabled:disabled']
</span><span class="cx">     isEnabled: true
</span><span class="cx">   });
</span><span class="lines">@@ -13882,7 +22039,7 @@
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="cx">   // Applies no class when isEnabled is true and class 'disabled' when isEnabled is false
</span><del>-  Ember.View.create({
</del><ins>+  Ember.View.extend({
</ins><span class="cx">     classNameBindings: ['isEnabled::disabled']
</span><span class="cx">     isEnabled: true
</span><span class="cx">   });
</span><span class="lines">@@ -13907,8 +22064,8 @@
</span><span class="cx">   will be removed.
</span><span class="cx"> 
</span><span class="cx">   Both `classNames` and `classNameBindings` are concatenated properties. See
</span><del>-  `Ember.Object` documentation for more information about concatenated
-  properties.
</del><ins>+  [Ember.Object](/api/classes/Ember.Object.html) documentation for more
+  information about concatenated properties.
</ins><span class="cx"> 
</span><span class="cx">   ## HTML Attributes
</span><span class="cx"> 
</span><span class="lines">@@ -13955,7 +22112,7 @@
</span><span class="cx">   MyTextInput = Ember.View.extend({
</span><span class="cx">     tagName: 'input',
</span><span class="cx">     attributeBindings: ['disabled'],
</span><del>-    disabled: function(){
</del><ins>+    disabled: function() {
</ins><span class="cx">       if (someLogic) {
</span><span class="cx">         return true;
</span><span class="cx">       } else {
</span><span class="lines">@@ -13968,7 +22125,7 @@
</span><span class="cx">   Updates to the the property of an attribute binding will result in automatic
</span><span class="cx">   update of the  HTML attribute in the view's rendered HTML representation.
</span><span class="cx"> 
</span><del>-  `attributeBindings` is a concatenated property. See `Ember.Object`
</del><ins>+  `attributeBindings` is a concatenated property. See [Ember.Object](/api/classes/Ember.Object.html)
</ins><span class="cx">   documentation for more information about concatenated properties.
</span><span class="cx"> 
</span><span class="cx">   ## Templates
</span><span class="lines">@@ -14008,12 +22165,25 @@
</span><span class="cx">   });
</span><span class="cx">   ```
</span><span class="cx"> 
</span><ins>+  If you have nested resources, your Handlebars template will look like this:
+
+  ```html
+  &lt;script type='text/x-handlebars' data-template-name='posts/new'&gt;
+    &lt;h1&gt;New Post&lt;/h1&gt;
+  &lt;/script&gt;
+  ```
+
+  And `templateName` property:
+
+  ```javascript
+  AView = Ember.View.extend({
+    templateName: 'posts/new'
+  });
+  ```
+
</ins><span class="cx">   Using a value for `templateName` that does not have a Handlebars template
</span><span class="cx">   with a matching `data-template-name` attribute will throw an error.
</span><span class="cx"> 
</span><del>-  Assigning a value to both `template` and `templateName` properties will throw
-  an error.
-
</del><span class="cx">   For views classes that may have a template later defined (e.g. as the block
</span><span class="cx">   portion of a `{{view}}` Handlebars helper call in another template or in
</span><span class="cx">   a subclass), you can provide a `defaultTemplate` property set to compiled
</span><span class="lines">@@ -14064,7 +22234,7 @@
</span><span class="cx"> 
</span><span class="cx">   aController = Ember.Object.create({
</span><span class="cx">     firstName: 'Barry',
</span><del>-    excitedGreeting: function(){
</del><ins>+    excitedGreeting: function() {
</ins><span class="cx">       return this.get(&quot;content.firstName&quot;) + &quot;!!!&quot;
</span><span class="cx">     }.property()
</span><span class="cx">   });
</span><span class="lines">@@ -14119,7 +22289,8 @@
</span><span class="cx">   &lt;/div&gt;
</span><span class="cx">   ```
</span><span class="cx"> 
</span><del>-  See `Handlebars.helpers.yield` for more information.
</del><ins>+  See [Ember.Handlebars.helpers.yield](/api/classes/Ember.Handlebars.helpers.html#method_yield)
+  for more information.
</ins><span class="cx"> 
</span><span class="cx">   ## Responding to Browser Events
</span><span class="cx"> 
</span><span class="lines">@@ -14135,7 +22306,7 @@
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="cx">   AView = Ember.View.extend({
</span><del>-    click: function(event){
</del><ins>+    click: function(event) {
</ins><span class="cx">       // will be called when when an instance's
</span><span class="cx">       // rendered element is clicked
</span><span class="cx">     }
</span><span class="lines">@@ -14156,7 +22327,7 @@
</span><span class="cx">   ```javascript
</span><span class="cx">   AView = Ember.View.extend({
</span><span class="cx">     eventManager: Ember.Object.create({
</span><del>-      doubleClick: function(event, view){
</del><ins>+      doubleClick: function(event, view) {
</ins><span class="cx">         // will be called when when an instance's
</span><span class="cx">         // rendered element or any rendering
</span><span class="cx">         // of this views's descendent
</span><span class="lines">@@ -14171,12 +22342,12 @@
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="cx">   AView = Ember.View.extend({
</span><del>-    mouseEnter: function(event){
</del><ins>+    mouseEnter: function(event) {
</ins><span class="cx">       // will never trigger.
</span><span class="cx">     },
</span><span class="cx">     eventManager: Ember.Object.create({
</span><del>-      mouseEnter: function(event, view){
-        // takes presedence over AView#mouseEnter
</del><ins>+      mouseEnter: function(event, view) {
+        // takes precedence over AView#mouseEnter
</ins><span class="cx">       }
</span><span class="cx">     })
</span><span class="cx">   });
</span><span class="lines">@@ -14193,21 +22364,21 @@
</span><span class="cx">   OuterView = Ember.View.extend({
</span><span class="cx">     template: Ember.Handlebars.compile(&quot;outer {{#view InnerView}}inner{{/view}} outer&quot;),
</span><span class="cx">     eventManager: Ember.Object.create({
</span><del>-      mouseEnter: function(event, view){
</del><ins>+      mouseEnter: function(event, view) {
</ins><span class="cx">         // view might be instance of either
</span><del>-        // OutsideView or InnerView depending on
</del><ins>+        // OuterView or InnerView depending on
</ins><span class="cx">         // where on the page the user interaction occured
</span><span class="cx">       }
</span><span class="cx">     })
</span><span class="cx">   });
</span><span class="cx"> 
</span><span class="cx">   InnerView = Ember.View.extend({
</span><del>-    click: function(event){
</del><ins>+    click: function(event) {
</ins><span class="cx">       // will be called if rendered inside
</span><span class="cx">       // an OuterView because OuterView's
</span><span class="cx">       // eventManager doesn't handle click events
</span><span class="cx">     },
</span><del>-    mouseEnter: function(event){
</del><ins>+    mouseEnter: function(event) {
</ins><span class="cx">       // will never be called if rendered inside
</span><span class="cx">       // an OuterView.
</span><span class="cx">     }
</span><span class="lines">@@ -14216,12 +22387,14 @@
</span><span class="cx"> 
</span><span class="cx">   ### Handlebars `{{action}}` Helper
</span><span class="cx"> 
</span><del>-  See `Handlebars.helpers.action`.
</del><ins>+  See [Handlebars.helpers.action](/api/classes/Ember.Handlebars.helpers.html#method_action).
</ins><span class="cx"> 
</span><span class="cx">   ### Event Names
</span><span class="cx"> 
</span><del>-  Possible events names for any of the responding approaches described above
-  are:
</del><ins>+  All of the event handling approaches described above respond to the same set
+  of events. The names of the built-in events are listed below. (The hash of
+  built-in events exists in `Ember.EventDispatcher`.) Additional, custom events
+  can be registered by using `Ember.Application.customEvents`.
</ins><span class="cx"> 
</span><span class="cx">   Touch events:
</span><span class="cx"> 
</span><span class="lines">@@ -14249,7 +22422,7 @@
</span><span class="cx">   * `mouseEnter`
</span><span class="cx">   * `mouseLeave`
</span><span class="cx"> 
</span><del>-  Form events: 
</del><ins>+  Form events:
</ins><span class="cx"> 
</span><span class="cx">   * `submit`
</span><span class="cx">   * `change`
</span><span class="lines">@@ -14257,7 +22430,7 @@
</span><span class="cx">   * `focusOut`
</span><span class="cx">   * `input`
</span><span class="cx"> 
</span><del>-  HTML5 drag and drop events: 
</del><ins>+  HTML5 drag and drop events:
</ins><span class="cx"> 
</span><span class="cx">   * `dragStart`
</span><span class="cx">   * `drag`
</span><span class="lines">@@ -14269,16 +22442,14 @@
</span><span class="cx">   ## Handlebars `{{view}}` Helper
</span><span class="cx"> 
</span><span class="cx">   Other `Ember.View` instances can be included as part of a view's template by
</span><del>-  using the `{{view}}` Handlebars helper. See `Handlebars.helpers.view` for
-  additional information.
</del><ins>+  using the `{{view}}` Handlebars helper. See [Ember.Handlebars.helpers.view](/api/classes/Ember.Handlebars.helpers.html#method_view)
+  for additional information.
</ins><span class="cx"> 
</span><span class="cx">   @class View
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Object
-  @uses Ember.Evented
</del><ins>+  @extends Ember.CoreView
</ins><span class="cx"> */
</span><del>-Ember.View = Ember.CoreView.extend(
-/** @scope Ember.View.prototype */ {
</del><ins>+Ember.View = Ember.CoreView.extend({
</ins><span class="cx"> 
</span><span class="cx">   concatenatedProperties: ['classNames', 'classNameBindings', 'attributeBindings'],
</span><span class="cx"> 
</span><span class="lines">@@ -14286,7 +22457,7 @@
</span><span class="cx">     @property isView
</span><span class="cx">     @type Boolean
</span><span class="cx">     @default true
</span><del>-    @final
</del><ins>+    @static
</ins><span class="cx">   */
</span><span class="cx">   isView: true,
</span><span class="cx"> 
</span><span class="lines">@@ -14297,9 +22468,8 @@
</span><span class="cx">   /**
</span><span class="cx">     The name of the template to lookup if no template is provided.
</span><span class="cx"> 
</span><del>-    `Ember.View` will look for a template with this name in this view's
-    `templates` object. By default, this will be a global object
-    shared in `Ember.TEMPLATES`.
</del><ins>+    By default `Ember.View` will lookup a template with this name in
+    `Ember.TEMPLATES` (a shared global object).
</ins><span class="cx"> 
</span><span class="cx">     @property templateName
</span><span class="cx">     @type String
</span><span class="lines">@@ -14310,9 +22480,8 @@
</span><span class="cx">   /**
</span><span class="cx">     The name of the layout to lookup if no layout is provided.
</span><span class="cx"> 
</span><del>-    `Ember.View` will look for a template with this name in this view's
-    `templates` object. By default, this will be a global object
-    shared in `Ember.TEMPLATES`.
</del><ins>+    By default `Ember.View` will lookup a template with this name in
+    `Ember.TEMPLATES` (a shared global object).
</ins><span class="cx"> 
</span><span class="cx">     @property layoutName
</span><span class="cx">     @type String
</span><span class="lines">@@ -14321,15 +22490,6 @@
</span><span class="cx">   layoutName: null,
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    The hash in which to look for `templateName`.
-
-    @property templates
-    @type Ember.Object
-    @default Ember.TEMPLATES
-  */
-  templates: Ember.TEMPLATES,
-
-  /**
</del><span class="cx">     The template used to render the view. This should be a function that
</span><span class="cx">     accepts an optional context parameter and returns a string of HTML that
</span><span class="cx">     will be inserted into the DOM relative to its parent view.
</span><span class="lines">@@ -14351,14 +22511,6 @@
</span><span class="cx">     return template || get(this, 'defaultTemplate');
</span><span class="cx">   }).property('templateName'),
</span><span class="cx"> 
</span><del>-  container: Ember.computed(function() {
-    var parentView = get(this, '_parentView');
-
-    if (parentView) { return get(parentView, 'container'); }
-
-    return Ember.Container &amp;&amp; Ember.Container.defaultContainer;
-  }),
-
</del><span class="cx">   /**
</span><span class="cx">     The controller managing this view. If this property is set, it will be
</span><span class="cx">     made available for use by the template.
</span><span class="lines">@@ -14394,16 +22546,18 @@
</span><span class="cx">     return layout || get(this, 'defaultLayout');
</span><span class="cx">   }).property('layoutName'),
</span><span class="cx"> 
</span><ins>+  _yield: function(context, options) {
+    var template = get(this, 'template');
+    if (template) { template(context, options); }
+  },
+
</ins><span class="cx">   templateForName: function(name, type) {
</span><span class="cx">     if (!name) { return; }
</span><del>-
</del><span class="cx">     Ember.assert(&quot;templateNames are not allowed to contain periods: &quot;+name, name.indexOf('.') === -1);
</span><span class="cx"> 
</span><del>-    var container = get(this, 'container');
-
-    if (container) {
-      return container.lookup('template:' + name);
-    }
</del><ins>+    // the defaultContainer is deprecated
+    var container = this.container || (Ember.Container &amp;&amp; Ember.Container.defaultContainer);
+    return container &amp;&amp; container.lookup('template:' + name);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -14428,8 +22582,6 @@
</span><span class="cx">   }).volatile(),
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Private copy of the view's template context. This can be set directly
</span><span class="cx">     by Handlebars without triggering the observer that causes the view
</span><span class="cx">     to be re-rendered.
</span><span class="lines">@@ -14445,6 +22597,7 @@
</span><span class="cx">     something of a hack and should be revisited.
</span><span class="cx"> 
</span><span class="cx">     @property _context
</span><ins>+    @private
</ins><span class="cx">   */
</span><span class="cx">   _context: Ember.computed(function(key) {
</span><span class="cx">     var parentView, controller;
</span><span class="lines">@@ -14462,16 +22615,15 @@
</span><span class="cx">   }),
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     If a value that affects template rendering changes, the view should be
</span><span class="cx">     re-rendered to reflect the new value.
</span><span class="cx"> 
</span><del>-    @method _displayPropertyDidChange
</del><ins>+    @method _contextDidChange
+    @private
</ins><span class="cx">   */
</span><del>-  _contextDidChange: Ember.observer(function() {
</del><ins>+  _contextDidChange: Ember.observer('context', function() {
</ins><span class="cx">     this.rerender();
</span><del>-  }, 'context'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     If `false`, the view will appear hidden in DOM.
</span><span class="lines">@@ -14483,36 +22635,35 @@
</span><span class="cx">   isVisible: true,
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Array of child views. You should never edit this array directly.
</span><span class="cx">     Instead, use `appendChild` and `removeFromParent`.
</span><span class="cx"> 
</span><span class="cx">     @property childViews
</span><span class="cx">     @type Array
</span><span class="cx">     @default []
</span><ins>+    @private
</ins><span class="cx">   */
</span><span class="cx">   childViews: childViewsProperty,
</span><span class="cx"> 
</span><del>-  _childViews: [],
</del><ins>+  _childViews: EMPTY_ARRAY,
</ins><span class="cx"> 
</span><span class="cx">   // When it's a virtual view, we need to notify the parent that their
</span><span class="cx">   // childViews will change.
</span><del>-  _childViewsWillChange: Ember.beforeObserver(function() {
</del><ins>+  _childViewsWillChange: Ember.beforeObserver('childViews', function() {
</ins><span class="cx">     if (this.isVirtual) {
</span><span class="cx">       var parentView = get(this, 'parentView');
</span><span class="cx">       if (parentView) { Ember.propertyWillChange(parentView, 'childViews'); }
</span><span class="cx">     }
</span><del>-  }, 'childViews'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><span class="cx">   // When it's a virtual view, we need to notify the parent that their
</span><span class="cx">   // childViews did change.
</span><del>-  _childViewsDidChange: Ember.observer(function() {
</del><ins>+  _childViewsDidChange: Ember.observer('childViews', function() {
</ins><span class="cx">     if (this.isVirtual) {
</span><span class="cx">       var parentView = get(this, 'parentView');
</span><span class="cx">       if (parentView) { Ember.propertyDidChange(parentView, 'childViews'); }
</span><span class="cx">     }
</span><del>-  }, 'childViews'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     Return the nearest ancestor that is an instance of the provided
</span><span class="lines">@@ -14528,7 +22679,7 @@
</span><span class="cx">     var view = get(this, 'parentView');
</span><span class="cx"> 
</span><span class="cx">     while (view) {
</span><del>-      if(view instanceof klass) { return view; }
</del><ins>+      if (view instanceof klass) { return view; }
</ins><span class="cx">       view = get(view, 'parentView');
</span><span class="cx">     }
</span><span class="cx">   },
</span><span class="lines">@@ -14549,7 +22700,7 @@
</span><span class="cx">                    function(view) { return klass.detect(view.constructor); };
</span><span class="cx"> 
</span><span class="cx">     while (view) {
</span><del>-      if( isOfType(view) ) { return view; }
</del><ins>+      if (isOfType(view)) { return view; }
</ins><span class="cx">       view = get(view, 'parentView');
</span><span class="cx">     }
</span><span class="cx">   },
</span><span class="lines">@@ -14557,7 +22708,7 @@
</span><span class="cx">   /**
</span><span class="cx">     Return the nearest ancestor that has a given property.
</span><span class="cx"> 
</span><del>-    @property nearestWithProperty
</del><ins>+    @function nearestWithProperty
</ins><span class="cx">     @param {String} property A property name
</span><span class="cx">     @return Ember.View
</span><span class="cx">   */
</span><span class="lines">@@ -14574,7 +22725,7 @@
</span><span class="cx">     Return the nearest ancestor whose parent is an instance of
</span><span class="cx">     `klass`.
</span><span class="cx"> 
</span><del>-    @property nearestChildOf
</del><ins>+    @method nearestChildOf
</ins><span class="cx">     @param {Class} klass Subclass of Ember.View (or Ember.View itself)
</span><span class="cx">     @return Ember.View
</span><span class="cx">   */
</span><span class="lines">@@ -14582,27 +22733,28 @@
</span><span class="cx">     var view = get(this, 'parentView');
</span><span class="cx"> 
</span><span class="cx">     while (view) {
</span><del>-      if(get(view, 'parentView') instanceof klass) { return view; }
</del><ins>+      if (get(view, 'parentView') instanceof klass) { return view; }
</ins><span class="cx">       view = get(view, 'parentView');
</span><span class="cx">     }
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     When the parent view changes, recursively invalidate `controller`
</span><span class="cx"> 
</span><span class="cx">     @method _parentViewDidChange
</span><ins>+    @private
</ins><span class="cx">   */
</span><del>-  _parentViewDidChange: Ember.observer(function() {
</del><ins>+  _parentViewDidChange: Ember.observer('_parentView', function() {
</ins><span class="cx">     if (this.isDestroying) { return; }
</span><span class="cx"> 
</span><ins>+    this.trigger('parentViewDidChange');
+
</ins><span class="cx">     if (get(this, 'parentView.controller') &amp;&amp; !get(this, 'controller')) {
</span><span class="cx">       this.notifyPropertyChange('controller');
</span><span class="cx">     }
</span><del>-  }, '_parentView'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><del>-  _controllerDidChange: Ember.observer(function() {
</del><ins>+  _controllerDidChange: Ember.observer('controller', function() {
</ins><span class="cx">     if (this.isDestroying) { return; }
</span><span class="cx"> 
</span><span class="cx">     this.rerender();
</span><span class="lines">@@ -14610,7 +22762,7 @@
</span><span class="cx">     this.forEachChildView(function(view) {
</span><span class="cx">       view.propertyDidChange('controller');
</span><span class="cx">     });
</span><del>-  }, 'controller'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><span class="cx">   cloneKeywords: function() {
</span><span class="cx">     var templateData = get(this, 'templateData');
</span><span class="lines">@@ -14705,14 +22857,13 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Iterates over the view's `classNameBindings` array, inserts the value
</span><span class="cx">     of the specified property into the `classNames` array, then creates an
</span><span class="cx">     observer to update the view's element if the bound property ever changes
</span><span class="cx">     in the future.
</span><span class="cx"> 
</span><span class="cx">     @method _applyClassNameBindings
</span><ins>+    @private
</ins><span class="cx">   */
</span><span class="cx">   _applyClassNameBindings: function(classBindings) {
</span><span class="cx">     var classNames = this.classNames,
</span><span class="lines">@@ -14783,16 +22934,15 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Iterates through the view's attribute bindings, sets up observers for each,
</span><span class="cx">     then applies the current value of the attributes to the passed render buffer.
</span><span class="cx"> 
</span><span class="cx">     @method _applyAttributeBindings
</span><span class="cx">     @param {Ember.RenderBuffer} buffer
</span><ins>+    @private
</ins><span class="cx">   */
</span><span class="cx">   _applyAttributeBindings: function(buffer, attributeBindings) {
</span><del>-    var attributeValue, elem, type;
</del><ins>+    var attributeValue, elem;
</ins><span class="cx"> 
</span><span class="cx">     a_forEach(attributeBindings, function(binding) {
</span><span class="cx">       var split = binding.split(':'),
</span><span class="lines">@@ -14803,7 +22953,6 @@
</span><span class="cx">       // JavaScript property changes.
</span><span class="cx">       var observer = function() {
</span><span class="cx">         elem = this.$();
</span><del>-        if (!elem) { return; }
</del><span class="cx"> 
</span><span class="cx">         attributeValue = get(this, property);
</span><span class="cx"> 
</span><span class="lines">@@ -14820,8 +22969,6 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Given a property name, returns a dasherized version of that
</span><span class="cx">     property name if the property evaluates to a non-falsy value.
</span><span class="cx"> 
</span><span class="lines">@@ -14830,6 +22977,7 @@
</span><span class="cx"> 
</span><span class="cx">     @method _classStringForProperty
</span><span class="cx">     @param property
</span><ins>+    @private
</ins><span class="cx">   */
</span><span class="cx">   _classStringForProperty: function(property) {
</span><span class="cx">     var parsedPath = Ember.View._parsePropertyPath(property);
</span><span class="lines">@@ -14869,9 +23017,9 @@
</span><span class="cx">     For example, calling `view.$('li')` will return a jQuery object containing
</span><span class="cx">     all of the `li` elements inside the DOM element of this view.
</span><span class="cx"> 
</span><del>-    @property $
</del><ins>+    @method $
</ins><span class="cx">     @param {String} [selector] a jQuery-compatible selector string
</span><del>-    @return {jQuery} the CoreQuery object for the DOM node
</del><ins>+    @return {jQuery} the jQuery object for the DOM node
</ins><span class="cx">   */
</span><span class="cx">   $: function(sel) {
</span><span class="cx">     return this.currentState.$(this, sel);
</span><span class="lines">@@ -14884,7 +23032,7 @@
</span><span class="cx"> 
</span><span class="cx">     while(--idx &gt;= 0) {
</span><span class="cx">       view = childViews[idx];
</span><del>-      callback.call(this, view, idx);
</del><ins>+      callback(this, view, idx);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return this;
</span><span class="lines">@@ -14898,9 +23046,9 @@
</span><span class="cx">     var len = childViews.length,
</span><span class="cx">         view, idx;
</span><span class="cx"> 
</span><del>-    for(idx = 0; idx &lt; len; idx++) {
</del><ins>+    for (idx = 0; idx &lt; len; idx++) {
</ins><span class="cx">       view = childViews[idx];
</span><del>-      callback.call(this, view);
</del><ins>+      callback(view);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return this;
</span><span class="lines">@@ -14930,6 +23078,7 @@
</span><span class="cx">     // Schedule the DOM element to be created and appended to the given
</span><span class="cx">     // element after bindings have synchronized.
</span><span class="cx">     this._insertElementLater(function() {
</span><ins>+      Ember.assert(&quot;You tried to append to (&quot; + target + &quot;) but that isn't in the DOM&quot;, Ember.$(target).length &gt; 0);
</ins><span class="cx">       Ember.assert(&quot;You cannot append to an existing Ember.View. Consider using Ember.ContainerView instead.&quot;, !Ember.$(target).is('.ember-view') &amp;&amp; !Ember.$(target).parents().is('.ember-view'));
</span><span class="cx">       this.$().appendTo(target);
</span><span class="cx">     });
</span><span class="lines">@@ -14947,10 +23096,11 @@
</span><span class="cx">     finished synchronizing
</span><span class="cx"> 
</span><span class="cx">     @method replaceIn
</span><del>-    @param {String|DOMElement|jQuery} A selector, element, HTML string, or jQuery object
</del><ins>+    @param {String|DOMElement|jQuery} target A selector, element, HTML string, or jQuery object
</ins><span class="cx">     @return {Ember.View} received
</span><span class="cx">   */
</span><span class="cx">   replaceIn: function(target) {
</span><ins>+    Ember.assert(&quot;You tried to replace in (&quot; + target + &quot;) but that isn't in the DOM&quot;, Ember.$(target).length &gt; 0);
</ins><span class="cx">     Ember.assert(&quot;You cannot replace an existing Ember.View. Consider using Ember.ContainerView instead.&quot;, !Ember.$(target).is('.ember-view') &amp;&amp; !Ember.$(target).parents().is('.ember-view'));
</span><span class="cx"> 
</span><span class="cx">     this._insertElementLater(function() {
</span><span class="lines">@@ -14962,8 +23112,6 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Schedules a DOM operation to occur during the next render phase. This
</span><span class="cx">     ensures that all bindings have finished synchronizing before the view is
</span><span class="cx">     rendered.
</span><span class="lines">@@ -14983,6 +23131,7 @@
</span><span class="cx"> 
</span><span class="cx">     @method _insertElementLater
</span><span class="cx">     @param {Function} fn the function that inserts the element into the DOM
</span><ins>+    @private
</ins><span class="cx">   */
</span><span class="cx">   _insertElementLater: function(fn) {
</span><span class="cx">     this._scheduledInsert = Ember.run.scheduleOnce('render', this, '_insertElement', fn);
</span><span class="lines">@@ -14998,6 +23147,10 @@
</span><span class="cx">     not have an HTML representation yet, `createElement()` will be called
</span><span class="cx">     automatically.
</span><span class="cx"> 
</span><ins>+    If your application uses the `rootElement` property, you must append
+    the view within that element. Rendering views outside of the `rootElement`
+    is not supported.
+
</ins><span class="cx">     Note that this method just schedules the view to be appended; the DOM
</span><span class="cx">     element will not be appended to the document body until all bindings have
</span><span class="cx">     finished synchronizing.
</span><span class="lines">@@ -15072,9 +23225,9 @@
</span><span class="cx">   willInsertElement: Ember.K,
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Called when the element of the view has been inserted into the DOM.
-    Override this function to do any set up that requires an element in the
-    document body.
</del><ins>+    Called when the element of the view has been inserted into the DOM
+    or after the view was re-rendered. Override this function to do any
+    set up that requires an element in the document body.
</ins><span class="cx"> 
</span><span class="cx">     @event didInsertElement
</span><span class="cx">   */
</span><span class="lines">@@ -15090,15 +23243,16 @@
</span><span class="cx">   willClearRender: Ember.K,
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
</del><ins>+    Run this callback on the current view (unless includeSelf is false) and recursively on child views.
</ins><span class="cx"> 
</span><del>-    Run this callback on the current view and recursively on child views.
-
</del><span class="cx">     @method invokeRecursively
</span><span class="cx">     @param fn {Function}
</span><ins>+    @param includeSelf {Boolean} Includes itself if true.
+    @private
</ins><span class="cx">   */
</span><del>-  invokeRecursively: function(fn) {
-    var childViews = [this], currentViews, view;
</del><ins>+  invokeRecursively: function(fn, includeSelf) {
+    var childViews = (includeSelf === false) ? this._childViews : [this];
+    var currentViews, view, currentChildViews;
</ins><span class="cx"> 
</span><span class="cx">     while (childViews.length) {
</span><span class="cx">       currentViews = childViews.slice();
</span><span class="lines">@@ -15106,16 +23260,17 @@
</span><span class="cx"> 
</span><span class="cx">       for (var i=0, l=currentViews.length; i&lt;l; i++) {
</span><span class="cx">         view = currentViews[i];
</span><del>-        fn.call(view, view);
-        if (view._childViews) {
-          childViews.push.apply(childViews, view._childViews);
</del><ins>+        currentChildViews = view._childViews ? view._childViews.slice(0) : null;
+        fn(view);
+        if (currentChildViews) {
+          childViews.push.apply(childViews, currentChildViews);
</ins><span class="cx">         }
</span><span class="cx">       }
</span><span class="cx">     }
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   triggerRecursively: function(eventName) {
</span><del>-    var childViews = [this], currentViews, view;
</del><ins>+    var childViews = [this], currentViews, view, currentChildViews;
</ins><span class="cx"> 
</span><span class="cx">     while (childViews.length) {
</span><span class="cx">       currentViews = childViews.slice();
</span><span class="lines">@@ -15123,14 +23278,29 @@
</span><span class="cx"> 
</span><span class="cx">       for (var i=0, l=currentViews.length; i&lt;l; i++) {
</span><span class="cx">         view = currentViews[i];
</span><ins>+        currentChildViews = view._childViews ? view._childViews.slice(0) : null;
</ins><span class="cx">         if (view.trigger) { view.trigger(eventName); }
</span><del>-        if (view._childViews) {
-          childViews.push.apply(childViews, view._childViews);
</del><ins>+        if (currentChildViews) {
+          childViews.push.apply(childViews, currentChildViews);
</ins><span class="cx">         }
</span><ins>+
</ins><span class="cx">       }
</span><span class="cx">     }
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  viewHierarchyCollection: function() {
+    var currentView, viewCollection = new ViewCollection([this]);
+
+    for (var i = 0; i &lt; viewCollection.length; i++) {
+      currentView = viewCollection.objectAt(i);
+      if (currentView._childViews) {
+        viewCollection.push.apply(viewCollection, currentView._childViews);
+      }
+    }
+
+    return viewCollection;
+  },
+
</ins><span class="cx">   /**
</span><span class="cx">     Destroys any existing element along with the element for any child views
</span><span class="cx">     as well. If the view does not currently have a element, then this method
</span><span class="lines">@@ -15143,8 +23313,8 @@
</span><span class="cx">     If you write a `willDestroyElement()` handler, you can assume that your
</span><span class="cx">     `didInsertElement()` handler was called earlier for the same element.
</span><span class="cx"> 
</span><del>-    Normally you will not call or override this method yourself, but you may
-    want to implement the above callbacks when it is run.
</del><ins>+    You should not call or override this method yourself, but you may
+    want to implement the above callbacks.
</ins><span class="cx"> 
</span><span class="cx">     @method destroyElement
</span><span class="cx">     @return {Ember.View} receiver
</span><span class="lines">@@ -15160,11 +23330,9 @@
</span><span class="cx"> 
</span><span class="cx">     @event willDestroyElement
</span><span class="cx">   */
</span><del>-  willDestroyElement: function() {},
</del><ins>+  willDestroyElement: Ember.K,
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Triggers the `willDestroyElement` event (which invokes the
</span><span class="cx">     `willDestroyElement()` method if it exists) on this view and all child
</span><span class="cx">     views.
</span><span class="lines">@@ -15173,32 +23341,28 @@
</span><span class="cx">     `willClearRender` event recursively.
</span><span class="cx"> 
</span><span class="cx">     @method _notifyWillDestroyElement
</span><ins>+    @private
</ins><span class="cx">   */
</span><span class="cx">   _notifyWillDestroyElement: function() {
</span><del>-    this.triggerRecursively('willClearRender');
-    this.triggerRecursively('willDestroyElement');
</del><ins>+    var viewCollection = this.viewHierarchyCollection();
+    viewCollection.trigger('willClearRender');
+    viewCollection.trigger('willDestroyElement');
+    return viewCollection;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  _elementWillChange: Ember.beforeObserver(function() {
-    this.forEachChildView(function(view) {
-      Ember.propertyWillChange(view, 'element');
-    });
-  }, 'element'),
-
</del><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     If this view's element changes, we need to invalidate the caches of our
</span><span class="cx">     child views so that we do not retain references to DOM elements that are
</span><span class="cx">     no longer needed.
</span><span class="cx"> 
</span><span class="cx">     @method _elementDidChange
</span><ins>+    @private
</ins><span class="cx">   */
</span><del>-  _elementDidChange: Ember.observer(function() {
</del><ins>+  _elementDidChange: Ember.observer('element', function() {
</ins><span class="cx">     this.forEachChildView(function(view) {
</span><del>-      Ember.propertyDidChange(view, 'element');
</del><ins>+      delete meta(view).cache.element;
</ins><span class="cx">     });
</span><del>-  }, 'element'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     Called when the parentView property has changed.
</span><span class="lines">@@ -15222,8 +23386,8 @@
</span><span class="cx">     return buffer;
</span><span class="cx">   },
</span><span class="cx"> 
</span><del>-  renderToBufferIfNeeded: function () {
-    return this.currentState.renderToBufferIfNeeded(this, this);
</del><ins>+  renderToBufferIfNeeded: function (buffer) {
+    return this.currentState.renderToBufferIfNeeded(this, buffer);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   beforeRender: function(buffer) {
</span><span class="lines">@@ -15291,7 +23455,7 @@
</span><span class="cx">     visually challenged users navigate rich web applications.
</span><span class="cx"> 
</span><span class="cx">     The full list of valid WAI-ARIA roles is available at:
</span><del>-    http://www.w3.org/TR/wai-aria/roles#roles_categorization
</del><ins>+    [http://www.w3.org/TR/wai-aria/roles#roles_categorization](http://www.w3.org/TR/wai-aria/roles#roles_categorization)
</ins><span class="cx"> 
</span><span class="cx">     @property ariaRole
</span><span class="cx">     @type String
</span><span class="lines">@@ -15317,7 +23481,7 @@
</span><span class="cx"> 
</span><span class="cx">     ```javascript
</span><span class="cx">     // Applies the 'high' class to the view element
</span><del>-    Ember.View.create({
</del><ins>+    Ember.View.extend({
</ins><span class="cx">       classNameBindings: ['priority']
</span><span class="cx">       priority: 'high'
</span><span class="cx">     });
</span><span class="lines">@@ -15328,7 +23492,7 @@
</span><span class="cx"> 
</span><span class="cx">     ```javascript
</span><span class="cx">     // Applies the 'is-urgent' class to the view element
</span><del>-    Ember.View.create({
</del><ins>+    Ember.View.extend({
</ins><span class="cx">       classNameBindings: ['isUrgent']
</span><span class="cx">       isUrgent: true
</span><span class="cx">     });
</span><span class="lines">@@ -15339,7 +23503,7 @@
</span><span class="cx"> 
</span><span class="cx">     ```javascript
</span><span class="cx">     // Applies the 'urgent' class to the view element
</span><del>-    Ember.View.create({
</del><ins>+    Ember.View.extend({
</ins><span class="cx">       classNameBindings: ['isUrgent:urgent']
</span><span class="cx">       isUrgent: true
</span><span class="cx">     });
</span><span class="lines">@@ -15351,7 +23515,7 @@
</span><span class="cx">     @type Array
</span><span class="cx">     @default []
</span><span class="cx">   */
</span><del>-  classNameBindings: [],
</del><ins>+  classNameBindings: EMPTY_ARRAY,
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     A list of properties of the view to apply as attributes. If the property is
</span><span class="lines">@@ -15360,7 +23524,7 @@
</span><span class="cx">     ```javascript
</span><span class="cx">     // Applies the type attribute to the element
</span><span class="cx">     // with the value &quot;button&quot;, like &lt;div type=&quot;button&quot;&gt;
</span><del>-    Ember.View.create({
</del><ins>+    Ember.View.extend({
</ins><span class="cx">       attributeBindings: ['type'],
</span><span class="cx">       type: 'button'
</span><span class="cx">     });
</span><span class="lines">@@ -15371,7 +23535,7 @@
</span><span class="cx"> 
</span><span class="cx">     ```javascript
</span><span class="cx">     // Renders something like &lt;div enabled=&quot;enabled&quot;&gt;
</span><del>-    Ember.View.create({
</del><ins>+    Ember.View.extend({
</ins><span class="cx">       attributeBindings: ['enabled'],
</span><span class="cx">       enabled: true
</span><span class="cx">     });
</span><span class="lines">@@ -15379,21 +23543,21 @@
</span><span class="cx"> 
</span><span class="cx">     @property attributeBindings
</span><span class="cx">   */
</span><del>-  attributeBindings: [],
</del><ins>+  attributeBindings: EMPTY_ARRAY,
</ins><span class="cx"> 
</span><span class="cx">   // .......................................................
</span><span class="cx">   // CORE DISPLAY METHODS
</span><span class="cx">   //
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
</del><ins>+    Setup a view, but do not finish waking it up.
</ins><span class="cx"> 
</span><del>-    Setup a view, but do not finish waking it up.
-    - configure `childViews`
-    - register the view with the global views hash, which is used for event
</del><ins>+    * configure `childViews`
+    * register the view with the global views hash, which is used for event
</ins><span class="cx">       dispatch
</span><span class="cx"> 
</span><span class="cx">     @method init
</span><ins>+    @private
</ins><span class="cx">   */
</span><span class="cx">   init: function() {
</span><span class="cx">     this.elementId = this.elementId || guidFor(this);
</span><span class="lines">@@ -15408,14 +23572,6 @@
</span><span class="cx"> 
</span><span class="cx">     Ember.assert(&quot;Only arrays are allowed for 'classNames'&quot;, Ember.typeOf(this.classNames) === 'array');
</span><span class="cx">     this.classNames = Ember.A(this.classNames.slice());
</span><del>-
-    var viewController = get(this, 'viewController');
-    if (viewController) {
-      viewController = get(viewController);
-      if (viewController) {
-        set(viewController, 'view', this);
-      }
-    }
</del><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   appendChild: function(view, options) {
</span><span class="lines">@@ -15455,13 +23611,13 @@
</span><span class="cx">     @return {Ember.View} receiver
</span><span class="cx">   */
</span><span class="cx">   removeAllChildren: function() {
</span><del>-    return this.mutateChildViews(function(view) {
-      this.removeChild(view);
</del><ins>+    return this.mutateChildViews(function(parentView, view) {
+      parentView.removeChild(view);
</ins><span class="cx">     });
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   destroyAllChildren: function() {
</span><del>-    return this.mutateChildViews(function(view) {
</del><ins>+    return this.mutateChildViews(function(parentView, view) {
</ins><span class="cx">       view.destroy();
</span><span class="cx">     });
</span><span class="cx">   },
</span><span class="lines">@@ -15489,18 +23645,16 @@
</span><span class="cx">     sure that the DOM element managed by the view can be released by the
</span><span class="cx">     memory manager.
</span><span class="cx"> 
</span><del>-    @method willDestroy
</del><ins>+    @method destroy
</ins><span class="cx">   */
</span><del>-  willDestroy: function() {
-    // calling this._super() will nuke computed properties and observers,
-    // so collect any information we need before calling super.
</del><ins>+  destroy: function() {
</ins><span class="cx">     var childViews = this._childViews,
</span><del>-        parent = this._parentView,
</del><ins>+        // get parentView before calling super because it'll be destroyed
+        nonVirtualParentView = get(this, 'parentView'),
+        viewName = this.viewName,
</ins><span class="cx">         childLen, i;
</span><span class="cx"> 
</span><del>-    // destroy the element -- this will avoid each child view destroying
-    // the element over and over again...
-    if (!this.removedFromDOM) { this.destroyElement(); }
</del><ins>+    if (!this._super()) { return; }
</ins><span class="cx"> 
</span><span class="cx">     childLen = childViews.length;
</span><span class="cx">     for (i=childLen-1; i&gt;=0; i--) {
</span><span class="lines">@@ -15508,27 +23662,16 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // remove from non-virtual parent view if viewName was specified
</span><del>-    if (this.viewName) {
-      var nonVirtualParentView = get(this, 'parentView');
-      if (nonVirtualParentView) {
-        set(nonVirtualParentView, this.viewName, null);
-      }
</del><ins>+    if (viewName &amp;&amp; nonVirtualParentView) {
+      nonVirtualParentView.set(viewName, null);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // remove from parent if found. Don't call removeFromParent,
-    // as removeFromParent will try to remove the element from
-    // the DOM again.
-    if (parent) { parent.removeChild(this); }
-
-    this.transitionTo('destroyed');
-
</del><span class="cx">     childLen = childViews.length;
</span><span class="cx">     for (i=childLen-1; i&gt;=0; i--) {
</span><span class="cx">       childViews[i].destroy();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // next remove view from global hash
-    if (!this.isVirtual) delete Ember.View.views[get(this, 'elementId')];
</del><ins>+    return this;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -15539,35 +23682,51 @@
</span><span class="cx">     act as a child of the parent.
</span><span class="cx"> 
</span><span class="cx">     @method createChildView
</span><del>-    @param {Class} viewClass
</del><ins>+    @param {Class|String} viewClass
</ins><span class="cx">     @param {Hash} [attrs] Attributes to add
</span><span class="cx">     @return {Ember.View} new instance
</span><span class="cx">   */
</span><span class="cx">   createChildView: function(view, attrs) {
</span><del>-    if (view.isView &amp;&amp; view._parentView === this) { return view; }
</del><ins>+    if (!view) {
+      throw new TypeError(&quot;createChildViews first argument must exist&quot;);
+    }
</ins><span class="cx"> 
</span><ins>+    if (view.isView &amp;&amp; view._parentView === this &amp;&amp; view.container === this.container) {
+      return view;
+    }
+
+    attrs = attrs || {};
+    attrs._parentView = this;
+
</ins><span class="cx">     if (Ember.CoreView.detect(view)) {
</span><del>-      attrs = attrs || {};
-      attrs._parentView = this;
</del><span class="cx">       attrs.templateData = attrs.templateData || get(this, 'templateData');
</span><span class="cx"> 
</span><ins>+      attrs.container = this.container;
</ins><span class="cx">       view = view.create(attrs);
</span><span class="cx"> 
</span><span class="cx">       // don't set the property on a virtual view, as they are invisible to
</span><span class="cx">       // consumers of the view API
</span><del>-      if (view.viewName) { set(get(this, 'concreteView'), view.viewName, view); }
</del><ins>+      if (view.viewName) {
+        set(get(this, 'concreteView'), view.viewName, view);
+      }
+    } else if ('string' === typeof view) {
+      var fullName = 'view:' + view;
+      var View = this.container.lookupFactory(fullName);
+
+      Ember.assert(&quot;Could not find view: '&quot; + fullName + &quot;'&quot;, !!View);
+
+      attrs.templateData = get(this, 'templateData');
+      view = View.create(attrs);
</ins><span class="cx">     } else {
</span><span class="cx">       Ember.assert('You must pass instance or subclass of View', view.isView);
</span><ins>+      attrs.container = this.container;
</ins><span class="cx"> 
</span><del>-      if (attrs) {
-        view.setProperties(attrs);
-      }
-
</del><span class="cx">       if (!get(view, 'templateData')) {
</span><del>-        set(view, 'templateData', get(this, 'templateData'));
</del><ins>+        attrs.templateData = get(this, 'templateData');
</ins><span class="cx">       }
</span><span class="cx"> 
</span><del>-      set(view, '_parentView', this);
</del><ins>+      Ember.setProperties(view, attrs);
+
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return view;
</span><span class="lines">@@ -15577,14 +23736,13 @@
</span><span class="cx">   becameHidden: Ember.K,
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     When the view's `isVisible` property changes, toggle the visibility
</span><span class="cx">     element of the actual DOM element.
</span><span class="cx"> 
</span><span class="cx">     @method _isVisibleDidChange
</span><ins>+    @private
</ins><span class="cx">   */
</span><del>-  _isVisibleDidChange: Ember.observer(function() {
</del><ins>+  _isVisibleDidChange: Ember.observer('isVisible', function() {
</ins><span class="cx">     var $el = this.$();
</span><span class="cx">     if (!$el) { return; }
</span><span class="cx"> 
</span><span class="lines">@@ -15599,7 +23757,7 @@
</span><span class="cx">     } else {
</span><span class="cx">       this._notifyBecameHidden();
</span><span class="cx">     }
</span><del>-  }, 'isVisible'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><span class="cx">   _notifyBecameVisible: function() {
</span><span class="cx">     this.trigger('becameVisible');
</span><span class="lines">@@ -15643,9 +23801,14 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   transitionTo: function(state, children) {
</span><del>-    this.currentState = this.states[state];
</del><ins>+    var priorState = this.currentState,
+        currentState = this.currentState = this.states[state];
</ins><span class="cx">     this.state = state;
</span><span class="cx"> 
</span><ins>+    if (priorState &amp;&amp; priorState.exit) { priorState.exit(this); }
+    if (currentState.enter) { currentState.enter(this); }
+    if (state === 'inDOM') { delete Ember.meta(this).cache.element; }
+
</ins><span class="cx">     if (children !== false) {
</span><span class="cx">       this.forEachChildView(function(view) {
</span><span class="cx">         view.transitionTo(state);
</span><span class="lines">@@ -15658,23 +23821,39 @@
</span><span class="cx">   //
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Handle events from `Ember.EventDispatcher`
</span><span class="cx"> 
</span><span class="cx">     @method handleEvent
</span><span class="cx">     @param eventName {String}
</span><span class="cx">     @param evt {Event}
</span><ins>+    @private
</ins><span class="cx">   */
</span><span class="cx">   handleEvent: function(eventName, evt) {
</span><span class="cx">     return this.currentState.handleEvent(this, eventName, evt);
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   registerObserver: function(root, path, target, observer) {
</span><del>-    Ember.addObserver(root, path, target, observer);
</del><ins>+    if (!observer &amp;&amp; 'function' === typeof target) {
+      observer = target;
+      target = null;
+    }
</ins><span class="cx"> 
</span><ins>+    if (!root || typeof root !== 'object') {
+      return;
+    }
+
+    var view = this,
+        stateCheckedObserver = function() {
+          view.currentState.invokeObserver(this, observer);
+        },
+        scheduledObserver = function() {
+          Ember.run.scheduleOnce('render', this, stateCheckedObserver);
+        };
+
+    Ember.addObserver(root, path, target, scheduledObserver);
+
</ins><span class="cx">     this.one('willClearRender', function() {
</span><del>-      Ember.removeObserver(root, path, target, observer);
</del><ins>+      Ember.removeObserver(root, path, target, scheduledObserver);
</ins><span class="cx">     });
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -15705,17 +23884,24 @@
</span><span class="cx">   // once the view has been inserted into the DOM, legal manipulations
</span><span class="cx">   // are done on the DOM element.
</span><span class="cx"> 
</span><ins>+function notifyMutationListeners() {
+  Ember.run.once(Ember.View, 'notifyMutationListeners');
+}
+
</ins><span class="cx"> var DOMManager = {
</span><span class="cx">   prepend: function(view, html) {
</span><span class="cx">     view.$().prepend(html);
</span><ins>+    notifyMutationListeners();
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   after: function(view, html) {
</span><span class="cx">     view.$().after(html);
</span><ins>+    notifyMutationListeners();
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   html: function(view, html) {
</span><span class="cx">     view.$().html(html);
</span><ins>+    notifyMutationListeners();
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   replace: function(view) {
</span><span class="lines">@@ -15725,15 +23911,18 @@
</span><span class="cx"> 
</span><span class="cx">     view._insertElementLater(function() {
</span><span class="cx">       Ember.$(element).replaceWith(get(view, 'element'));
</span><ins>+      notifyMutationListeners();
</ins><span class="cx">     });
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   remove: function(view) {
</span><span class="cx">     view.$().remove();
</span><ins>+    notifyMutationListeners();
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   empty: function(view) {
</span><span class="cx">     view.$().empty();
</span><ins>+    notifyMutationListeners();
</ins><span class="cx">   }
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -15744,11 +23933,9 @@
</span><span class="cx"> Ember.View.reopenClass({
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Parse a path and return an object which holds the parsed properties.
</span><span class="cx"> 
</span><del>-    For example a path like &quot;content.isEnabled:enabled:disabled&quot; wil return the
</del><ins>+    For example a path like &quot;content.isEnabled:enabled:disabled&quot; will return the
</ins><span class="cx">     following object:
</span><span class="cx"> 
</span><span class="cx">     ```javascript
</span><span class="lines">@@ -15762,6 +23949,7 @@
</span><span class="cx"> 
</span><span class="cx">     @method _parsePropertyPath
</span><span class="cx">     @static
</span><ins>+    @private
</ins><span class="cx">   */
</span><span class="cx">   _parsePropertyPath: function(path) {
</span><span class="cx">     var split = path.split(':'),
</span><span class="lines">@@ -15788,20 +23976,18 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Get the class name for a given value, based on the path, optional
</span><span class="cx">     `className` and optional `falsyClassName`.
</span><span class="cx"> 
</span><span class="cx">     - if a `className` or `falsyClassName` has been specified:
</span><del>-      - if the value is truthy and `className` has been specified, 
</del><ins>+      - if the value is truthy and `className` has been specified,
</ins><span class="cx">         `className` is returned
</span><del>-      - if the value is falsy and `falsyClassName` has been specified, 
</del><ins>+      - if the value is falsy and `falsyClassName` has been specified,
</ins><span class="cx">         `falsyClassName` is returned
</span><span class="cx">       - otherwise `null` is returned
</span><del>-    - if the value is `true`, the dasherized last part of the supplied path 
</del><ins>+    - if the value is `true`, the dasherized last part of the supplied path
</ins><span class="cx">       is returned
</span><del>-    - if the value is not `false`, `undefined` or `null`, the `value` 
</del><ins>+    - if the value is not `false`, `undefined` or `null`, the `value`
</ins><span class="cx">       is returned
</span><span class="cx">     - if none of the above rules apply, `null` is returned
</span><span class="cx"> 
</span><span class="lines">@@ -15811,6 +23997,7 @@
</span><span class="cx">     @param className
</span><span class="cx">     @param falsyClassName
</span><span class="cx">     @static
</span><ins>+    @private
</ins><span class="cx">   */
</span><span class="cx">   _classStringForValue: function(path, val, className, falsyClassName) {
</span><span class="cx">     // When using the colon syntax, evaluate the truthiness or falsiness
</span><span class="lines">@@ -15837,7 +24024,7 @@
</span><span class="cx"> 
</span><span class="cx">     // If the value is not false, undefined, or null, return the current
</span><span class="cx">     // value of the property.
</span><del>-    } else if (val !== false &amp;&amp; val !== undefined &amp;&amp; val !== null) {
</del><ins>+    } else if (val !== false &amp;&amp; val != null) {
</ins><span class="cx">       return val;
</span><span class="cx"> 
</span><span class="cx">     // Nothing to display. Return null so that the old class is removed
</span><span class="lines">@@ -15848,6 +24035,20 @@
</span><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><ins>+var mutation = Ember.Object.extend(Ember.Evented).create();
+
+Ember.View.addMutationListener = function(callback) {
+  mutation.on('change', callback);
+};
+
+Ember.View.removeMutationListener = function(callback) {
+  mutation.off('change', callback);
+};
+
+Ember.View.notifyMutationListeners = function() {
+  mutation.trigger('change');
+};
+
</ins><span class="cx"> /**
</span><span class="cx">   Global views hash
</span><span class="cx"> 
</span><span class="lines">@@ -15873,6 +24074,13 @@
</span><span class="cx">       elem.attr(name, value);
</span><span class="cx">     }
</span><span class="cx">   } else if (name === 'value' || type === 'boolean') {
</span><ins>+    // We can't set properties to undefined or null
+    if (Ember.isNone(value)) { value = ''; }
+
+    if (!value) {
+      elem.removeAttr(name);
+    }
+
</ins><span class="cx">     if (value !== elem.prop(name)) {
</span><span class="cx">       // value and booleans should always be properties
</span><span class="cx">       elem.prop(name, value);
</span><span class="lines">@@ -15928,7 +24136,8 @@
</span><span class="cx">     return false;
</span><span class="cx">   },
</span><span class="cx"> 
</span><del>-  rerender: Ember.K
</del><ins>+  rerender: Ember.K,
+  invokeObserver: Ember.K
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> })();
</span><span class="lines">@@ -15948,15 +24157,26 @@
</span><span class="cx">   // created (createElement).
</span><span class="cx">   insertElement: function(view, fn) {
</span><span class="cx">     view.createElement();
</span><del>-    view.triggerRecursively('willInsertElement');
-    // after createElement, the view will be in the hasElement state.
</del><ins>+    var viewCollection = view.viewHierarchyCollection();
+
+    viewCollection.trigger('willInsertElement');
+
</ins><span class="cx">     fn.call(view);
</span><del>-    view.transitionTo('inDOM');
-    view.triggerRecursively('didInsertElement');
</del><ins>+
+    // We transition to `inDOM` if the element exists in the DOM
+    var element = view.get('element');
+    while (element = element.parentNode) {
+      if (element === document) {
+        viewCollection.transitionTo('inDOM', false);
+        viewCollection.trigger('didInsertElement');
+      }
+    }
+
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  renderToBufferIfNeeded: function(view) {
-    return view.renderToBuffer();
</del><ins>+  renderToBufferIfNeeded: function(view, buffer) {
+    view.renderToBuffer(buffer);
+    return true;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   empty: Ember.K,
</span><span class="lines">@@ -15979,7 +24199,7 @@
</span><span class="cx"> @submodule ember-views
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var get = Ember.get, set = Ember.set, meta = Ember.meta;
</del><ins>+var get = Ember.get, set = Ember.set;
</ins><span class="cx"> 
</span><span class="cx"> var inBuffer = Ember.View.states.inBuffer = Ember.create(Ember.View.states._default);
</span><span class="cx"> 
</span><span class="lines">@@ -16003,10 +24223,11 @@
</span><span class="cx">   // view will render that view and append the resulting
</span><span class="cx">   // buffer into its buffer.
</span><span class="cx">   appendChild: function(view, childView, options) {
</span><del>-    var buffer = view.buffer;
</del><ins>+    var buffer = view.buffer, _childViews = view._childViews;
</ins><span class="cx"> 
</span><span class="cx">     childView = view.createChildView(childView, options);
</span><del>-    view._childViews.push(childView);
</del><ins>+    if (!_childViews.length) { _childViews = view._childViews = _childViews.slice(); }
+    _childViews.push(childView);
</ins><span class="cx"> 
</span><span class="cx">     childView.renderToBuffer(buffer);
</span><span class="cx"> 
</span><span class="lines">@@ -16020,18 +24241,21 @@
</span><span class="cx">   // state back into the preRender state.
</span><span class="cx">   destroyElement: function(view) {
</span><span class="cx">     view.clearBuffer();
</span><del>-    view._notifyWillDestroyElement();
-    view.transitionTo('preRender');
</del><ins>+    var viewCollection = view._notifyWillDestroyElement();
+    viewCollection.transitionTo('preRender', false);
</ins><span class="cx"> 
</span><span class="cx">     return view;
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   empty: function() {
</span><del>-    Ember.assert(&quot;Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property change notifications.&quot;);
</del><ins>+    Ember.assert(&quot;Emptying a view in the inBuffer state is not allowed and &quot; +
+                 &quot;should not happen under normal circumstances. Most likely &quot; +
+                 &quot;there is a bug in your application. This may be due to &quot; +
+                 &quot;excessive property change notifications.&quot;);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  renderToBufferIfNeeded: function (view) {
-    return view.buffer;
</del><ins>+  renderToBufferIfNeeded: function (view, buffer) {
+    return false;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   // It should be impossible for a rendered view to be scheduled for
</span><span class="lines">@@ -16049,6 +24273,10 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return value;
</span><ins>+  },
+
+  invokeObserver: function(target, observer) {
+    observer.call(target);
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -16063,7 +24291,7 @@
</span><span class="cx"> @submodule ember-views
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var get = Ember.get, set = Ember.set, meta = Ember.meta;
</del><ins>+var get = Ember.get, set = Ember.set;
</ins><span class="cx"> 
</span><span class="cx"> var hasElement = Ember.View.states.hasElement = Ember.create(Ember.View.states._default);
</span><span class="cx"> 
</span><span class="lines">@@ -16136,12 +24364,33 @@
</span><span class="cx">     } else {
</span><span class="cx">       return true; // continue event propagation
</span><span class="cx">     }
</span><ins>+  },
+
+  invokeObserver: function(target, observer) {
+    observer.call(target);
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> var inDOM = Ember.View.states.inDOM = Ember.create(hasElement);
</span><span class="cx"> 
</span><span class="cx"> Ember.merge(inDOM, {
</span><ins>+  enter: function(view) {
+    // Register the view for event handling. This hash is used by
+    // Ember.EventDispatcher to dispatch incoming events.
+    if (!view.isVirtual) {
+      Ember.assert(&quot;Attempted to register a view with an id already in use: &quot;+view.elementId, !Ember.View.views[view.elementId]);
+      Ember.View.views[view.elementId] = view;
+    }
+
+    view.addBeforeObserver('elementId', function() {
+      throw new Ember.Error(&quot;Changing a view's elementId after creation is not allowed&quot;);
+    });
+  },
+
+  exit: function(view) {
+    if (!this.isVirtual) delete Ember.View.views[view.elementId];
+  },
+
</ins><span class="cx">   insertElement: function(view, fn) {
</span><span class="cx">     throw &quot;You can't insert an element into the DOM that has already been inserted&quot;;
</span><span class="cx">   }
</span><span class="lines">@@ -16157,30 +24406,30 @@
</span><span class="cx"> @submodule ember-views
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var destroyedError = &quot;You can't call %@ on a destroyed view&quot;, fmt = Ember.String.fmt;
</del><ins>+var destroyingError = &quot;You can't call %@ on a view being destroyed&quot;, fmt = Ember.String.fmt;
</ins><span class="cx"> 
</span><del>-var destroyed = Ember.View.states.destroyed = Ember.create(Ember.View.states._default);
</del><ins>+var destroying = Ember.View.states.destroying = Ember.create(Ember.View.states._default);
</ins><span class="cx"> 
</span><del>-Ember.merge(destroyed, {
</del><ins>+Ember.merge(destroying, {
</ins><span class="cx">   appendChild: function() {
</span><del>-    throw fmt(destroyedError, ['appendChild']);
</del><ins>+    throw fmt(destroyingError, ['appendChild']);
</ins><span class="cx">   },
</span><span class="cx">   rerender: function() {
</span><del>-    throw fmt(destroyedError, ['rerender']);
</del><ins>+    throw fmt(destroyingError, ['rerender']);
</ins><span class="cx">   },
</span><span class="cx">   destroyElement: function() {
</span><del>-    throw fmt(destroyedError, ['destroyElement']);
</del><ins>+    throw fmt(destroyingError, ['destroyElement']);
</ins><span class="cx">   },
</span><span class="cx">   empty: function() {
</span><del>-    throw fmt(destroyedError, ['empty']);
</del><ins>+    throw fmt(destroyingError, ['empty']);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   setElement: function() {
</span><del>-    throw fmt(destroyedError, [&quot;set('element', ...)&quot;]);
</del><ins>+    throw fmt(destroyingError, [&quot;set('element', ...)&quot;]);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   renderToBufferIfNeeded: function() {
</span><del>-    throw fmt(destroyedError, [&quot;renderToBufferIfNeeded&quot;]);
</del><ins>+    return false;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   // Since element insertion is scheduled, don't do anything if
</span><span class="lines">@@ -16199,13 +24448,11 @@
</span><span class="cx"> 
</span><span class="cx">   into._default = {};
</span><span class="cx">   into.preRender = Ember.create(into._default);
</span><del>-  into.destroyed = Ember.create(into._default);
</del><ins>+  into.destroying = Ember.create(into._default);
</ins><span class="cx">   into.inBuffer = Ember.create(into._default);
</span><span class="cx">   into.hasElement = Ember.create(into._default);
</span><span class="cx">   into.inDOM = Ember.create(into.hasElement);
</span><span class="cx"> 
</span><del>-  var viewState;
-
</del><span class="cx">   for (var stateName in from) {
</span><span class="cx">     if (!from.hasOwnProperty(stateName)) { continue; }
</span><span class="cx">     Ember.merge(into[stateName], from[stateName]);
</span><span class="lines">@@ -16226,12 +24473,13 @@
</span><span class="cx"> @submodule ember-views
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var get = Ember.get, set = Ember.set, meta = Ember.meta;
</del><ins>+var get = Ember.get, set = Ember.set;
</ins><span class="cx"> var forEach = Ember.EnumerableUtils.forEach;
</span><ins>+var ViewCollection = Ember._ViewCollection;
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><span class="cx">   A `ContainerView` is an `Ember.View` subclass that implements `Ember.MutableArray`
</span><del>-  allowing programatic management of its child views.
</del><ins>+  allowing programmatic management of its child views.
</ins><span class="cx"> 
</span><span class="cx">   ## Setting Initial Child Views
</span><span class="cx"> 
</span><span class="lines">@@ -16271,7 +24519,7 @@
</span><span class="cx"> 
</span><span class="cx">   ## Adding and Removing Child Views
</span><span class="cx"> 
</span><del>-  The container view implements `Ember.MutableArray` allowing programatic management of its child views.
</del><ins>+  The container view implements `Ember.MutableArray` allowing programmatic management of its child views.
</ins><span class="cx"> 
</span><span class="cx">   To remove a view, pass that view into a `removeObject` call on the container view.
</span><span class="cx"> 
</span><span class="lines">@@ -16375,30 +24623,6 @@
</span><span class="cx">   or layout being rendered. The HTML contents of a `Ember.ContainerView`'s DOM
</span><span class="cx">   representation will only be the rendered HTML of its child views.
</span><span class="cx"> 
</span><del>-  ## Binding a View to Display
-
-  If you would like to display a single view in your ContainerView, you can set
-  its `currentView` property. When the `currentView` property is set to a view
-  instance, it will be added to the ContainerView. If the `currentView` property
-  is later changed to a different view, the new view will replace the old view.
-  If `currentView` is set to `null`, the last `currentView` will be removed.
-
-  This functionality is useful for cases where you want to bind the display of
-  a ContainerView to a controller or state manager. For example, you can bind
-  the `currentView` of a container to a controller like this:
-
-  ```javascript
-  App.appController = Ember.Object.create({
-    view: Ember.View.create({
-      templateName: 'person_template'
-    })
-  });
-  ```
-
-  ```handlebars
-  {{view Ember.ContainerView currentViewBinding=&quot;App.appController.view&quot;}}
-  ```
-
</del><span class="cx">   @class ContainerView
</span><span class="cx">   @namespace Ember
</span><span class="cx">   @extends Ember.View
</span><span class="lines">@@ -16432,12 +24656,15 @@
</span><span class="cx"> 
</span><span class="cx">     var currentView = get(this, 'currentView');
</span><span class="cx">     if (currentView) {
</span><ins>+      if (!_childViews.length) { _childViews = this._childViews = this._childViews.slice(); }
</ins><span class="cx">       _childViews.push(this.createChildView(currentView));
</span><span class="cx">     }
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   replace: function(idx, removedCount, addedViews) {
</span><span class="cx">     var addedCount = addedViews ? get(addedViews, 'length') : 0;
</span><ins>+    var self = this;
+    Ember.assert(&quot;You can't add a child to a container that is already a child of another view&quot;, Ember.A(addedViews).every(function(item) { return !get(item, '_parentView') || get(item, '_parentView') === self; }));
</ins><span class="cx"> 
</span><span class="cx">     this.arrayContentWillChange(idx, removedCount, addedCount);
</span><span class="cx">     this.childViewsWillChange(this._childViews, idx, removedCount);
</span><span class="lines">@@ -16446,6 +24673,7 @@
</span><span class="cx">       this._childViews.splice(idx, removedCount) ;
</span><span class="cx">     } else {
</span><span class="cx">       var args = [idx, removedCount].concat(addedViews);
</span><ins>+      if (addedViews.length &amp;&amp; !this._childViews.length) { this._childViews = this._childViews.slice(); }
</ins><span class="cx">       this._childViews.splice.apply(this._childViews, args);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -16461,13 +24689,12 @@
</span><span class="cx"> 
</span><span class="cx">   length: Ember.computed(function () {
</span><span class="cx">     return this._childViews.length;
</span><del>-  }),
</del><ins>+  }).volatile(),
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Instructs each child view to render to the passed render buffer.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method render
</span><span class="cx">     @param {Ember.RenderBuffer} buffer the buffer to render to
</span><span class="cx">   */
</span><span class="lines">@@ -16477,17 +24704,16 @@
</span><span class="cx">     });
</span><span class="cx">   },
</span><span class="cx"> 
</span><del>-  instrumentName: 'render.container',
</del><ins>+  instrumentName: 'container',
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     When a child view is removed, destroy its element so that
</span><span class="cx">     it is removed from the DOM.
</span><span class="cx"> 
</span><span class="cx">     The array observer that triggers this action is set up in the
</span><span class="cx">     `renderToBuffer` method.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method childViewsWillChange
</span><span class="cx">     @param {Ember.Array} views the child views array before mutation
</span><span class="cx">     @param {Number} start the start position of the mutation
</span><span class="lines">@@ -16510,8 +24736,6 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     When a child view is added, make sure the DOM gets updated appropriately.
</span><span class="cx"> 
</span><span class="cx">     If the view has already rendered an element, we tell the child view to
</span><span class="lines">@@ -16520,6 +24744,7 @@
</span><span class="cx">     into an element, we insert the string representation of the child into the
</span><span class="cx">     appropriate place in the buffer.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method childViewsDidChange
</span><span class="cx">     @param {Ember.Array} views the array of child views afte the mutation has occurred
</span><span class="cx">     @param {Number} start the start position of the mutation
</span><span class="lines">@@ -16539,6 +24764,10 @@
</span><span class="cx">     forEach(views, function(view) {
</span><span class="cx">       set(view, '_parentView', parentView);
</span><span class="cx"> 
</span><ins>+      if (!view.container &amp;&amp; parentView) {
+        set(view, 'container', parentView.container);
+      }
+
</ins><span class="cx">       if (!get(view, 'templateData')) {
</span><span class="cx">         set(view, 'templateData', templateData);
</span><span class="cx">       }
</span><span class="lines">@@ -16547,19 +24776,20 @@
</span><span class="cx"> 
</span><span class="cx">   currentView: null,
</span><span class="cx"> 
</span><del>-  _currentViewWillChange: Ember.beforeObserver(function() {
</del><ins>+  _currentViewWillChange: Ember.beforeObserver('currentView', function() {
</ins><span class="cx">     var currentView = get(this, 'currentView');
</span><span class="cx">     if (currentView) {
</span><span class="cx">       currentView.destroy();
</span><span class="cx">     }
</span><del>-  }, 'currentView'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><del>-  _currentViewDidChange: Ember.observer(function() {
</del><ins>+  _currentViewDidChange: Ember.observer('currentView', function() {
</ins><span class="cx">     var currentView = get(this, 'currentView');
</span><span class="cx">     if (currentView) {
</span><ins>+      Ember.assert(&quot;You tried to set a current view that already has a parent. Make sure you don't have multiple outlets in the same view.&quot;, !get(currentView, '_parentView'));
</ins><span class="cx">       this.pushObject(currentView);
</span><span class="cx">     }
</span><del>-  }, 'currentView'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><span class="cx">   _ensureChildrenAreInDOM: function () {
</span><span class="cx">     this.currentState.ensureChildrenAreInDOM(this);
</span><span class="lines">@@ -16574,7 +24804,7 @@
</span><span class="cx"> 
</span><span class="cx"> Ember.merge(states.inBuffer, {
</span><span class="cx">   childViewsDidChange: function(parentView, views, start, added) {
</span><del>-    throw new Error('You cannot modify child views while in the inBuffer state');
</del><ins>+    throw new Ember.Error('You cannot modify child views while in the inBuffer state');
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -16590,26 +24820,48 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   ensureChildrenAreInDOM: function(view) {
</span><del>-    var childViews = view._childViews, i, len, childView, previous, buffer;
</del><ins>+    var childViews = view._childViews, i, len, childView, previous, buffer, viewCollection = new ViewCollection();
+
</ins><span class="cx">     for (i = 0, len = childViews.length; i &lt; len; i++) {
</span><span class="cx">       childView = childViews[i];
</span><del>-      buffer = childView.renderToBufferIfNeeded();
-      if (buffer) {
-        childView.triggerRecursively('willInsertElement');
-        if (previous) {
-          previous.domManager.after(previous, buffer.string());
-        } else {
-          view.domManager.prepend(view, buffer.string());
-        }
-        childView.transitionTo('inDOM');
-        childView.propertyDidChange('element');
-        childView.triggerRecursively('didInsertElement');
</del><ins>+
+      if (!buffer) { buffer = Ember.RenderBuffer(); buffer._hasElement = false; }
+
+      if (childView.renderToBufferIfNeeded(buffer)) {
+        viewCollection.push(childView);
+      } else if (viewCollection.length) {
+        insertViewCollection(view, viewCollection, previous, buffer);
+        buffer = null;
+        previous = childView;
+        viewCollection.clear();
+      } else {
+        previous = childView;
</ins><span class="cx">       }
</span><del>-      previous = childView;
</del><span class="cx">     }
</span><ins>+
+    if (viewCollection.length) {
+      insertViewCollection(view, viewCollection, previous, buffer);
+    }
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><ins>+function insertViewCollection(view, viewCollection, previous, buffer) {
+  viewCollection.triggerRecursively('willInsertElement');
+
+  if (previous) {
+    previous.domManager.after(previous, buffer.string());
+  } else {
+    view.domManager.prepend(view, buffer.string());
+  }
+
+  viewCollection.forEach(function(v) {
+    v.transitionTo('inDOM');
+    v.propertyDidChange('element');
+    v.triggerRecursively('didInsertElement');
+  });
+}
+
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -16624,7 +24876,7 @@
</span><span class="cx"> 
</span><span class="cx"> /**
</span><span class="cx">   `Ember.CollectionView` is an `Ember.View` descendent responsible for managing
</span><del>-  a collection (an array or array-like object) by maintaing a child view object
</del><ins>+  a collection (an array or array-like object) by maintaining a child view object
</ins><span class="cx">   and associated DOM representation for each item in the array and ensuring
</span><span class="cx">   that child views and their associated rendered HTML are updated when items in
</span><span class="cx">   the array are added, removed, or replaced.
</span><span class="lines">@@ -16651,7 +24903,7 @@
</span><span class="cx"> 
</span><span class="cx">   Given an empty `&lt;body&gt;` and the following code:
</span><span class="cx"> 
</span><del>-  ```javascript 
</del><ins>+  ```javascript
</ins><span class="cx">   someItemsView = Ember.CollectionView.create({
</span><span class="cx">     classNames: ['a-collection'],
</span><span class="cx">     content: ['A','B','C'],
</span><span class="lines">@@ -16710,7 +24962,7 @@
</span><span class="cx">   Ember.CollectionView.CONTAINER_MAP['article'] = 'section'
</span><span class="cx">   ```
</span><span class="cx"> 
</span><del>-  ## Programatic creation of child views
</del><ins>+  ## Programmatic creation of child views
</ins><span class="cx"> 
</span><span class="cx">   For cases where additional customization beyond the use of a single
</span><span class="cx">   `itemViewClass` or `tagName` matching is required CollectionView's
</span><span class="lines">@@ -16724,7 +24976,7 @@
</span><span class="cx">       } else {
</span><span class="cx">         viewClass = App.SongView;
</span><span class="cx">       }
</span><del>-      this._super(viewClass, attrs);
</del><ins>+      return this._super(viewClass, attrs);
</ins><span class="cx">     }
</span><span class="cx">   });
</span><span class="cx">   ```
</span><span class="lines">@@ -16764,19 +25016,13 @@
</span><span class="cx">   manipulated. Instead, add, remove, replace items from its `content` property.
</span><span class="cx">   This will trigger appropriate changes to its rendered HTML.
</span><span class="cx"> 
</span><del>-  ## Use in templates via the `{{collection}}` `Ember.Handlebars` helper
</del><span class="cx"> 
</span><del>-  `Ember.Handlebars` provides a helper specifically for adding
-  `CollectionView`s to templates. See `Ember.Handlebars.collection` for more
-  details
-
</del><span class="cx">   @class CollectionView
</span><span class="cx">   @namespace Ember
</span><span class="cx">   @extends Ember.ContainerView
</span><span class="cx">   @since Ember 0.9
</span><span class="cx"> */
</span><del>-Ember.CollectionView = Ember.ContainerView.extend(
-/** @scope Ember.CollectionView.prototype */ {
</del><ins>+Ember.CollectionView = Ember.ContainerView.extend({
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     A list of items to be displayed by the `Ember.CollectionView`.
</span><span class="lines">@@ -16788,12 +25034,11 @@
</span><span class="cx">   content: null,
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     This provides metadata about what kind of empty view class this
</span><span class="cx">     collection would like if it is being instantiated from another
</span><span class="cx">     system (like Handlebars)
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @property emptyViewClass
</span><span class="cx">   */
</span><span class="cx">   emptyViewClass: Ember.View,
</span><span class="lines">@@ -16814,53 +25059,94 @@
</span><span class="cx">   */
</span><span class="cx">   itemViewClass: Ember.View,
</span><span class="cx"> 
</span><ins>+  /**
+    Setup a CollectionView
+
+    @method init
+  */
</ins><span class="cx">   init: function() {
</span><span class="cx">     var ret = this._super();
</span><span class="cx">     this._contentDidChange();
</span><span class="cx">     return ret;
</span><span class="cx">   },
</span><span class="cx"> 
</span><del>-  _contentWillChange: Ember.beforeObserver(function() {
</del><ins>+  /**
+    Invoked when the content property is about to change. Notifies observers that the
+    entire array content will change.
+
+    @private
+    @method _contentWillChange
+  */
+  _contentWillChange: Ember.beforeObserver('content', function() {
</ins><span class="cx">     var content = this.get('content');
</span><span class="cx"> 
</span><span class="cx">     if (content) { content.removeArrayObserver(this); }
</span><span class="cx">     var len = content ? get(content, 'length') : 0;
</span><span class="cx">     this.arrayWillChange(content, 0, len);
</span><del>-  }, 'content'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Check to make sure that the content has changed, and if so,
</span><span class="cx">     update the children directly. This is always scheduled
</span><span class="cx">     asynchronously, to allow the element to be created before
</span><span class="cx">     bindings have synchronized and vice versa.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method _contentDidChange
</span><span class="cx">   */
</span><del>-  _contentDidChange: Ember.observer(function() {
</del><ins>+  _contentDidChange: Ember.observer('content', function() {
</ins><span class="cx">     var content = get(this, 'content');
</span><span class="cx"> 
</span><span class="cx">     if (content) {
</span><del>-      Ember.assert(fmt(&quot;an Ember.CollectionView's content must implement Ember.Array. You passed %@&quot;, [content]), Ember.Array.detect(content));
</del><ins>+      this._assertArrayLike(content);
</ins><span class="cx">       content.addArrayObserver(this);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     var len = content ? get(content, 'length') : 0;
</span><span class="cx">     this.arrayDidChange(content, 0, null, len);
</span><del>-  }, 'content'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><del>-  willDestroy: function() {
</del><ins>+  /**
+    Ensure that the content implements Ember.Array
+
+    @private
+    @method _assertArrayLike
+  */
+  _assertArrayLike: function(content) {
+    Ember.assert(fmt(&quot;an Ember.CollectionView's content must implement Ember.Array. You passed %@&quot;, [content]), Ember.Array.detect(content));
+  },
+
+  /**
+    Removes the content and content observers.
+
+    @method destroy
+  */
+  destroy: function() {
+    if (!this._super()) { return; }
+
</ins><span class="cx">     var content = get(this, 'content');
</span><span class="cx">     if (content) { content.removeArrayObserver(this); }
</span><span class="cx"> 
</span><del>-    this._super();
-
</del><span class="cx">     if (this._createdEmptyView) {
</span><span class="cx">       this._createdEmptyView.destroy();
</span><span class="cx">     }
</span><ins>+
+    return this;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    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
+  */
</ins><span class="cx">   arrayWillChange: function(content, start, removedCount) {
</span><span class="cx">     // If the contents were empty before and this template collection has an
</span><span class="cx">     // empty view remove it now.
</span><span class="lines">@@ -16880,11 +25166,13 @@
</span><span class="cx"> 
</span><span class="cx">     if (removingAll) {
</span><span class="cx">       this.currentState.empty(this);
</span><ins>+      this.invokeRecursively(function(view) {
+        view.removedFromDOM = true;
+      }, false);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     for (idx = start + removedCount - 1; idx &gt;= start; idx--) {
</span><span class="cx">       childView = childViews[idx];
</span><del>-      if (removingAll) { childView.removedFromDOM = true; }
</del><span class="cx">       childView.destroy();
</span><span class="cx">     }
</span><span class="cx">   },
</span><span class="lines">@@ -16898,22 +25186,26 @@
</span><span class="cx">     This array observer is added in `contentDidChange`.
</span><span class="cx"> 
</span><span class="cx">     @method arrayDidChange
</span><del>-    @param {Array} addedObjects the objects that were added to the content
-    @param {Array} removedObjects the objects that were removed from the content
-    @param {Number} changeIndex the index at which the changes occurred
</del><ins>+    @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
</ins><span class="cx">   */
</span><span class="cx">   arrayDidChange: function(content, start, removed, added) {
</span><del>-    var itemViewClass = get(this, 'itemViewClass'),
-        addedViews = [], view, item, idx, len, itemTagName;
</del><ins>+    var addedViews = [], view, item, idx, len, itemViewClass,
+      emptyView;
</ins><span class="cx"> 
</span><del>-    if ('string' === typeof itemViewClass) {
-      itemViewClass = get(itemViewClass);
-    }
</del><ins>+    len = content ? get(content, 'length') : 0;
</ins><span class="cx"> 
</span><del>-    Ember.assert(fmt(&quot;itemViewClass must be a subclass of Ember.View, not %@&quot;, [itemViewClass]), Ember.View.detect(itemViewClass));
</del><ins>+    if (len) {
+      itemViewClass = get(this, 'itemViewClass');
</ins><span class="cx"> 
</span><del>-    len = content ? get(content, 'length') : 0;
-    if (len) {
</del><ins>+      if ('string' === typeof itemViewClass) {
+        itemViewClass = get(itemViewClass) || itemViewClass;
+      }
+
+      Ember.assert(fmt(&quot;itemViewClass must be a subclass of Ember.View, not %@&quot;, [itemViewClass]), 'string' === typeof itemViewClass || Ember.View.detect(itemViewClass));
+
</ins><span class="cx">       for (idx = start; idx &lt; start+added; idx++) {
</span><span class="cx">         item = content.objectAt(idx);
</span><span class="cx"> 
</span><span class="lines">@@ -16925,27 +25217,50 @@
</span><span class="cx">         addedViews.push(view);
</span><span class="cx">       }
</span><span class="cx">     } else {
</span><del>-      var emptyView = get(this, 'emptyView');
</del><ins>+      emptyView = get(this, 'emptyView');
+
</ins><span class="cx">       if (!emptyView) { return; }
</span><span class="cx"> 
</span><del>-      var isClass = Ember.CoreView.detect(emptyView);
</del><ins>+      if ('string' === typeof emptyView) {
+        emptyView = get(emptyView) || emptyView;
+      }
</ins><span class="cx"> 
</span><span class="cx">       emptyView = this.createChildView(emptyView);
</span><span class="cx">       addedViews.push(emptyView);
</span><span class="cx">       set(this, 'emptyView', emptyView);
</span><span class="cx"> 
</span><del>-      if (isClass) { this._createdEmptyView = emptyView; }
</del><ins>+      if (Ember.CoreView.detect(emptyView)) {
+        this._createdEmptyView = emptyView;
+      }
</ins><span class="cx">     }
</span><ins>+
</ins><span class="cx">     this.replace(start, 0, addedViews);
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    Instantiates a view to be added to the childViews array during view
+    initialization. You generally will not call this method directly unless
+    you are overriding `createChildViews()`. Note that this method will
+    automatically configure the correct settings on the new view instance to
+    act as a child of the parent.
+
+    The tag name for the view will be set to the tagName of the viewClass
+    passed in.
+
+    @method createChildView
+    @param {Class} viewClass
+    @param {Hash} [attrs] Attributes to add
+    @return {Ember.View} new instance
+  */
</ins><span class="cx">   createChildView: function(view, attrs) {
</span><span class="cx">     view = this._super(view, attrs);
</span><span class="cx"> 
</span><span class="cx">     var itemTagName = get(view, 'tagName');
</span><del>-    var tagName = (itemTagName === null || itemTagName === undefined) ? Ember.CollectionView.CONTAINER_MAP[get(this, 'tagName')] : itemTagName;
</del><span class="cx"> 
</span><del>-    set(view, 'tagName', tagName);
</del><ins>+    if (itemTagName === null || itemTagName === undefined) {
+      itemTagName = Ember.CollectionView.CONTAINER_MAP[get(this, 'tagName')];
+      set(view, 'tagName', itemTagName);
+    }
</ins><span class="cx"> 
</span><span class="cx">     return view;
</span><span class="cx">   }
</span><span class="lines">@@ -16977,14 +25292,336 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><ins>+var get = Ember.get, set = Ember.set, isNone = Ember.isNone,
+    a_slice = Array.prototype.slice;
</ins><span class="cx"> 
</span><ins>+
+/**
+@module ember
+@submodule ember-views
+*/
+
+/**
+  An `Ember.Component` is a view that is completely
+  isolated. Property access in its templates go
+  to the view object and actions are targeted at
+  the view object. There is no access to the
+  surrounding context or outer controller; all
+  contextual information must be passed in.
+
+  The easiest way to create an `Ember.Component` is via
+  a template. If you name a template
+  `components/my-foo`, you will be able to use
+  `{{my-foo}}` in other templates, which will make
+  an instance of the isolated component.
+
+  ```html
+  {{app-profile person=currentUser}}
+  ```
+
+  ```html
+  &lt;!-- app-profile template --&gt;
+  &lt;h1&gt;{{person.title}}&lt;/h1&gt;
+  &lt;img {{bind-attr src=person.avatar}}&gt;
+  &lt;p class='signature'&gt;{{person.signature}}&lt;/p&gt;
+  ```
+
+  You can use `yield` inside a template to
+  include the **contents** of any block attached to
+  the component. The block will be executed in the
+  context of the surrounding context or outer controller:
+
+  ```handlebars
+  {{#app-profile person=currentUser}}
+    &lt;p&gt;Admin mode&lt;/p&gt;
+    {{! Executed in the controllers context. }}
+  {{/app-profile}}
+  ```
+
+  ```handlebars
+  &lt;!-- app-profile template --&gt;
+  &lt;h1&gt;{{person.title}}&lt;/h1&gt;
+  {{! Executed in the components context. }}
+  {{yield}} {{! block contents }}
+  ```
+
+  If you want to customize the component, in order to
+  handle events or actions, you implement a subclass
+  of `Ember.Component` named after the name of the
+  component. Note that `Component` needs to be appended to the name of
+  your subclass like `AppProfileComponent`.
+
+  For example, you could implement the action
+  `hello` for the `app-profile` component:
+
+  ```javascript
+  App.AppProfileComponent = Ember.Component.extend({
+    actions: {
+      hello: function(name) {
+        console.log(&quot;Hello&quot;, name);
+      }
+    }
+  });
+  ```
+
+  And then use it in the component's template:
+
+  ```html
+  &lt;!-- app-profile template --&gt;
+
+  &lt;h1&gt;{{person.title}}&lt;/h1&gt;
+  {{yield}} &lt;!-- block contents --&gt;
+
+  &lt;button {{action 'hello' person.name}}&gt;
+    Say Hello to {{person.name}}
+  &lt;/button&gt;
+  ```
+
+  Components must have a `-` in their name to avoid
+  conflicts with built-in controls that wrap HTML
+  elements. This is consistent with the same
+  requirement in web components.
+
+  @class Component
+  @namespace Ember
+  @extends Ember.View
+*/
+Ember.Component = Ember.View.extend(Ember.TargetActionSupport, {
+  init: function() {
+    this._super();
+    set(this, 'context', this);
+    set(this, 'controller', this);
+  },
+
+  defaultLayout: function(options){
+    options.data = {view: options._context};
+    Ember.Handlebars.helpers['yield'].apply(this, [options]);
+  },
+
+  // during render, isolate keywords
+  cloneKeywords: function() {
+    return {
+      view: this,
+      controller: this
+    };
+  },
+
+  _yield: function(context, options) {
+    var view = options.data.view,
+        parentView = this._parentView,
+        template = get(this, 'template');
+
+    if (template) {
+      Ember.assert(&quot;A Component must have a parent view in order to yield.&quot;, parentView);
+
+      view.appendChild(Ember.View, {
+        isVirtual: true,
+        tagName: '',
+        _contextView: parentView,
+        template: template,
+        context: get(parentView, 'context'),
+        controller: get(parentView, 'controller'),
+        templateData: { keywords: parentView.cloneKeywords() }
+      });
+    }
+  },
+
+  /**
+    If the component is currently inserted into the DOM of a parent view, this
+    property will point to the controller of the parent view.
+
+    @property targetObject
+    @type Ember.Controller
+    @default null
+  */
+  targetObject: Ember.computed(function(key) {
+    var parentView = get(this, '_parentView');
+    return parentView ? get(parentView, 'controller') : null;
+  }).property('_parentView'),
+
+  /**
+    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 &quot;play&quot; or &quot;stop&quot; depending on some internal state
+    of the component:
+
+
+    ```javascript
+    App.PlayButtonComponent = Ember.Component.extend({
+      click: function(){
+        if (this.get('isPlaying')) {
+          this.triggerAction('play');
+        } else {
+          this.triggerAction('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=&quot;musicStarted&quot; stop=&quot;musicStopped&quot;}}
+    ```
+
+    When the component receives a browser `click` event it translate this
+    interaction into application-specific semantics (&quot;play&quot; or &quot;stop&quot;) 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 &quot;action&quot;
+    is assumed.
+
+    ```javascript
+    App.NextButtonComponent = Ember.Component.extend({
+      click: function(){
+        this.sendAction();
+      }
+    });
+    ```
+
+    ```handlebars
+    {{! application.hbs }}
+    {{next-button action=&quot;playNextSongInAlbum&quot;}}
+    ```
+
+    ```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
+  */
+  sendAction: function(action) {
+    var actionName,
+        contexts = a_slice.call(arguments, 1);
+
+    // Send the default action
+    if (action === undefined) {
+      actionName = get(this, 'action');
+      Ember.assert(&quot;The default action was triggered on the component &quot; + this.toString() +
+                   &quot;, but the action name (&quot; + actionName + &quot;) was not a string.&quot;,
+                   isNone(actionName) || typeof actionName === 'string');
+    } else {
+      actionName = get(this, action);
+      Ember.assert(&quot;The &quot; + action + &quot; action was triggered on the component &quot; +
+                   this.toString() + &quot;, but the action name (&quot; + actionName +
+                   &quot;) was not a string.&quot;,
+                   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
+    });
+  }
+});
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-/*globals jQuery*/
</del><ins>+
+})();
+
+
+
+(function() {
</ins><span class="cx"> /**
</span><ins>+`Ember.ViewTargetActionSupport` is a mixin that can be included in a
+view class to add a `triggerAction` method with semantics similar to
+the Handlebars `{{action}}` helper. It provides intelligent defaults
+for the action's target: the view's controller; and the context that is
+sent with the action: the view's context.
+
+Note: In normal Ember usage, the `{{action}}` helper is usually the best
+choice. This mixin is most often useful when you are doing more complex
+event handling in custom View subclasses.
+
+For example:
+
+```javascript
+App.SaveButtonView = Ember.View.extend(Ember.ViewTargetActionSupport, {
+  action: 'save',
+  click: function() {
+    this.triggerAction(); // Sends the `save` action, along with the current context
+                          // to the current controller
+  }
+});
+```
+
+The `action` can be provided as properties of an optional object argument
+to `triggerAction` as well.
+
+```javascript
+App.SaveButtonView = Ember.View.extend(Ember.ViewTargetActionSupport, {
+  click: function() {
+    this.triggerAction({
+      action: 'save'
+    }); // Sends the `save` action, along with the current context
+        // to the current controller
+  }
+});
+```
+
+@class ViewTargetActionSupport
+@namespace Ember
+@extends Ember.TargetActionSupport
+*/
+Ember.ViewTargetActionSupport = Ember.Mixin.create(Ember.TargetActionSupport, {
+  /**
+  @property target
+  */
+  target: Ember.computed.alias('controller'),
+  /**
+  @property actionContext
+  */
+  actionContext: Ember.computed.alias('context')
+});
+
+})();
+
+
+
+(function() {
+
+})();
+
+
+
+(function() {
+/**
</ins><span class="cx"> Ember Views
</span><span class="cx"> 
</span><span class="cx"> @module ember
</span><span class="lines">@@ -17002,20 +25639,28 @@
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx">     // ==========================================================================
</span><span class="cx">     // Project:   metamorph
</span><del>-    // Copyright: ©2011 My Company Inc. All rights reserved.
</del><ins>+    // Copyright: ©2014 Tilde, Inc. All rights reserved.
</ins><span class="cx">     // ==========================================================================
</span><span class="cx"> 
</span><del>-    var K = function(){},
</del><ins>+    var K = function() {},
</ins><span class="cx">         guid = 0,
</span><del>-        document = window.document,
</del><ins>+        disableRange = (function(){
+          if ('undefined' !== typeof MetamorphENV) {
+            return MetamorphENV.DISABLE_RANGE_API;
+          } else if ('undefined' !== ENV) {
+            return ENV.DISABLE_RANGE_API;
+          } else {
+            return false;
+          }
+        })(),
</ins><span class="cx"> 
</span><span class="cx">         // Feature-detect the W3C range API, the extended check is for IE9 which only partially supports ranges
</span><del>-        supportsRange = ('createRange' in document) &amp;&amp; (typeof Range !== 'undefined') &amp;&amp; Range.prototype.createContextualFragment,
</del><ins>+        supportsRange = (!disableRange) &amp;&amp; document &amp;&amp; ('createRange' in document) &amp;&amp; (typeof Range !== 'undefined') &amp;&amp; Range.prototype.createContextualFragment,
</ins><span class="cx"> 
</span><span class="cx">         // Internet Explorer prior to 9 does not allow setting innerHTML if the first element
</span><span class="cx">         // is a &quot;zero-scope&quot; element. This problem can be worked around by making
</span><span class="cx">         // the first node an invisible text node. We, like Modernizr, use &amp;shy;
</span><del>-        needsShy = (function(){
</del><ins>+        needsShy = document &amp;&amp; (function() {
</ins><span class="cx">           var testEl = document.createElement('div');
</span><span class="cx">           testEl.innerHTML = &quot;&lt;div&gt;&lt;/div&gt;&quot;;
</span><span class="cx">           testEl.firstChild.innerHTML = &quot;&lt;script&gt;&lt;/script&gt;&quot;;
</span><span class="lines">@@ -17026,7 +25671,7 @@
</span><span class="cx">         // IE 8 (and likely earlier) likes to move whitespace preceeding
</span><span class="cx">         // a script tag to appear after it. This means that we can
</span><span class="cx">         // accidentally remove whitespace when updating a morph.
</span><del>-        movesWhitespace = (function() {
</del><ins>+        movesWhitespace = document &amp;&amp; (function() {
</ins><span class="cx">           var testEl = document.createElement('div');
</span><span class="cx">           testEl.innerHTML = &quot;Test: &lt;script type='text/x-placeholder'&gt;&lt;/script&gt;Value&quot;;
</span><span class="cx">           return testEl.childNodes[0].nodeValue === 'Test:' &amp;&amp;
</span><span class="lines">@@ -17117,6 +25762,14 @@
</span><span class="cx">         range.insertNode(fragment);
</span><span class="cx">       };
</span><span class="cx"> 
</span><ins>+      /**
+      * @public
+      *
+      * Remove this object (including starting and ending
+      * placeholders).
+      *
+      * @method remove
+      */
</ins><span class="cx">       removeFunc = function() {
</span><span class="cx">         // get a range for the current metamorph object including
</span><span class="cx">         // the starting and ending placeholders.
</span><span class="lines">@@ -17157,7 +25810,7 @@
</span><span class="cx">       };
</span><span class="cx"> 
</span><span class="cx">     } else {
</span><del>-      /**
</del><ins>+      /*
</ins><span class="cx">        * This code is mostly taken from jQuery, with one exception. In jQuery's case, we
</span><span class="cx">        * have some HTML and we need to figure out how to convert it into some nodes.
</span><span class="cx">        *
</span><span class="lines">@@ -17211,12 +25864,12 @@
</span><span class="cx">         }
</span><span class="cx">       };
</span><span class="cx"> 
</span><del>-      /**
</del><ins>+      /*
</ins><span class="cx">        * Given a parent node and some HTML, generate a set of nodes. Return the first
</span><span class="cx">        * node, which will allow us to traverse the rest using nextSibling.
</span><span class="cx">        *
</span><span class="cx">        * We need to do this because innerHTML in IE does not really parse the nodes.
</span><del>-       **/
</del><ins>+       */
</ins><span class="cx">       var firstNodeFor = function(parentNode, html) {
</span><span class="cx">         var arr = wrapMap[parentNode.tagName.toLowerCase()] || wrapMap._default;
</span><span class="cx">         var depth = arr[0], start = arr[1], end = arr[2];
</span><span class="lines">@@ -17249,7 +25902,7 @@
</span><span class="cx">         return element;
</span><span class="cx">       };
</span><span class="cx"> 
</span><del>-      /**
</del><ins>+      /*
</ins><span class="cx">        * In some cases, Internet Explorer can create an anonymous node in
</span><span class="cx">        * the hierarchy with no tagName. You can create this scenario via:
</span><span class="cx">        *
</span><span class="lines">@@ -17259,7 +25912,7 @@
</span><span class="cx">        *
</span><span class="cx">        * If our script markers are inside such a node, we need to find that
</span><span class="cx">        * node and use *it* as the marker.
</span><del>-       **/
</del><ins>+       */
</ins><span class="cx">       var realNode = function(start) {
</span><span class="cx">         while (start.parentNode.tagName === &quot;&quot;) {
</span><span class="cx">           start = start.parentNode;
</span><span class="lines">@@ -17268,7 +25921,7 @@
</span><span class="cx">         return start;
</span><span class="cx">       };
</span><span class="cx"> 
</span><del>-      /**
</del><ins>+      /*
</ins><span class="cx">        * When automatically adding a tbody, Internet Explorer inserts the
</span><span class="cx">        * tbody immediately before the first &lt;tr&gt;. Other browsers create it
</span><span class="cx">        * before the first node, no matter what.
</span><span class="lines">@@ -17295,7 +25948,8 @@
</span><span class="cx">        *
</span><span class="cx">        * This code reparents the first script tag by making it the tbody's
</span><span class="cx">        * first child.
</span><del>-       **/
</del><ins>+       *
+       */
</ins><span class="cx">       var fixParentage = function(start, end) {
</span><span class="cx">         if (start.parentNode !== end.parentNode) {
</span><span class="cx">           end.parentNode.insertBefore(start, end.parentNode.firstChild);
</span><span class="lines">@@ -17346,6 +26000,10 @@
</span><span class="cx">         // swallow some of the content.
</span><span class="cx">         node = firstNodeFor(start.parentNode, html);
</span><span class="cx"> 
</span><ins>+        if (outerToo) {
+          start.parentNode.removeChild(start);
+        }
+
</ins><span class="cx">         // copy the nodes for the HTML between the starting and ending
</span><span class="cx">         // placeholder.
</span><span class="cx">         while (node) {
</span><span class="lines">@@ -17460,7 +26118,7 @@
</span><span class="cx"> (function() {
</span><span class="cx"> /**
</span><span class="cx"> @module ember
</span><del>-@submodule ember-handlebars
</del><ins>+@submodule ember-handlebars-compiler
</ins><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> // Eliminate dependency on any Ember to simplify precompilation workflow
</span><span class="lines">@@ -17470,9 +26128,20 @@
</span><span class="cx">   return new F();
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-var Handlebars = this.Handlebars || Ember.imports.Handlebars;
-Ember.assert(&quot;Ember Handlebars requires Handlebars 1.0.0-rc.3 or greater&quot;, Handlebars &amp;&amp; Handlebars.VERSION.match(/^1\.0\.[0-9](\.rc\.[23456789]+)?/));
</del><ins>+var Handlebars = (Ember.imports &amp;&amp; Ember.imports.Handlebars) || (this &amp;&amp; this.Handlebars);
+if (!Handlebars &amp;&amp; typeof require === 'function') {
+  Handlebars = require('handlebars');
+}
</ins><span class="cx"> 
</span><ins>+Ember.assert(&quot;Ember Handlebars requires Handlebars version 1.0 or 1.1. Include &quot; +
+             &quot;a SCRIPT tag in the HTML HEAD linking to the Handlebars file &quot; +
+             &quot;before you link to Ember.&quot;, Handlebars);
+
+Ember.assert(&quot;Ember Handlebars requires Handlebars version 1.0 or 1.1, &quot; +
+             &quot;COMPILER_REVISION expected: 4, got: &quot; +  Handlebars.COMPILER_REVISION +
+             &quot; - Please note: Builds of master may have other COMPILER_REVISION values.&quot;,
+             Handlebars.COMPILER_REVISION === 4);
+
</ins><span class="cx"> /**
</span><span class="cx">   Prepares the Handlebars templating library for use inside Ember's view
</span><span class="cx">   system.
</span><span class="lines">@@ -17490,6 +26159,87 @@
</span><span class="cx"> Ember.Handlebars = objectCreate(Handlebars);
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+  Register a bound helper or custom view helper.
+
+  ## Simple bound helper example
+
+  ```javascript
+  Ember.Handlebars.helper('capitalize', function(value) {
+    return value.toUpperCase();
+  });
+  ```
+
+  The above bound helper can be used inside of templates as follows:
+
+  ```handlebars
+  {{capitalize name}}
+  ```
+
+  In this case, when the `name` property of the template's context changes,
+  the rendered value of the helper will update to reflect this change.
+
+  For more examples of bound helpers, see documentation for
+  `Ember.Handlebars.registerBoundHelper`.
+
+  ## Custom view helper example
+
+  Assuming a view subclass named `App.CalendarView` were defined, a helper
+  for rendering instances of this view could be registered as follows:
+
+  ```javascript
+  Ember.Handlebars.helper('calendar', App.CalendarView):
+  ```
+
+  The above bound helper can be used inside of templates as follows:
+
+  ```handlebars
+  {{calendar}}
+  ```
+
+  Which is functionally equivalent to:
+
+  ```handlebars
+  {{view App.CalendarView}}
+  ```
+
+  Options in the helper will be passed to the view in exactly the same
+  manner as with the `view` helper.
+
+  @method helper
+  @for Ember.Handlebars
+  @param {String} name
+  @param {Function|Ember.View} function or view class constructor
+  @param {String} dependentKeys*
+*/
+Ember.Handlebars.helper = function(name, value) {
+  Ember.assert(&quot;You tried to register a component named '&quot; + name + &quot;', but component names must include a '-'&quot;, !Ember.Component.detect(value) || name.match(/-/));
+
+  if (Ember.View.detect(value)) {
+    Ember.Handlebars.registerHelper(name, Ember.Handlebars.makeViewHelper(value));
+  } else {
+    Ember.Handlebars.registerBoundHelper.apply(null, arguments);
+  }
+};
+
+/**
+  Returns a helper function that renders the provided ViewClass.
+
+  Used internally by Ember.Handlebars.helper and other methods
+  involving helper/component registration.
+
+  @private
+  @method helper
+  @for Ember.Handlebars
+  @param {Function} ViewClass view class constructor
+*/
+Ember.Handlebars.makeViewHelper = function(ViewClass) {
+  return function(options) {
+    Ember.assert(&quot;You can only pass attributes (such as name=value) not bare values to a helper for a View found in '&quot; + ViewClass.toString() + &quot;'&quot;, arguments.length &lt; 2);
+    return Ember.Handlebars.helpers.view.call(this, ViewClass, options);
+  };
+};
+
+/**
</ins><span class="cx"> @class helpers
</span><span class="cx"> @namespace Ember.Handlebars
</span><span class="cx"> */
</span><span class="lines">@@ -17529,18 +26279,16 @@
</span><span class="cx"> 
</span><span class="cx"> Ember.Handlebars.JavaScriptCompiler.prototype.namespace = &quot;Ember.Handlebars&quot;;
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> Ember.Handlebars.JavaScriptCompiler.prototype.initializeBuffer = function() {
</span><span class="cx">   return &quot;''&quot;;
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   Override the default buffer for Ember Handlebars. By default, Handlebars
</span><span class="cx">   creates an empty String at the beginning of each invocation and appends to
</span><span class="cx">   it. Ember's Handlebars overrides this to append to a single shared buffer.
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method appendToBuffer
</span><span class="cx">   @param string {String}
</span><span class="cx"> */
</span><span class="lines">@@ -17548,15 +26296,51 @@
</span><span class="cx">   return &quot;data.buffer.push(&quot;+string+&quot;);&quot;;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+// Hacks ahead:
+// Handlebars presently has a bug where the `blockHelperMissing` hook
+// doesn't get passed the name of the missing helper name, but rather
+// gets passed the value of that missing helper evaluated on the current
+// context, which is most likely `undefined` and totally useless.
+//
+// So we alter the compiled template function to pass the name of the helper
+// instead, as expected.
+//
+// This can go away once the following is closed:
+// https://github.com/wycats/handlebars.js/issues/634
+
+var DOT_LOOKUP_REGEX = /helpers\.(.*?)\)/,
+    BRACKET_STRING_LOOKUP_REGEX = /helpers\['(.*?)'/,
+    INVOCATION_SPLITTING_REGEX = /(.*blockHelperMissing\.call\(.*)(stack[0-9]+)(,.*)/;
+
+Ember.Handlebars.JavaScriptCompiler.stringifyLastBlockHelperMissingInvocation = function(source) {
+  var helperInvocation = source[source.length - 1],
+      helperName = (DOT_LOOKUP_REGEX.exec(helperInvocation) || BRACKET_STRING_LOOKUP_REGEX.exec(helperInvocation))[1],
+      matches = INVOCATION_SPLITTING_REGEX.exec(helperInvocation);
+
+  source[source.length - 1] = matches[1] + &quot;'&quot; + helperName + &quot;'&quot; + matches[3];
+}
+var stringifyBlockHelperMissing = Ember.Handlebars.JavaScriptCompiler.stringifyLastBlockHelperMissingInvocation;
+
+var originalBlockValue = Ember.Handlebars.JavaScriptCompiler.prototype.blockValue;
+Ember.Handlebars.JavaScriptCompiler.prototype.blockValue = function() {
+  originalBlockValue.apply(this, arguments);
+  stringifyBlockHelperMissing(this.source);
+};
+
+var originalAmbiguousBlockValue = Ember.Handlebars.JavaScriptCompiler.prototype.ambiguousBlockValue;
+Ember.Handlebars.JavaScriptCompiler.prototype.ambiguousBlockValue = function() {
+  originalAmbiguousBlockValue.apply(this, arguments);
+  stringifyBlockHelperMissing(this.source);
+};
+
</ins><span class="cx"> var prefix = &quot;ember&quot; + (+new Date()), incr = 1;
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   Rewrite simple mustaches from `{{foo}}` to `{{bind &quot;foo&quot;}}`. This means that
</span><span class="cx">   all simple mustaches in Ember's Handlebars will also set up an observer to
</span><span class="cx">   keep the DOM up to date when the underlying property changes.
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method mustache
</span><span class="cx">   @for Ember.Handlebars.Compiler
</span><span class="cx">   @param mustache
</span><span class="lines">@@ -17568,12 +26352,12 @@
</span><span class="cx">   } else if (mustache.params.length || mustache.hash) {
</span><span class="cx">     // no changes required
</span><span class="cx">   } else {
</span><del>-    var id = new Handlebars.AST.IdNode(['_triageMustache']);
</del><ins>+    var id = new Handlebars.AST.IdNode([{ part: '_triageMustache' }]);
</ins><span class="cx"> 
</span><span class="cx">     // Update the mustache node to include a hash value indicating whether the original node
</span><span class="cx">     // was escaped. This will allow us to properly escape values when the underlying value
</span><span class="cx">     // changes and we need to re-render the value.
</span><del>-    if(!mustache.escaped) {
</del><ins>+    if (!mustache.escaped) {
</ins><span class="cx">       mustache.hash = mustache.hash || new Handlebars.AST.HashNode([]);
</span><span class="cx">       mustache.hash.pairs.push([&quot;unescaped&quot;, new Handlebars.AST.StringNode(&quot;true&quot;)]);
</span><span class="cx">     }
</span><span class="lines">@@ -17599,7 +26383,7 @@
</span><span class="cx">     knownHelpers: {
</span><span class="cx">       action: true,
</span><span class="cx">       unbound: true,
</span><del>-      bindAttr: true,
</del><ins>+      'bind-attr': true,
</ins><span class="cx">       template: true,
</span><span class="cx">       view: true,
</span><span class="cx">       _triageMustache: true
</span><span class="lines">@@ -17631,7 +26415,10 @@
</span><span class="cx">     var environment = new Ember.Handlebars.Compiler().compile(ast, options);
</span><span class="cx">     var templateSpec = new Ember.Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
</span><span class="cx"> 
</span><del>-    return Ember.Handlebars.template(templateSpec);
</del><ins>+    var template = Ember.Handlebars.template(templateSpec);
+    template.isMethod = false; //Make sure we don't wrap templates with ._super
+
+    return template;
</ins><span class="cx">   };
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -17639,14 +26426,14 @@
</span><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-var slice = Array.prototype.slice;
</del><ins>+var slice = Array.prototype.slice,
+    originalTemplate = Ember.Handlebars.template;
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   If a path starts with a reserved keyword, returns the root
</span><span class="cx">   that should be used.
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method normalizePath
</span><span class="cx">   @for Ember
</span><span class="cx">   @param root {Object}
</span><span class="lines">@@ -17700,22 +26487,19 @@
</span><span class="cx">       normalizedPath = normalizePath(root, path, data),
</span><span class="cx">       value;
</span><span class="cx"> 
</span><del>-  // In cases where the path begins with a keyword, change the
-  // root to the value represented by that keyword, and ensure
-  // the path is relative to it.
-  root = normalizedPath.root;
-  path = normalizedPath.path;
</del><ins>+  
+    root = normalizedPath.root;
+    path = normalizedPath.path;
</ins><span class="cx"> 
</span><del>-  value = Ember.get(root, path);
</del><ins>+    value = Ember.get(root, path);
</ins><span class="cx"> 
</span><del>-  // If the path starts with a capital letter, look it up on Ember.lookup,
-  // which defaults to the `window` object in browsers.
-  if (value === undefined &amp;&amp; root !== Ember.lookup &amp;&amp; Ember.isGlobalPath(path)) {
-    value = Ember.get(Ember.lookup, path);
-  }
</del><ins>+    if (value === undefined &amp;&amp; root !== Ember.lookup &amp;&amp; Ember.isGlobalPath(path)) {
+      value = Ember.get(Ember.lookup, path);
+    }
+  
+
</ins><span class="cx">   return value;
</span><span class="cx"> };
</span><del>-Ember.Handlebars.getPath = Ember.deprecateFunc('`Ember.Handlebars.getPath` has been changed to `Ember.Handlebars.get` for consistency.', Ember.Handlebars.get);
</del><span class="cx"> 
</span><span class="cx"> Ember.Handlebars.resolveParams = function(context, params, options) {
</span><span class="cx">   var resolvedParams = [], types = options.types, param, type;
</span><span class="lines">@@ -17753,8 +26537,6 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   Registers a helper in Handlebars that will be called if no property with the
</span><span class="cx">   given name can be found on the current context object, and no helper with
</span><span class="cx">   that name is registered.
</span><span class="lines">@@ -17762,22 +26544,66 @@
</span><span class="cx">   This throws an exception with a more helpful error message so the user can
</span><span class="cx">   track down where the problem is happening.
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method helperMissing
</span><span class="cx">   @for Ember.Handlebars.helpers
</span><span class="cx">   @param {String} path
</span><span class="cx">   @param {Hash} options
</span><span class="cx"> */
</span><del>-Ember.Handlebars.registerHelper('helperMissing', function(path, options) {
</del><ins>+Ember.Handlebars.registerHelper('helperMissing', function(path) {
</ins><span class="cx">   var error, view = &quot;&quot;;
</span><span class="cx"> 
</span><ins>+  var options = arguments[arguments.length - 1];
+
+  var helper = Ember.Handlebars.resolveHelper(options.data.view.container, path);
+
+  if (helper) {
+    return helper.apply(this, slice.call(arguments, 1));
+  }
+
</ins><span class="cx">   error = &quot;%@ Handlebars error: Could not find property '%@' on object %@.&quot;;
</span><del>-  if (options.data){
</del><ins>+  if (options.data) {
</ins><span class="cx">     view = options.data.view;
</span><span class="cx">   }
</span><span class="cx">   throw new Ember.Error(Ember.String.fmt(error, [view, path, this]));
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+  Registers a helper in Handlebars that will be called if no property with the
+  given name can be found on the current context object, and no helper with
+  that name is registered.
+
+  This throws an exception with a more helpful error message so the user can
+  track down where the problem is happening.
+
+  @private
+  @method helperMissing
+  @for Ember.Handlebars.helpers
+  @param {String} path
+  @param {Hash} options
+*/
+Ember.Handlebars.registerHelper('blockHelperMissing', function(path) {
+
+  var options = arguments[arguments.length - 1];
+
+  Ember.assert(&quot;`blockHelperMissing` was invoked without a helper name, which &quot; +
+               &quot;is most likely due to a mismatch between the version of &quot; +
+               &quot;Ember.js you're running now and the one used to precompile your &quot; +
+               &quot;templates. Please make sure the version of &quot; +
+               &quot;`ember-handlebars-compiler` you're using is up to date.&quot;, path);
+
+  var helper = Ember.Handlebars.resolveHelper(options.data.view.container, path);
+
+  if (helper) {
+    return helper.apply(this, slice.call(arguments, 1));
+  } else {
+    return Handlebars.helpers.helperMissing.call(this, path);
+  }
+
+  return Handlebars.helpers.blockHelperMissing.apply(this, arguments);
+});
+
+/**
</ins><span class="cx">   Register a bound handlebars helper. Bound helpers behave similarly to regular
</span><span class="cx">   handlebars helpers, with the added ability to re-render when the underlying data
</span><span class="cx">   changes.
</span><span class="lines">@@ -17808,7 +26634,7 @@
</span><span class="cx">   Ember.Handlebars.registerBoundHelper('repeat', function(value, options) {
</span><span class="cx">     var count = options.hash.count;
</span><span class="cx">     var a = [];
</span><del>-    while(a.length &lt; count){
</del><ins>+    while(a.length &lt; count) {
</ins><span class="cx">         a.push(value);
</span><span class="cx">     }
</span><span class="cx">     return a.join('');
</span><span class="lines">@@ -17823,7 +26649,7 @@
</span><span class="cx"> 
</span><span class="cx">   ## Example with bound options
</span><span class="cx"> 
</span><del>-  Bound hash options are also supported. Example: 
</del><ins>+  Bound hash options are also supported. Example:
</ins><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><span class="cx">   {{repeat text countBinding=&quot;numRepeats&quot;}}
</span><span class="lines">@@ -17852,30 +26678,34 @@
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="cx">   Ember.Handlebars.registerBoundHelper('concatenate', function() {
</span><del>-    var values = arguments[arguments.length - 1];
</del><ins>+    var values = Array.prototype.slice.call(arguments, 0, -1);
</ins><span class="cx">     return values.join('||');
</span><span class="cx">   });
</span><span class="cx">   ```
</span><span class="cx"> 
</span><del>-  Which allows for template syntax such as {{concatenate prop1 prop2}} or
-  {{concatenate prop1 prop2 prop3}}. If any of the properties change,
</del><ins>+  Which allows for template syntax such as `{{concatenate prop1 prop2}}` or
+  `{{concatenate prop1 prop2 prop3}}`. If any of the properties change,
</ins><span class="cx">   the helpr will re-render.  Note that dependency keys cannot be
</span><span class="cx">   using in conjunction with multi-property helpers, since it is ambiguous
</span><del>-  which property the dependent keys would belong to. 
-  
</del><ins>+  which property the dependent keys would belong to.
+
</ins><span class="cx">   ## Use with unbound helper
</span><span class="cx"> 
</span><del>-  The {{unbound}} helper can be used with bound helper invocations 
</del><ins>+  The `{{unbound}}` helper can be used with bound helper invocations
</ins><span class="cx">   to render them in their unbound form, e.g.
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><del>-  {{unbound capitalize name}} 
</del><ins>+  {{unbound capitalize name}}
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   In this example, if the name property changes, the helper
</span><span class="cx">   will not re-render.
</span><span class="cx"> 
</span><ins>+  ## Use with blocks not supported
</ins><span class="cx"> 
</span><ins>+  Bound helpers do not support use with Handlebars blocks or
+  the addition of child views of any kind.
+
</ins><span class="cx">   @method registerBoundHelper
</span><span class="cx">   @for Ember.Handlebars
</span><span class="cx">   @param {String} name
</span><span class="lines">@@ -17883,161 +26713,177 @@
</span><span class="cx">   @param {String} dependentKeys*
</span><span class="cx"> */
</span><span class="cx"> Ember.Handlebars.registerBoundHelper = function(name, fn) {
</span><del>-  var dependentKeys = slice.call(arguments, 2);
</del><ins>+  var boundHelperArgs = slice.call(arguments, 1),
+      boundFn = Ember.Handlebars.makeBoundHelper.apply(this, boundHelperArgs);
+  Ember.Handlebars.registerHelper(name, boundFn);
+};
</ins><span class="cx"> 
</span><ins>+/**
+  A (mostly) private helper function to `registerBoundHelper`. Takes the
+  provided Handlebars helper function fn and returns it in wrapped
+  bound helper form.
+
+  The main use case for using this outside of `registerBoundHelper`
+  is for registering helpers on the container:
+
+  ```js
+  var boundHelperFn = Ember.Handlebars.makeBoundHelper(function(word) {
+    return word.toUpperCase();
+  });
+
+  container.register('helper:my-bound-helper', boundHelperFn);
+  ```
+
+  In the above example, if the helper function hadn't been wrapped in
+  `makeBoundHelper`, the registered helper would be unbound.
+
+  @private
+  @method makeBoundHelper
+  @for Ember.Handlebars
+  @param {Function} function
+  @param {String} dependentKeys*
+*/
+Ember.Handlebars.makeBoundHelper = function(fn) {
+  var dependentKeys = slice.call(arguments, 1);
+
</ins><span class="cx">   function helper() {
</span><span class="cx">     var properties = slice.call(arguments, 0, -1),
</span><span class="cx">       numProperties = properties.length,
</span><span class="cx">       options = arguments[arguments.length - 1],
</span><span class="cx">       normalizedProperties = [],
</span><span class="cx">       data = options.data,
</span><ins>+      types = data.isUnbound ? slice.call(options.types, 1) : options.types,
</ins><span class="cx">       hash = options.hash,
</span><span class="cx">       view = data.view,
</span><del>-      currentContext = (options.contexts &amp;&amp; options.contexts[0]) || this,
-      normalized,
-      pathRoot, path, 
-      loc, hashOption;
</del><ins>+      contexts = options.contexts,
+      currentContext = (contexts &amp;&amp; contexts.length) ? contexts[0] : this,
+      prefixPathForDependentKeys = '',
+      loc, len, hashOption,
+      boundOption, property,
+      normalizedValue = Ember._SimpleHandlebarsView.prototype.normalizedValue;
</ins><span class="cx"> 
</span><ins>+    Ember.assert(&quot;registerBoundHelper-generated helpers do not support use with Handlebars blocks.&quot;, !options.fn);
+
</ins><span class="cx">     // Detect bound options (e.g. countBinding=&quot;otherCount&quot;)
</span><del>-    hash.boundOptions = {};
</del><ins>+    var boundOptions = hash.boundOptions = {};
</ins><span class="cx">     for (hashOption in hash) {
</span><del>-      if (!hash.hasOwnProperty(hashOption)) { continue; }
-
-      if (Ember.IS_BINDING.test(hashOption) &amp;&amp; typeof hash[hashOption] === 'string') {
</del><ins>+      if (Ember.IS_BINDING.test(hashOption)) {
</ins><span class="cx">         // Lop off 'Binding' suffix.
</span><del>-        hash.boundOptions[hashOption.slice(0, -7)] = hash[hashOption];
</del><ins>+        boundOptions[hashOption.slice(0, -7)] = hash[hashOption];
</ins><span class="cx">       }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Expose property names on data.properties object.
</span><ins>+    var watchedProperties = [];
</ins><span class="cx">     data.properties = [];
</span><span class="cx">     for (loc = 0; loc &lt; numProperties; ++loc) {
</span><span class="cx">       data.properties.push(properties[loc]);
</span><del>-      normalizedProperties.push(normalizePath(currentContext, properties[loc], data));
</del><ins>+      if (types[loc] === 'ID') {
+        var normalizedProp = normalizePath(currentContext, properties[loc], data);
+        normalizedProperties.push(normalizedProp);
+        watchedProperties.push(normalizedProp);
+      } else {
+        if(data.isUnbound) {
+          normalizedProperties.push({path: properties[loc]});
+        }else {
+          normalizedProperties.push(null);
+        }
+      }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // Handle case when helper invocation is preceded by `unbound`, e.g.
+    // {{unbound myHelper foo}}
</ins><span class="cx">     if (data.isUnbound) {
</span><span class="cx">       return evaluateUnboundHelper(this, fn, normalizedProperties, options);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (dependentKeys.length === 0) {
-      return evaluateMultiPropertyBoundHelper(currentContext, fn, normalizedProperties, options);
-    }
</del><ins>+    var bindView = new Ember._SimpleHandlebarsView(null, null, !options.hash.unescaped, options.data);
</ins><span class="cx"> 
</span><del>-    Ember.assert(&quot;Dependent keys can only be used with single-property helpers.&quot;, properties.length === 1);
</del><ins>+    // Override SimpleHandlebarsView's method for generating the view's content.
+    bindView.normalizedValue = function() {
+      var args = [], boundOption;
</ins><span class="cx"> 
</span><del>-    normalized = normalizedProperties[0];
</del><ins>+      // Copy over bound hash options.
+      for (boundOption in boundOptions) {
+        if (!boundOptions.hasOwnProperty(boundOption)) { continue; }
+        property = normalizePath(currentContext, boundOptions[boundOption], data);
+        bindView.path = property.path;
+        bindView.pathRoot = property.root;
+        hash[boundOption] = normalizedValue.call(bindView);
+      }
</ins><span class="cx"> 
</span><del>-    pathRoot = normalized.root;
-    path = normalized.path;
</del><ins>+      for (loc = 0; loc &lt; numProperties; ++loc) {
+        property = normalizedProperties[loc];
+        if (property) {
+          bindView.path = property.path;
+          bindView.pathRoot = property.root;
+          args.push(normalizedValue.call(bindView));
+        } else {
+          args.push(properties[loc]);
+        }
+      }
+      args.push(options);
</ins><span class="cx"> 
</span><del>-    var bindView = new Ember._SimpleHandlebarsView(
-      path, pathRoot, !options.hash.unescaped, options.data
-    );
-
-    bindView.normalizedValue = function() {
-      var value = Ember._SimpleHandlebarsView.prototype.normalizedValue.call(bindView);
-      return fn.call(view, value, options);
</del><ins>+      // Run the supplied helper function.
+      return fn.apply(currentContext, args);
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     view.appendChild(bindView);
</span><span class="cx"> 
</span><del>-    view.registerObserver(pathRoot, path, bindView, rerenderBoundHelperView);
-
-    for (var i=0, l=dependentKeys.length; i&lt;l; i++) {
-      view.registerObserver(pathRoot, path + '.' + dependentKeys[i], bindView, rerenderBoundHelperView);
</del><ins>+    // Assemble list of watched properties that'll re-render this helper.
+    for (boundOption in boundOptions) {
+      if (boundOptions.hasOwnProperty(boundOption)) {
+        watchedProperties.push(normalizePath(currentContext, boundOptions[boundOption], data));
+      }
</ins><span class="cx">     }
</span><del>-  }
</del><span class="cx"> 
</span><del>-  helper._rawFunction = fn;
-  Ember.Handlebars.registerHelper(name, helper);
-};
-
-/**
-  @private
-
-  Renders the unbound form of an otherwise bound helper function.
-
-  @param {Function} fn
-  @param {Object} context
-  @param {Array} normalizedProperties
-  @param {String} options
-*/
-function evaluateMultiPropertyBoundHelper(context, fn, normalizedProperties, options) {
-  var numProperties = normalizedProperties.length,
-      self = this,
-      data = options.data,
-      view = data.view,
-      hash = options.hash,
-      boundOptions = hash.boundOptions,
-      watchedProperties,
-      boundOption, bindView, loc, property, len;
-
-  bindView = new Ember._SimpleHandlebarsView(null, null, !hash.unescaped, data);
-  bindView.normalizedValue = function() {
-    var args = [], value, boundOption;
-
-    // Copy over bound options.
-    for (boundOption in boundOptions) {
-      if (!boundOptions.hasOwnProperty(boundOption)) { continue; }
-      property = normalizePath(context, boundOptions[boundOption], data);
-      bindView.path = property.path;
-      bindView.pathRoot = property.root;
-      hash[boundOption] = Ember._SimpleHandlebarsView.prototype.normalizedValue.call(bindView);
</del><ins>+    // Observe each property.
+    for (loc = 0, len = watchedProperties.length; loc &lt; len; ++loc) {
+      property = watchedProperties[loc];
+      view.registerObserver(property.root, property.path, bindView, bindView.rerender);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    for (loc = 0; loc &lt; numProperties; ++loc) {
-      property = normalizedProperties[loc];
-      bindView.path = property.path;
-      bindView.pathRoot = property.root;
-      args.push(Ember._SimpleHandlebarsView.prototype.normalizedValue.call(bindView));
</del><ins>+    if (types[0] !== 'ID' || normalizedProperties.length === 0) {
+      return;
</ins><span class="cx">     }
</span><del>-    args.push(options);
-    return fn.apply(context, args);
-  };
</del><span class="cx"> 
</span><del>-  view.appendChild(bindView);
</del><ins>+    // Add dependent key observers to the first param
+    var normalized = normalizedProperties[0],
+        pathRoot = normalized.root,
+        path = normalized.path;
</ins><span class="cx"> 
</span><del>-  // Assemble liast of watched properties that'll re-render this helper.
-  watchedProperties = [];
-  for (boundOption in boundOptions) {
-    if (boundOptions.hasOwnProperty(boundOption)) { 
-      watchedProperties.push(normalizePath(context, boundOptions[boundOption], data));
</del><ins>+    if(!Ember.isEmpty(path)) {
+      prefixPathForDependentKeys = path + '.';
</ins><span class="cx">     }
</span><ins>+    for (var i=0, l=dependentKeys.length; i&lt;l; i++) {
+      view.registerObserver(pathRoot, prefixPathForDependentKeys + dependentKeys[i], bindView, bindView.rerender);
+    }
</ins><span class="cx">   }
</span><del>-  watchedProperties = watchedProperties.concat(normalizedProperties);
</del><span class="cx"> 
</span><del>-  // Observe each property.
-  for (loc = 0, len = watchedProperties.length; loc &lt; len; ++loc) {
-    property = watchedProperties[loc];
-    view.registerObserver(property.root, property.path, bindView, rerenderBoundHelperView);
-  }
</del><ins>+  helper._rawFunction = fn;
+  return helper;
+};
</ins><span class="cx"> 
</span><del>-}
-
</del><span class="cx"> /**
</span><del>-  @private
</del><ins>+  Renders the unbound form of an otherwise bound helper function.
</ins><span class="cx"> 
</span><del>-  An observer function used with bound helpers which
-  will schedule a re-render of the _SimpleHandlebarsView
-  connected with the helper.
-*/
-function rerenderBoundHelperView() {
-  Ember.run.scheduleOnce('render', this, 'rerender');
-}
-
-/**
</del><span class="cx">   @private
</span><del>-
-  Renders the unbound form of an otherwise bound helper function.
-
</del><ins>+  @method evaluateUnboundHelper
</ins><span class="cx">   @param {Function} fn
</span><span class="cx">   @param {Object} context
</span><span class="cx">   @param {Array} normalizedProperties
</span><span class="cx">   @param {String} options
</span><span class="cx"> */
</span><span class="cx"> function evaluateUnboundHelper(context, fn, normalizedProperties, options) {
</span><del>-  var args = [], hash = options.hash, boundOptions = hash.boundOptions, loc, len, property, boundOption;
</del><ins>+  var args = [],
+   hash = options.hash,
+   boundOptions = hash.boundOptions,
+   types = slice.call(options.types, 1),
+   loc,
+   len,
+   property,
+   propertyType,
+   boundOption;
</ins><span class="cx"> 
</span><span class="cx">   for (boundOption in boundOptions) {
</span><span class="cx">     if (!boundOptions.hasOwnProperty(boundOption)) { continue; }
</span><span class="lines">@@ -18046,38 +26892,50 @@
</span><span class="cx"> 
</span><span class="cx">   for(loc = 0, len = normalizedProperties.length; loc &lt; len; ++loc) {
</span><span class="cx">     property = normalizedProperties[loc];
</span><del>-    args.push(Ember.Handlebars.get(context, property.path, options));
</del><ins>+    propertyType = types[loc];
+    if(propertyType === &quot;ID&quot;) {
+      args.push(Ember.Handlebars.get(property.root, property.path, options));
+    } else {
+      args.push(property.path);
+    }
</ins><span class="cx">   }
</span><span class="cx">   args.push(options);
</span><span class="cx">   return fn.apply(context, args);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   Overrides Handlebars.template so that we can distinguish
</span><span class="cx">   user-created, top-level templates from inner contexts.
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method template
</span><span class="cx">   @for Ember.Handlebars
</span><del>-  @param {String} template spec
</del><ins>+  @param {String} spec
</ins><span class="cx"> */
</span><del>-Ember.Handlebars.template = function(spec){
-  var t = Handlebars.template(spec);
</del><ins>+Ember.Handlebars.template = function(spec) {
+  var t = originalTemplate(spec);
</ins><span class="cx">   t.isTop = true;
</span><span class="cx">   return t;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><span class="cx"> /**
</span><ins>+  Mark a string as safe for unescaped output with Handlebars. If you
+  return HTML from a Handlebars helper, use this function to
+  ensure Handlebars does not escape the HTML.
+
+  ```javascript
+  Ember.String.htmlSafe('&lt;div&gt;someString&lt;/div&gt;')
+  ```
+
</ins><span class="cx">   @method htmlSafe
</span><span class="cx">   @for Ember.String
</span><span class="cx">   @static
</span><ins>+  @return {Handlebars.SafeString} a string that will not be html escaped by Handlebars
</ins><span class="cx"> */
</span><span class="cx"> Ember.String.htmlSafe = function(str) {
</span><span class="cx">   return new Handlebars.SafeString(str);
</span><span class="lines">@@ -18088,10 +26946,17 @@
</span><span class="cx"> if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    See {{#crossLink &quot;Ember.String/htmlSafe&quot;}}{{/crossLink}}
</del><ins>+    Mark a string as being safe for unescaped output with Handlebars.
</ins><span class="cx"> 
</span><ins>+    ```javascript
+    '&lt;div&gt;someString&lt;/div&gt;'.htmlSafe()
+    ```
+
+    See [Ember.String.htmlSafe](/api/classes/Ember.String.html#method_htmlSafe).
+
</ins><span class="cx">     @method htmlSafe
</span><span class="cx">     @for String
</span><ins>+    @return {Handlebars.SafeString} a string that will not be html escaped by Handlebars
</ins><span class="cx">   */
</span><span class="cx">   String.prototype.htmlSafe = function() {
</span><span class="cx">     return htmlSafe(this);
</span><span class="lines">@@ -18130,22 +26995,30 @@
</span><span class="cx"> var set = Ember.set, get = Ember.get;
</span><span class="cx"> var Metamorph = requireModule('metamorph');
</span><span class="cx"> 
</span><ins>+function notifyMutationListeners() {
+  Ember.run.once(Ember.View, 'notifyMutationListeners');
+}
+
</ins><span class="cx"> // DOMManager should just abstract dom manipulation between jquery and metamorph
</span><span class="cx"> var DOMManager = {
</span><span class="cx">   remove: function(view) {
</span><span class="cx">     view.morph.remove();
</span><ins>+    notifyMutationListeners();
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   prepend: function(view, html) {
</span><span class="cx">     view.morph.prepend(html);
</span><ins>+    notifyMutationListeners();
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   after: function(view, html) {
</span><span class="cx">     view.morph.after(html);
</span><ins>+    notifyMutationListeners();
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   html: function(view, html) {
</span><span class="cx">     view.morph.html(html);
</span><ins>+    notifyMutationListeners();
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   // This is messed up.
</span><span class="lines">@@ -18154,25 +27027,32 @@
</span><span class="cx"> 
</span><span class="cx">     view.transitionTo('preRender');
</span><span class="cx"> 
</span><del>-    Ember.run.schedule('render', this, function() {
</del><ins>+    Ember.run.schedule('render', this, function renderMetamorphView() {
</ins><span class="cx">       if (view.isDestroying) { return; }
</span><span class="cx"> 
</span><span class="cx">       view.clearRenderedChildren();
</span><span class="cx">       var buffer = view.renderToBuffer();
</span><span class="cx"> 
</span><span class="cx">       view.invokeRecursively(function(view) {
</span><del>-        view.propertyDidChange('element');
</del><ins>+        view.propertyWillChange('element');
</ins><span class="cx">       });
</span><ins>+      view.triggerRecursively('willInsertElement');
</ins><span class="cx"> 
</span><del>-      view.triggerRecursively('willInsertElement');
</del><span class="cx">       morph.replaceWith(buffer.string());
</span><span class="cx">       view.transitionTo('inDOM');
</span><ins>+
+      view.invokeRecursively(function(view) {
+        view.propertyDidChange('element');
+      });
</ins><span class="cx">       view.triggerRecursively('didInsertElement');
</span><ins>+
+      notifyMutationListeners();
</ins><span class="cx">     });
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   empty: function(view) {
</span><span class="cx">     view.morph.html(&quot;&quot;);
</span><ins>+    notifyMutationListeners();
</ins><span class="cx">   }
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -18182,18 +27062,18 @@
</span><span class="cx"> /**
</span><span class="cx">   @class _Metamorph
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Mixin
</del><span class="cx">   @private
</span><span class="cx"> */
</span><span class="cx"> Ember._Metamorph = Ember.Mixin.create({
</span><span class="cx">   isVirtual: true,
</span><span class="cx">   tagName: '',
</span><span class="cx"> 
</span><del>-  instrumentName: 'render.metamorph',
</del><ins>+  instrumentName: 'metamorph',
</ins><span class="cx"> 
</span><span class="cx">   init: function() {
</span><span class="cx">     this._super();
</span><span class="cx">     this.morph = Metamorph();
</span><ins>+    Ember.deprecate('Supplying a tagName to Metamorph views is unreliable and is deprecated. You may be setting the tagName on a Handlebars helper that creates a Metamorph.', !this.tagName);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   beforeRender: function(buffer) {
</span><span class="lines">@@ -18227,7 +27107,7 @@
</span><span class="cx"> /**
</span><span class="cx">   @class _SimpleMetamorphView
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.View
</del><ins>+  @extends Ember.CoreView
</ins><span class="cx">   @uses Ember._Metamorph
</span><span class="cx">   @private
</span><span class="cx"> */
</span><span class="lines">@@ -18257,6 +27137,8 @@
</span><span class="cx">   this.morph = Metamorph();
</span><span class="cx">   this.state = 'preRender';
</span><span class="cx">   this.updateId = null;
</span><ins>+  this._parentView = null;
+  this.buffer = null;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ember._SimpleHandlebarsView = SimpleHandlebarsView;
</span><span class="lines">@@ -18270,9 +27152,15 @@
</span><span class="cx">       Ember.run.cancel(this.updateId);
</span><span class="cx">       this.updateId = null;
</span><span class="cx">     }
</span><ins>+    if (this._parentView) {
+      this._parentView.removeChild(this);
+    }
</ins><span class="cx">     this.morph = null;
</span><ins>+    this.state = 'destroyed';
</ins><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  propertyWillChange: Ember.K,
+
</ins><span class="cx">   propertyDidChange: Ember.K,
</span><span class="cx"> 
</span><span class="cx">   normalizedValue: function() {
</span><span class="lines">@@ -18354,7 +27242,7 @@
</span><span class="cx"> 
</span><span class="cx"> merge(states.inDOM, {
</span><span class="cx">   rerenderIfNeeded: function(view) {
</span><del>-    if (get(view, 'normalizedValue') !== view._lastNormalizedValue) {
</del><ins>+    if (view.normalizedValue() !== view._lastNormalizedValue) {
</ins><span class="cx">       view.rerender();
</span><span class="cx">     }
</span><span class="cx">   }
</span><span class="lines">@@ -18375,7 +27263,7 @@
</span><span class="cx">   @private
</span><span class="cx"> */
</span><span class="cx"> Ember._HandlebarsBoundView = Ember._MetamorphView.extend({
</span><del>-  instrumentName: 'render.boundHandlebars',
</del><ins>+  instrumentName: 'boundHandlebars',
</ins><span class="cx">   states: states,
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -18458,7 +27346,7 @@
</span><span class="cx">   */
</span><span class="cx">   pathRoot: null,
</span><span class="cx"> 
</span><del>-  normalizedValue: Ember.computed(function() {
</del><ins>+  normalizedValue: function() {
</ins><span class="cx">     var path = get(this, 'path'),
</span><span class="cx">         pathRoot  = get(this, 'pathRoot'),
</span><span class="cx">         valueNormalizer = get(this, 'valueNormalizerFunc'),
</span><span class="lines">@@ -18476,7 +27364,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return valueNormalizer ? valueNormalizer(result) : result;
</span><del>-  }).property('path', 'pathRoot', 'valueNormalizerFunc').volatile(),
</del><ins>+  },
</ins><span class="cx"> 
</span><span class="cx">   rerenderIfNeeded: function() {
</span><span class="cx">     this.currentState.rerenderIfNeeded(this);
</span><span class="lines">@@ -18511,7 +27399,7 @@
</span><span class="cx">     var inverseTemplate = get(this, 'inverseTemplate'),
</span><span class="cx">         displayTemplate = get(this, 'displayTemplate');
</span><span class="cx"> 
</span><del>-    var result = get(this, 'normalizedValue');
</del><ins>+    var result = this.normalizedValue();
</ins><span class="cx">     this._lastNormalizedValue = result;
</span><span class="cx"> 
</span><span class="cx">     // First, test the conditional to see if we should
</span><span class="lines">@@ -18571,9 +27459,28 @@
</span><span class="cx"> var get = Ember.get, set = Ember.set, fmt = Ember.String.fmt;
</span><span class="cx"> var handlebarsGet = Ember.Handlebars.get, normalizePath = Ember.Handlebars.normalizePath;
</span><span class="cx"> var forEach = Ember.ArrayPolyfills.forEach;
</span><ins>+var o_create = Ember.create;
</ins><span class="cx"> 
</span><span class="cx"> var EmberHandlebars = Ember.Handlebars, helpers = EmberHandlebars.helpers;
</span><span class="cx"> 
</span><ins>+function exists(value) {
+  return !Ember.isNone(value);
+}
+
+function sanitizedHandlebarsGet(currentContext, property, options) {
+  var result = handlebarsGet(currentContext, property, options);
+  if (result === null || result === undefined) {
+    result = &quot;&quot;;
+  } else if (!(result instanceof Handlebars.SafeString)) {
+    result = String(result);
+  }
+  if (!options.hash.unescaped){
+    result = Handlebars.Utils.escapeExpression(result);
+  }
+
+  return result;
+}
+
</ins><span class="cx"> // Binds a property into the DOM. This will create a hook in DOM that the
</span><span class="cx"> // KVO system will look for and update if the property changes.
</span><span class="cx"> function bind(property, options, preserveContext, shouldDisplay, valueNormalizer, childProperties) {
</span><span class="lines">@@ -18595,7 +27502,7 @@
</span><span class="cx"> 
</span><span class="cx">       var template, context, result = handlebarsGet(currentContext, property, options);
</span><span class="cx"> 
</span><del>-      result = valueNormalizer(result);
</del><ins>+      result = valueNormalizer ? valueNormalizer(result) : result;
</ins><span class="cx"> 
</span><span class="cx">       context = preserveContext ? currentContext : result;
</span><span class="cx">       if (shouldDisplay(result)) {
</span><span class="lines">@@ -18648,24 +27555,26 @@
</span><span class="cx">   }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function simpleBind(property, options) {
</del><ins>+EmberHandlebars.bind = bind;
+
+function simpleBind(currentContext, property, options) {
</ins><span class="cx">   var data = options.data,
</span><span class="cx">       view = data.view,
</span><del>-      currentContext = this,
-      normalized, observer;
</del><ins>+      normalized, observer, pathRoot, output;
</ins><span class="cx"> 
</span><span class="cx">   normalized = normalizePath(currentContext, property, data);
</span><ins>+  pathRoot = normalized.root;
</ins><span class="cx"> 
</span><span class="cx">   // Set up observers for observable objects
</span><del>-  if ('object' === typeof this) {
</del><ins>+  if (pathRoot &amp;&amp; ('object' === typeof pathRoot)) {
</ins><span class="cx">     if (data.insideGroup) {
</span><span class="cx">       observer = function() {
</span><span class="cx">         Ember.run.once(view, 'rerender');
</span><span class="cx">       };
</span><span class="cx"> 
</span><del>-      var result = handlebarsGet(currentContext, property, options);
-      if (result === null || result === undefined) { result = &quot;&quot;; }
-      data.buffer.push(result);
</del><ins>+      output = sanitizedHandlebarsGet(currentContext, property, options);
+
+      data.buffer.push(output);
</ins><span class="cx">     } else {
</span><span class="cx">       var bindView = new Ember._SimpleHandlebarsView(
</span><span class="cx">         property, currentContext, !options.hash.unescaped, options.data
</span><span class="lines">@@ -18689,39 +27598,63 @@
</span><span class="cx">   } else {
</span><span class="cx">     // The object is not observable, so just render it out and
</span><span class="cx">     // be done with it.
</span><del>-    data.buffer.push(handlebarsGet(currentContext, property, options));
</del><ins>+    output = sanitizedHandlebarsGet(currentContext, property, options);
+
+    data.buffer.push(output);
</ins><span class="cx">   }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-
-  '_triageMustache' is used internally select between a binding and helper for
</del><ins>+  '_triageMustache' is used internally select between a binding, helper, or component for
</ins><span class="cx">   the given context. Until this point, it would be hard to determine if the
</span><span class="cx">   mustache is a property reference or a regular helper reference. This triage
</span><span class="cx">   helper resolves that.
</span><span class="cx"> 
</span><span class="cx">   This would not be typically invoked by directly.
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method _triageMustache
</span><span class="cx">   @for Ember.Handlebars.helpers
</span><span class="cx">   @param {String} property Property/helperID to triage
</span><del>-  @param {Function} fn Context to provide for rendering
</del><ins>+  @param {Object} options hash of template/rendering options
</ins><span class="cx">   @return {String} HTML string
</span><span class="cx"> */
</span><del>-EmberHandlebars.registerHelper('_triageMustache', function(property, fn) {
</del><ins>+EmberHandlebars.registerHelper('_triageMustache', function(property, options) {
</ins><span class="cx">   Ember.assert(&quot;You cannot pass more than one argument to the _triageMustache helper&quot;, arguments.length &lt;= 2);
</span><ins>+
</ins><span class="cx">   if (helpers[property]) {
</span><del>-    return helpers[property].call(this, fn);
</del><ins>+    return helpers[property].call(this, options);
</ins><span class="cx">   }
</span><del>-  else {
-    return helpers.bind.apply(this, arguments);
</del><ins>+
+  var helper = Ember.Handlebars.resolveHelper(options.data.view.container, property);
+  if (helper) {
+    return helper.call(this, options);
</ins><span class="cx">   }
</span><ins>+
+  return helpers.bind.call(this, property, options);
</ins><span class="cx"> });
</span><span class="cx"> 
</span><ins>+Ember.Handlebars.resolveHelper = function(container, name) {
+
+  if (!container || name.indexOf('-') === -1) {
+    return;
+  }
+
+  var helper = container.lookup('helper:' + name);
+  if (!helper) {
+    var componentLookup = container.lookup('component-lookup:main');
+    Ember.assert(&quot;Could not find 'component-lookup:main' on the provided container, which is necessary for performing component lookups&quot;, componentLookup);
+
+    var Component = componentLookup.lookupFactory(name, container);
+    if (Component) {
+      helper = EmberHandlebars.makeViewHelper(Component);
+      container.register('helper:' + name, helper);
+    }
+  }
+  return helper;
+};
+
</ins><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   `bind` can be used to display a value, then update that value if it
</span><span class="cx">   changes. For example, if you wanted to print the `title` property of
</span><span class="cx">   `content`:
</span><span class="lines">@@ -18737,29 +27670,26 @@
</span><span class="cx">   relies on Ember's KVO system. For all other browsers this will be handled for
</span><span class="cx">   you automatically.
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method bind
</span><span class="cx">   @for Ember.Handlebars.helpers
</span><span class="cx">   @param {String} property Property to bind
</span><span class="cx">   @param {Function} fn Context to provide for rendering
</span><span class="cx">   @return {String} HTML string
</span><span class="cx"> */
</span><del>-EmberHandlebars.registerHelper('bind', function(property, options) {
</del><ins>+EmberHandlebars.registerHelper('bind', function bindHelper(property, options) {
</ins><span class="cx">   Ember.assert(&quot;You cannot pass more than one argument to the bind helper&quot;, arguments.length &lt;= 2);
</span><span class="cx"> 
</span><del>-  var context = (options.contexts &amp;&amp; options.contexts[0]) || this;
</del><ins>+  var context = (options.contexts &amp;&amp; options.contexts.length) ? options.contexts[0] : this;
</ins><span class="cx"> 
</span><span class="cx">   if (!options.fn) {
</span><del>-    return simpleBind.call(context, property, options);
</del><ins>+    return simpleBind(context, property, options);
</ins><span class="cx">   }
</span><span class="cx"> 
</span><del>-  return bind.call(context, property, options, false, function(result) {
-    return !Ember.isNone(result);
-  });
</del><ins>+  return bind.call(context, property, options, false, exists);
</ins><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   Use the `boundIf` helper to create a conditional that re-evaluates
</span><span class="cx">   whenever the truthiness of the bound value changes.
</span><span class="cx"> 
</span><span class="lines">@@ -18769,14 +27699,15 @@
</span><span class="cx">   {{/boundIf}}
</span><span class="cx">   ```
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method boundIf
</span><span class="cx">   @for Ember.Handlebars.helpers
</span><span class="cx">   @param {String} property Property to bind
</span><span class="cx">   @param {Function} fn Context to provide for rendering
</span><span class="cx">   @return {String} HTML string
</span><span class="cx"> */
</span><del>-EmberHandlebars.registerHelper('boundIf', function(property, fn) {
-  var context = (fn.contexts &amp;&amp; fn.contexts[0]) || this;
</del><ins>+EmberHandlebars.registerHelper('boundIf', function boundIfHelper(property, fn) {
+  var context = (fn.contexts &amp;&amp; fn.contexts.length) ? fn.contexts[0] : this;
</ins><span class="cx">   var func = function(result) {
</span><span class="cx">     var truthy = result &amp;&amp; get(result, 'isTruthy');
</span><span class="cx">     if (typeof truthy === 'boolean') { return truthy; }
</span><span class="lines">@@ -18792,15 +27723,65 @@
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+  Use the `{{with}}` helper when you want to scope context. Take the following code as an example:
+
+  ```handlebars
+  &lt;h5&gt;{{user.name}}&lt;/h5&gt;
+
+  &lt;div class=&quot;role&quot;&gt;
+    &lt;h6&gt;{{user.role.label}}&lt;/h6&gt;
+    &lt;span class=&quot;role-id&quot;&gt;{{user.role.id}}&lt;/span&gt;
+
+    &lt;p class=&quot;role-desc&quot;&gt;{{user.role.description}}&lt;/p&gt;
+  &lt;/div&gt;
+  ```
+
+  `{{with}}` can be our best friend in these cases, 
+  instead of writing `user.role.*` over and over, we use `{{#with user.role}}`.
+  Now the context within the `{{#with}} .. {{/with}}` block is `user.role` so you can do the following:
+
+  ```handlebars
+  &lt;h5&gt;{{user.name}}&lt;/h5&gt;
+
+  &lt;div class=&quot;role&quot;&gt;
+    {{#with user.role}}
+      &lt;h6&gt;{{label}}&lt;/h6&gt;
+      &lt;span class=&quot;role-id&quot;&gt;{{id}}&lt;/span&gt;
+
+      &lt;p class=&quot;role-desc&quot;&gt;{{description}}&lt;/p&gt;
+    {{/with}}
+  &lt;/div&gt;
+  ```
+
+  ### `as` operator
+
+  This operator aliases the scope to a new name. It's helpful for semantic clarity and to retain 
+  default scope or to reference from another `{{with}}` block.
+
+  ```handlebars
+  // posts might not be
+  {{#with user.posts as blogPosts}}
+    &lt;div class=&quot;notice&quot;&gt;
+      There are {{blogPosts.length}} blog posts written by {{user.name}}.
+    &lt;/div&gt;
+
+    {{#each post in blogPosts}}
+      &lt;li&gt;{{post.title}}&lt;/li&gt;
+    {{/each}}
+  {{/with}}
+  ```
+
+  Without the `as` operator, it would be impossible to reference `user.name` in the example above.
+
</ins><span class="cx">   @method with
</span><span class="cx">   @for Ember.Handlebars.helpers
</span><span class="cx">   @param {Function} context
</span><span class="cx">   @param {Hash} options
</span><span class="cx">   @return {String} HTML string
</span><span class="cx"> */
</span><del>-EmberHandlebars.registerHelper('with', function(context, options) {
</del><ins>+EmberHandlebars.registerHelper('with', function withHelper(context, options) {
</ins><span class="cx">   if (arguments.length === 4) {
</span><del>-    var keywordName, path, rootPath, normalized;
</del><ins>+    var keywordName, path, rootPath, normalized, contextPath;
</ins><span class="cx"> 
</span><span class="cx">     Ember.assert(&quot;If you pass more than one argument to the with helper, it must be in the form #with foo as bar&quot;, arguments[1] === &quot;as&quot;);
</span><span class="cx">     options = arguments[3];
</span><span class="lines">@@ -18809,8 +27790,12 @@
</span><span class="cx"> 
</span><span class="cx">     Ember.assert(&quot;You must pass a block to the with helper&quot;, options.fn &amp;&amp; options.fn !== Handlebars.VM.noop);
</span><span class="cx"> 
</span><ins>+    var localizedOptions = o_create(options);
+    localizedOptions.data = o_create(options.data);
+    localizedOptions.data.keywords = o_create(options.data.keywords || {});
+
</ins><span class="cx">     if (Ember.isGlobalPath(path)) {
</span><del>-      Ember.bind(options.data.keywords, keywordName, path);
</del><ins>+      contextPath = path;
</ins><span class="cx">     } else {
</span><span class="cx">       normalized = normalizePath(this, path, options.data);
</span><span class="cx">       path = normalized.path;
</span><span class="lines">@@ -18819,16 +27804,14 @@
</span><span class="cx">       // This is a workaround for the fact that you cannot bind separate objects
</span><span class="cx">       // together. When we implement that functionality, we should use it here.
</span><span class="cx">       var contextKey = Ember.$.expando + Ember.guidFor(rootPath);
</span><del>-      options.data.keywords[contextKey] = rootPath;
-
</del><ins>+      localizedOptions.data.keywords[contextKey] = rootPath;
</ins><span class="cx">       // if the path is '' (&quot;this&quot;), just bind directly to the current context
</span><del>-      var contextPath = path ? contextKey + '.' + path : contextKey;
-      Ember.bind(options.data.keywords, keywordName, contextPath);
</del><ins>+      contextPath = path ? contextKey + '.' + path : contextKey;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return bind.call(this, path, options, true, function(result) {
-      return !Ember.isNone(result);
-    });
</del><ins>+    Ember.bind(localizedOptions.data.keywords, keywordName, contextPath);
+
+    return bind.call(this, path, localizedOptions, true, exists);
</ins><span class="cx">   } else {
</span><span class="cx">     Ember.assert(&quot;You must pass exactly one argument to the with helper&quot;, arguments.length === 2);
</span><span class="cx">     Ember.assert(&quot;You must pass a block to the with helper&quot;, options.fn &amp;&amp; options.fn !== Handlebars.VM.noop);
</span><span class="lines">@@ -18838,7 +27821,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  See `boundIf`
</del><ins>+  See [boundIf](/api/classes/Ember.Handlebars.helpers.html#method_boundIf)
</ins><span class="cx"> 
</span><span class="cx">   @method if
</span><span class="cx">   @for Ember.Handlebars.helpers
</span><span class="lines">@@ -18846,7 +27829,7 @@
</span><span class="cx">   @param {Hash} options
</span><span class="cx">   @return {String} HTML string
</span><span class="cx"> */
</span><del>-EmberHandlebars.registerHelper('if', function(context, options) {
</del><ins>+EmberHandlebars.registerHelper('if', function ifHelper(context, options) {
</ins><span class="cx">   Ember.assert(&quot;You must pass exactly one argument to the if helper&quot;, arguments.length === 2);
</span><span class="cx">   Ember.assert(&quot;You must pass a block to the if helper&quot;, options.fn &amp;&amp; options.fn !== Handlebars.VM.noop);
</span><span class="cx"> 
</span><span class="lines">@@ -18860,7 +27843,7 @@
</span><span class="cx">   @param {Hash} options
</span><span class="cx">   @return {String} HTML string
</span><span class="cx"> */
</span><del>-EmberHandlebars.registerHelper('unless', function(context, options) {
</del><ins>+EmberHandlebars.registerHelper('unless', function unlessHelper(context, options) {
</ins><span class="cx">   Ember.assert(&quot;You must pass exactly one argument to the unless helper&quot;, arguments.length === 2);
</span><span class="cx">   Ember.assert(&quot;You must pass a block to the unless helper&quot;, options.fn &amp;&amp; options.fn !== Handlebars.VM.noop);
</span><span class="cx"> 
</span><span class="lines">@@ -18873,11 +27856,11 @@
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  `bindAttr` allows you to create a binding between DOM element attributes and
</del><ins>+  `bind-attr` allows you to create a binding between DOM element attributes and
</ins><span class="cx">   Ember objects. For example:
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><del>-  &lt;img {{bindAttr src=&quot;imageUrl&quot; alt=&quot;imageTitle&quot;}}&gt;
</del><ins>+  &lt;img {{bind-attr src=&quot;imageUrl&quot; alt=&quot;imageTitle&quot;}}&gt;
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   The above handlebars template will fill the `&lt;img&gt;`'s `src` attribute will
</span><span class="lines">@@ -18899,51 +27882,51 @@
</span><span class="cx">   &lt;img src=&quot;http://lolcats.info/haz-a-funny&quot; alt=&quot;A humorous image of a cat&quot;&gt;
</span><span class="cx">   ```
</span><span class="cx"> 
</span><del>-  `bindAttr` cannot redeclare existing DOM element attributes. The use of `src`
-  in the following `bindAttr` example will be ignored and the hard coded value
</del><ins>+  `bind-attr` cannot redeclare existing DOM element attributes. The use of `src`
+  in the following `bind-attr` example will be ignored and the hard coded value
</ins><span class="cx">   of `src=&quot;/failwhale.gif&quot;` will take precedence:
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><del>-  &lt;img src=&quot;/failwhale.gif&quot; {{bindAttr src=&quot;imageUrl&quot; alt=&quot;imageTitle&quot;}}&gt;
</del><ins>+  &lt;img src=&quot;/failwhale.gif&quot; {{bind-attr src=&quot;imageUrl&quot; alt=&quot;imageTitle&quot;}}&gt;
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><del>-  ### `bindAttr` and the `class` attribute
</del><ins>+  ### `bind-attr` and the `class` attribute
</ins><span class="cx"> 
</span><del>-  `bindAttr` supports a special syntax for handling a number of cases unique
</del><ins>+  `bind-attr` supports a special syntax for handling a number of cases unique
</ins><span class="cx">   to the `class` DOM element attribute. The `class` attribute combines
</span><del>-  multiple discreet values into a single attribute as a space-delimited
</del><ins>+  multiple discrete values into a single attribute as a space-delimited
</ins><span class="cx">   list of strings. Each string can be:
</span><span class="cx"> 
</span><span class="cx">   * a string return value of an object's property.
</span><span class="cx">   * a boolean return value of an object's property
</span><span class="cx">   * a hard-coded value
</span><span class="cx"> 
</span><del>-  A string return value works identically to other uses of `bindAttr`. The
</del><ins>+  A string return value works identically to other uses of `bind-attr`. The
</ins><span class="cx">   return value of the property will become the value of the attribute. For
</span><span class="cx">   example, the following view and template:
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="cx">     AView = Ember.View.extend({
</span><del>-      someProperty: function(){
</del><ins>+      someProperty: function() {
</ins><span class="cx">         return &quot;aValue&quot;;
</span><span class="cx">       }.property()
</span><span class="cx">     })
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><del>-  &lt;img {{bindAttr class=&quot;view.someProperty}}&gt;
</del><ins>+  &lt;img {{bind-attr class=&quot;view.someProperty}}&gt;
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   Result in the following rendered output:
</span><span class="cx"> 
</span><del>-  ```html 
</del><ins>+  ```html
</ins><span class="cx">   &lt;img class=&quot;aValue&quot;&gt;
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   A boolean return value will insert a specified class name if the property
</span><span class="cx">   returns `true` and remove the class name if the property returns `false`.
</span><span class="cx"> 
</span><del>-  A class name is provided via the syntax 
</del><ins>+  A class name is provided via the syntax
</ins><span class="cx">   `somePropertyName:class-name-if-true`.
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="lines">@@ -18953,7 +27936,7 @@
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><del>-  &lt;img {{bindAttr class=&quot;view.someBool:class-name-if-true&quot;}}&gt;
</del><ins>+  &lt;img {{bind-attr class=&quot;view.someBool:class-name-if-true&quot;}}&gt;
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   Result in the following rendered output:
</span><span class="lines">@@ -18967,39 +27950,39 @@
</span><span class="cx">   value changes:
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><del>-  &lt;img {{bindAttr class=&quot;view.someBool:class-name-if-true:class-name-if-false&quot;}}&gt;
</del><ins>+  &lt;img {{bind-attr class=&quot;view.someBool:class-name-if-true:class-name-if-false&quot;}}&gt;
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   A hard-coded value can be used by prepending `:` to the desired
</span><span class="cx">   class name: `:class-name-to-always-apply`.
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><del>-  &lt;img {{bindAttr class=&quot;:class-name-to-always-apply&quot;}}&gt;
</del><ins>+  &lt;img {{bind-attr class=&quot;:class-name-to-always-apply&quot;}}&gt;
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   Results in the following rendered output:
</span><span class="cx"> 
</span><span class="cx">   ```html
</span><del>-  &lt;img class=&quot;:class-name-to-always-apply&quot;&gt;
</del><ins>+  &lt;img class=&quot;class-name-to-always-apply&quot;&gt;
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   All three strategies - string return value, boolean return value, and
</span><span class="cx">   hard-coded value – can be combined in a single declaration:
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><del>-  &lt;img {{bindAttr class=&quot;:class-name-to-always-apply view.someBool:class-name-if-true view.someProperty&quot;}}&gt;
</del><ins>+  &lt;img {{bind-attr class=&quot;:class-name-to-always-apply view.someBool:class-name-if-true view.someProperty&quot;}}&gt;
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><del>-  @method bindAttr
</del><ins>+  @method bind-attr
</ins><span class="cx">   @for Ember.Handlebars.helpers
</span><span class="cx">   @param {Hash} options
</span><span class="cx">   @return {String} HTML string
</span><span class="cx"> */
</span><del>-EmberHandlebars.registerHelper('bindAttr', function(options) {
</del><ins>+EmberHandlebars.registerHelper('bind-attr', function bindAttrHelper(options) {
</ins><span class="cx"> 
</span><span class="cx">   var attrs = options.hash;
</span><span class="cx"> 
</span><del>-  Ember.assert(&quot;You must specify at least one hash argument to bindAttr&quot;, !!Ember.keys(attrs).length);
</del><ins>+  Ember.assert(&quot;You must specify at least one hash argument to bind-attr&quot;, !!Ember.keys(attrs).length);
</ins><span class="cx"> 
</span><span class="cx">   var view = options.data.view;
</span><span class="cx">   var ret = [];
</span><span class="lines">@@ -19012,7 +27995,7 @@
</span><span class="cx"> 
</span><span class="cx">   // Handle classes differently, as we can bind multiple classes
</span><span class="cx">   var classBindings = attrs['class'];
</span><del>-  if (classBindings !== null &amp;&amp; classBindings !== undefined) {
</del><ins>+  if (classBindings != null) {
</ins><span class="cx">     var classResults = EmberHandlebars.bindClasses(this, classBindings, view, dataId, options);
</span><span class="cx"> 
</span><span class="cx">     ret.push('class=&quot;' + Handlebars.Utils.escapeExpression(classResults.join(' ')) + '&quot;');
</span><span class="lines">@@ -19027,7 +28010,7 @@
</span><span class="cx">     var path = attrs[attr],
</span><span class="cx">         normalized;
</span><span class="cx"> 
</span><del>-    Ember.assert(fmt(&quot;You must provide a String for a bound attribute, not %@&quot;, [path]), typeof path === 'string');
</del><ins>+    Ember.assert(fmt(&quot;You must provide an expression as the value of bound attribute. You specified: %@=%@&quot;, [attr, path]), typeof path === 'string');
</ins><span class="cx"> 
</span><span class="cx">     normalized = normalizePath(ctx, path, options.data);
</span><span class="cx"> 
</span><span class="lines">@@ -19041,7 +28024,9 @@
</span><span class="cx">     observer = function observer() {
</span><span class="cx">       var result = handlebarsGet(ctx, path, options);
</span><span class="cx"> 
</span><del>-      Ember.assert(fmt(&quot;Attributes must be numbers, strings or booleans, not %@&quot;, [result]), result === null || result === undefined || typeof result === 'number' || typeof result === 'string' || typeof result === 'boolean');
</del><ins>+      Ember.assert(fmt(&quot;Attributes must be numbers, strings or booleans, not %@&quot;, [result]),
+                   result === null || result === undefined || typeof result === 'number' ||
+                     typeof result === 'string' || typeof result === 'boolean');
</ins><span class="cx"> 
</span><span class="cx">       var elem = view.$(&quot;[data-bindattr-&quot; + dataId + &quot;='&quot; + dataId + &quot;']&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -19057,15 +28042,13 @@
</span><span class="cx">       Ember.View.applyAttributeBindings(elem, attr, result);
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    invoker = function() {
-      Ember.run.scheduleOnce('render', observer);
-    };
-
</del><span class="cx">     // Add an observer to the view for when the property changes.
</span><span class="cx">     // When the observer fires, find the element using the
</span><span class="cx">     // unique data id and update the attribute to the new value.
</span><del>-    if (path !== 'this') {
-      view.registerObserver(normalized.root, normalized.path, invoker);
</del><ins>+    // Note: don't add observer when path is 'this' or path
+    // is whole keyword e.g. {{#each x in list}} ... {{bind-attr attr=&quot;x&quot;}}
+    if (path !== 'this' &amp;&amp; !(normalized.isKeyword &amp;&amp; normalized.path === '' )) {
+      view.registerObserver(normalized.root, normalized.path, observer);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // if this changes, also change the logic in ember-views/lib/views/view.js
</span><span class="lines">@@ -19084,8 +28067,21 @@
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
</del><ins>+  See `bind-attr`
</ins><span class="cx"> 
</span><ins>+  @method bindAttr
+  @for Ember.Handlebars.helpers
+  @deprecated
+  @param {Function} context
+  @param {Hash} options
+  @return {String} HTML string
+*/
+EmberHandlebars.registerHelper('bindAttr', function bindAttrHelper() {
+  Ember.warn(&quot;The 'bindAttr' view helper is deprecated in favor of 'bind-attr'&quot;);
+  return EmberHandlebars.helpers['bind-attr'].apply(this, arguments);
+});
+
+/**
</ins><span class="cx">   Helper that, given a space-separated string of property paths and a context,
</span><span class="cx">   returns an array of class names. Calling this method also has the side
</span><span class="cx">   effect of setting up observers at those property paths, such that if they
</span><span class="lines">@@ -19097,12 +28093,13 @@
</span><span class="cx">   &quot;fooBar&quot;). If the value is a string, it will add that string as the class.
</span><span class="cx">   Otherwise, it will not add any new class name.
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method bindClasses
</span><span class="cx">   @for Ember.Handlebars
</span><span class="cx">   @param {Ember.Object} context The context from which to lookup properties
</span><del>-  @param {String} classBindings A string, space-separated, of class bindings 
</del><ins>+  @param {String} classBindings A string, space-separated, of class bindings
</ins><span class="cx">     to use
</span><del>-  @param {Ember.View} view The view in which observers should look for the 
</del><ins>+  @param {Ember.View} view The view in which observers should look for the
</ins><span class="cx">     element to update
</span><span class="cx">   @param {Srting} bindAttrId Optional bindAttr id used to lookup elements
</span><span class="cx">   @return {Array} An array of class names to add
</span><span class="lines">@@ -19179,12 +28176,8 @@
</span><span class="cx">       }
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    invoker = function() {
-      Ember.run.scheduleOnce('render', observer);
-    };
-
</del><span class="cx">     if (path !== '' &amp;&amp; path !== 'this') {
</span><del>-      view.registerObserver(pathRoot, path, invoker);
</del><ins>+      view.registerObserver(pathRoot, path, observer);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // We've already setup the observer; now we just need to figure out the
</span><span class="lines">@@ -19218,12 +28211,42 @@
</span><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> var get = Ember.get, set = Ember.set;
</span><del>-var PARENT_VIEW_PATH = /^parentView\./;
</del><span class="cx"> var EmberHandlebars = Ember.Handlebars;
</span><ins>+var LOWERCASE_A_Z = /^[a-z]/;
+var VIEW_PREFIX = /^view\./;
</ins><span class="cx"> 
</span><ins>+function makeBindings(thisContext, options) {
+  var hash = options.hash,
+      hashType = options.hashTypes;
+
+  for (var prop in hash) {
+    if (hashType[prop] === 'ID') {
+
+      var value = hash[prop];
+
+      if (Ember.IS_BINDING.test(prop)) {
+        Ember.warn(&quot;You're attempting to render a view by passing &quot; + prop + &quot;=&quot; + value + &quot; to a view helper, but this syntax is ambiguous. You should either surround &quot; + value + &quot; in quotes or remove `Binding` from &quot; + prop + &quot;.&quot;);
+      } else {
+        hash[prop + 'Binding'] = value;
+        hashType[prop + 'Binding'] = 'STRING';
+        delete hash[prop];
+        delete hashType[prop];
+      }
+    }
+  }
+
+  if (hash.hasOwnProperty('idBinding')) {
+    // id can't be bound, so just perform one-time lookup.
+    hash.id = EmberHandlebars.get(thisContext, hash.idBinding, options);
+    hashType.id = 'STRING';
+    delete hash.idBinding;
+    delete hashType.idBinding;
+  }
+}
+
</ins><span class="cx"> EmberHandlebars.ViewHelper = Ember.Object.create({
</span><span class="cx"> 
</span><del>-  propertiesFromHTMLOptions: function(options, thisContext) {
</del><ins>+  propertiesFromHTMLOptions: function(options) {
</ins><span class="cx">     var hash = options.hash, data = options.data;
</span><span class="cx">     var extensions = {},
</span><span class="cx">         classes = hash['class'],
</span><span class="lines">@@ -19234,6 +28257,11 @@
</span><span class="cx">       dup = true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (hash.tag) {
+      extensions.tagName = hash.tag;
+      dup = true;
+    }
+
</ins><span class="cx">     if (classes) {
</span><span class="cx">       classes = classes.split(' ');
</span><span class="cx">       extensions.classNames = classes;
</span><span class="lines">@@ -19260,6 +28288,7 @@
</span><span class="cx">     if (dup) {
</span><span class="cx">       hash = Ember.$.extend({}, hash);
</span><span class="cx">       delete hash.id;
</span><ins>+      delete hash.tag;
</ins><span class="cx">       delete hash['class'];
</span><span class="cx">       delete hash.classBinding;
</span><span class="cx">     }
</span><span class="lines">@@ -19312,7 +28341,7 @@
</span><span class="cx">       return 'templateData.keywords.' + path;
</span><span class="cx">     } else if (Ember.isGlobalPath(path)) {
</span><span class="cx">       return null;
</span><del>-    } else if (path === 'this') {
</del><ins>+    } else if (path === 'this' || path === '') {
</ins><span class="cx">       return '_parentView.context';
</span><span class="cx">     } else {
</span><span class="cx">       return '_parentView.context.' + path;
</span><span class="lines">@@ -19320,15 +28349,25 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   helper: function(thisContext, path, options) {
</span><del>-    var inverse = options.inverse,
-        data = options.data,
-        view = data.view,
</del><ins>+    var data = options.data,
</ins><span class="cx">         fn = options.fn,
</span><del>-        hash = options.hash,
</del><span class="cx">         newView;
</span><span class="cx"> 
</span><ins>+    makeBindings(thisContext, options);
+
</ins><span class="cx">     if ('string' === typeof path) {
</span><del>-      newView = EmberHandlebars.get(thisContext, path, options);
</del><ins>+
+      // TODO: this is a lame conditional, this should likely change
+      // but something along these lines will likely need to be added
+      // as deprecation warnings
+      //
+      if (options.types[0] === 'STRING' &amp;&amp; LOWERCASE_A_Z.test(path) &amp;&amp; !VIEW_PREFIX.test(path)) {
+        Ember.assert(&quot;View requires a container&quot;, !!data.view.container);
+        newView = data.view.container.lookupFactory('view:' + path);
+      } else {
+        newView = EmberHandlebars.get(thisContext, path, options);
+      }
+
</ins><span class="cx">       Ember.assert(&quot;Unable to find view at path '&quot; + path + &quot;'&quot;, !!newView);
</span><span class="cx">     } else {
</span><span class="cx">       newView = path;
</span><span class="lines">@@ -19338,7 +28377,7 @@
</span><span class="cx"> 
</span><span class="cx">     var viewOptions = this.propertiesFromHTMLOptions(options, thisContext);
</span><span class="cx">     var currentView = data.view;
</span><del>-    viewOptions.templateData = options.data;
</del><ins>+    viewOptions.templateData = data;
</ins><span class="cx">     var newViewProto = newView.proto ? newView.proto() : newView;
</span><span class="cx"> 
</span><span class="cx">     if (fn) {
</span><span class="lines">@@ -19465,9 +28504,8 @@
</span><span class="cx">   {{/view}}
</span><span class="cx">   ```
</span><span class="cx"> 
</span><del>-  The first argument can also be a relative path. Ember will search for the
-  view class starting at the `Ember.View` of the template where `{{view}}` was
-  used as the root object:
</del><ins>+  The first argument can also be a relative path accessible from the current
+  context.
</ins><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="cx">   MyApp = Ember.Application.create({});
</span><span class="lines">@@ -19475,7 +28513,7 @@
</span><span class="cx">     innerViewClass: Ember.View.extend({
</span><span class="cx">       classNames: ['a-custom-view-class-as-property']
</span><span class="cx">     }),
</span><del>-    template: Ember.Handlebars.compile('{{#view &quot;innerViewClass&quot;}} hi {{/view}}')
</del><ins>+    template: Ember.Handlebars.compile('{{#view &quot;view.innerViewClass&quot;}} hi {{/view}}')
</ins><span class="cx">   });
</span><span class="cx"> 
</span><span class="cx">   MyApp.OuterView.create().appendTo('body');
</span><span class="lines">@@ -19522,7 +28560,7 @@
</span><span class="cx">   @param {Hash} options
</span><span class="cx">   @return {String} HTML string
</span><span class="cx"> */
</span><del>-EmberHandlebars.registerHelper('view', function(path, options) {
</del><ins>+EmberHandlebars.registerHelper('view', function viewHelper(path, options) {
</ins><span class="cx">   Ember.assert(&quot;The view helper only takes a single argument&quot;, arguments.length &lt;= 2);
</span><span class="cx"> 
</span><span class="cx">   // If no path is provided, treat path param as options.
</span><span class="lines">@@ -19540,8 +28578,6 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-/*globals Handlebars */
-
</del><span class="cx"> // TODO: Don't require all of this module
</span><span class="cx"> /**
</span><span class="cx"> @module ember
</span><span class="lines">@@ -19552,8 +28588,8 @@
</span><span class="cx"> 
</span><span class="cx"> /**
</span><span class="cx">   `{{collection}}` is a `Ember.Handlebars` helper for adding instances of
</span><del>-  `Ember.CollectionView` to a template. See `Ember.CollectionView` for
-  additional information on how a `CollectionView` functions.
</del><ins>+  `Ember.CollectionView` to a template. See [Ember.CollectionView](/api/classes/Ember.CollectionView.html)
+   for additional information on how a `CollectionView` functions.
</ins><span class="cx"> 
</span><span class="cx">   `{{collection}}`'s primary use is as a block helper with a `contentBinding`
</span><span class="cx">   option pointing towards an `Ember.Array`-compatible object. An `Ember.View`
</span><span class="lines">@@ -19672,7 +28708,7 @@
</span><span class="cx">   @return {String} HTML string
</span><span class="cx">   @deprecated Use `{{each}}` helper instead.
</span><span class="cx"> */
</span><del>-Ember.Handlebars.registerHelper('collection', function(path, options) {
</del><ins>+Ember.Handlebars.registerHelper('collection', function collectionHelper(path, options) {
</ins><span class="cx">   Ember.deprecate(&quot;Using the {{collection}} helper without specifying a class has been deprecated as the {{each}} helper now supports the same functionality.&quot;, path !== 'collection');
</span><span class="cx"> 
</span><span class="cx">   // If no path is provided, treat path param as options.
</span><span class="lines">@@ -19698,11 +28734,32 @@
</span><span class="cx">   var hash = options.hash, itemHash = {}, match;
</span><span class="cx"> 
</span><span class="cx">   // Extract item view class if provided else default to the standard class
</span><del>-  var itemViewClass, itemViewPath = hash.itemViewClass;
-  var collectionPrototype = collectionClass.proto();
</del><ins>+  var collectionPrototype = collectionClass.proto(),
+      itemViewClass;
+
+  if (hash.itemView) {
+    var controller = data.keywords.controller;
+    Ember.assert('You specified an itemView, but the current context has no ' +
+                 'container to look the itemView up in. This probably means ' +
+                 'that you created a view manually, instead of through the ' +
+                 'container. Instead, use container.lookup(&quot;view:viewName&quot;), ' +
+                 'which will properly instantiate your view.',
+                 controller &amp;&amp; controller.container);
+    var container = controller.container;
+    itemViewClass = container.resolve('view:' + hash.itemView);
+    Ember.assert('You specified the itemView ' + hash.itemView + &quot;, but it was &quot; +
+                 &quot;not found at &quot; + container.describe(&quot;view:&quot; + hash.itemView) +
+                 &quot; (and it was not registered in the container)&quot;, !!itemViewClass);
+  } else if (hash.itemViewClass) {
+    itemViewClass = handlebarsGet(collectionPrototype, hash.itemViewClass, options);
+  } else {
+    itemViewClass = collectionPrototype.itemViewClass;
+  }
+
+  Ember.assert(fmt(&quot;%@ #collection: Could not find itemViewClass %@&quot;, [data.view, itemViewClass]), !!itemViewClass);
+
</ins><span class="cx">   delete hash.itemViewClass;
</span><del>-  itemViewClass = itemViewPath ? handlebarsGet(collectionPrototype, itemViewPath, options) : collectionPrototype.itemViewClass;
-  Ember.assert(fmt(&quot;%@ #collection: Could not find itemViewClass %@&quot;, [data.view, itemViewPath]), !!itemViewClass);
</del><ins>+  delete hash.itemView;
</ins><span class="cx"> 
</span><span class="cx">   // Go through options passed to the {{collection}} helper and extract options
</span><span class="cx">   // that configure item views instead of the collection itself.
</span><span class="lines">@@ -19710,7 +28767,7 @@
</span><span class="cx">     if (hash.hasOwnProperty(prop)) {
</span><span class="cx">       match = prop.match(/^item(.)(.*)$/);
</span><span class="cx"> 
</span><del>-      if(match &amp;&amp; prop !== 'itemController') {
</del><ins>+      if (match &amp;&amp; prop !== 'itemController') {
</ins><span class="cx">         // Convert itemShouldFoo -&gt; shouldFoo
</span><span class="cx">         itemHash[match[1].toLowerCase() + match[2]] = hash[prop];
</span><span class="cx">         // Delete from hash as this will end up getting passed to the
</span><span class="lines">@@ -19720,15 +28777,13 @@
</span><span class="cx">     }
</span><span class="cx">   }
</span><span class="cx"> 
</span><del>-  var tagName = hash.tagName || collectionPrototype.tagName;
-
</del><span class="cx">   if (fn) {
</span><span class="cx">     itemHash.template = fn;
</span><span class="cx">     delete options.fn;
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   var emptyViewClass;
</span><del>-  if (inverse &amp;&amp; inverse !== Handlebars.VM.noop) {
</del><ins>+  if (inverse &amp;&amp; inverse !== Ember.Handlebars.VM.noop) {
</ins><span class="cx">     emptyViewClass = get(collectionPrototype, 'emptyViewClass');
</span><span class="cx">     emptyViewClass = emptyViewClass.extend({
</span><span class="cx">           template: inverse,
</span><span class="lines">@@ -19739,12 +28794,10 @@
</span><span class="cx">   }
</span><span class="cx">   if (emptyViewClass) { hash.emptyView = emptyViewClass; }
</span><span class="cx"> 
</span><del>-  if(!hash.keyword){
</del><ins>+  if (!hash.keyword) {
</ins><span class="cx">     itemHash._context = Ember.computed.alias('content');
</span><span class="cx">   }
</span><span class="cx"> 
</span><del>-  var viewString = view.toString();
-
</del><span class="cx">   var viewOptions = Ember.Handlebars.ViewHelper.propertiesFromHTMLOptions({ data: data, hash: itemHash }, this);
</span><span class="cx">   hash.itemViewClass = itemViewClass.extend(viewOptions);
</span><span class="cx"> 
</span><span class="lines">@@ -19785,19 +28838,19 @@
</span><span class="cx">   @param {String} property
</span><span class="cx">   @return {String} HTML string
</span><span class="cx"> */
</span><del>-Ember.Handlebars.registerHelper('unbound', function(property, fn) {
</del><ins>+Ember.Handlebars.registerHelper('unbound', function unboundHelper(property, fn) {
</ins><span class="cx">   var options = arguments[arguments.length - 1], helper, context, out;
</span><span class="cx"> 
</span><del>-  if(arguments.length &gt; 2) {
</del><ins>+  if (arguments.length &gt; 2) {
</ins><span class="cx">     // Unbound helper call.
</span><span class="cx">     options.data.isUnbound = true;
</span><del>-    helper = Ember.Handlebars.helpers[arguments[0]] || Ember.Handlebars.helperMissing;
-    out = helper.apply(this, Array.prototype.slice.call(arguments, 1)); 
</del><ins>+    helper = Ember.Handlebars.helpers[arguments[0]] || Ember.Handlebars.helpers.helperMissing;
+    out = helper.apply(this, Array.prototype.slice.call(arguments, 1));
</ins><span class="cx">     delete options.data.isUnbound;
</span><span class="cx">     return out;
</span><span class="cx">   }
</span><span class="cx"> 
</span><del>-  context = (fn.contexts &amp;&amp; fn.contexts[0]) || this;
</del><ins>+  context = (fn.contexts &amp;&amp; fn.contexts.length) ? fn.contexts[0] : this;
</ins><span class="cx">   return handlebarsGet(context, property, fn);
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -19812,10 +28865,10 @@
</span><span class="cx"> @submodule ember-handlebars
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var handlebarsGet = Ember.Handlebars.get, normalizePath = Ember.Handlebars.normalizePath;
</del><ins>+var get = Ember.get, handlebarsGet = Ember.Handlebars.get, normalizePath = Ember.Handlebars.normalizePath;
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  `log` allows you to output the value of a value in the current rendering
</del><ins>+  `log` allows you to output the value of a variable in the current rendering
</ins><span class="cx">   context.
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><span class="lines">@@ -19826,8 +28879,8 @@
</span><span class="cx">   @for Ember.Handlebars.helpers
</span><span class="cx">   @param {String} property
</span><span class="cx"> */
</span><del>-Ember.Handlebars.registerHelper('log', function(property, options) {
-  var context = (options.contexts &amp;&amp; options.contexts[0]) || this,
</del><ins>+Ember.Handlebars.registerHelper('log', function logHelper(property, options) {
+  var context = (options.contexts &amp;&amp; options.contexts.length) ? options.contexts[0] : this,
</ins><span class="cx">       normalized = normalizePath(context, property, options.data),
</span><span class="cx">       pathRoot = normalized.root,
</span><span class="cx">       path = normalized.path,
</span><span class="lines">@@ -19842,14 +28895,44 @@
</span><span class="cx">   {{debugger}}
</span><span class="cx">   ```
</span><span class="cx"> 
</span><ins>+  Before invoking the `debugger` statement, there
+  are a few helpful variables defined in the
+  body of this helper that you can inspect while
+  debugging that describe how and where this
+  helper was invoked:
+
+  - templateContext: this is most likely a controller
+    from which this template looks up / displays properties
+  - typeOfTemplateContext: a string description of
+    what the templateContext is
+
+  For example, if you're wondering why a value `{{foo}}`
+  isn't rendering as expected within a template, you
+  could place a `{{debugger}}` statement, and when
+  the `debugger;` breakpoint is hit, you can inspect
+  `templateContext`, determine if it's the object you
+  expect, and/or evaluate expressions in the console
+  to perform property lookups on the `templateContext`:
+
+  ```
+    &gt; templateContext.get('foo') // -&gt; &quot;&lt;value of {{foo}}&gt;&quot;
+  ```
+
</ins><span class="cx">   @method debugger
</span><span class="cx">   @for Ember.Handlebars.helpers
</span><span class="cx">   @param {String} property
</span><span class="cx"> */
</span><del>-Ember.Handlebars.registerHelper('debugger', function() {
</del><ins>+Ember.Handlebars.registerHelper('debugger', function debuggerHelper(options) {
+
+  // These are helpful values you can inspect while debugging.
+  var templateContext = this;
+  var typeOfTemplateContext = Ember.inspect(templateContext);
+
</ins><span class="cx">   debugger;
</span><span class="cx"> });
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -19868,11 +28951,12 @@
</span><span class="cx">     var binding;
</span><span class="cx"> 
</span><span class="cx">     if (itemController) {
</span><del>-      var controller = Ember.ArrayController.create();
-      set(controller, 'itemController', itemController);
-      set(controller, 'container', get(this, 'controller.container'));
-      set(controller, '_eachView', this);
-      set(controller, 'target', get(this, 'controller'));
</del><ins>+      var controller = get(this, 'controller.container').lookupFactory('controller:array').create({
+        parentController: get(this, 'controller'),
+        itemController: itemController,
+        target: get(this, 'controller'),
+        _eachView: this
+      });
</ins><span class="cx"> 
</span><span class="cx">       this.disableContentObservers(function() {
</span><span class="cx">         set(this, 'content', controller);
</span><span class="lines">@@ -19891,11 +28975,16 @@
</span><span class="cx">     return this._super();
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  _assertArrayLike: function(content) {
+    Ember.assert(&quot;The value that #each loops over must be an Array. You passed &quot; + content.constructor + &quot;, but it should have been an ArrayController&quot;, !Ember.ControllerMixin.detect(content) || (content &amp;&amp; content.isGenerated) || content instanceof Ember.ArrayController);
+    Ember.assert(&quot;The value that #each loops over must be an Array. You passed &quot; + ((Ember.ControllerMixin.detect(content) &amp;&amp; content.get('model') !== undefined) ? (&quot;&quot; + content.get('model') + &quot; (wrapped in &quot; + content + &quot;)&quot;) : (&quot;&quot; + content)), Ember.Array.detect(content));
+  },
+
</ins><span class="cx">   disableContentObservers: function(callback) {
</span><span class="cx">     Ember.removeBeforeObserver(this, 'content', null, '_contentWillChange');
</span><span class="cx">     Ember.removeObserver(this, 'content', null, '_contentDidChange');
</span><span class="cx"> 
</span><del>-    callback.apply(this);
</del><ins>+    callback.call(this);
</ins><span class="cx"> 
</span><span class="cx">     Ember.addBeforeObserver(this, 'content', null, '_contentWillChange');
</span><span class="cx">     Ember.addObserver(this, 'content', null, '_contentDidChange');
</span><span class="lines">@@ -19934,14 +29023,16 @@
</span><span class="cx">     return view;
</span><span class="cx">   },
</span><span class="cx"> 
</span><del>-  willDestroy: function() {
</del><ins>+  destroy: function() {
+    if (!this._super()) { return; }
+
</ins><span class="cx">     var arrayController = get(this, '_arrayController');
</span><span class="cx"> 
</span><span class="cx">     if (arrayController) {
</span><span class="cx">       arrayController.destroy();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return this._super();
</del><ins>+    return this;
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -19988,6 +29079,8 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   addArrayObservers: function() {
</span><ins>+    if (!this.content) { return; }
+
</ins><span class="cx">     this.content.addArrayObserver(this, {
</span><span class="cx">       willChange: 'contentArrayWillChange',
</span><span class="cx">       didChange: 'contentArrayDidChange'
</span><span class="lines">@@ -19995,6 +29088,8 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   removeArrayObservers: function() {
</span><ins>+    if (!this.content) { return; }
+
</ins><span class="cx">     this.content.removeArrayObserver(this, {
</span><span class="cx">       willChange: 'contentArrayWillChange',
</span><span class="cx">       didChange: 'contentArrayDidChange'
</span><span class="lines">@@ -20012,6 +29107,8 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   render: function() {
</span><ins>+    if (!this.content) { return; }
+
</ins><span class="cx">     var content = this.content,
</span><span class="cx">         contentLength = get(content, 'length'),
</span><span class="cx">         data = this.options.data,
</span><span class="lines">@@ -20024,12 +29121,21 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   rerenderContainingView: function() {
</span><del>-    Ember.run.scheduleOnce('render', this.containingView, 'rerender');
</del><ins>+    var self = this;
+    Ember.run.scheduleOnce('render', this, function() {
+      // It's possible it's been destroyed after we enqueued a re-render call.
+      if (!self.destroyed) {
+        self.containingView.rerender();
+      }
+    });
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   destroy: function() {
</span><span class="cx">     this.removeContentObservers();
</span><del>-    this.removeArrayObservers();
</del><ins>+    if (this.content) {
+      this.removeArrayObservers();
+    }
+    this.destroyed = true;
</ins><span class="cx">   }
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -20087,7 +29193,7 @@
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><span class="cx">   {{#view App.MyView }}
</span><del>-    {{each view.items itemViewClass=&quot;App.AnItemView&quot;}} 
</del><ins>+    {{each view.items itemViewClass=&quot;App.AnItemView&quot;}}
</ins><span class="cx">   {{/view}}
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="lines">@@ -20118,7 +29224,13 @@
</span><span class="cx">     &lt;div class=&quot;ember-view&quot;&gt;Greetings Sara&lt;/div&gt;
</span><span class="cx">   &lt;/div&gt;
</span><span class="cx">   ```
</span><del>-  
</del><ins>+
+  If an `itemViewClass` is defined on the helper, and therefore the helper is not
+  being used as a block, an `emptyViewClass` can also be provided optionally.
+  The `emptyViewClass` will match the behavior of the `{{else}}` condition
+  described above. That is, the `emptyViewClass` will render if the collection
+  is empty.
+
</ins><span class="cx">   ### Representing each item with a Controller.
</span><span class="cx">   By default the controller lookup within an `{{#each}}` block will be
</span><span class="cx">   the controller of the template where the `{{#each}}` was used. If each
</span><span class="lines">@@ -20126,33 +29238,80 @@
</span><span class="cx">   `itemController` option which references a controller by lookup name.
</span><span class="cx">   Each item in the loop will be wrapped in an instance of this controller
</span><span class="cx">   and the item itself will be set to the `content` property of that controller.
</span><del>-  
</del><ins>+
</ins><span class="cx">   This is useful in cases where properties of model objects need transformation
</span><span class="cx">   or synthesis for display:
</span><del>-  
</del><ins>+
</ins><span class="cx">   ```javascript
</span><span class="cx">   App.DeveloperController = Ember.ObjectController.extend({
</span><del>-    isAvailableForHire: function(){
</del><ins>+    isAvailableForHire: function() {
</ins><span class="cx">       return !this.get('content.isEmployed') &amp;&amp; this.get('content.isSeekingWork');
</span><span class="cx">     }.property('isEmployed', 'isSeekingWork')
</span><span class="cx">   })
</span><span class="cx">   ```
</span><del>-  
</del><ins>+
</ins><span class="cx">   ```handlebars
</span><del>-  {{#each person in Developers itemController=&quot;developer&quot;}}
</del><ins>+  {{#each person in developers itemController=&quot;developer&quot;}}
</ins><span class="cx">     {{person.name}} {{#if person.isAvailableForHire}}Hire me!{{/if}}
</span><span class="cx">   {{/each}}
</span><span class="cx">   ```
</span><del>-  
</del><ins>+
+  Each itemController will receive a reference to the current controller as
+  a `parentController` property.
+
+  ### (Experimental) Grouped Each
+
+  When used in conjunction with the experimental [group helper](https://github.com/emberjs/group-helper),
+  you can inform Handlebars to re-render an entire group of items instead of
+  re-rendering them one at a time (in the event that they are changed en masse
+  or an item is added/removed).
+
+  ```handlebars
+  {{#group}}
+    {{#each people}}
+      {{firstName}} {{lastName}}
+    {{/each}}
+  {{/group}}
+  ```
+
+  This can be faster than the normal way that Handlebars re-renders items
+  in some cases.
+
+  If for some reason you have a group with more than one `#each`, you can make
+  one of the collections be updated in normal (non-grouped) fashion by setting
+  the option `groupedRows=true` (counter-intuitive, I know).
+
+  For example,
+
+  ```handlebars
+  {{dealershipName}}
+
+  {{#group}}
+    {{#each dealers}}
+      {{firstName}} {{lastName}}
+    {{/each}}
+
+    {{#each car in cars groupedRows=true}}
+      {{car.make}} {{car.model}} {{car.color}}
+    {{/each}}
+  {{/group}}
+  ```
+  Any change to `dealershipName` or the `dealers` collection will cause the
+  entire group to be re-rendered. However, changes to the `cars` collection
+  will be re-rendered individually (as normal).
+
+  Note that `group` behavior is also disabled by specifying an `itemViewClass`.
+
</ins><span class="cx">   @method each
</span><span class="cx">   @for Ember.Handlebars.helpers
</span><span class="cx">   @param [name] {String} name for item (used with `in`)
</span><del>-  @param path {String} path
</del><ins>+  @param [path] {String} path
</ins><span class="cx">   @param [options] {Object} Handlebars key/value pairs of options
</span><span class="cx">   @param [options.itemViewClass] {String} a path to a view class used for each item
</span><span class="cx">   @param [options.itemController] {String} name of a controller to be created for each item
</span><ins>+  @param [options.groupedRows] {boolean} enable normal item-by-item rendering when inside a `#group` helper
</ins><span class="cx"> */
</span><del>-Ember.Handlebars.registerHelper('each', function(path, options) {
</del><ins>+Ember.Handlebars.registerHelper('each', function eachHelper(path, options) {
</ins><span class="cx">   if (arguments.length === 4) {
</span><span class="cx">     Ember.assert(&quot;If you pass more than one argument to the each helper, it must be in the form #each foo in bar&quot;, arguments[1] === &quot;in&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -20165,6 +29324,11 @@
</span><span class="cx">     options.hash.keyword = keywordName;
</span><span class="cx">   }
</span><span class="cx"> 
</span><ins>+  if (arguments.length === 1) {
+    options = path;
+    path = 'this';
+  }
+
</ins><span class="cx">   options.hash.dataSourceBinding = path;
</span><span class="cx">   // Set up emptyView as a metamorph with no tag
</span><span class="cx">   //options.hash.emptyViewClass = Ember._MetamorphView;
</span><span class="lines">@@ -20206,6 +29370,14 @@
</span><span class="cx">   &lt;/script&gt;
</span><span class="cx">   ```
</span><span class="cx"> 
</span><ins>+  ```handlebars
+  {{#if isUser}}
+    {{template &quot;user_info&quot;}}
+  {{else}}
+    {{template &quot;unlogged_user_info&quot;}}
+  {{/if}}
+  ```
+
</ins><span class="cx">   This helper looks for templates in the global `Ember.TEMPLATES` hash. If you
</span><span class="cx">   add `&lt;script&gt;` tags to your page with the `data-template-name` attribute set,
</span><span class="cx">   they will be compiled and placed in this hash automatically.
</span><span class="lines">@@ -20216,37 +29388,118 @@
</span><span class="cx">   Ember.TEMPLATES[&quot;my_cool_template&quot;] = Ember.Handlebars.compile('&lt;b&gt;{{user}}&lt;/b&gt;');
</span><span class="cx">   ```
</span><span class="cx"> 
</span><ins>+  @deprecated
</ins><span class="cx">   @method template
</span><span class="cx">   @for Ember.Handlebars.helpers
</span><span class="cx">   @param {String} templateName the template to render
</span><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> Ember.Handlebars.registerHelper('template', function(name, options) {
</span><del>-  var template = Ember.TEMPLATES[name];
</del><ins>+  Ember.deprecate(&quot;The `template` helper has been deprecated in favor of the `partial` helper. Please use `partial` instead, which will work the same way.&quot;);
+  return Ember.Handlebars.helpers.partial.apply(this, arguments);
+});
</ins><span class="cx"> 
</span><del>-  Ember.assert(&quot;Unable to find template with name '&quot;+name+&quot;'.&quot;, !!template);
</del><ins>+})();
</ins><span class="cx"> 
</span><del>-  Ember.TEMPLATES[name](this, { data: options.data });
</del><ins>+
+
+(function() {
+/**
+@module ember
+@submodule ember-handlebars
+*/
+
+/**
+  The `partial` helper renders another template without
+  changing the template context:
+
+  ```handlebars
+  {{foo}}
+  {{partial &quot;nav&quot;}}
+  ```
+
+  The above example template will render a template named
+  &quot;_nav&quot;, which has the same context as the parent template
+  it's rendered into, so if the &quot;_nav&quot; template also referenced
+  `{{foo}}`, it would print the same thing as the `{{foo}}`
+  in the above example.
+
+  If a &quot;_nav&quot; template isn't found, the `partial` helper will
+  fall back to a template named &quot;nav&quot;.
+
+  ## Bound template names
+
+  The parameter supplied to `partial` can also be a path
+  to a property containing a template name, e.g.:
+
+  ```handlebars
+  {{partial someTemplateName}}
+  ```
+
+  The above example will look up the value of `someTemplateName`
+  on the template context (e.g. a controller) and use that
+  value as the name of the template to render. If the resolved
+  value is falsy, nothing will be rendered. If `someTemplateName`
+  changes, the partial will be re-rendered using the new template
+  name.
+
+  ## Setting the partial's context with `with`
+
+  The `partial` helper can be used in conjunction with the `with`
+  helper to set a context that will be used by the partial:
+
+  ```handlebars
+  {{#with currentUser}}
+    {{partial &quot;user_info&quot;}}
+  {{/with}}
+  ```
+
+  @method partial
+  @for Ember.Handlebars.helpers
+  @param {String} partialName the name of the template to render minus the leading underscore
+*/
+
+Ember.Handlebars.registerHelper('partial', function partialHelper(name, options) {
+
+  var context = (options.contexts &amp;&amp; options.contexts.length) ? options.contexts[0] : this;
+
+  if (options.types[0] === &quot;ID&quot;) {
+    // Helper was passed a property path; we need to
+    // create a binding that will re-render whenever
+    // this property changes.
+    options.fn = function(context, fnOptions) {
+      var partialName = Ember.Handlebars.get(context, name, fnOptions);
+      renderPartial(context, partialName, fnOptions);
+    };
+
+    return Ember.Handlebars.bind.call(context, name, options, true, exists);
+  } else {
+    // Render the partial right into parent template.
+    renderPartial(context, name, options);
+  }
</ins><span class="cx"> });
</span><span class="cx"> 
</span><del>-Ember.Handlebars.registerHelper('partial', function(name, options) {
</del><ins>+function exists(value) {
+  return !Ember.isNone(value);
+}
+
+function renderPartial(context, name, options) {
</ins><span class="cx">   var nameParts = name.split(&quot;/&quot;),
</span><span class="cx">       lastPart = nameParts[nameParts.length - 1];
</span><span class="cx"> 
</span><span class="cx">   nameParts[nameParts.length - 1] = &quot;_&quot; + lastPart;
</span><span class="cx"> 
</span><del>-  var underscoredName = nameParts.join(&quot;/&quot;);
</del><ins>+  var view = options.data.view,
+      underscoredName = nameParts.join(&quot;/&quot;),
+      template = view.templateForName(underscoredName),
+      deprecatedTemplate = !template &amp;&amp; view.templateForName(name);
</ins><span class="cx"> 
</span><del>-  var template = Ember.TEMPLATES[underscoredName],
-      deprecatedTemplate = Ember.TEMPLATES[name];
-
-  Ember.deprecate(&quot;You tried to render the partial &quot; + name + &quot;, which should be at '&quot; + underscoredName + &quot;', but Ember found '&quot; + name + &quot;'. Please use a leading underscore in your partials&quot;, template);
</del><span class="cx">   Ember.assert(&quot;Unable to find partial with name '&quot;+name+&quot;'.&quot;, template || deprecatedTemplate);
</span><span class="cx"> 
</span><span class="cx">   template = template || deprecatedTemplate;
</span><span class="cx"> 
</span><del>-  template(this, { data: options.data });
-});
</del><ins>+  template(context, { data: options.data });
+}
</ins><span class="cx"> 
</span><span class="cx"> })();
</span><span class="cx"> 
</span><span class="lines">@@ -20261,6 +29514,10 @@
</span><span class="cx"> var get = Ember.get, set = Ember.set;
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+  `{{yield}}` denotes an area of a template that will be rendered inside
+  of another template. It has two main uses:
+
+  ### Use with `layout`
</ins><span class="cx">   When used in a Handlebars template that is assigned to an `Ember.View`
</span><span class="cx">   instance's `layout` property Ember will render the layout template first,
</span><span class="cx">   inserting the view's own rendered output at the `{{yield}}` location.
</span><span class="lines">@@ -20303,26 +29560,87 @@
</span><span class="cx">   bView.appendTo('body');
</span><span class="cx"> 
</span><span class="cx">   // throws
</span><del>-  // Uncaught Error: assertion failed: You called yield in a template that was not a layout
</del><ins>+  // Uncaught Error: assertion failed:
+  // You called yield in a template that was not a layout
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><ins>+  ### Use with Ember.Component
+  When designing components `{{yield}}` is used to denote where, inside the component's
+  template, an optional block passed to the component should render:
+
+  ```handlebars
+  &lt;!-- application.hbs --&gt;
+  {{#labeled-textfield value=someProperty}}
+    First name:
+  {{/labeled-textfield}}
+  ```
+
+  ```handlebars
+  &lt;!-- components/labeled-textfield.hbs --&gt;
+  &lt;label&gt;
+    {{yield}} {{input value=value}}
+  &lt;/label&gt;
+  ```
+
+  Result:
+
+  ```html
+  &lt;label&gt;
+    First name: &lt;input type=&quot;text&quot; /&gt;
+  &lt;label&gt;
+  ```
+
</ins><span class="cx">   @method yield
</span><span class="cx">   @for Ember.Handlebars.helpers
</span><span class="cx">   @param {Hash} options
</span><span class="cx">   @return {String} HTML string
</span><span class="cx"> */
</span><del>-Ember.Handlebars.registerHelper('yield', function(options) {
-  var view = options.data.view, template;
</del><ins>+Ember.Handlebars.registerHelper('yield', function yieldHelper(options) {
+  var view = options.data.view;
</ins><span class="cx"> 
</span><span class="cx">   while (view &amp;&amp; !get(view, 'layout')) {
</span><del>-    view = get(view, 'parentView');
</del><ins>+    if (view._contextView) {
+      view = view._contextView;
+    } else {
+      view = get(view, 'parentView');
+    }
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   Ember.assert(&quot;You called yield in a template that was not a layout&quot;, !!view);
</span><span class="cx"> 
</span><del>-  template = get(view, 'template');
</del><ins>+  view._yield(this, options);
+});
</ins><span class="cx"> 
</span><del>-  if (template) { template(this, options); }
</del><ins>+})();
+
+
+
+(function() {
+/**
+@module ember
+@submodule ember-handlebars
+*/
+
+/**
+  `loc` looks up the string in the localized strings hash.
+  This is a convenient way to localize text. For example:
+
+  ```html
+  &lt;script type=&quot;text/x-handlebars&quot; data-template-name=&quot;home&quot;&gt;
+    {{loc &quot;welcome&quot;}}
+  &lt;/script&gt;
+  ```
+
+  Take note that `&quot;welcome&quot;` is a string and not an object
+  reference.
+
+  @method loc
+  @for Ember.Handlebars.helpers
+  @param {String} str The string to format
+*/
+
+Ember.Handlebars.registerHelper('loc', function locHelper(str) {
+  return Ember.String.loc(str);
</ins><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> })();
</span><span class="lines">@@ -20350,27 +29668,13 @@
</span><span class="cx"> var set = Ember.set, get = Ember.get;
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  The `Ember.Checkbox` view class renders a checkbox
-  [input](https://developer.mozilla.org/en/HTML/Element/Input) element. It
-  allows for binding an Ember property (`checked`) to the status of the
-  checkbox.
</del><ins>+  The internal class used to create text inputs when the `{{input}}`
+  helper is used with `type` of `checkbox`.
</ins><span class="cx"> 
</span><del>-  Example:
</del><ins>+  See [handlebars.helpers.input](/api/classes/Ember.Handlebars.helpers.html#method_input)  for usage details.
</ins><span class="cx"> 
</span><del>-  ```handlebars
-  {{view Ember.Checkbox checkedBinding=&quot;receiveEmail&quot;}}
-  ```
</del><ins>+  ## Direct manipulation of `checked`
</ins><span class="cx"> 
</span><del>-  You can add a `label` tag yourself in the template where the `Ember.Checkbox`
-  is being used.
-
-  ```html
-  &lt;label&gt;
-    {{view Ember.Checkbox classNames=&quot;applicaton-specific-checkbox&quot;}}
-    Some Title
-  &lt;/label&gt;
-  ```
-
</del><span class="cx">   The `checked` attribute of an `Ember.Checkbox` object should always be set
</span><span class="cx">   through the Ember object or by interacting with its rendered element
</span><span class="cx">   representation via the mouse, keyboard, or touch. Updating the value of the
</span><span class="lines">@@ -20380,8 +29684,8 @@
</span><span class="cx">   ## Layout and LayoutName properties
</span><span class="cx"> 
</span><span class="cx">   Because HTML `input` elements are self closing `layout` and `layoutName`
</span><del>-  properties will not be applied. See `Ember.View`'s layout section for more
-  information.
</del><ins>+  properties will not be applied. See [Ember.View](/api/classes/Ember.View.html)'s
+  layout section for more information.
</ins><span class="cx"> 
</span><span class="cx">   @class Checkbox
</span><span class="cx">   @namespace Ember
</span><span class="lines">@@ -20392,17 +29696,23 @@
</span><span class="cx"> 
</span><span class="cx">   tagName: 'input',
</span><span class="cx"> 
</span><del>-  attributeBindings: ['type', 'checked', 'disabled', 'tabindex'],
</del><ins>+  attributeBindings: ['type', 'checked', 'indeterminate', 'disabled', 'tabindex', 'name'],
</ins><span class="cx"> 
</span><span class="cx">   type: &quot;checkbox&quot;,
</span><span class="cx">   checked: false,
</span><span class="cx">   disabled: false,
</span><ins>+  indeterminate: false,
</ins><span class="cx"> 
</span><span class="cx">   init: function() {
</span><span class="cx">     this._super();
</span><span class="cx">     this.on(&quot;change&quot;, this, this._updateElementValue);
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  didInsertElement: function() {
+    this._super();
+    this.get('element').indeterminate = !!this.get('indeterminate');
+  },
+
</ins><span class="cx">   _updateElementValue: function() {
</span><span class="cx">     set(this, 'checked', this.$().prop('checked'));
</span><span class="cx">   }
</span><span class="lines">@@ -20425,20 +29735,16 @@
</span><span class="cx"> 
</span><span class="cx">   @class TextSupport
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.Mixin
</del><span class="cx">   @private
</span><span class="cx"> */
</span><span class="cx"> Ember.TextSupport = Ember.Mixin.create({
</span><span class="cx">   value: &quot;&quot;,
</span><span class="cx"> 
</span><del>-  attributeBindings: ['placeholder', 'disabled', 'maxlength', 'tabindex'],
</del><ins>+  attributeBindings: ['placeholder', 'disabled', 'maxlength', 'tabindex', 'readonly'],
</ins><span class="cx">   placeholder: null,
</span><span class="cx">   disabled: false,
</span><span class="cx">   maxlength: null,
</span><span class="cx"> 
</span><del>-  insertNewline: Ember.K,
-  cancel: Ember.K,
-
</del><span class="cx">   init: function() {
</span><span class="cx">     this._super();
</span><span class="cx">     this.on(&quot;focusOut&quot;, this, this._elementValueDidChange);
</span><span class="lines">@@ -20449,6 +29755,50 @@
</span><span class="cx">     this.on(&quot;keyUp&quot;, this, this.interpretKeyEvents);
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    The action to be sent when the user presses the return key.
+
+    This is similar to the `{{action}}` helper, but is fired when
+    the user presses the return key when editing a text field, and sends
+    the value of the field as the context.
+
+    @property action
+    @type String
+    @default null
+  */
+  action: null,
+
+  /**
+    The event that should send the action.
+
+    Options are:
+
+    * `enter`: the user pressed enter
+    * `keyPress`: the user pressed a key
+
+    @property onEvent
+    @type String
+    @default enter
+  */
+  onEvent: 'enter',
+
+  /**
+    Whether they `keyUp` event that triggers an `action` to be sent continues
+    propagating to other views.
+
+    By default, when the user presses the return key on their keyboard and
+    the text field has an `action` set, the action will be sent to the view's
+    controller and the key event will stop propagating.
+
+    If you would like parent views to receive the `keyUp` event even after an
+    action has been dispatched, set `bubbles` to true.
+
+    @property bubbles
+    @type Boolean
+    @default false
+  */
+  bubbles: false,
+
</ins><span class="cx">   interpretKeyEvents: function(event) {
</span><span class="cx">     var map = Ember.TextSupport.KEY_EVENTS;
</span><span class="cx">     var method = map[event.keyCode];
</span><span class="lines">@@ -20459,6 +29809,66 @@
</span><span class="cx"> 
</span><span class="cx">   _elementValueDidChange: function() {
</span><span class="cx">     set(this, 'value', this.$().val());
</span><ins>+  },
+
+  /**
+    The action to be sent when the user inserts a new line.
+
+    Called by the `Ember.TextSupport` mixin on keyUp if keycode matches 13.
+    Uses sendAction to send the `enter` action to the controller.
+
+    @method insertNewline
+    @param {Event} event
+  */
+  insertNewline: function(event) {
+    sendAction('enter', this, event);
+    sendAction('insert-newline', this, event);
+  },
+
+  /**
+    Called when the user hits escape.
+
+    Called by the `Ember.TextSupport` mixin on keyUp if keycode matches 27.
+    Uses sendAction to send the `escape-press` action to the controller.
+
+    @method cancel
+    @param {Event} event
+  */
+  cancel: function(event) {
+    sendAction('escape-press', this, event);
+  },
+
+  /**
+    Called when the text area is focused.
+
+    @method focusIn
+    @param {Event} event
+  */
+  focusIn: function(event) {
+    sendAction('focus-in', this, event);
+  },
+
+  /**
+    Called when the text area is blurred.
+
+    @method focusOut
+    @param {Event} event
+  */
+  focusOut: function(event) {
+    sendAction('focus-out', this, event);
+  },
+
+  /**
+    The action to be sent when the user presses a key. Enabled by setting
+    the `onEvent` property to `keyPress`.
+
+    Uses sendAction to send the `keyPress` action to the controller.
+
+    @method keyPress
+    @param {Event} event
+  */
+  keyPress: function(event) {
+    sendAction('key-press', this, event);
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx"> });
</span><span class="lines">@@ -20468,6 +29878,30 @@
</span><span class="cx">   27: 'cancel'
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+// In principle, this shouldn't be necessary, but the legacy
+// sectionAction semantics for TextField are different from
+// the component semantics so this method normalizes them.
+function sendAction(eventName, view, event) {
+  var action = get(view, eventName),
+      on = get(view, 'onEvent'),
+      value = get(view, 'value');
+
+  // back-compat support for keyPress as an event name even though
+  // it's also a method name that consumes the event (and therefore
+  // incompatible with sendAction semantics).
+  if (on === eventName || (on === 'keyPress' &amp;&amp; eventName === 'key-press')) {
+    view.sendAction('action', value);
+  }
+
+  view.sendAction(eventName, value);
+
+  if (action || on === eventName) {
+    if(!get(view, 'bubbles')) {
+      event.stopPropagation();
+    }
+  }
+}
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -20481,50 +29915,28 @@
</span><span class="cx"> var get = Ember.get, set = Ember.set;
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  The `Ember.TextField` view class renders a text
-  [input](https://developer.mozilla.org/en/HTML/Element/Input) element. It
-  allows for binding Ember properties to the text field contents (`value`),
-  live-updating as the user inputs text.
</del><span class="cx"> 
</span><del>-  Example:
</del><ins>+  The internal class used to create text inputs when the `{{input}}`
+  helper is used with `type` of `text`.
</ins><span class="cx"> 
</span><del>-  ```handlebars
-  {{view Ember.TextField valueBinding=&quot;firstName&quot;}}
-  ```
</del><ins>+  See [Handlebars.helpers.input](/api/classes/Ember.Handlebars.helpers.html#method_input)  for usage details.
</ins><span class="cx"> 
</span><span class="cx">   ## Layout and LayoutName properties
</span><span class="cx"> 
</span><span class="cx">   Because HTML `input` elements are self closing `layout` and `layoutName`
</span><del>-  properties will not be applied. See `Ember.View`'s layout section for more
-  information.
</del><ins>+  properties will not be applied. See [Ember.View](/api/classes/Ember.View.html)'s
+  layout section for more information.
</ins><span class="cx"> 
</span><del>-  ## HTML Attributes
-
-  By default `Ember.TextField` provides support for `type`, `value`, `size`,
-  `placeholder`, `disabled`, `maxlength` and `tabindex` attributes on a
-  test field. If you need to support more attributes have a look at the
-  `attributeBindings` property in `Ember.View`'s HTML Attributes section.
-
-  To globally add support for additional attributes you can reopen
-  `Ember.TextField` or `Ember.TextSupport`.
-
-  ```javascript
-  Ember.TextSupport.reopen({
-    attributeBindings: [&quot;required&quot;]
-  })
-  ```
-
</del><span class="cx">   @class TextField
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.View
</del><ins>+  @extends Ember.Component
</ins><span class="cx">   @uses Ember.TextSupport
</span><span class="cx"> */
</span><del>-Ember.TextField = Ember.View.extend(Ember.TextSupport,
-  /** @scope Ember.TextField.prototype */ {
</del><ins>+Ember.TextField = Ember.Component.extend(Ember.TextSupport, {
</ins><span class="cx"> 
</span><span class="cx">   classNames: ['ember-text-field'],
</span><span class="cx">   tagName: &quot;input&quot;,
</span><del>-  attributeBindings: ['type', 'value', 'size', 'pattern'],
</del><ins>+  attributeBindings: ['type', 'value', 'size', 'pattern', 'name'],
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     The `value` attribute of the input element. As the user inputs text, this
</span><span class="lines">@@ -20561,50 +29973,7 @@
</span><span class="cx">     @type String
</span><span class="cx">     @default null
</span><span class="cx">   */
</span><del>-  pattern: null,
-
-  /**
-    The action to be sent when the user presses the return key.
-
-    This is similar to the `{{action}}` helper, but is fired when
-    the user presses the return key when editing a text field, and sends
-    the value of the field as the context.
-
-   @property action
-   @type String
-   @default null
-  */
-  action: null,
-
-  /**
-    Whether they `keyUp` event that triggers an `action` to be sent continues
-    propagating to other views.
-
-    By default, when the user presses the return key on their keyboard and
-    the text field has an `action` set, the action will be sent to the view's
-    controller and the key event will stop propagating.
-
-    If you would like parent views to receive the `keyUp` event even after an
-    action has been dispatched, set `bubbles` to true.
-
-    @property bubbles
-    @type Boolean
-    @default false
-  */
-  bubbles: false,
-
-  insertNewline: function(event) {
-    var controller = get(this, 'controller'),
-        action = get(this, 'action');
-
-    if (action) {
-      controller.send(action, get(this, 'value'), this);
-
-      if (!get(this, 'bubbles')) {
-        event.stopPropagation();
-      }
-    }
-  }
</del><ins>+  pattern: null
</ins><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> })();
</span><span class="lines">@@ -20612,14 +29981,14 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-/**
</del><ins>+/*
</ins><span class="cx"> @module ember
</span><span class="cx"> @submodule ember-handlebars
</span><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> var get = Ember.get, set = Ember.set;
</span><span class="cx"> 
</span><del>-/**
</del><ins>+/*
</ins><span class="cx">   @class Button
</span><span class="cx">   @namespace Ember
</span><span class="cx">   @extends Ember.View
</span><span class="lines">@@ -20636,7 +30005,7 @@
</span><span class="cx"> 
</span><span class="cx">   attributeBindings: ['type', 'disabled', 'href', 'tabindex'],
</span><span class="cx"> 
</span><del>-  /**
</del><ins>+  /*
</ins><span class="cx">     @private
</span><span class="cx"> 
</span><span class="cx">     Overrides `TargetActionSupport`'s `targetObject` computed
</span><span class="lines">@@ -20748,54 +30117,38 @@
</span><span class="cx"> var get = Ember.get, set = Ember.set;
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  The `Ember.TextArea` view class renders a
-  [textarea](https://developer.mozilla.org/en/HTML/Element/textarea) element.
-  It allows for binding Ember properties to the text area contents (`value`),
-  live-updating as the user inputs text.
</del><ins>+  The internal class used to create textarea element when the `{{textarea}}`
+  helper is used.
</ins><span class="cx"> 
</span><ins>+  See [handlebars.helpers.textarea](/api/classes/Ember.Handlebars.helpers.html#method_textarea)  for usage details.
+
</ins><span class="cx">   ## Layout and LayoutName properties
</span><span class="cx"> 
</span><span class="cx">   Because HTML `textarea` elements do not contain inner HTML the `layout` and
</span><del>-  `layoutName` properties will not be applied. See `Ember.View`'s layout
-  section for more information.
</del><ins>+  `layoutName` properties will not be applied. See [Ember.View](/api/classes/Ember.View.html)'s
+  layout section for more information.
</ins><span class="cx"> 
</span><del>-  ## HTML Attributes
-
-  By default `Ember.TextArea` provides support for `rows`, `cols`,
-  `placeholder`, `disabled`, `maxlength` and `tabindex` attributes on a
-  textarea. If you need to support  more attributes have a look at the
-  `attributeBindings` property in `Ember.View`'s HTML Attributes section.
-
-  To globally add support for additional attributes you can reopen
-  `Ember.TextArea` or `Ember.TextSupport`.
-
-  ```javascript
-  Ember.TextSupport.reopen({
-    attributeBindings: [&quot;required&quot;]
-  })
-  ```
-
</del><span class="cx">   @class TextArea
</span><span class="cx">   @namespace Ember
</span><del>-  @extends Ember.View
</del><ins>+  @extends Ember.Component
</ins><span class="cx">   @uses Ember.TextSupport
</span><span class="cx"> */
</span><del>-Ember.TextArea = Ember.View.extend(Ember.TextSupport, {
</del><ins>+Ember.TextArea = Ember.Component.extend(Ember.TextSupport, {
</ins><span class="cx">   classNames: ['ember-text-area'],
</span><span class="cx"> 
</span><span class="cx">   tagName: &quot;textarea&quot;,
</span><del>-  attributeBindings: ['rows', 'cols'],
</del><ins>+  attributeBindings: ['rows', 'cols', 'name'],
</ins><span class="cx">   rows: null,
</span><span class="cx">   cols: null,
</span><span class="cx"> 
</span><del>-  _updateElementValue: Ember.observer(function() {
</del><ins>+  _updateElementValue: Ember.observer('value', function() {
</ins><span class="cx">     // We do this check so cursor position doesn't get affected in IE
</span><span class="cx">     var value = get(this, 'value'),
</span><span class="cx">         $el = this.$();
</span><span class="cx">     if ($el &amp;&amp; value !== $el.val()) {
</span><span class="cx">       $el.val(value);
</span><span class="cx">     }
</span><del>-  }, 'value'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><span class="cx">   init: function() {
</span><span class="cx">     this._super();
</span><span class="lines">@@ -20820,10 +30173,72 @@
</span><span class="cx">     get = Ember.get,
</span><span class="cx">     indexOf = Ember.EnumerableUtils.indexOf,
</span><span class="cx">     indexesOf = Ember.EnumerableUtils.indexesOf,
</span><ins>+    forEach = Ember.EnumerableUtils.forEach,
</ins><span class="cx">     replace = Ember.EnumerableUtils.replace,
</span><span class="cx">     isArray = Ember.isArray,
</span><span class="cx">     precompileTemplate = Ember.Handlebars.compile;
</span><span class="cx"> 
</span><ins>+Ember.SelectOption = Ember.View.extend({
+  tagName: 'option',
+  attributeBindings: ['value', 'selected'],
+
+  defaultTemplate: function(context, options) {
+    options = { data: options.data, hash: {} };
+    Ember.Handlebars.helpers.bind.call(context, &quot;view.label&quot;, options);
+  },
+
+  init: function() {
+    this.labelPathDidChange();
+    this.valuePathDidChange();
+
+    this._super();
+  },
+
+  selected: Ember.computed(function() {
+    var content = get(this, 'content'),
+        selection = get(this, 'parentView.selection');
+    if (get(this, 'parentView.multiple')) {
+      return selection &amp;&amp; indexOf(selection, content.valueOf()) &gt; -1;
+    } else {
+      // Primitives get passed through bindings as objects... since
+      // `new Number(4) !== 4`, we use `==` below
+      return content == selection;
+    }
+  }).property('content', 'parentView.selection'),
+
+  labelPathDidChange: Ember.observer('parentView.optionLabelPath', function() {
+    var labelPath = get(this, 'parentView.optionLabelPath');
+
+    if (!labelPath) { return; }
+
+    Ember.defineProperty(this, 'label', Ember.computed(function() {
+      return get(this, labelPath);
+    }).property(labelPath));
+  }),
+
+  valuePathDidChange: Ember.observer('parentView.optionValuePath', function() {
+    var valuePath = get(this, 'parentView.optionValuePath');
+
+    if (!valuePath) { return; }
+
+    Ember.defineProperty(this, 'value', Ember.computed(function() {
+      return get(this, valuePath);
+    }).property(valuePath));
+  })
+});
+
+Ember.SelectOptgroup = Ember.CollectionView.extend({
+  tagName: 'optgroup',
+  attributeBindings: ['label'],
+
+  selectionBinding: 'parentView.selection',
+  multipleBinding: 'parentView.multiple',
+  optionLabelPathBinding: 'parentView.optionLabelPath',
+  optionValuePathBinding: 'parentView.optionValuePath',
+
+  itemViewClassBinding: 'parentView.optionView'
+});
+
</ins><span class="cx"> /**
</span><span class="cx">   The `Ember.Select` view class renders a
</span><span class="cx">   [select](https://developer.mozilla.org/en/HTML/Element/select) HTML element,
</span><span class="lines">@@ -20834,7 +30249,7 @@
</span><span class="cx">   `content` property. The underlying data object of the selected `&lt;option&gt;` is
</span><span class="cx">   stored in the `Element.Select`'s `value` property.
</span><span class="cx"> 
</span><del>-  ### `content` as an array of Strings
</del><ins>+  ## The Content Property (array of strings)
</ins><span class="cx"> 
</span><span class="cx">   The simplest version of an `Ember.Select` takes an array of strings as its
</span><span class="cx">   `content` property. The string will be used as both the `value` property and
</span><span class="lines">@@ -20843,11 +30258,13 @@
</span><span class="cx">   Example:
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><del>-  App.names = [&quot;Yehuda&quot;, &quot;Tom&quot;];
</del><ins>+  App.ApplicationController = Ember.Controller.extend({
+    names: [&quot;Yehuda&quot;, &quot;Tom&quot;]
+  });
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><del>-  {{view Ember.Select contentBinding=&quot;App.names&quot;}}
</del><ins>+  {{view Ember.Select content=names}}
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   Would result in the following HTML:
</span><span class="lines">@@ -20860,19 +30277,19 @@
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   You can control which `&lt;option&gt;` is selected through the `Ember.Select`'s
</span><del>-  `value` property directly or as a binding:
</del><ins>+  `value` property:
</ins><span class="cx"> 
</span><span class="cx">   ```javascript
</span><del>-  App.names = Ember.Object.create({
-    selected: 'Tom',
-    content: [&quot;Yehuda&quot;, &quot;Tom&quot;]
</del><ins>+  App.ApplicationController = Ember.Controller.extend({
+    selectedName: 'Tom',
+    names: [&quot;Yehuda&quot;, &quot;Tom&quot;]
</ins><span class="cx">   });
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><span class="cx">   {{view Ember.Select
</span><del>-         contentBinding=&quot;App.names.content&quot;
-         valueBinding=&quot;App.names.selected&quot;
</del><ins>+         content=names
+         value=selectedName
</ins><span class="cx">   }}
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="lines">@@ -20886,9 +30303,9 @@
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   A user interacting with the rendered `&lt;select&gt;` to choose &quot;Yehuda&quot; would
</span><del>-  update the value of `App.names.selected` to &quot;Yehuda&quot;.
</del><ins>+  update the value of `selectedName` to &quot;Yehuda&quot;.
</ins><span class="cx"> 
</span><del>-  ### `content` as an Array of Objects
</del><ins>+  ## The Content Property (array of Objects)
</ins><span class="cx"> 
</span><span class="cx">   An `Ember.Select` can also take an array of JavaScript or Ember objects as
</span><span class="cx">   its `content` property.
</span><span class="lines">@@ -20903,15 +30320,17 @@
</span><span class="cx">   element's text. Both paths must reference each object itself as `content`:
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><del>-  App.programmers = [
-    Ember.Object.create({firstName: &quot;Yehuda&quot;, id: 1}),
-    Ember.Object.create({firstName: &quot;Tom&quot;,    id: 2})
-  ];
</del><ins>+  App.ApplicationController = Ember.Controller.extend({
+    programmers: [
+      {firstName: &quot;Yehuda&quot;, id: 1},
+      {firstName: &quot;Tom&quot;,    id: 2}
+    ]
+  });
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><span class="cx">   {{view Ember.Select
</span><del>-         contentBinding=&quot;App.programmers&quot;
</del><ins>+         content=programmers
</ins><span class="cx">          optionValuePath=&quot;content.id&quot;
</span><span class="cx">          optionLabelPath=&quot;content.firstName&quot;}}
</span><span class="cx">   ```
</span><span class="lines">@@ -20920,97 +30339,94 @@
</span><span class="cx"> 
</span><span class="cx">   ```html
</span><span class="cx">   &lt;select class=&quot;ember-select&quot;&gt;
</span><del>-    &lt;option value&gt;Please Select&lt;/option&gt;
</del><span class="cx">     &lt;option value=&quot;1&quot;&gt;Yehuda&lt;/option&gt;
</span><span class="cx">     &lt;option value=&quot;2&quot;&gt;Tom&lt;/option&gt;
</span><span class="cx">   &lt;/select&gt;
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   The `value` attribute of the selected `&lt;option&gt;` within an `Ember.Select`
</span><del>-  can be bound to a property on another object by providing a
-  `valueBinding` option:
</del><ins>+  can be bound to a property on another object:
</ins><span class="cx"> 
</span><span class="cx">   ```javascript
</span><del>-  App.programmers = [
-    Ember.Object.create({firstName: &quot;Yehuda&quot;, id: 1}),
-    Ember.Object.create({firstName: &quot;Tom&quot;,    id: 2})
-  ];
-
-  App.currentProgrammer = Ember.Object.create({
-    id: 2
</del><ins>+  App.ApplicationController = Ember.Controller.extend({
+    programmers: [
+      {firstName: &quot;Yehuda&quot;, id: 1},
+      {firstName: &quot;Tom&quot;,    id: 2}
+    ],
+    currentProgrammer: {
+      id: 2
+    }
</ins><span class="cx">   });
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><span class="cx">   {{view Ember.Select
</span><del>-         contentBinding=&quot;App.programmers&quot;
</del><ins>+         content=programmers
</ins><span class="cx">          optionValuePath=&quot;content.id&quot;
</span><span class="cx">          optionLabelPath=&quot;content.firstName&quot;
</span><del>-         valueBinding=&quot;App.currentProgrammer.id&quot;}}
</del><ins>+         value=currentProgrammer.id}}
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   Would result in the following HTML with a selected option:
</span><span class="cx"> 
</span><span class="cx">   ```html
</span><span class="cx">   &lt;select class=&quot;ember-select&quot;&gt;
</span><del>-    &lt;option value&gt;Please Select&lt;/option&gt;
</del><span class="cx">     &lt;option value=&quot;1&quot;&gt;Yehuda&lt;/option&gt;
</span><span class="cx">     &lt;option value=&quot;2&quot; selected=&quot;selected&quot;&gt;Tom&lt;/option&gt;
</span><span class="cx">   &lt;/select&gt;
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   Interacting with the rendered element by selecting the first option
</span><del>-  ('Yehuda') will update the `id` value of `App.currentProgrammer`
</del><ins>+  ('Yehuda') will update the `id` of `currentProgrammer`
</ins><span class="cx">   to match the `value` property of the newly selected `&lt;option&gt;`.
</span><span class="cx"> 
</span><span class="cx">   Alternatively, you can control selection through the underlying objects
</span><del>-  used to render each object providing a `selectionBinding`. When the selected
-  `&lt;option&gt;` is changed, the property path provided to `selectionBinding`
</del><ins>+  used to render each object by binding the `selection` option. When the selected
+  `&lt;option&gt;` is changed, the property path provided to `selection`
</ins><span class="cx">   will be updated to match the content object of the rendered `&lt;option&gt;`
</span><span class="cx">   element:
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><del>-  App.controller = Ember.Object.create({
</del><ins>+  App.ApplicationController = Ember.Controller.extend({
</ins><span class="cx">     selectedPerson: null,
</span><del>-    content: [
-      Ember.Object.create({firstName: &quot;Yehuda&quot;, id: 1}),
-      Ember.Object.create({firstName: &quot;Tom&quot;,    id: 2})
</del><ins>+    programmers: [
+      {firstName: &quot;Yehuda&quot;, id: 1},
+      {firstName: &quot;Tom&quot;,    id: 2}
</ins><span class="cx">     ]
</span><span class="cx">   });
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><span class="cx">   {{view Ember.Select
</span><del>-         contentBinding=&quot;App.controller.content&quot;
</del><ins>+         content=programmers
</ins><span class="cx">          optionValuePath=&quot;content.id&quot;
</span><span class="cx">          optionLabelPath=&quot;content.firstName&quot;
</span><del>-         selectionBinding=&quot;App.controller.selectedPerson&quot;}}
</del><ins>+         selection=selectedPerson}}
</ins><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   Would result in the following HTML with a selected option:
</span><span class="cx"> 
</span><span class="cx">   ```html
</span><span class="cx">   &lt;select class=&quot;ember-select&quot;&gt;
</span><del>-    &lt;option value&gt;Please Select&lt;/option&gt;
</del><span class="cx">     &lt;option value=&quot;1&quot;&gt;Yehuda&lt;/option&gt;
</span><span class="cx">     &lt;option value=&quot;2&quot; selected=&quot;selected&quot;&gt;Tom&lt;/option&gt;
</span><span class="cx">   &lt;/select&gt;
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   Interacting with the rendered element by selecting the first option
</span><del>-  ('Yehuda') will update the `selectedPerson` value of `App.controller`
-  to match the content object of the newly selected `&lt;option&gt;`. In this
-  case it is the first object in the `App.content.content`
</del><ins>+  ('Yehuda') will update the `selectedPerson` to match the object of
+  the newly selected `&lt;option&gt;`. In this case it is the first object
+  in the `programmers`
</ins><span class="cx"> 
</span><del>-  ### Supplying a Prompt
</del><ins>+  ## Supplying a Prompt
</ins><span class="cx"> 
</span><span class="cx">   A `null` value for the `Ember.Select`'s `value` or `selection` property
</span><span class="cx">   results in there being no `&lt;option&gt;` with a `selected` attribute:
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><del>-  App.controller = Ember.Object.create({
-    selected: null,
-    content: [
</del><ins>+  App.ApplicationController = Ember.Controller.extend({
+    selectedProgrammer: null,
+    programmers: [
</ins><span class="cx">       &quot;Yehuda&quot;,
</span><span class="cx">       &quot;Tom&quot;
</span><span class="cx">     ]
</span><span class="lines">@@ -21019,8 +30435,8 @@
</span><span class="cx"> 
</span><span class="cx">   ``` handlebars
</span><span class="cx">   {{view Ember.Select
</span><del>-         contentBinding=&quot;App.controller.content&quot;
-         valueBinding=&quot;App.controller.selected&quot;
</del><ins>+         content=programmers
+         value=selectedProgrammer
</ins><span class="cx">   }}
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="lines">@@ -21033,16 +30449,16 @@
</span><span class="cx">   &lt;/select&gt;
</span><span class="cx">   ```
</span><span class="cx"> 
</span><del>-  Although `App.controller.selected` is `null` and no `&lt;option&gt;`
</del><ins>+  Although `selectedProgrammer` is `null` and no `&lt;option&gt;`
</ins><span class="cx">   has a `selected` attribute the rendered HTML will display the
</span><span class="cx">   first item as though it were selected. You can supply a string
</span><span class="cx">   value for the `Ember.Select` to display when there is no selection
</span><span class="cx">   with the `prompt` option:
</span><span class="cx"> 
</span><span class="cx">   ```javascript
</span><del>-  App.controller = Ember.Object.create({
-    selected: null,
-    content: [
</del><ins>+  App.ApplicationController = Ember.Controller.extend({
+    selectedProgrammer: null,
+    programmers: [
</ins><span class="cx">       &quot;Yehuda&quot;,
</span><span class="cx">       &quot;Tom&quot;
</span><span class="cx">     ]
</span><span class="lines">@@ -21051,8 +30467,8 @@
</span><span class="cx"> 
</span><span class="cx">   ```handlebars
</span><span class="cx">   {{view Ember.Select
</span><del>-         contentBinding=&quot;App.controller.content&quot;
-         valueBinding=&quot;App.controller.selected&quot;
</del><ins>+         content=programmers
+         value=selectedProgrammer
</ins><span class="cx">          prompt=&quot;Please select a name&quot;
</span><span class="cx">   }}
</span><span class="cx">   ```
</span><span class="lines">@@ -21071,45 +30487,77 @@
</span><span class="cx">   @namespace Ember
</span><span class="cx">   @extends Ember.View
</span><span class="cx"> */
</span><del>-Ember.Select = Ember.View.extend(
-  /** @scope Ember.Select.prototype */ {
-
</del><ins>+Ember.Select = Ember.View.extend({
</ins><span class="cx">   tagName: 'select',
</span><span class="cx">   classNames: ['ember-select'],
</span><span class="cx">   defaultTemplate: Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) {
</span><del>-this.compilerInfo = [2,'&gt;= 1.0.0-rc.3'];
-helpers = helpers || Ember.Handlebars.helpers; data = data || {};
-  var buffer = '', stack1, hashTypes, escapeExpression=this.escapeExpression, self=this;
</del><ins>+this.compilerInfo = [4,'&gt;= 1.0.0'];
+helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
+  var buffer = '', stack1, hashTypes, hashContexts, escapeExpression=this.escapeExpression, self=this;
</ins><span class="cx"> 
</span><span class="cx"> function program1(depth0,data) {
</span><span class="cx">   
</span><del>-  var buffer = '', hashTypes;
</del><ins>+  var buffer = '', stack1, hashTypes, hashContexts;
</ins><span class="cx">   data.buffer.push(&quot;&lt;option value=\&quot;\&quot;&gt;&quot;);
</span><span class="cx">   hashTypes = {};
</span><del>-  data.buffer.push(escapeExpression(helpers._triageMustache.call(depth0, &quot;view.prompt&quot;, {hash:{},contexts:[depth0],types:[&quot;ID&quot;],hashTypes:hashTypes,data:data})));
</del><ins>+  hashContexts = {};
+  stack1 = helpers._triageMustache.call(depth0, &quot;view.prompt&quot;, {hash:{},contexts:[depth0],types:[&quot;ID&quot;],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
+  if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
</ins><span class="cx">   data.buffer.push(&quot;&lt;/option&gt;&quot;);
</span><span class="cx">   return buffer;
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx"> function program3(depth0,data) {
</span><span class="cx">   
</span><del>-  var hashTypes;
-  hashTypes = {'contentBinding': &quot;STRING&quot;};
-  data.buffer.push(escapeExpression(helpers.view.call(depth0, &quot;Ember.SelectOption&quot;, {hash:{
-    'contentBinding': (&quot;this&quot;)
-  },contexts:[depth0],types:[&quot;ID&quot;],hashTypes:hashTypes,data:data})));
</del><ins>+  var stack1, hashTypes, hashContexts;
+  hashTypes = {};
+  hashContexts = {};
+  stack1 = helpers.each.call(depth0, &quot;view.groupedContent&quot;, {hash:{},inverse:self.noop,fn:self.program(4, program4, data),contexts:[depth0],types:[&quot;ID&quot;],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
+  if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
+  else { data.buffer.push(''); }
</ins><span class="cx">   }
</span><ins>+function program4(depth0,data) {
+  
+  var hashContexts, hashTypes;
+  hashContexts = {'content': depth0,'label': depth0};
+  hashTypes = {'content': &quot;ID&quot;,'label': &quot;ID&quot;};
+  data.buffer.push(escapeExpression(helpers.view.call(depth0, &quot;view.groupView&quot;, {hash:{
+    'content': (&quot;content&quot;),
+    'label': (&quot;label&quot;)
+  },contexts:[depth0],types:[&quot;ID&quot;],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
+  }
</ins><span class="cx"> 
</span><ins>+function program6(depth0,data) {
+  
+  var stack1, hashTypes, hashContexts;
</ins><span class="cx">   hashTypes = {};
</span><del>-  stack1 = helpers['if'].call(depth0, &quot;view.prompt&quot;, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),contexts:[depth0],types:[&quot;ID&quot;],hashTypes:hashTypes,data:data});
</del><ins>+  hashContexts = {};
+  stack1 = helpers.each.call(depth0, &quot;view.content&quot;, {hash:{},inverse:self.noop,fn:self.program(7, program7, data),contexts:[depth0],types:[&quot;ID&quot;],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
</ins><span class="cx">   if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
</span><ins>+  else { data.buffer.push(''); }
+  }
+function program7(depth0,data) {
+  
+  var hashContexts, hashTypes;
+  hashContexts = {'content': depth0};
+  hashTypes = {'content': &quot;ID&quot;};
+  data.buffer.push(escapeExpression(helpers.view.call(depth0, &quot;view.optionView&quot;, {hash:{
+    'content': (&quot;&quot;)
+  },contexts:[depth0],types:[&quot;ID&quot;],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
+  }
+
</ins><span class="cx">   hashTypes = {};
</span><del>-  stack1 = helpers.each.call(depth0, &quot;view.content&quot;, {hash:{},inverse:self.noop,fn:self.program(3, program3, data),contexts:[depth0],types:[&quot;ID&quot;],hashTypes:hashTypes,data:data});
</del><ins>+  hashContexts = {};
+  stack1 = helpers['if'].call(depth0, &quot;view.prompt&quot;, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),contexts:[depth0],types:[&quot;ID&quot;],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
</ins><span class="cx">   if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
</span><ins>+  hashTypes = {};
+  hashContexts = {};
+  stack1 = helpers['if'].call(depth0, &quot;view.optionGroupPath&quot;, {hash:{},inverse:self.program(6, program6, data),fn:self.program(3, program3, data),contexts:[depth0],types:[&quot;ID&quot;],hashContexts:hashContexts,hashTypes:hashTypes,data:data});
+  if(stack1 || stack1 === 0) { data.buffer.push(stack1); }
</ins><span class="cx">   return buffer;
</span><span class="cx">   
</span><span class="cx"> }),
</span><del>-  attributeBindings: ['multiple', 'disabled', 'tabindex'],
</del><ins>+  attributeBindings: ['multiple', 'disabled', 'tabindex', 'name'],
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     The `multiple` attribute of the select element. Indicates whether multiple
</span><span class="lines">@@ -21121,6 +30569,14 @@
</span><span class="cx">   */
</span><span class="cx">   multiple: false,
</span><span class="cx"> 
</span><ins>+  /**
+    The `disabled` attribute of the select element. Indicates whether
+    the element is disabled from interactions.
+
+    @property disabled
+    @type Boolean
+    @default false
+  */
</ins><span class="cx">   disabled: false,
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -21187,7 +30643,7 @@
</span><span class="cx">   prompt: null,
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    The path of the option labels. See `content`.
</del><ins>+    The path of the option labels. See [content](/api/classes/Ember.Select.html#property_content).
</ins><span class="cx"> 
</span><span class="cx">     @property optionLabelPath
</span><span class="cx">     @type String
</span><span class="lines">@@ -21196,7 +30652,7 @@
</span><span class="cx">   optionLabelPath: 'content',
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    The path of the option values. See `content`.
</del><ins>+    The path of the option values. See [content](/api/classes/Ember.Select.html#property_content).
</ins><span class="cx"> 
</span><span class="cx">     @property optionValuePath
</span><span class="cx">     @type String
</span><span class="lines">@@ -21204,6 +30660,55 @@
</span><span class="cx">   */
</span><span class="cx">   optionValuePath: 'content',
</span><span class="cx"> 
</span><ins>+  /**
+    The path of the option group.
+    When this property is used, `content` should be sorted by `optionGroupPath`.
+
+    @property optionGroupPath
+    @type String
+    @default null
+  */
+  optionGroupPath: null,
+
+  /**
+    The view class for optgroup.
+
+    @property groupView
+    @type Ember.View
+    @default Ember.SelectOptgroup
+  */
+  groupView: Ember.SelectOptgroup,
+
+  groupedContent: Ember.computed(function() {
+    var groupPath = get(this, 'optionGroupPath');
+    var groupedContent = Ember.A();
+    var content = get(this, 'content') || [];
+
+    forEach(content, function(item) {
+      var label = get(item, groupPath);
+
+      if (get(groupedContent, 'lastObject.label') !== label) {
+        groupedContent.pushObject({
+          label: label,
+          content: Ember.A()
+        });
+      }
+
+      get(groupedContent, 'lastObject.content').push(item);
+    });
+
+    return groupedContent;
+  }).property('optionGroupPath', 'content.@each'),
+
+  /**
+    The view class for option.
+
+    @property optionView
+    @type Ember.View
+    @default Ember.SelectOption
+  */
+  optionView: Ember.SelectOption,
+
</ins><span class="cx">   _change: function() {
</span><span class="cx">     if (get(this, 'multiple')) {
</span><span class="cx">       this._changeMultiple();
</span><span class="lines">@@ -21212,7 +30717,7 @@
</span><span class="cx">     }
</span><span class="cx">   },
</span><span class="cx"> 
</span><del>-  selectionDidChange: Ember.observer(function() {
</del><ins>+  selectionDidChange: Ember.observer('selection.@each', function() {
</ins><span class="cx">     var selection = get(this, 'selection');
</span><span class="cx">     if (get(this, 'multiple')) {
</span><span class="cx">       if (!isArray(selection)) {
</span><span class="lines">@@ -21223,9 +30728,9 @@
</span><span class="cx">     } else {
</span><span class="cx">       this._selectionDidChangeSingle();
</span><span class="cx">     }
</span><del>-  }, 'selection.@each'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><del>-  valueDidChange: Ember.observer(function() {
</del><ins>+  valueDidChange: Ember.observer('value', function() {
</ins><span class="cx">     var content = get(this, 'content'),
</span><span class="cx">         value = get(this, 'value'),
</span><span class="cx">         valuePath = get(this, 'optionValuePath').replace(/^content\.?/, ''),
</span><span class="lines">@@ -21233,21 +30738,21 @@
</span><span class="cx">         selection;
</span><span class="cx"> 
</span><span class="cx">     if (value !== selectedValue) {
</span><del>-      selection = content.find(function(obj) {
</del><ins>+      selection = content ? content.find(function(obj) {
</ins><span class="cx">         return value === (valuePath ? get(obj, valuePath) : obj);
</span><del>-      });
</del><ins>+      }) : null;
</ins><span class="cx"> 
</span><span class="cx">       this.set('selection', selection);
</span><span class="cx">     }
</span><del>-  }, 'value'),
</del><ins>+  }),
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">   _triggerChange: function() {
</span><span class="cx">     var selection = get(this, 'selection');
</span><span class="cx">     var value = get(this, 'value');
</span><span class="cx"> 
</span><del>-    if (selection) { this.selectionDidChange(); }
-    if (value) { this.valueDidChange(); }
</del><ins>+    if (!Ember.isNone(selection)) { this.selectionDidChange(); }
+    if (!Ember.isNone(value)) { this.valueDidChange(); }
</ins><span class="cx"> 
</span><span class="cx">     this._change();
</span><span class="cx">   },
</span><span class="lines">@@ -21257,7 +30762,7 @@
</span><span class="cx">         content = get(this, 'content'),
</span><span class="cx">         prompt = get(this, 'prompt');
</span><span class="cx"> 
</span><del>-    if (!get(content, 'length')) { return; }
</del><ins>+    if (!content || !get(content, 'length')) { return; }
</ins><span class="cx">     if (prompt &amp;&amp; selectedIndex === 0) { set(this, 'selection', null); return; }
</span><span class="cx"> 
</span><span class="cx">     if (prompt) { selectedIndex -= 1; }
</span><span class="lines">@@ -21272,9 +30777,9 @@
</span><span class="cx">         content = get(this, 'content'),
</span><span class="cx">         selection = get(this, 'selection');
</span><span class="cx"> 
</span><del>-    if (!content){ return; }
</del><ins>+    if (!content) { return; }
</ins><span class="cx">     if (options) {
</span><del>-      var selectedIndexes = options.map(function(){
</del><ins>+      var selectedIndexes = options.map(function() {
</ins><span class="cx">         return this.index - offset;
</span><span class="cx">       }).toArray();
</span><span class="cx">       var newSelection = content.objectsAt(selectedIndexes);
</span><span class="lines">@@ -21324,61 +30829,364 @@
</span><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-Ember.SelectOption = Ember.View.extend({
-  tagName: 'option',
-  attributeBindings: ['value', 'selected'],
</del><ins>+})();
</ins><span class="cx"> 
</span><del>-  defaultTemplate: function(context, options) {
-    options = { data: options.data, hash: {} };
-    Ember.Handlebars.helpers.bind.call(context, &quot;view.label&quot;, options);
-  },
</del><span class="cx"> 
</span><del>-  init: function() {
-    this.labelPathDidChange();
-    this.valuePathDidChange();
</del><span class="cx"> 
</span><del>-    this._super();
-  },
</del><ins>+(function() {
+/**
+@module ember
+@submodule ember-handlebars-compiler
+*/
</ins><span class="cx"> 
</span><del>-  selected: Ember.computed(function() {
-    var content = get(this, 'content'),
-        selection = get(this, 'parentView.selection');
-    if (get(this, 'parentView.multiple')) {
-      return selection &amp;&amp; indexOf(selection, content.valueOf()) &gt; -1;
-    } else {
-      // Primitives get passed through bindings as objects... since
-      // `new Number(4) !== 4`, we use `==` below
-      return content == selection;
-    }
-  }).property('content', 'parentView.selection').volatile(),
</del><ins>+/**
</ins><span class="cx"> 
</span><del>-  labelPathDidChange: Ember.observer(function() {
-    var labelPath = get(this, 'parentView.optionLabelPath');
</del><ins>+  The `{{input}}` helper inserts an HTML `&lt;input&gt;` tag into the template,
+  with a `type` value of either `text` or `checkbox`. If no `type` is provided,
+  `text` will be the default value applied. The attributes of `{{input}}`
+  match those of the native HTML tag as closely as possible for these two types.
</ins><span class="cx"> 
</span><del>-    if (!labelPath) { return; }
</del><ins>+  ## Use as text field
+  An `{{input}}` with no `type` or a `type` of `text` will render an HTML text input.
+  The following HTML attributes can be set via the helper:
</ins><span class="cx"> 
</span><del>-    Ember.defineProperty(this, 'label', Ember.computed(function() {
-      return get(this, labelPath);
-    }).property(labelPath));
-  }, 'parentView.optionLabelPath'),
</del><ins>+* `value`
+* `size`
+* `name`
+* `pattern`
+* `placeholder`
+* `disabled`
+* `maxlength`
+* `tabindex`
</ins><span class="cx"> 
</span><del>-  valuePathDidChange: Ember.observer(function() {
-    var valuePath = get(this, 'parentView.optionValuePath');
</del><span class="cx"> 
</span><del>-    if (!valuePath) { return; }
</del><ins>+  When set to a quoted string, these values will be directly applied to the HTML
+  element. When left unquoted, these values will be bound to a property on the
+  template's current rendering context (most typically a controller instance).
</ins><span class="cx"> 
</span><del>-    Ember.defineProperty(this, 'value', Ember.computed(function() {
-      return get(this, valuePath);
-    }).property(valuePath));
-  }, 'parentView.optionValuePath')
</del><ins>+  ## Unbound:
+
+  ```handlebars
+  {{input value=&quot;http://www.facebook.com&quot;}}
+  ```
+
+
+  ```html
+  &lt;input type=&quot;text&quot; value=&quot;http://www.facebook.com&quot;/&gt;
+  ```
+
+  ## Bound:
+
+  ```javascript
+  App.ApplicationController = Ember.Controller.extend({
+    firstName: &quot;Stanley&quot;,
+    entryNotAllowed: true
+  });
+  ```
+
+
+  ```handlebars
+  {{input type=&quot;text&quot; value=firstName disabled=entryNotAllowed size=&quot;50&quot;}}
+  ```
+
+
+  ```html
+  &lt;input type=&quot;text&quot; value=&quot;Stanley&quot; disabled=&quot;disabled&quot; size=&quot;50&quot;/&gt;
+  ```
+
+  ## Extension
+
+  Internally, `{{input type=&quot;text&quot;}}` creates an instance of `Ember.TextField`, passing
+  arguments from the helper to `Ember.TextField`'s `create` method. You can extend the
+  capablilties of text inputs in your applications by reopening this class. For example,
+  if you are deploying to browsers where the `required` attribute is used, you
+  can add this to the `TextField`'s `attributeBindings` property:
+
+
+  ```javascript
+  Ember.TextField.reopen({
+    attributeBindings: ['required']
+  });
+  ```
+
+  Keep in mind when writing `Ember.TextField` subclasses that `Ember.TextField`
+  itself extends `Ember.Component`, meaning that it does NOT inherit
+  the `controller` of the parent view.
+
+  See more about [Ember components](api/classes/Ember.Component.html)
+
+
+  ## Use as checkbox
+
+  An `{{input}}` with a `type` of `checkbox` will render an HTML checkbox input.
+  The following HTML attributes can be set via the helper:
+
+* `checked`
+* `disabled`
+* `tabindex`
+* `indeterminate`
+* `name`
+
+
+  When set to a quoted string, these values will be directly applied to the HTML
+  element. When left unquoted, these values will be bound to a property on the
+  template's current rendering context (most typically a controller instance).
+
+  ## Unbound:
+
+  ```handlebars
+  {{input type=&quot;checkbox&quot; name=&quot;isAdmin&quot;}}
+  ```
+
+  ```html
+  &lt;input type=&quot;checkbox&quot; name=&quot;isAdmin&quot; /&gt;
+  ```
+
+  ## Bound:
+
+  ```javascript
+  App.ApplicationController = Ember.Controller.extend({
+    isAdmin: true
+  });
+  ```
+
+
+  ```handlebars
+  {{input type=&quot;checkbox&quot; checked=isAdmin }}
+  ```
+
+
+  ```html
+  &lt;input type=&quot;checkbox&quot; checked=&quot;checked&quot; /&gt;
+  ```
+
+  ## Extension
+
+  Internally, `{{input type=&quot;checkbox&quot;}}` creates an instance of `Ember.Checkbox`, passing
+  arguments from the helper to `Ember.Checkbox`'s `create` method. You can extend the
+  capablilties of checkbox inputs in your applications by reopening this class. For example,
+  if you wanted to add a css class to all checkboxes in your application:
+
+
+  ```javascript
+  Ember.Checkbox.reopen({
+    classNames: ['my-app-checkbox']
+  });
+  ```
+
+
+  @method input
+  @for Ember.Handlebars.helpers
+  @param {Hash} options
+*/
+Ember.Handlebars.registerHelper('input', function(options) {
+  Ember.assert('You can only pass attributes to the `input` helper, not arguments', arguments.length &lt; 2);
+
+  var hash = options.hash,
+      types = options.hashTypes,
+      inputType = hash.type,
+      onEvent = hash.on;
+
+  delete hash.type;
+  delete hash.on;
+
+  if (inputType === 'checkbox') {
+    return Ember.Handlebars.helpers.view.call(this, Ember.Checkbox, options);
+  } else {
+    if (inputType) { hash.type = inputType; }
+    hash.onEvent = onEvent || 'enter';
+    return Ember.Handlebars.helpers.view.call(this, Ember.TextField, options);
+  }
</ins><span class="cx"> });
</span><span class="cx"> 
</span><ins>+/**
+  `{{textarea}}` inserts a new instance of `&lt;textarea&gt;` tag into the template.
+  The attributes of `{{textarea}}` match those of the native HTML tags as
+  closely as possible.
+
+  The following HTML attributes can be set:
+
+    * `value`
+    * `name`
+    * `rows`
+    * `cols`
+    * `placeholder`
+    * `disabled`
+    * `maxlength`
+    * `tabindex`
+
+  When set to a quoted string, these value will be directly applied to the HTML
+  element. When left unquoted, these values will be bound to a property on the
+  template's current rendering context (most typically a controller instance).
+
+  Unbound:
+
+  ```handlebars
+  {{textarea value=&quot;Lots of static text that ISN'T bound&quot;}}
+  ```
+
+  Would result in the following HTML:
+
+  ```html
+  &lt;textarea class=&quot;ember-text-area&quot;&gt;
+    Lots of static text that ISN'T bound
+  &lt;/textarea&gt;
+  ```
+
+  Bound:
+
+  In the following example, the `writtenWords` property on `App.ApplicationController`
+  will be updated live as the user types 'Lots of text that IS bound' into
+  the text area of their browser's window.
+
+  ```javascript
+  App.ApplicationController = Ember.Controller.extend({
+    writtenWords: &quot;Lots of text that IS bound&quot;
+  });
+  ```
+
+  ```handlebars
+  {{textarea value=writtenWords}}
+  ```
+
+   Would result in the following HTML:
+
+  ```html
+  &lt;textarea class=&quot;ember-text-area&quot;&gt;
+    Lots of text that IS bound
+  &lt;/textarea&gt;
+  ```
+
+  If you wanted a one way binding between the text area and a div tag
+  somewhere else on your screen, you could use `Ember.computed.oneWay`:
+
+  ```javascript
+  App.ApplicationController = Ember.Controller.extend({
+    writtenWords: &quot;Lots of text that IS bound&quot;,
+    outputWrittenWords: Ember.computed.oneWay(&quot;writtenWords&quot;)
+  });
+  ```
+
+  ```handlebars
+  {{textarea value=writtenWords}}
+
+  &lt;div&gt;
+    {{outputWrittenWords}}
+  &lt;/div&gt;
+  ```
+
+  Would result in the following HTML:
+
+  ```html
+  &lt;textarea class=&quot;ember-text-area&quot;&gt;
+    Lots of text that IS bound
+  &lt;/textarea&gt;
+
+  &lt;-- the following div will be updated in real time as you type --&gt;
+
+  &lt;div&gt;
+    Lots of text that IS bound
+  &lt;/div&gt;
+  ```
+
+  Finally, this example really shows the power and ease of Ember when two
+  properties are bound to eachother via `Ember.computed.alias`. Type into
+  either text area box and they'll both stay in sync. Note that
+  `Ember.computed.alias` costs more in terms of performance, so only use it when
+  your really binding in both directions:
+
+  ```javascript
+  App.ApplicationController = Ember.Controller.extend({
+    writtenWords: &quot;Lots of text that IS bound&quot;,
+    twoWayWrittenWords: Ember.computed.alias(&quot;writtenWords&quot;)
+  });
+  ```
+
+  ```handlebars
+  {{textarea value=writtenWords}}
+  {{textarea value=twoWayWrittenWords}}
+  ```
+
+  ```html
+  &lt;textarea id=&quot;ember1&quot; class=&quot;ember-text-area&quot;&gt;
+    Lots of text that IS bound
+  &lt;/textarea&gt;
+
+  &lt;-- both updated in real time --&gt;
+
+  &lt;textarea id=&quot;ember2&quot; class=&quot;ember-text-area&quot;&gt;
+    Lots of text that IS bound
+  &lt;/textarea&gt;
+  ```
+
+  ## Extension
+
+  Internally, `{{textarea}}` creates an instance of `Ember.TextArea`, passing
+  arguments from the helper to `Ember.TextArea`'s `create` method. You can
+  extend the capabilities of text areas in your application by reopening this
+  class. For example, if you are deploying to browsers where the `required`
+  attribute is used, you can globally add support for the `required` attribute
+  on all `{{textarea}}`s' in your app by reopening `Ember.TextArea` or
+  `Ember.TextSupport` and adding it to the `attributeBindings` concatenated
+  property:
+
+  ```javascript
+  Ember.TextArea.reopen({
+    attributeBindings: ['required']
+  });
+  ```
+
+  Keep in mind when writing `Ember.TextArea` subclasses that `Ember.TextArea`
+  itself extends `Ember.Component`, meaning that it does NOT inherit
+  the `controller` of the parent view.
+
+  See more about [Ember components](api/classes/Ember.Component.html)
+
+  @method textarea
+  @for Ember.Handlebars.helpers
+  @param {Hash} options
+*/
+Ember.Handlebars.registerHelper('textarea', function(options) {
+  Ember.assert('You can only pass attributes to the `textarea` helper, not arguments', arguments.length &lt; 2);
+
+  var hash = options.hash,
+      types = options.hashTypes;
+
+  return Ember.Handlebars.helpers.view.call(this, Ember.TextArea, options);
+});
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><ins>+Ember.ComponentLookup = Ember.Object.extend({
+  lookupFactory: function(name, container) {
</ins><span class="cx"> 
</span><ins>+    container = container || this.container;
+
+    var fullName = 'component:' + name,
+        templateFullName = 'template:components/' + name,
+        templateRegistered = container &amp;&amp; container.has(templateFullName);
+
+    if (templateRegistered) {
+      container.injection(fullName, 'layout', templateFullName);
+    }
+
+    var Component = container.lookupFactory(fullName);
+
+    // Only treat as a component if either the component
+    // or a template has been registered.
+    if (templateRegistered || Component) {
+      if (!Component) {
+        container.register(fullName, Ember.Component);
+        Component = container.lookupFactory(fullName);
+      }
+      return Component;
+    }
+  }
+});
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -21391,8 +31199,6 @@
</span><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   Find templates stored in the head tag as script tags and make them available
</span><span class="cx">   to `Ember.CoreView` in the global `Ember.TEMPLATES` object. This will be run
</span><span class="cx">   as as jQuery DOM-ready callback.
</span><span class="lines">@@ -21402,6 +31208,7 @@
</span><span class="cx">   Those with type `text/x-raw-handlebars` will be compiled with regular
</span><span class="cx">   Handlebars and are suitable for use in views' computed properties.
</span><span class="cx"> 
</span><ins>+  @private
</ins><span class="cx">   @method bootstrap
</span><span class="cx">   @for Ember.Handlebars
</span><span class="cx">   @static
</span><span class="lines">@@ -21413,8 +31220,7 @@
</span><span class="cx">   Ember.$(selectors, ctx)
</span><span class="cx">     .each(function() {
</span><span class="cx">     // Get a reference to the script tag
</span><del>-    var script = Ember.$(this),
-        type   = script.attr('type');
</del><ins>+    var script = Ember.$(this);
</ins><span class="cx"> 
</span><span class="cx">     var compile = (script.attr('type') === 'text/x-raw-handlebars') ?
</span><span class="cx">                   Ember.$.proxy(Handlebars.compile, Handlebars) :
</span><span class="lines">@@ -21425,6 +31231,11 @@
</span><span class="cx">       templateName = script.attr('data-template-name') || script.attr('id') || 'application',
</span><span class="cx">       template = compile(script.html());
</span><span class="cx"> 
</span><ins>+    // Check if template of same name already exists
+    if (Ember.TEMPLATES[templateName] !== undefined) {
+      throw new Ember.Error('Template named &quot;' + templateName  + '&quot; already exists.');
+    }
+
</ins><span class="cx">     // For templates which have a name, we save them and then remove them from the DOM
</span><span class="cx">     Ember.TEMPLATES[templateName] = template;
</span><span class="cx"> 
</span><span class="lines">@@ -21437,6 +31248,10 @@
</span><span class="cx">   Ember.Handlebars.bootstrap( Ember.$(document) );
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+function registerComponentLookup(container) {
+  container.register('component-lookup:main', Ember.ComponentLookup);
+}
+
</ins><span class="cx"> /*
</span><span class="cx">   We tie this to application.load to ensure that we've at least
</span><span class="cx">   attempted to bootstrap at the point that the application is loaded.
</span><span class="lines">@@ -21448,8 +31263,19 @@
</span><span class="cx">   from the DOM after processing.
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-Ember.onLoad('application', bootstrap);
</del><ins>+Ember.onLoad('Ember.Application', function(Application) {
+  Application.initializer({
+    name: 'domTemplates',
+    initialize: bootstrap
+  });
</ins><span class="cx"> 
</span><ins>+  Application.initializer({
+    name: 'registerComponentLookup',
+    after: 'domTemplates',
+    initialize: registerComponentLookup
+  });
+});
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -21702,7 +31528,7 @@
</span><span class="cx">       return states.sort(function(a, b) {
</span><span class="cx">         if (a.types.stars !== b.types.stars) { return a.types.stars - b.types.stars; }
</span><span class="cx">         if (a.types.dynamics !== b.types.dynamics) { return a.types.dynamics - b.types.dynamics; }
</span><del>-        if (a.types.statics !== b.types.statics) { return a.types.statics - b.types.statics; }
</del><ins>+        if (a.types.statics !== b.types.statics) { return b.types.statics - a.types.statics; }
</ins><span class="cx"> 
</span><span class="cx">         return 0;
</span><span class="cx">       });
</span><span class="lines">@@ -21720,19 +31546,31 @@
</span><span class="cx">       return nextStates;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    function findHandler(state, path) {
</del><ins>+    function findHandler(state, path, queryParams) {
</ins><span class="cx">       var handlers = state.handlers, regex = state.regex;
</span><span class="cx">       var captures = path.match(regex), currentCapture = 1;
</span><span class="cx">       var result = [];
</span><span class="cx"> 
</span><span class="cx">       for (var i=0, l=handlers.length; i&lt;l; i++) {
</span><del>-        var handler = handlers[i], names = handler.names, params = {};
</del><ins>+        var handler = handlers[i], names = handler.names, params = {},
+          watchedQueryParams = handler.queryParams || [],
+          activeQueryParams = {},
+          j, m;
</ins><span class="cx"> 
</span><del>-        for (var j=0, m=names.length; j&lt;m; j++) {
</del><ins>+        for (j=0, m=names.length; j&lt;m; j++) {
</ins><span class="cx">           params[names[j]] = captures[currentCapture++];
</span><span class="cx">         }
</span><del>-
-        result.push({ handler: handler.handler, params: params, isDynamic: !!names.length });
</del><ins>+        for (j=0, m=watchedQueryParams.length; j &lt; m; j++) {
+          var key = watchedQueryParams[j];
+          if(queryParams[key]){
+            activeQueryParams[key] = queryParams[key];
+          }
+        }
+        var currentResult = { handler: handler.handler, params: params, isDynamic: !!names.length };
+        if(watchedQueryParams &amp;&amp; watchedQueryParams.length &gt; 0) {
+          currentResult.queryParams = activeQueryParams;
+        }
+        result.push(currentResult);
</ins><span class="cx">       }
</span><span class="cx"> 
</span><span class="cx">       return result;
</span><span class="lines">@@ -21787,7 +31625,11 @@
</span><span class="cx">             regex += segment.regex();
</span><span class="cx">           }
</span><span class="cx"> 
</span><del>-          handlers.push({ handler: route.handler, names: names });
</del><ins>+          var handler = { handler: route.handler, names: names };
+          if(route.queryParams) {
+            handler.queryParams = route.queryParams;
+          }
+          handlers.push(handler);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (isEmpty) {
</span><span class="lines">@@ -21839,18 +31681,67 @@
</span><span class="cx"> 
</span><span class="cx">         if (output.charAt(0) !== '/') { output = '/' + output; }
</span><span class="cx"> 
</span><ins>+        if (params &amp;&amp; params.queryParams) {
+          output += this.generateQueryString(params.queryParams, route.handlers);
+        }
+
</ins><span class="cx">         return output;
</span><span class="cx">       },
</span><span class="cx"> 
</span><ins>+      generateQueryString: function(params, handlers) {
+        var pairs = [], allowedParams = [];
+        for(var i=0; i &lt; handlers.length; i++) {
+          var currentParamList = handlers[i].queryParams;
+          if(currentParamList) {
+            allowedParams.push.apply(allowedParams, currentParamList);
+          }
+        }
+        for(var key in params) {
+          if (params.hasOwnProperty(key)) {
+            if(allowedParams.indexOf(key) === -1) {
+              throw 'Query param &quot;' + key + '&quot; is not specified as a valid param for this route';
+            }
+            var value = params[key];
+            var pair = encodeURIComponent(key);
+            if(value !== true) {
+              pair += &quot;=&quot; + encodeURIComponent(value);
+            }
+            pairs.push(pair);
+          }
+        }
+
+        if (pairs.length === 0) { return ''; }
+
+        return &quot;?&quot; + pairs.join(&quot;&amp;&quot;);
+      },
+
+      parseQueryString: function(queryString) {
+        var pairs = queryString.split(&quot;&amp;&quot;), queryParams = {};
+        for(var i=0; i &lt; pairs.length; i++) {
+          var pair      = pairs[i].split('='),
+              key       = decodeURIComponent(pair[0]),
+              value     = pair[1] ? decodeURIComponent(pair[1]) : true;
+          queryParams[key] = value;
+        }
+        return queryParams;
+      },
+
</ins><span class="cx">       recognize: function(path) {
</span><del>-        var states = [ this.rootState ], i, l;
</del><ins>+        var states = [ this.rootState ],
+            pathLen, i, l, queryStart, queryParams = {};
</ins><span class="cx"> 
</span><ins>+        queryStart = path.indexOf('?');
+        if (queryStart !== -1) {
+          var queryString = path.substr(queryStart + 1, path.length);
+          path = path.substr(0, queryStart);
+          queryParams = this.parseQueryString(queryString);
+        }
+
</ins><span class="cx">         // DEBUG GROUP path
</span><span class="cx"> 
</span><del>-        var pathLen = path.length;
-
</del><span class="cx">         if (path.charAt(0) !== &quot;/&quot;) { path = &quot;/&quot; + path; }
</span><span class="cx"> 
</span><ins>+        pathLen = path.length;
</ins><span class="cx">         if (pathLen &gt; 1 &amp;&amp; path.charAt(pathLen - 1) === &quot;/&quot;) {
</span><span class="cx">           path = path.substr(0, pathLen - 1);
</span><span class="cx">         }
</span><span class="lines">@@ -21872,7 +31763,7 @@
</span><span class="cx">         var state = solutions[0];
</span><span class="cx"> 
</span><span class="cx">         if (state &amp;&amp; state.handlers) {
</span><del>-          return findHandler(state, path);
</del><ins>+          return findHandler(state, path, queryParams);
</ins><span class="cx">         }
</span><span class="cx">       }
</span><span class="cx">     };
</span><span class="lines">@@ -21897,12 +31788,25 @@
</span><span class="cx">           if (callback.length === 0) { throw new Error(&quot;You must have an argument in the function passed to `to`&quot;); }
</span><span class="cx">           this.matcher.addChild(this.path, target, callback, this.delegate);
</span><span class="cx">         }
</span><ins>+        return this;
+      },
+
+      withQueryParams: function() {
+        if (arguments.length === 0) { throw new Error(&quot;you must provide arguments to the withQueryParams method&quot;); }
+        for (var i = 0; i &lt; arguments.length; i++) {
+          if (typeof arguments[i] !== &quot;string&quot;) {
+            throw new Error('you should call withQueryParams with a list of strings, e.g. withQueryParams(&quot;foo&quot;, &quot;bar&quot;)');
+          }
+        }
+        var queryParams = [].slice.call(arguments);
+        this.matcher.addQueryParams(this.path, queryParams);
</ins><span class="cx">       }
</span><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     function Matcher(target) {
</span><span class="cx">       this.routes = {};
</span><span class="cx">       this.children = {};
</span><ins>+      this.queryParams = {};
</ins><span class="cx">       this.target = target;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -21911,6 +31815,10 @@
</span><span class="cx">         this.routes[path] = handler;
</span><span class="cx">       },
</span><span class="cx"> 
</span><ins>+      addQueryParams: function(path, params) {
+        this.queryParams[path] = params;
+      },
+
</ins><span class="cx">       addChild: function(path, target, callback, delegate) {
</span><span class="cx">         var matcher = new Matcher(target);
</span><span class="cx">         this.children[path] = matcher;
</span><span class="lines">@@ -21937,23 +31845,26 @@
</span><span class="cx">       };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    function addRoute(routeArray, path, handler) {
</del><ins>+    function addRoute(routeArray, path, handler, queryParams) {
</ins><span class="cx">       var len = 0;
</span><span class="cx">       for (var i=0, l=routeArray.length; i&lt;l; i++) {
</span><span class="cx">         len += routeArray[i].path.length;
</span><span class="cx">       }
</span><span class="cx"> 
</span><span class="cx">       path = path.substr(len);
</span><del>-      routeArray.push({ path: path, handler: handler });
</del><ins>+      var route = { path: path, handler: handler };
+      if(queryParams) { route.queryParams = queryParams; }
+      routeArray.push(route);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     function eachRoute(baseRoute, matcher, callback, binding) {
</span><span class="cx">       var routes = matcher.routes;
</span><ins>+      var queryParams = matcher.queryParams;
</ins><span class="cx"> 
</span><span class="cx">       for (var path in routes) {
</span><span class="cx">         if (routes.hasOwnProperty(path)) {
</span><span class="cx">           var routeArray = baseRoute.slice();
</span><del>-          addRoute(routeArray, path, routes[path]);
</del><ins>+          addRoute(routeArray, path, routes[path], queryParams[path]);
</ins><span class="cx"> 
</span><span class="cx">           if (matcher.children[path]) {
</span><span class="cx">             eachRoute(routeArray, matcher.children[path], callback, binding);
</span><span class="lines">@@ -21983,8 +31894,8 @@
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><span class="cx"> define(&quot;router&quot;,
</span><del>-  [&quot;route-recognizer&quot;],
-  function(RouteRecognizer) {
</del><ins>+  [&quot;route-recognizer&quot;,&quot;rsvp&quot;,&quot;exports&quot;],
+  function(__dependency1__, __dependency2__, __exports__) {
</ins><span class="cx">     &quot;use strict&quot;;
</span><span class="cx">     /**
</span><span class="cx">       @private
</span><span class="lines">@@ -21996,26 +31907,192 @@
</span><span class="cx">       * `{String} handler`: A handler name
</span><span class="cx">       * `{Object} params`: A hash of recognized parameters
</span><span class="cx"> 
</span><del>-      ## `UnresolvedHandlerInfo`
</del><ins>+      ## `HandlerInfo`
</ins><span class="cx"> 
</span><span class="cx">       * `{Boolean} isDynamic`: whether a handler has any dynamic segments
</span><span class="cx">       * `{String} name`: the name of a handler
</span><del>-      * `{Object} context`: the active context for the handler
-
-      ## `HandlerInfo`
-
-      * `{Boolean} isDynamic`: whether a handler has any dynamic segments
-      * `{String} name`: the original unresolved handler name
</del><span class="cx">       * `{Object} handler`: a handler object
</span><span class="cx">       * `{Object} context`: the active context for the handler
</span><span class="cx">     */
</span><span class="cx"> 
</span><ins>+    var RouteRecognizer = __dependency1__;
+    var RSVP = __dependency2__;
</ins><span class="cx"> 
</span><ins>+    var slice = Array.prototype.slice;
+
+
+
+    /**
+      @private
+
+      A Transition is a thennable (a promise-like object) that represents
+      an attempt to transition to another route. It can be aborted, either
+      explicitly via `abort` or by attempting another transition while a
+      previous one is still underway. An aborted transition can also
+      be `retry()`d later.
+     */
+
+    function Transition(router, promise) {
+      this.router = router;
+      this.promise = promise;
+      this.data = {};
+      this.resolvedModels = {};
+      this.providedModels = {};
+      this.providedModelsArray = [];
+      this.sequence = ++Transition.currentSequence;
+      this.params = {};
+    }
+
+    Transition.currentSequence = 0;
+
+    Transition.prototype = {
+      targetName: null,
+      urlMethod: 'update',
+      providedModels: null,
+      resolvedModels: null,
+      params: null,
+      pivotHandler: null,
+      resolveIndex: 0,
+      handlerInfos: null,
+
+      isActive: true,
+
+      /**
+        The Transition's internal promise. Calling `.then` on this property
+        is that same as calling `.then` on the Transition object itself, but
+        this property is exposed for when you want to pass around a
+        Transition's promise, but not the Transition object itself, since
+        Transition object can be externally `abort`ed, while the promise
+        cannot.
+       */
+      promise: null,
+
+      /**
+        Custom state can be stored on a Transition's `data` object.
+        This can be useful for decorating a Transition within an earlier
+        hook and shared with a later hook. Properties set on `data` will
+        be copied to new transitions generated by calling `retry` on this
+        transition.
+       */
+      data: null,
+
+      /**
+        A standard promise hook that resolves if the transition
+        succeeds and rejects if it fails/redirects/aborts.
+
+        Forwards to the internal `promise` property which you can
+        use in situations where you want to pass around a thennable,
+        but not the Transition itself.
+
+        @param {Function} success
+        @param {Function} failure
+       */
+      then: function(success, failure) {
+        return this.promise.then(success, failure);
+      },
+
+      /**
+        Aborts the Transition. Note you can also implicitly abort a transition
+        by initiating another transition while a previous one is underway.
+       */
+      abort: function() {
+        if (this.isAborted) { return this; }
+        log(this.router, this.sequence, this.targetName + &quot;: transition was aborted&quot;);
+        this.isAborted = true;
+        this.isActive = false;
+        this.router.activeTransition = null;
+        return this;
+      },
+
+      /**
+        Retries a previously-aborted transition (making sure to abort the
+        transition if it's still active). Returns a new transition that
+        represents the new attempt to transition.
+       */
+      retry: function() {
+        this.abort();
+        var recogHandlers = this.router.recognizer.handlersFor(this.targetName),
+            handlerInfos  = generateHandlerInfosWithQueryParams(this.router, recogHandlers, this.queryParams),
+            newTransition = performTransition(this.router, handlerInfos, this.providedModelsArray, this.params, this.queryParams, this.data);
+
+        return newTransition;
+      },
+
+      /**
+        Sets the URL-changing method to be employed at the end of a
+        successful transition. By default, a new Transition will just
+        use `updateURL`, but passing 'replace' to this method will
+        cause the URL to update using 'replaceWith' instead. Omitting
+        a parameter will disable the URL change, allowing for transitions
+        that don't update the URL at completion (this is also used for
+        handleURL, since the URL has already changed before the
+        transition took place).
+
+        @param {String} method the type of URL-changing method to use
+          at the end of a transition. Accepted values are 'replace',
+          falsy values, or any other non-falsy value (which is
+          interpreted as an updateURL transition).
+
+        @return {Transition} this transition
+       */
+      method: function(method) {
+        this.urlMethod = method;
+        return this;
+      },
+
+      /**
+        Fires an event on the current list of resolved/resolving
+        handlers within this transition. Useful for firing events
+        on route hierarchies that haven't fully been entered yet.
+
+        @param {Boolean} ignoreFailure the name of the event to fire
+        @param {String} name the name of the event to fire
+       */
+      trigger: function(ignoreFailure) {
+        var args = slice.call(arguments);
+        if (typeof ignoreFailure === 'boolean') {
+          args.shift();
+        } else {
+          // Throw errors on unhandled trigger events by default
+          ignoreFailure = false;
+        }
+        trigger(this.router, this.handlerInfos.slice(0, this.resolveIndex + 1), ignoreFailure, args);
+      },
+
+      toString: function() {
+        return &quot;Transition (sequence &quot; + this.sequence + &quot;)&quot;;
+      }
+    };
+
</ins><span class="cx">     function Router() {
</span><span class="cx">       this.recognizer = new RouteRecognizer();
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // TODO: separate into module?
+    Router.Transition = Transition;
</ins><span class="cx"> 
</span><ins>+    __exports__[&quot;default&quot;] = Router;
+
+
+    /**
+      Promise reject reasons passed to promise rejection
+      handlers for failed transitions.
+     */
+    Router.UnrecognizedURLError = function(message) {
+      this.message = (message || &quot;UnrecognizedURLError&quot;);
+      this.name = &quot;UnrecognizedURLError&quot;;
+    };
+
+    Router.TransitionAborted = function(message) {
+      this.message = (message || &quot;TransitionAborted&quot;);
+      this.name = &quot;TransitionAborted&quot;;
+    };
+
+    function errorTransition(router, reason) {
+      return new Transition(router, RSVP.reject(reason));
+    }
+
+
</ins><span class="cx">     Router.prototype = {
</span><span class="cx">       /**
</span><span class="cx">         The main entry point into the router. The API is essentially
</span><span class="lines">@@ -22041,6 +32118,25 @@
</span><span class="cx">       },
</span><span class="cx"> 
</span><span class="cx">       /**
</span><ins>+        Clears the current and target route handlers and triggers exit
+        on each of them starting at the leaf and traversing up through
+        its ancestors.
+      */
+      reset: function() {
+        eachHandler(this.currentHandlerInfos || [], function(handlerInfo) {
+          var handler = handlerInfo.handler;
+          if (handler.exit) {
+            handler.exit();
+          }
+        });
+        this.currentHandlerInfos = null;
+        this.targetHandlerInfos = null;
+      },
+
+      activeTransition: null,
+
+      /**
+        var handler = handlerInfo.handler;
</ins><span class="cx">         The entry point for handling a change to the URL (usually
</span><span class="cx">         via the back and forward button).
</span><span class="cx"> 
</span><span class="lines">@@ -22052,14 +32148,11 @@
</span><span class="cx">         @return {Array} an Array of `[handler, parameter]` tuples
</span><span class="cx">       */
</span><span class="cx">       handleURL: function(url) {
</span><del>-        var results = this.recognizer.recognize(url),
-            objects = [];
-
-        if (!results) {
-          throw new Error(&quot;No route matched the URL '&quot; + url + &quot;'&quot;);
-        }
-
-        collectObjects(this, results, 0, []);
</del><ins>+        // Perform a URL-based transition, but don't change
+        // the URL afterward, since it already happened.
+        var args = slice.call(arguments);
+        if (url.charAt(0) !== '/') { args[0] = '/' + url; }
+        return doTransition(this, args).method(null);
</ins><span class="cx">       },
</span><span class="cx"> 
</span><span class="cx">       /**
</span><span class="lines">@@ -22068,7 +32161,7 @@
</span><span class="cx">         @param {String} url a URL to update to
</span><span class="cx">       */
</span><span class="cx">       updateURL: function() {
</span><del>-        throw &quot;updateURL is not implemented&quot;;
</del><ins>+        throw new Error(&quot;updateURL is not implemented&quot;);
</ins><span class="cx">       },
</span><span class="cx"> 
</span><span class="cx">       /**
</span><span class="lines">@@ -22091,10 +32184,13 @@
</span><span class="cx">         @param {String} name the name of the route
</span><span class="cx">       */
</span><span class="cx">       transitionTo: function(name) {
</span><del>-        var args = Array.prototype.slice.call(arguments, 1);
-        doTransition(this, name, this.updateURL, args);
</del><ins>+        return doTransition(this, arguments);
</ins><span class="cx">       },
</span><span class="cx"> 
</span><ins>+      intermediateTransitionTo: function(name) {
+        doTransition(this, arguments, true);
+      },
+
</ins><span class="cx">       /**
</span><span class="cx">         Identical to `transitionTo` except that the current URL will be replaced
</span><span class="cx">         if possible.
</span><span class="lines">@@ -22104,8 +32200,7 @@
</span><span class="cx">         @param {String} name the name of the route
</span><span class="cx">       */
</span><span class="cx">       replaceWith: function(name) {
</span><del>-        var args = Array.prototype.slice.call(arguments, 1);
-        doTransition(this, name, this.replaceURL, args);
</del><ins>+        return doTransition(this, arguments).method('replace');
</ins><span class="cx">       },
</span><span class="cx"> 
</span><span class="cx">       /**
</span><span class="lines">@@ -22118,12 +32213,24 @@
</span><span class="cx">         @param {Array[Object]} contexts
</span><span class="cx">         @return {Object} a serialized parameter hash
</span><span class="cx">       */
</span><del>-      paramsForHandler: function(handlerName, callback) {
-        var output = this._paramsForHandler(handlerName, [].slice.call(arguments, 1));
-        return output.params;
</del><ins>+
+      paramsForHandler: function(handlerName, contexts) {
+        var partitionedArgs = extractQueryParams(slice.call(arguments, 1));
+        return paramsForHandler(this, handlerName, partitionedArgs[0], partitionedArgs[1]);
</ins><span class="cx">       },
</span><span class="cx"> 
</span><span class="cx">       /**
</span><ins>+        This method takes a handler name and returns a list of query params
+        that are valid to pass to the handler or its parents
+
+        @param {String} handlerName
+        @return {Array[String]} a list of query parameters
+      */
+      queryParamsForHandler: function (handlerName) {
+        return queryParamsForHandler(this, handlerName);
+      },
+
+      /**
</ins><span class="cx">         Take a named route and context objects and generate a
</span><span class="cx">         URL.
</span><span class="cx"> 
</span><span class="lines">@@ -22134,262 +32241,390 @@
</span><span class="cx">         @return {String} a URL
</span><span class="cx">       */
</span><span class="cx">       generate: function(handlerName) {
</span><del>-        var params = this.paramsForHandler.apply(this, arguments);
-        return this.recognizer.generate(handlerName, params);
-      },
</del><ins>+        var partitionedArgs = extractQueryParams(slice.call(arguments, 1)),
+          suppliedParams = partitionedArgs[0],
+          queryParams = partitionedArgs[1];
</ins><span class="cx"> 
</span><del>-      /**
-        @private
</del><ins>+        var params = paramsForHandler(this, handlerName, suppliedParams, queryParams),
+          validQueryParams = queryParamsForHandler(this, handlerName);
</ins><span class="cx"> 
</span><del>-        Used internally by `generate` and `transitionTo`.
-      */
-      _paramsForHandler: function(handlerName, objects, doUpdate) {
-        var handlers = this.recognizer.handlersFor(handlerName),
-            params = {},
-            toSetup = [],
-            startIdx = handlers.length,
-            objectsToMatch = objects.length,
-            object, objectChanged, handlerObj, handler, names, i, len;
</del><ins>+        var missingParams = [];
</ins><span class="cx"> 
</span><del>-        // Find out which handler to start matching at
-        for (i=handlers.length-1; i&gt;=0 &amp;&amp; objectsToMatch&gt;0; i--) {
-          if (handlers[i].names.length) {
-            objectsToMatch--;
-            startIdx = i;
</del><ins>+        for (var key in queryParams) {
+          if (queryParams.hasOwnProperty(key) &amp;&amp; !~validQueryParams.indexOf(key)) {
+            missingParams.push(key);
</ins><span class="cx">           }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (objectsToMatch &gt; 0) {
-          throw &quot;More objects were passed than dynamic segments&quot;;
-        }
</del><ins>+        if (missingParams.length &gt; 0) {
+          var err = 'You supplied the params ';
+          err += missingParams.map(function(param) {
+            return '&quot;' + param + &quot;=&quot; + queryParams[param] + '&quot;';
+          }).join(' and ');
</ins><span class="cx"> 
</span><del>-        // Connect the objects to the routes
-        for (i=0, len=handlers.length; i&lt;len; i++) {
-          handlerObj = handlers[i];
-          handler = this.getHandler(handlerObj.handler);
-          names = handlerObj.names;
-          objectChanged = false;
</del><ins>+          err += ' which are not valid for the &quot;' + handlerName + '&quot; handler or its parents';
</ins><span class="cx"> 
</span><del>-          // If it's a dynamic segment
-          if (names.length) {
-            // If we have objects, use them
-            if (i &gt;= startIdx) {
-              object = objects.shift();
-              objectChanged = true;
-            // Otherwise use existing context
-            } else {
-              object = handler.context;
-            }
-
-            // Serialize to generate params
-            if (handler.serialize) {
-              merge(params, handler.serialize(object, names));
-            }
-          // If it's not a dynamic segment and we're updating
-          } else if (doUpdate) {
-            // If we've passed the match point we need to deserialize again
-            // or if we never had a context
-            if (i &gt; startIdx || !handler.hasOwnProperty('context')) {
-              if (handler.deserialize) {
-                object = handler.deserialize({});
-                objectChanged = true;
-              }
-            // Otherwise use existing context
-            } else {
-              object = handler.context;
-            }
-          }
-
-          // Make sure that we update the context here so it's available to
-          // subsequent deserialize calls
-          if (doUpdate &amp;&amp; objectChanged) {
-            // TODO: It's a bit awkward to set the context twice, see if we can DRY things up
-            setContext(handler, object);
-          }
-
-          toSetup.push({
-            isDynamic: !!handlerObj.names.length,
-            handler: handlerObj.handler,
-            name: handlerObj.name,
-            context: object
-          });
</del><ins>+          throw new Error(err);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        return { params: params, toSetup: toSetup };
</del><ins>+        return this.recognizer.generate(handlerName, params);
</ins><span class="cx">       },
</span><span class="cx"> 
</span><span class="cx">       isActive: function(handlerName) {
</span><del>-        var contexts = [].slice.call(arguments, 1);
</del><ins>+        var partitionedArgs   = extractQueryParams(slice.call(arguments, 1)),
+            contexts          = partitionedArgs[0],
+            queryParams       = partitionedArgs[1],
+            activeQueryParams  = {},
+            effectiveQueryParams = {};
</ins><span class="cx"> 
</span><del>-        var currentHandlerInfos = this.currentHandlerInfos,
</del><ins>+        var targetHandlerInfos = this.targetHandlerInfos,
</ins><span class="cx">             found = false, names, object, handlerInfo, handlerObj;
</span><span class="cx"> 
</span><del>-        for (var i=currentHandlerInfos.length-1; i&gt;=0; i--) {
-          handlerInfo = currentHandlerInfos[i];
</del><ins>+        if (!targetHandlerInfos) { return false; }
+
+        var recogHandlers = this.recognizer.handlersFor(targetHandlerInfos[targetHandlerInfos.length - 1].name);
+        for (var i=targetHandlerInfos.length-1; i&gt;=0; i--) {
+          handlerInfo = targetHandlerInfos[i];
</ins><span class="cx">           if (handlerInfo.name === handlerName) { found = true; }
</span><span class="cx"> 
</span><span class="cx">           if (found) {
</span><del>-            if (contexts.length === 0) { break; }
</del><ins>+            var recogHandler = recogHandlers[i];
</ins><span class="cx"> 
</span><del>-            if (handlerInfo.isDynamic) {
</del><ins>+            merge(activeQueryParams, handlerInfo.queryParams);
+            if (queryParams !== false) {
+              merge(effectiveQueryParams, handlerInfo.queryParams);
+              mergeSomeKeys(effectiveQueryParams, queryParams, recogHandler.queryParams);
+            }
+
+            if (handlerInfo.isDynamic &amp;&amp; contexts.length &gt; 0) {
</ins><span class="cx">               object = contexts.pop();
</span><del>-              if (handlerInfo.context !== object) { return false; }
</del><ins>+
+              if (isParam(object)) {
+                var name = recogHandler.names[0];
+                if (!this.currentParams || &quot;&quot; + object !== this.currentParams[name]) { return false; }
+              } else if (handlerInfo.context !== object) {
+                return false;
+              }
</ins><span class="cx">             }
</span><span class="cx">           }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        return contexts.length === 0 &amp;&amp; found;
</del><ins>+
+        return contexts.length === 0 &amp;&amp; found &amp;&amp; queryParamsEqual(activeQueryParams, effectiveQueryParams);
</ins><span class="cx">       },
</span><span class="cx"> 
</span><span class="cx">       trigger: function(name) {
</span><del>-        var args = [].slice.call(arguments);
-        trigger(this, args);
-      }
</del><ins>+        var args = slice.call(arguments);
+        trigger(this, this.currentHandlerInfos, false, args);
+      },
+
+      /**
+        Hook point for logging transition status updates.
+
+        @param {String} message The message to log.
+      */
+      log: null
</ins><span class="cx">     };
</span><span class="cx"> 
</span><del>-    function merge(hash, other) {
-      for (var prop in other) {
-        if (other.hasOwnProperty(prop)) { hash[prop] = other[prop]; }
</del><ins>+    /**
+      @private
+
+      Used internally for both URL and named transition to determine
+      a shared pivot parent route and other data necessary to perform
+      a transition.
+     */
+    function getMatchPoint(router, handlers, objects, inputParams, queryParams) {
+
+      var matchPoint = handlers.length,
+          providedModels = {}, i,
+          currentHandlerInfos = router.currentHandlerInfos || [],
+          params = {},
+          oldParams = router.currentParams || {},
+          activeTransition = router.activeTransition,
+          handlerParams = {},
+          obj;
+
+      objects = slice.call(objects);
+      merge(params, inputParams);
+
+      for (i = handlers.length - 1; i &gt;= 0; i--) {
+        var handlerObj = handlers[i],
+            handlerName = handlerObj.handler,
+            oldHandlerInfo = currentHandlerInfos[i],
+            hasChanged = false;
+
+        // Check if handler names have changed.
+        if (!oldHandlerInfo || oldHandlerInfo.name !== handlerObj.handler) { hasChanged = true; }
+
+        if (handlerObj.isDynamic) {
+          // URL transition.
+
+          if (obj = getMatchPointObject(objects, handlerName, activeTransition, true, params)) {
+            hasChanged = true;
+            providedModels[handlerName] = obj;
+          } else {
+            handlerParams[handlerName] = {};
+            for (var prop in handlerObj.params) {
+              if (!handlerObj.params.hasOwnProperty(prop)) { continue; }
+              var newParam = handlerObj.params[prop];
+              if (oldParams[prop] !== newParam) { hasChanged = true; }
+              handlerParams[handlerName][prop] = params[prop] = newParam;
+            }
+          }
+        } else if (handlerObj.hasOwnProperty('names')) {
+          // Named transition.
+
+          if (objects.length) { hasChanged = true; }
+
+          if (obj = getMatchPointObject(objects, handlerName, activeTransition, handlerObj.names[0], params)) {
+            providedModels[handlerName] = obj;
+          } else {
+            var names = handlerObj.names;
+            handlerParams[handlerName] = {};
+            for (var j = 0, len = names.length; j &lt; len; ++j) {
+              var name = names[j];
+              handlerParams[handlerName][name] = params[name] = params[name] || oldParams[name];
+            }
+          }
+        }
+
+        // If there is an old handler, see if query params are the same. If there isn't an old handler,
+        // hasChanged will already be true here
+        if(oldHandlerInfo &amp;&amp; !queryParamsEqual(oldHandlerInfo.queryParams, handlerObj.queryParams)) {
+            hasChanged = true;
+        }
+
+        if (hasChanged) { matchPoint = i; }
</ins><span class="cx">       }
</span><ins>+
+      if (objects.length &gt; 0) {
+        throw new Error(&quot;More context objects were passed than there are dynamic segments for the route: &quot; + handlers[handlers.length - 1].handler);
+      }
+
+      var pivotHandlerInfo = currentHandlerInfos[matchPoint - 1],
+          pivotHandler = pivotHandlerInfo &amp;&amp; pivotHandlerInfo.handler;
+
+      return { matchPoint: matchPoint, providedModels: providedModels, params: params, handlerParams: handlerParams, pivotHandler: pivotHandler };
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    function isCurrent(currentHandlerInfos, handlerName) {
-      return currentHandlerInfos[currentHandlerInfos.length - 1].name === handlerName;
</del><ins>+    function getMatchPointObject(objects, handlerName, activeTransition, paramName, params) {
+
+      if (objects.length &amp;&amp; paramName) {
+
+        var object = objects.pop();
+
+        // If provided object is string or number, treat as param.
+        if (isParam(object)) {
+          params[paramName] = object.toString();
+        } else {
+          return object;
+        }
+      } else if (activeTransition) {
+        // Use model from previous transition attempt, preferably the resolved one.
+        return activeTransition.resolvedModels[handlerName] ||
+               (paramName &amp;&amp; activeTransition.providedModels[handlerName]);
+      }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    function isParam(object) {
+      return (typeof object === &quot;string&quot; || object instanceof String || typeof object === &quot;number&quot; || object instanceof Number);
+    }
+
+
+
</ins><span class="cx">     /**
</span><span class="cx">       @private
</span><span class="cx"> 
</span><del>-      This function is called the first time the `collectObjects`
-      function encounters a promise while converting URL parameters
-      into objects.
</del><ins>+      This method takes a handler name and returns a list of query params
+      that are valid to pass to the handler or its parents
</ins><span class="cx"> 
</span><del>-      It triggers the `enter` and `setup` methods on the `loading`
-      handler.
-
</del><span class="cx">       @param {Router} router
</span><ins>+      @param {String} handlerName
+      @return {Array[String]} a list of query parameters
</ins><span class="cx">     */
</span><del>-    function loading(router) {
-      if (!router.isLoading) {
-        router.isLoading = true;
-        var handler = router.getHandler('loading');
</del><ins>+    function queryParamsForHandler(router, handlerName) {
+      var handlers = router.recognizer.handlersFor(handlerName),
+        queryParams = [];
</ins><span class="cx"> 
</span><del>-        if (handler) {
-          if (handler.enter) { handler.enter(); }
-          if (handler.setup) { handler.setup(); }
-        }
</del><ins>+      for (var i = 0; i &lt; handlers.length; i++) {
+        queryParams.push.apply(queryParams, handlers[i].queryParams || []);
</ins><span class="cx">       }
</span><ins>+
+      return queryParams;
</ins><span class="cx">     }
</span><del>-
</del><span class="cx">     /**
</span><span class="cx">       @private
</span><span class="cx"> 
</span><del>-      This function is called if a promise was previously
-      encountered once all promises are resolved.
</del><ins>+      This method takes a handler name and a list of contexts and returns
+      a serialized parameter hash suitable to pass to `recognizer.generate()`.
</ins><span class="cx"> 
</span><del>-      It triggers the `exit` method on the `loading` handler.
-
</del><span class="cx">       @param {Router} router
</span><ins>+      @param {String} handlerName
+      @param {Array[Object]} objects
+      @return {Object} a serialized parameter hash
</ins><span class="cx">     */
</span><del>-    function loaded(router) {
-      router.isLoading = false;
-      var handler = router.getHandler('loading');
-      if (handler &amp;&amp; handler.exit) { handler.exit(); }
</del><ins>+    function paramsForHandler(router, handlerName, objects, queryParams) {
+
+      var handlers = router.recognizer.handlersFor(handlerName),
+          params = {},
+          handlerInfos = generateHandlerInfosWithQueryParams(router, handlers, queryParams),
+          matchPoint = getMatchPoint(router, handlerInfos, objects).matchPoint,
+          mergedQueryParams = {},
+          object, handlerObj, handler, names, i;
+
+      params.queryParams = {};
+
+      for (i=0; i&lt;handlers.length; i++) {
+        handlerObj = handlers[i];
+        handler = router.getHandler(handlerObj.handler);
+        names = handlerObj.names;
+
+        // If it's a dynamic segment
+        if (names.length) {
+          // If we have objects, use them
+          if (i &gt;= matchPoint) {
+            object = objects.shift();
+          // Otherwise use existing context
+          } else {
+            object = handler.context;
+          }
+
+          // Serialize to generate params
+          merge(params, serialize(handler, object, names));
+        }
+        if (queryParams !== false) {
+          mergeSomeKeys(params.queryParams, router.currentQueryParams, handlerObj.queryParams);
+          mergeSomeKeys(params.queryParams, queryParams, handlerObj.queryParams);
+        }
+      }
+
+      if (queryParamsEqual(params.queryParams, {})) { delete params.queryParams; }
+      return params;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    function merge(hash, other) {
+      for (var prop in other) {
+        if (other.hasOwnProperty(prop)) { hash[prop] = other[prop]; }
+      }
+    }
+
+    function mergeSomeKeys(hash, other, keys) {
+      if (!other || !keys) { return; }
+      for(var i = 0; i &lt; keys.length; i++) {
+        var key = keys[i], value;
+        if(other.hasOwnProperty(key)) {
+          value = other[key];
+          if(value === null || value === false || typeof value === &quot;undefined&quot;) {
+            delete hash[key];
+          } else {
+            hash[key] = other[key];
+          }
+        }
+      }
+    }
+
</ins><span class="cx">     /**
</span><span class="cx">       @private
</span><ins>+    */
</ins><span class="cx"> 
</span><del>-      This function is called if any encountered promise
-      is rejected.
</del><ins>+    function generateHandlerInfosWithQueryParams(router, handlers, queryParams) {
+      var handlerInfos = [];
</ins><span class="cx"> 
</span><del>-      It triggers the `exit` method on the `loading` handler,
-      the `enter` method on the `failure` handler, and the
-      `setup` method on the `failure` handler with the
-      `error`.
</del><ins>+      for (var i = 0; i &lt; handlers.length; i++) {
+        var handler = handlers[i],
+          handlerInfo = { handler: handler.handler, names: handler.names, context: handler.context, isDynamic: handler.isDynamic },
+          activeQueryParams = {};
</ins><span class="cx"> 
</span><del>-      @param {Router} router
-      @param {Object} error the reason for the promise
-        rejection, to pass into the failure handler's
-        `setup` method.
-    */
-    function failure(router, error) {
-      loaded(router);
-      var handler = router.getHandler('failure');
-      if (handler &amp;&amp; handler.setup) { handler.setup(error); }
</del><ins>+        if (queryParams !== false) {
+          mergeSomeKeys(activeQueryParams, router.currentQueryParams, handler.queryParams);
+          mergeSomeKeys(activeQueryParams, queryParams, handler.queryParams);
+        }
+
+        if (handler.queryParams &amp;&amp; handler.queryParams.length &gt; 0) {
+          handlerInfo.queryParams = activeQueryParams;
+        }
+
+        handlerInfos.push(handlerInfo);
+      }
+
+      return handlerInfos;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="cx">       @private
</span><span class="cx">     */
</span><del>-    function doTransition(router, name, method, args) {
-      var output = router._paramsForHandler(name, args, true);
-      var params = output.params, toSetup = output.toSetup;
</del><ins>+    function createQueryParamTransition(router, queryParams, isIntermediate) {
+      var currentHandlers = router.currentHandlerInfos,
+          currentHandler = currentHandlers[currentHandlers.length - 1],
+          name = currentHandler.name;
</ins><span class="cx"> 
</span><del>-      var url = router.recognizer.generate(name, params);
-      method.call(router, url);
</del><ins>+      log(router, &quot;Attempting query param transition&quot;);
</ins><span class="cx"> 
</span><del>-      setupContexts(router, toSetup);
</del><ins>+      return createNamedTransition(router, [name, queryParams], isIntermediate);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="cx">       @private
</span><ins>+    */
+    function createNamedTransition(router, args, isIntermediate) {
+      var partitionedArgs     = extractQueryParams(args),
+        pureArgs              = partitionedArgs[0],
+        queryParams           = partitionedArgs[1],
+        handlers              = router.recognizer.handlersFor(pureArgs[0]),
+        handlerInfos          = generateHandlerInfosWithQueryParams(router, handlers, queryParams);
</ins><span class="cx"> 
</span><del>-      This function is called after a URL change has been handled
-      by `router.handleURL`.
</del><span class="cx"> 
</span><del>-      Takes an Array of `RecognizedHandler`s, and converts the raw
-      params hashes into deserialized objects by calling deserialize
-      on the handlers. This process builds up an Array of
-      `HandlerInfo`s. It then calls `setupContexts` with the Array.
</del><ins>+      log(router, &quot;Attempting transition to &quot; + pureArgs[0]);
</ins><span class="cx"> 
</span><del>-      If the `deserialize` method on a handler returns a promise
-      (i.e. has a method called `then`), this function will pause
-      building up the `HandlerInfo` Array until the promise is
-      resolved. It will use the resolved value as the context of
-      `HandlerInfo`.
</del><ins>+      return performTransition(router,
+                               handlerInfos,
+                               slice.call(pureArgs, 1),
+                               router.currentParams,
+                               queryParams,
+                               null,
+                               isIntermediate);
+    }
+
+    /**
+      @private
</ins><span class="cx">     */
</span><del>-    function collectObjects(router, results, index, objects) {
-      if (results.length === index) {
-        loaded(router);
-        setupContexts(router, objects);
-        return;
-      }
</del><ins>+    function createURLTransition(router, url, isIntermediate) {
+      var results = router.recognizer.recognize(url),
+          currentHandlerInfos = router.currentHandlerInfos,
+          queryParams = {},
+          i, len;
</ins><span class="cx"> 
</span><del>-      var result = results[index];
-      var handler = router.getHandler(result.handler);
-      var object = handler.deserialize &amp;&amp; handler.deserialize(result.params);
</del><ins>+      log(router, &quot;Attempting URL transition to &quot; + url);
</ins><span class="cx"> 
</span><del>-      if (object &amp;&amp; typeof object.then === 'function') {
-        loading(router);
</del><ins>+      if (results) {
+        // Make sure this route is actually accessible by URL.
+        for (i = 0, len = results.length; i &lt; len; ++i) {
</ins><span class="cx"> 
</span><del>-        // The chained `then` means that we can also catch errors that happen in `proceed`
-        object.then(proceed).then(null, function(error) {
-          failure(router, error);
-        });
-      } else {
-        proceed(object);
</del><ins>+          if (router.getHandler(results[i].handler).inaccessibleByURL) {
+            results = null;
+            break;
+          }
+        }
</ins><span class="cx">       }
</span><span class="cx"> 
</span><del>-      function proceed(value) {
-        if (handler.context !== object) {
-          setContext(handler, object);
-        }
</del><ins>+      if (!results) {
+        return errorTransition(router, new Router.UnrecognizedURLError(url));
+      }
</ins><span class="cx"> 
</span><del>-        var updatedObjects = objects.concat([{
-          context: value,
-          handler: result.handler,
-          isDynamic: result.isDynamic
-        }]);
-        collectObjects(router, results, index + 1, updatedObjects);
</del><ins>+      for(i = 0, len = results.length; i &lt; len; i++) {
+        merge(queryParams, results[i].queryParams);
</ins><span class="cx">       }
</span><ins>+
+      return performTransition(router, results, [], {}, queryParams, null, isIntermediate);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     /**
</span><span class="cx">       @private
</span><span class="cx"> 
</span><del>-      Takes an Array of `UnresolvedHandlerInfo`s, resolves the handler names
-      into handlers, and then figures out what to do with each of the handlers.
</del><ins>+      Takes an Array of `HandlerInfo`s, figures out which ones are
+      exiting, entering, or changing contexts, and calls the
+      proper handler hooks.
</ins><span class="cx"> 
</span><span class="cx">       For example, consider the following tree of handlers. Each handler is
</span><span class="cx">       followed by the URL segment it handles.
</span><span class="lines">@@ -22406,7 +32641,7 @@
</span><span class="cx">       Consider the following transitions:
</span><span class="cx"> 
</span><span class="cx">       1. A URL transition to `/posts/1`.
</span><del>-         1. Triggers the `deserialize` callback on the
</del><ins>+         1. Triggers the `*model` callbacks on the
</ins><span class="cx">             `index`, `posts`, and `showPost` handlers
</span><span class="cx">          2. Triggers the `enter` callback on the same
</span><span class="cx">          3. Triggers the `setup` callback on the same
</span><span class="lines">@@ -22422,44 +32657,66 @@
</span><span class="cx">          3. Triggers the `enter` callback on `about`
</span><span class="cx">          4. Triggers the `setup` callback on `about`
</span><span class="cx"> 
</span><del>-      @param {Router} router
-      @param {Array[UnresolvedHandlerInfo]} handlerInfos
</del><ins>+      @param {Transition} transition
+      @param {Array[HandlerInfo]} handlerInfos
</ins><span class="cx">     */
</span><del>-    function setupContexts(router, handlerInfos) {
-      resolveHandlers(router, handlerInfos);
</del><ins>+    function setupContexts(transition, handlerInfos) {
+      var router = transition.router,
+          partition = partitionHandlers(router.currentHandlerInfos || [], handlerInfos);
</ins><span class="cx"> 
</span><del>-      var partition =
-        partitionHandlers(router.currentHandlerInfos || [], handlerInfos);
</del><ins>+      router.targetHandlerInfos = handlerInfos;
</ins><span class="cx"> 
</span><del>-      router.currentHandlerInfos = handlerInfos;
-
-      eachHandler(partition.exited, function(handler, context) {
</del><ins>+      eachHandler(partition.exited, function(handlerInfo) {
+        var handler = handlerInfo.handler;
</ins><span class="cx">         delete handler.context;
</span><span class="cx">         if (handler.exit) { handler.exit(); }
</span><span class="cx">       });
</span><span class="cx"> 
</span><del>-      eachHandler(partition.updatedContext, function(handler, context) {
-        setContext(handler, context);
-        if (handler.setup) { handler.setup(context); }
</del><ins>+      var currentHandlerInfos = partition.unchanged.slice();
+      router.currentHandlerInfos = currentHandlerInfos;
+
+      eachHandler(partition.updatedContext, function(handlerInfo) {
+        handlerEnteredOrUpdated(transition, currentHandlerInfos, handlerInfo, false);
</ins><span class="cx">       });
</span><span class="cx"> 
</span><del>-      var aborted = false;
-      eachHandler(partition.entered, function(handler, context) {
-        if (aborted) { return; }
-        if (handler.enter) { handler.enter(); }
</del><ins>+      eachHandler(partition.entered, function(handlerInfo) {
+        handlerEnteredOrUpdated(transition, currentHandlerInfos, handlerInfo, true);
+      });
+    }
+
+    /**
+      @private
+
+      Helper method used by setupContexts. Handles errors or redirects
+      that may happen in enter/setup.
+    */
+    function handlerEnteredOrUpdated(transition, currentHandlerInfos, handlerInfo, enter) {
+      var handler = handlerInfo.handler,
+          context = handlerInfo.context;
+
+      try {
+        if (enter &amp;&amp; handler.enter) { handler.enter(); }
+        checkAbort(transition);
+
</ins><span class="cx">         setContext(handler, context);
</span><del>-        if (handler.setup) {
-          if (false === handler.setup(context)) {
-            aborted = true;
-          }
</del><ins>+        setQueryParams(handler, handlerInfo.queryParams);
+
+        if (handler.setup) { handler.setup(context, handlerInfo.queryParams); }
+        checkAbort(transition);
+      } catch(e) {
+        if (!(e instanceof Router.TransitionAborted)) {
+          // Trigger the `error` event starting from this failed handler.
+          transition.trigger(true, 'error', e, transition, handler);
</ins><span class="cx">         }
</span><del>-      });
</del><span class="cx"> 
</span><del>-      if (router.didTransition) {
-        router.didTransition(handlerInfos);
</del><ins>+        // Propagate the error so that the transition promise will reject.
+        throw e;
</ins><span class="cx">       }
</span><ins>+
+      currentHandlerInfos.push(handlerInfo);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     /**
</span><span class="cx">       @private
</span><span class="cx"> 
</span><span class="lines">@@ -22471,41 +32728,38 @@
</span><span class="cx">     */
</span><span class="cx">     function eachHandler(handlerInfos, callback) {
</span><span class="cx">       for (var i=0, l=handlerInfos.length; i&lt;l; i++) {
</span><del>-        var handlerInfo = handlerInfos[i],
-            handler = handlerInfo.handler,
-            context = handlerInfo.context;
-
-        callback(handler, context);
</del><ins>+        callback(handlerInfos[i]);
</ins><span class="cx">       }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="cx">       @private
</span><span class="cx"> 
</span><del>-      Updates the `handler` field in each element in an Array of
-      `UnresolvedHandlerInfo`s from a handler name to a resolved handler.
-
-      When done, the Array will contain `HandlerInfo` structures.
-
-      @param {Router} router
-      @param {Array[UnresolvedHandlerInfo]} handlerInfos
-    */
-    function resolveHandlers(router, handlerInfos) {
-      var handlerInfo;
-
-      for (var i=0, l=handlerInfos.length; i&lt;l; i++) {
-        handlerInfo = handlerInfos[i];
-
-        handlerInfo.name = handlerInfo.handler;
-        handlerInfo.handler = router.getHandler(handlerInfo.handler);
</del><ins>+      determines if two queryparam objects are the same or not
+    **/
+    function queryParamsEqual(a, b) {
+      a = a || {};
+      b = b || {};
+      var checkedKeys = [], key;
+      for(key in a) {
+        if (!a.hasOwnProperty(key)) { continue; }
+        if(b[key] !== a[key]) { return false; }
+        checkedKeys.push(key);
</ins><span class="cx">       }
</span><ins>+      for(key in b) {
+        if (!b.hasOwnProperty(key)) { continue; }
+        if (~checkedKeys.indexOf(key)) { continue; }
+        // b has a key not in a
+        return false;
+      }
+      return true;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="cx">       @private
</span><span class="cx"> 
</span><span class="cx">       This function is called when transitioning from one URL to
</span><del>-      another to determine which handlers are not longer active,
</del><ins>+      another to determine which handlers are no longer active,
</ins><span class="cx">       which handlers are newly active, and which handlers remain
</span><span class="cx">       active but have their context changed.
</span><span class="cx"> 
</span><span class="lines">@@ -22523,7 +32777,7 @@
</span><span class="cx">       * entered: the handler was not active in the old URL, but
</span><span class="cx">         is now active.
</span><span class="cx"> 
</span><del>-      The PartitionedHandlers structure has three fields:
</del><ins>+      The PartitionedHandlers structure has four fields:
</ins><span class="cx"> 
</span><span class="cx">       * `updatedContext`: a list of `HandlerInfo` objects that
</span><span class="cx">         represent handlers that remain active but have a changed
</span><span class="lines">@@ -22532,6 +32786,7 @@
</span><span class="cx">         handlers that are newly active
</span><span class="cx">       * `exited`: a list of `HandlerInfo` objects that are no
</span><span class="cx">         longer active.
</span><ins>+      * `unchanged`: a list of `HanderInfo` objects that remain active.
</ins><span class="cx"> 
</span><span class="cx">       @param {Array[HandlerInfo]} oldHandlers a list of the handler
</span><span class="cx">         information for the previous URL (or `[]` if this is the
</span><span class="lines">@@ -22545,24 +32800,29 @@
</span><span class="cx">       var handlers = {
</span><span class="cx">             updatedContext: [],
</span><span class="cx">             exited: [],
</span><del>-            entered: []
</del><ins>+            entered: [],
+            unchanged: []
</ins><span class="cx">           };
</span><span class="cx"> 
</span><del>-      var handlerChanged, contextChanged, i, l;
</del><ins>+      var handlerChanged, contextChanged, queryParamsChanged, i, l;
</ins><span class="cx"> 
</span><span class="cx">       for (i=0, l=newHandlers.length; i&lt;l; i++) {
</span><span class="cx">         var oldHandler = oldHandlers[i], newHandler = newHandlers[i];
</span><span class="cx"> 
</span><span class="cx">         if (!oldHandler || oldHandler.handler !== newHandler.handler) {
</span><span class="cx">           handlerChanged = true;
</span><ins>+        } else if (!queryParamsEqual(oldHandler.queryParams, newHandler.queryParams)) {
+          queryParamsChanged = true;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (handlerChanged) {
</span><span class="cx">           handlers.entered.push(newHandler);
</span><span class="cx">           if (oldHandler) { handlers.exited.unshift(oldHandler); }
</span><del>-        } else if (contextChanged || oldHandler.context !== newHandler.context) {
</del><ins>+        } else if (contextChanged || oldHandler.context !== newHandler.context || queryParamsChanged) {
</ins><span class="cx">           contextChanged = true;
</span><span class="cx">           handlers.updatedContext.push(newHandler);
</span><ins>+        } else {
+          handlers.unchanged.push(oldHandler);
</ins><span class="cx">         }
</span><span class="cx">       }
</span><span class="cx"> 
</span><span class="lines">@@ -22573,33 +32833,516 @@
</span><span class="cx">       return handlers;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    function trigger(router, args) {
-      var currentHandlerInfos = router.currentHandlerInfos;
</del><ins>+    function trigger(router, handlerInfos, ignoreFailure, args) {
+      if (router.triggerEvent) {
+        router.triggerEvent(handlerInfos, ignoreFailure, args);
+        return;
+      }
</ins><span class="cx"> 
</span><span class="cx">       var name = args.shift();
</span><span class="cx"> 
</span><del>-      if (!currentHandlerInfos) {
</del><ins>+      if (!handlerInfos) {
+        if (ignoreFailure) { return; }
</ins><span class="cx">         throw new Error(&quot;Could not trigger event '&quot; + name + &quot;'. There are no active handlers&quot;);
</span><span class="cx">       }
</span><span class="cx"> 
</span><del>-      for (var i=currentHandlerInfos.length-1; i&gt;=0; i--) {
-        var handlerInfo = currentHandlerInfos[i],
</del><ins>+      var eventWasHandled = false;
+
+      for (var i=handlerInfos.length-1; i&gt;=0; i--) {
+        var handlerInfo = handlerInfos[i],
</ins><span class="cx">             handler = handlerInfo.handler;
</span><span class="cx"> 
</span><span class="cx">         if (handler.events &amp;&amp; handler.events[name]) {
</span><del>-          handler.events[name].apply(handler, args);
-          return;
</del><ins>+          if (handler.events[name].apply(handler, args) === true) {
+            eventWasHandled = true;
+          } else {
+            return;
+          }
</ins><span class="cx">         }
</span><span class="cx">       }
</span><span class="cx"> 
</span><del>-      throw new Error(&quot;Nothing handled the event '&quot; + name + &quot;'.&quot;);
</del><ins>+      if (!eventWasHandled &amp;&amp; !ignoreFailure) {
+        throw new Error(&quot;Nothing handled the event '&quot; + name + &quot;'.&quot;);
+      }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     function setContext(handler, context) {
</span><span class="cx">       handler.context = context;
</span><span class="cx">       if (handler.contextDidChange) { handler.contextDidChange(); }
</span><span class="cx">     }
</span><del>-    return Router;
</del><ins>+
+    function setQueryParams(handler, queryParams) {
+      handler.queryParams = queryParams;
+      if (handler.queryParamsDidChange) { handler.queryParamsDidChange(); }
+    }
+
+
+    /**
+      @private
+
+      Extracts query params from the end of an array
+    **/
+
+    function extractQueryParams(array) {
+      var len = (array &amp;&amp; array.length), head, queryParams;
+
+      if(len &amp;&amp; len &gt; 0 &amp;&amp; array[len - 1] &amp;&amp; array[len - 1].hasOwnProperty('queryParams')) {
+        queryParams = array[len - 1].queryParams;
+        head = slice.call(array, 0, len - 1);
+        return [head, queryParams];
+      } else {
+        return [array, null];
+      }
+    }
+
+    function performIntermediateTransition(router, recogHandlers, matchPointResults) {
+
+      var handlerInfos = generateHandlerInfos(router, recogHandlers);
+      for (var i = 0; i &lt; handlerInfos.length; ++i) {
+        var handlerInfo = handlerInfos[i];
+        handlerInfo.context = matchPointResults.providedModels[handlerInfo.name];
+      }
+
+      var stubbedTransition = {
+        router: router,
+        isAborted: false
+      };
+
+      setupContexts(stubbedTransition, handlerInfos);
+    }
+
+    /**
+      @private
+
+      Creates, begins, and returns a Transition.
+     */
+    function performTransition(router, recogHandlers, providedModelsArray, params, queryParams, data, isIntermediate) {
+
+      var matchPointResults = getMatchPoint(router, recogHandlers, providedModelsArray, params, queryParams),
+          targetName = recogHandlers[recogHandlers.length - 1].handler,
+          wasTransitioning = false,
+          currentHandlerInfos = router.currentHandlerInfos;
+
+      if (isIntermediate) {
+        return performIntermediateTransition(router, recogHandlers, matchPointResults);
+      }
+
+      // Check if there's already a transition underway.
+      if (router.activeTransition) {
+        if (transitionsIdentical(router.activeTransition, targetName, providedModelsArray, queryParams)) {
+          return router.activeTransition;
+        }
+        router.activeTransition.abort();
+        wasTransitioning = true;
+      }
+
+      var deferred = RSVP.defer(),
+          transition = new Transition(router, deferred.promise);
+
+      transition.targetName = targetName;
+      transition.providedModels = matchPointResults.providedModels;
+      transition.providedModelsArray = providedModelsArray;
+      transition.params = matchPointResults.params;
+      transition.data = data || {};
+      transition.queryParams = queryParams;
+      transition.pivotHandler = matchPointResults.pivotHandler;
+      router.activeTransition = transition;
+
+      var handlerInfos = generateHandlerInfos(router, recogHandlers);
+      transition.handlerInfos = handlerInfos;
+
+      // Fire 'willTransition' event on current handlers, but don't fire it
+      // if a transition was already underway.
+      if (!wasTransitioning) {
+        trigger(router, currentHandlerInfos, true, ['willTransition', transition]);
+      }
+
+      log(router, transition.sequence, &quot;Beginning validation for transition to &quot; + transition.targetName);
+      validateEntry(transition, matchPointResults.matchPoint, matchPointResults.handlerParams)
+                   .then(transitionSuccess, transitionFailure);
+
+      return transition;
+
+      function transitionSuccess() {
+        checkAbort(transition);
+
+        try {
+          finalizeTransition(transition, handlerInfos);
+
+          // currentHandlerInfos was updated in finalizeTransition
+          trigger(router, router.currentHandlerInfos, true, ['didTransition']);
+
+          if (router.didTransition) {
+            router.didTransition(handlerInfos);
+          }
+
+          log(router, transition.sequence, &quot;TRANSITION COMPLETE.&quot;);
+
+          // Resolve with the final handler.
+          transition.isActive = false;
+          deferred.resolve(handlerInfos[handlerInfos.length - 1].handler);
+        } catch(e) {
+          deferred.reject(e);
+        }
+
+        // Don't nullify if another transition is underway (meaning
+        // there was a transition initiated with enter/setup).
+        if (!transition.isAborted) {
+          router.activeTransition = null;
+        }
+      }
+
+      function transitionFailure(reason) {
+        deferred.reject(reason);
+      }
+    }
+
+    /**
+      @private
+
+      Accepts handlers in Recognizer format, either returned from
+      recognize() or handlersFor(), and returns unified
+      `HandlerInfo`s.
+     */
+    function generateHandlerInfos(router, recogHandlers) {
+      var handlerInfos = [];
+      for (var i = 0, len = recogHandlers.length; i &lt; len; ++i) {
+        var handlerObj = recogHandlers[i],
+            isDynamic = handlerObj.isDynamic || (handlerObj.names &amp;&amp; handlerObj.names.length);
+
+        var handlerInfo = {
+          isDynamic: !!isDynamic,
+          name: handlerObj.handler,
+          handler: router.getHandler(handlerObj.handler)
+        };
+        if(handlerObj.queryParams) {
+          handlerInfo.queryParams = handlerObj.queryParams;
+        }
+        handlerInfos.push(handlerInfo);
+      }
+      return handlerInfos;
+    }
+
+    /**
+      @private
+     */
+    function transitionsIdentical(oldTransition, targetName, providedModelsArray, queryParams) {
+
+      if (oldTransition.targetName !== targetName) { return false; }
+
+      var oldModels = oldTransition.providedModelsArray;
+      if (oldModels.length !== providedModelsArray.length) { return false; }
+
+      for (var i = 0, len = oldModels.length; i &lt; len; ++i) {
+        if (oldModels[i] !== providedModelsArray[i]) { return false; }
+      }
+
+      if(!queryParamsEqual(oldTransition.queryParams, queryParams)) {
+        return false;
+      }
+
+      return true;
+    }
+
+    /**
+      @private
+
+      Updates the URL (if necessary) and calls `setupContexts`
+      to update the router's array of `currentHandlerInfos`.
+     */
+    function finalizeTransition(transition, handlerInfos) {
+
+      log(transition.router, transition.sequence, &quot;Validation succeeded, finalizing transition;&quot;);
+
+      var router = transition.router,
+          seq = transition.sequence,
+          handlerName = handlerInfos[handlerInfos.length - 1].name,
+          urlMethod = transition.urlMethod,
+          i;
+
+      // Collect params for URL.
+      var objects = [], providedModels = transition.providedModelsArray.slice();
+      for (i = handlerInfos.length - 1; i&gt;=0; --i) {
+        var handlerInfo = handlerInfos[i];
+        if (handlerInfo.isDynamic) {
+          var providedModel = providedModels.pop();
+          objects.unshift(isParam(providedModel) ? providedModel.toString() : handlerInfo.context);
+        }
+
+        if (handlerInfo.handler.inaccessibleByURL) {
+          urlMethod = null;
+        }
+      }
+
+      var newQueryParams = {};
+      for (i = handlerInfos.length - 1; i&gt;=0; --i) {
+        merge(newQueryParams, handlerInfos[i].queryParams);
+      }
+      router.currentQueryParams = newQueryParams;
+
+
+      var params = paramsForHandler(router, handlerName, objects, transition.queryParams);
+
+      router.currentParams = params;
+
+      if (urlMethod) {
+        var url = router.recognizer.generate(handlerName, params);
+
+        if (urlMethod === 'replace') {
+          router.replaceURL(url);
+        } else {
+          // Assume everything else is just a URL update for now.
+          router.updateURL(url);
+        }
+      }
+
+      setupContexts(transition, handlerInfos);
+    }
+
+    /**
+      @private
+
+      Internal function used to construct the chain of promises used
+      to validate a transition. Wraps calls to `beforeModel`, `model`,
+      and `afterModel` in promises, and checks for redirects/aborts
+      between each.
+     */
+    function validateEntry(transition, matchPoint, handlerParams) {
+
+      var handlerInfos = transition.handlerInfos,
+          index = transition.resolveIndex;
+
+      if (index === handlerInfos.length) {
+        // No more contexts to resolve.
+        return RSVP.resolve(transition.resolvedModels);
+      }
+
+      var router = transition.router,
+          handlerInfo = handlerInfos[index],
+          handler = handlerInfo.handler,
+          handlerName = handlerInfo.name,
+          seq = transition.sequence;
+
+      if (index &lt; matchPoint) {
+        log(router, seq, handlerName + &quot;: using context from already-active handler&quot;);
+
+        // We're before the match point, so don't run any hooks,
+        // just use the already resolved context from the handler.
+        transition.resolvedModels[handlerInfo.name] =
+          transition.providedModels[handlerInfo.name] ||
+          handlerInfo.handler.context;
+        return proceed();
+      }
+
+      transition.trigger(true, 'willResolveModel', transition, handler);
+
+      return RSVP.resolve().then(handleAbort)
+                           .then(beforeModel)
+                           .then(handleAbort)
+                           .then(model)
+                           .then(handleAbort)
+                           .then(afterModel)
+                           .then(handleAbort)
+                           .then(null, handleError)
+                           .then(proceed);
+
+      function handleAbort(result) {
+        if (transition.isAborted) {
+          log(transition.router, transition.sequence, &quot;detected abort.&quot;);
+          return RSVP.reject(new Router.TransitionAborted());
+        }
+
+        return result;
+      }
+
+      function handleError(reason) {
+        if (reason instanceof Router.TransitionAborted || transition.isAborted) {
+          // if the transition was aborted and *no additional* error was thrown,
+          // reject with the Router.TransitionAborted instance
+          return RSVP.reject(reason);
+        }
+
+        // otherwise, we're here because of a different error
+        transition.abort();
+
+        log(router, seq, handlerName + &quot;: handling error: &quot; + reason);
+
+        // An error was thrown / promise rejected, so fire an
+        // `error` event from this handler info up to root.
+        transition.trigger(true, 'error', reason, transition, handlerInfo.handler);
+
+        // Propagate the original error.
+        return RSVP.reject(reason);
+      }
+
+      function beforeModel() {
+
+        log(router, seq, handlerName + &quot;: calling beforeModel hook&quot;);
+
+        var args;
+
+        if (handlerInfo.queryParams) {
+          args = [handlerInfo.queryParams, transition];
+        } else {
+          args = [transition];
+        }
+
+        var p = handler.beforeModel &amp;&amp; handler.beforeModel.apply(handler, args);
+        return (p instanceof Transition) ? null : p;
+      }
+
+      function model() {
+        log(router, seq, handlerName + &quot;: resolving model&quot;);
+        var p = getModel(handlerInfo, transition, handlerParams[handlerName], index &gt;= matchPoint);
+        return (p instanceof Transition) ? null : p;
+      }
+
+      function afterModel(context) {
+
+        log(router, seq, handlerName + &quot;: calling afterModel hook&quot;);
+
+        // Pass the context and resolved parent contexts to afterModel, but we don't
+        // want to use the value returned from `afterModel` in any way, but rather
+        // always resolve with the original `context` object.
+
+        transition.resolvedModels[handlerInfo.name] = context;
+
+        var args;
+
+        if (handlerInfo.queryParams) {
+          args = [context, handlerInfo.queryParams, transition];
+        } else {
+          args = [context, transition];
+        }
+
+        var p = handler.afterModel &amp;&amp; handler.afterModel.apply(handler, args);
+        return (p instanceof Transition) ? null : p;
+      }
+
+      function proceed() {
+        log(router, seq, handlerName + &quot;: validation succeeded, proceeding&quot;);
+
+        handlerInfo.context = transition.resolvedModels[handlerInfo.name];
+        transition.resolveIndex++;
+        return validateEntry(transition, matchPoint, handlerParams);
+      }
+    }
+
+    /**
+      @private
+
+      Throws a TransitionAborted if the provided transition has been aborted.
+     */
+    function checkAbort(transition) {
+      if (transition.isAborted) {
+        log(transition.router, transition.sequence, &quot;detected abort.&quot;);
+        throw new Router.TransitionAborted();
+      }
+    }
+
+    /**
+      @private
+
+      Encapsulates the logic for whether to call `model` on a route,
+      or use one of the models provided to `transitionTo`.
+     */
+    function getModel(handlerInfo, transition, handlerParams, needsUpdate) {
+      var handler = handlerInfo.handler,
+          handlerName = handlerInfo.name, args;
+
+      if (!needsUpdate &amp;&amp; handler.hasOwnProperty('context')) {
+        return handler.context;
+      }
+
+      if (transition.providedModels.hasOwnProperty(handlerName)) {
+        var providedModel = transition.providedModels[handlerName];
+        return typeof providedModel === 'function' ? providedModel() : providedModel;
+      }
+
+      if (handlerInfo.queryParams) {
+        args = [handlerParams || {}, handlerInfo.queryParams, transition];
+      } else {
+        args = [handlerParams || {}, transition, handlerInfo.queryParams];
+      }
+
+      return handler.model &amp;&amp; handler.model.apply(handler, args);
+    }
+
+    /**
+      @private
+     */
+    function log(router, sequence, msg) {
+
+      if (!router.log) { return; }
+
+      if (arguments.length === 3) {
+        router.log(&quot;Transition #&quot; + sequence + &quot;: &quot; + msg);
+      } else {
+        msg = sequence;
+        router.log(msg);
+      }
+    }
+
+    /**
+      @private
+
+      Begins and returns a Transition based on the provided
+      arguments. Accepts arguments in the form of both URL
+      transitions and named transitions.
+
+      @param {Router} router
+      @param {Array[Object]} args arguments passed to transitionTo,
+        replaceWith, or handleURL
+    */
+    function doTransition(router, args, isIntermediate) {
+      // Normalize blank transitions to root URL transitions.
+      var name = args[0] || '/';
+
+      if(args.length === 1 &amp;&amp; args[0].hasOwnProperty('queryParams')) {
+        return createQueryParamTransition(router, args[0], isIntermediate);
+      } else if (name.charAt(0) === '/') {
+        return createURLTransition(router, name, isIntermediate);
+      } else {
+        return createNamedTransition(router, slice.call(args), isIntermediate);
+      }
+    }
+
+    /**
+      @private
+
+      Serializes a handler using its custom `serialize` method or
+      by a default that looks up the expected property name from
+      the dynamic segment.
+
+      @param {Object} handler a router handler
+      @param {Object} model the model to be serialized for this handler
+      @param {Array[Object]} names the names array attached to an
+        handler object returned from router.recognizer.handlersFor()
+    */
+    function serialize(handler, model, names) {
+
+      var object = {};
+      if (isParam(model)) {
+        object[names[0]] = model;
+        return object;
+      }
+
+      // Use custom serialize if it exists.
+      if (handler.serialize) {
+        return handler.serialize(model, names);
+      }
+
+      if (names.length !== 1) { return; }
+
+      var name = names[0];
+
+      if (/_id$/.test(name)) {
+        object[name] = model.id;
+      } else {
+        object[name] = model;
+      }
+      return object;
+    }
</ins><span class="cx">   });
</span><span class="cx"> 
</span><span class="cx"> })();
</span><span class="lines">@@ -22634,35 +33377,28 @@
</span><span class="cx"> 
</span><span class="cx">     if (callback) {
</span><span class="cx">       var dsl = new DSL(name);
</span><ins>+      route(dsl, 'loading');
+      route(dsl, 'error', { path: &quot;/_unused_dummy_error_path_route_&quot; + name + &quot;/:error&quot; });
</ins><span class="cx">       callback.call(dsl);
</span><del>-      this.push(options.path, name, dsl.generate());
</del><ins>+      this.push(options.path, name, dsl.generate(), options.queryParams);
</ins><span class="cx">     } else {
</span><del>-      this.push(options.path, name);
</del><ins>+      this.push(options.path, name, null, options.queryParams);
</ins><span class="cx">     }
</span><del>-  },
</del><span class="cx"> 
</span><del>-  push: function(url, name, callback) {
-    if (url === &quot;&quot; || url === &quot;/&quot;) { this.explicitIndex = true; }
</del><span class="cx"> 
</span><del>-    this.matches.push([url, name, callback]);
</del><ins>+      },
+
+  push: function(url, name, callback, queryParams) {
+    var parts = name.split('.');
+    if (url === &quot;&quot; || url === &quot;/&quot; || parts[parts.length-1] === &quot;index&quot;) { this.explicitIndex = true; }
+
+    this.matches.push([url, name, callback, queryParams]);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   route: function(name, options) {
</span><del>-    Ember.assert(&quot;You must use `this.resource` to nest&quot;, typeof options !== 'function');
</del><ins>+    route(this, name, options);
+      },
</ins><span class="cx"> 
</span><del>-    options = options || {};
-
-    if (typeof options.path !== 'string') {
-      options.path = &quot;/&quot; + name;
-    }
-
-    if (this.parent &amp;&amp; this.parent !== 'application') {
-      name = this.parent + &quot;.&quot; + name;
-    }
-
-    this.push(options.path, name);
-  },
-
</del><span class="cx">   generate: function() {
</span><span class="cx">     var dslMatches = this.matches;
</span><span class="cx"> 
</span><span class="lines">@@ -22673,12 +33409,28 @@
</span><span class="cx">     return function(match) {
</span><span class="cx">       for (var i=0, l=dslMatches.length; i&lt;l; i++) {
</span><span class="cx">         var dslMatch = dslMatches[i];
</span><del>-        match(dslMatch[0]).to(dslMatch[1], dslMatch[2]);
-      }
</del><ins>+        var matchObj = match(dslMatch[0]).to(dslMatch[1], dslMatch[2]);
+              }
</ins><span class="cx">     };
</span><span class="cx">   }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+function route(dsl, name, options) {
+  Ember.assert(&quot;You must use `this.resource` to nest&quot;, typeof options !== 'function');
+
+  options = options || {};
+
+  if (typeof options.path !== 'string') {
+    options.path = &quot;/&quot; + name;
+  }
+
+  if (dsl.parent &amp;&amp; dsl.parent !== 'application') {
+    name = dsl.parent + &quot;.&quot; + name;
+  }
+
+  dsl.push(options.path, name, null, options.queryParams);
+}
+
</ins><span class="cx"> DSL.map = function(callback) {
</span><span class="cx">   var dsl = new DSL();
</span><span class="cx">   callback.call(dsl);
</span><span class="lines">@@ -22692,39 +33444,91 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><ins>+var get = Ember.get;
+
</ins><span class="cx"> /**
</span><span class="cx"> @module ember
</span><span class="cx"> @submodule ember-routing
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-Ember.controllerFor = function(container, controllerName, context) {
-  return container.lookup('controller:' + controllerName) ||
-         Ember.generateController(container, controllerName, context);
</del><ins>+/**
+
+  Finds a controller instance.
+
+  @for Ember
+  @method controllerFor
+  @private
+*/
+Ember.controllerFor = function(container, controllerName, lookupOptions) {
+  return container.lookup('controller:' + controllerName, lookupOptions);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-Ember.generateController = function(container, controllerName, context) {
-  var controller;
</del><ins>+/**
+  Generates a controller factory
</ins><span class="cx"> 
</span><ins>+  The type of the generated controller factory is derived
+  from the context. If the context is an array an array controller
+  is generated, if an object, an object controller otherwise, a basic
+  controller is generated.
+
+  You can customize your generated controllers by defining
+  `App.ObjectController` or `App.ArrayController`.
+
+  @for Ember
+  @method generateControllerFactory
+  @private
+*/
+Ember.generateControllerFactory = function(container, controllerName, context) {
+  var Factory, fullName, instance, name, factoryName, controllerType;
+
</ins><span class="cx">   if (context &amp;&amp; Ember.isArray(context)) {
</span><del>-    controller = Ember.ArrayController.extend({
-      content: context
-    });
</del><ins>+    controllerType = 'array';
</ins><span class="cx">   } else if (context) {
</span><del>-    controller = Ember.ObjectController.extend({
-      content: context
-    });
</del><ins>+    controllerType = 'object';
</ins><span class="cx">   } else {
</span><del>-    controller = Ember.Controller.extend();
</del><ins>+    controllerType = 'basic';
</ins><span class="cx">   }
</span><span class="cx"> 
</span><del>-  controller.toString = function() {
-    return &quot;(generated &quot; + controllerName + &quot; controller)&quot;;
-  };
</del><ins>+  factoryName = 'controller:' + controllerType;
</ins><span class="cx"> 
</span><del>-  container.register('controller', controllerName, controller);
-  return container.lookup('controller:' + controllerName);
</del><ins>+  Factory = container.lookupFactory(factoryName).extend({
+    isGenerated: true,
+    toString: function() {
+      return &quot;(generated &quot; + controllerName + &quot; controller)&quot;;
+    }
+  });
+
+  fullName = 'controller:' + controllerName;
+
+  container.register(fullName,  Factory);
+
+  return Factory;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><ins>+/**
+  Generates and instantiates a controller.
+
+  The type of the generated controller factory is derived
+  from the context. If the context is an array an array controller
+  is generated, if an object, an object controller otherwise, a basic
+  controller is generated.
+
+  @for Ember
+  @method generateController
+  @private
+*/
+Ember.generateController = function(container, controllerName, context) {
+  Ember.generateControllerFactory(container, controllerName, context);
+  var fullName = 'controller:' + controllerName;
+  var instance = container.lookup(fullName);
+
+  if (get(instance, 'namespace.LOG_ACTIVE_GENERATION')) {
+    Ember.Logger.info(&quot;generated -&gt; &quot; + fullName, { fullName: fullName });
+  }
+
+  return instance;
+};
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -22735,25 +33539,12 @@
</span><span class="cx"> @submodule ember-routing
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var Router = requireModule(&quot;router&quot;);
-var get = Ember.get, set = Ember.set, classify = Ember.String.classify;
</del><ins>+var Router = requireModule(&quot;router&quot;)['default'];
+var get = Ember.get, set = Ember.set;
+var defineProperty = Ember.defineProperty;
+var slice = Array.prototype.slice;
</ins><span class="cx"> 
</span><span class="cx"> var DefaultView = Ember._MetamorphView;
</span><del>-function setupLocation(router) {
-  var location = get(router, 'location'),
-      rootURL = get(router, 'rootURL');
-
-  if ('string' === typeof location) {
-    location = set(router, 'location', Ember.Location.create({
-      implementation: location
-    }));
-
-    if (typeof rootURL === 'string') {
-      set(location, 'rootURL', rootURL);
-    }
-  }
-}
-
</del><span class="cx"> /**
</span><span class="cx">   The `Ember.Router` class manages the application state and URLs. Refer to
</span><span class="cx">   the [routing guide](http://emberjs.com/guides/routing/) for documentation.
</span><span class="lines">@@ -22762,19 +33553,50 @@
</span><span class="cx">   @namespace Ember
</span><span class="cx">   @extends Ember.Object
</span><span class="cx"> */
</span><del>-Ember.Router = Ember.Object.extend({
</del><ins>+Ember.Router = Ember.Object.extend(Ember.Evented, {
+  /**
+    The `location` property determines the type of URL's that your
+    application will use.
+
+    The following location types are currently available:
+
+    * `hash`
+    * `history`
+    * `none`
+
+    @property location
+    @default 'hash'
+    @see {Ember.Location}
+  */
</ins><span class="cx">   location: 'hash',
</span><span class="cx"> 
</span><span class="cx">   init: function() {
</span><del>-    this.router = this.constructor.router;
</del><ins>+    this.router = this.constructor.router || this.constructor.map(Ember.K);
</ins><span class="cx">     this._activeViews = {};
</span><del>-    setupLocation(this);
</del><ins>+    this._setupLocation();
+
+    if (get(this, 'namespace.LOG_TRANSITIONS_INTERNAL')) {
+      this.router.log = Ember.Logger.debug;
+    }
</ins><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    Represents the current URL.
+
+    @method url
+    @returns {String} The current URL.
+  */
</ins><span class="cx">   url: Ember.computed(function() {
</span><span class="cx">     return get(this, 'location').getURL();
</span><span class="cx">   }),
</span><span class="cx"> 
</span><ins>+  /**
+    Initializes the current router instance and sets up the change handling
+    event listeners used by the instances `location` implementation.
+
+    @method startRouting
+    @private
+  */
</ins><span class="cx">   startRouting: function() {
</span><span class="cx">     this.router = this.router || this.constructor.map(Ember.K);
</span><span class="cx"> 
</span><span class="lines">@@ -22783,10 +33605,10 @@
</span><span class="cx">         container = this.container,
</span><span class="cx">         self = this;
</span><span class="cx"> 
</span><del>-    setupRouter(this, router, location);
</del><ins>+    this._setupRouter(router, location);
</ins><span class="cx"> 
</span><del>-    container.register('view', 'default', DefaultView);
-    container.register('view', 'toplevel', Ember.View.extend());
</del><ins>+    container.register('view:default', DefaultView);
+    container.register('view:toplevel', Ember.View.extend());
</ins><span class="cx"> 
</span><span class="cx">     location.onUpdateURL(function(url) {
</span><span class="cx">       self.handleURL(url);
</span><span class="lines">@@ -22795,36 +33617,52 @@
</span><span class="cx">     this.handleURL(location.getURL());
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    Handles updating the paths and notifying any listeners of the URL
+    change.
+
+    Triggers the router level `didTransition` hook.
+
+    @method didTransition
+    @private
+  */
</ins><span class="cx">   didTransition: function(infos) {
</span><del>-    // Don't do any further action here if we redirected
-    for (var i=0, l=infos.length; i&lt;l; i++) {
-      if (infos[i].handler.redirected) { return; }
-    }
</del><ins>+    updatePaths(this);
</ins><span class="cx"> 
</span><del>-    var appController = this.container.lookup('controller:application'),
-        path = routePath(infos);
</del><ins>+    this._cancelLoadingEvent();
</ins><span class="cx"> 
</span><del>-    set(appController, 'currentPath', path);
</del><span class="cx">     this.notifyPropertyChange('url');
</span><span class="cx"> 
</span><ins>+    // Put this in the runloop so url will be accurate. Seems
+    // less surprising than didTransition being out of sync.
+    Ember.run.once(this, this.trigger, 'didTransition');
+
</ins><span class="cx">     if (get(this, 'namespace').LOG_TRANSITIONS) {
</span><del>-      Ember.Logger.log(&quot;Transitioned into '&quot; + path + &quot;'&quot;);
</del><ins>+      Ember.Logger.log(&quot;Transitioned into '&quot; + Ember.Router._routePath(infos) + &quot;'&quot;);
</ins><span class="cx">     }
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   handleURL: function(url) {
</span><del>-    this.router.handleURL(url);
-    this.notifyPropertyChange('url');
</del><ins>+    return this._doTransition('handleURL', [url]);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  transitionTo: function(name) {
-    var args = [].slice.call(arguments);
-    doTransition(this, 'transitionTo', args);
</del><ins>+  transitionTo: function() {
+    return this._doTransition('transitionTo', arguments);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  intermediateTransitionTo: function() {
+    this.router.intermediateTransitionTo.apply(this.router, arguments);
+
+    updatePaths(this);
+
+    var infos = this.router.currentHandlerInfos;
+    if (get(this, 'namespace').LOG_TRANSITIONS) {
+      Ember.Logger.log(&quot;Intermediate-transitioned into '&quot; + Ember.Router._routePath(infos) + &quot;'&quot;);
+    }
+  },
+
</ins><span class="cx">   replaceWith: function() {
</span><del>-    var args = [].slice.call(arguments);
-    doTransition(this, 'replaceWith', args);
</del><ins>+    return this._doTransition('replaceWith', arguments);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   generate: function() {
</span><span class="lines">@@ -22832,6 +33670,14 @@
</span><span class="cx">     return this.location.formatURL(url);
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    Determines if the supplied route is currently active.
+
+    @method isActive
+    @param routeName
+    @returns {Boolean}
+    @private
+  */
</ins><span class="cx">   isActive: function(routeName) {
</span><span class="cx">     var router = this.router;
</span><span class="cx">     return router.isActive.apply(router, arguments);
</span><span class="lines">@@ -22841,10 +33687,35 @@
</span><span class="cx">     this.router.trigger.apply(this.router, arguments);
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    Does this router instance have the given route.
+
+    @method hasRoute
+    @returns {Boolean}
+    @private
+  */
</ins><span class="cx">   hasRoute: function(route) {
</span><span class="cx">     return this.router.hasRoute(route);
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    Resets the state of the router by clearing the current route
+    handlers and deactivating them.
+
+    @private
+    @method reset
+   */
+  reset: function() {
+    this.router.reset();
+  },
+
+  willDestroy: function(){
+    var location = get(this, 'location');
+    location.destroy();
+
+    this._super.apply(this, arguments);
+  },
+
</ins><span class="cx">   _lookupActiveView: function(templateName) {
</span><span class="cx">     var active = this._activeViews[templateName];
</span><span class="cx">     return active &amp;&amp; active[0];
</span><span class="lines">@@ -22863,128 +33734,379 @@
</span><span class="cx"> 
</span><span class="cx">     this._activeViews[templateName] = [view, disconnect];
</span><span class="cx">     view.one('willDestroyElement', this, disconnect);
</span><del>-  }
-});
</del><ins>+  },
</ins><span class="cx"> 
</span><del>-Ember.Router.reopenClass({
-  defaultFailureHandler: {
-    setup: function(error) {
-      Ember.Logger.error('Error while loading route:', error);
</del><ins>+  _setupLocation: function() {
+    var location = get(this, 'location'),
+        rootURL = get(this, 'rootURL'),
+        options = {};
</ins><span class="cx"> 
</span><del>-      // Using setTimeout allows us to escape from the Promise's try/catch block
-      setTimeout(function() { throw error; });
</del><ins>+    if (typeof rootURL === 'string') {
+      options.rootURL = rootURL;
</ins><span class="cx">     }
</span><ins>+
+    if ('string' === typeof location) {
+      options.implementation = location;
+      location = set(this, 'location', Ember.Location.create(options));
+    }
+
+    // ensure that initState is called AFTER the rootURL is set on
+    // the location instance
+    if (typeof location.initState === 'function') { location.initState(); }
+  },
+
+  _getHandlerFunction: function() {
+    var seen = {}, container = this.container,
+        DefaultRoute = container.lookupFactory('route:basic'),
+        self = this;
+
+    return function(name) {
+      var routeName = 'route:' + name,
+          handler = container.lookup(routeName);
+
+      if (seen[name]) { return handler; }
+
+      seen[name] = true;
+
+      if (!handler) {
+        container.register(routeName, DefaultRoute.extend());
+        handler = container.lookup(routeName);
+
+        if (get(self, 'namespace.LOG_ACTIVE_GENERATION')) {
+          Ember.Logger.info(&quot;generated -&gt; &quot; + routeName, { fullName: routeName });
+        }
+      }
+
+      handler.routeName = name;
+      return handler;
+    };
+  },
+
+  _setupRouter: function(router, location) {
+    var lastURL, emberRouter = this;
+
+    router.getHandler = this._getHandlerFunction();
+
+    var doUpdateURL = function() {
+      location.setURL(lastURL);
+    };
+
+    router.updateURL = function(path) {
+      lastURL = path;
+      Ember.run.once(doUpdateURL);
+    };
+
+    if (location.replaceURL) {
+      var doReplaceURL = function() {
+        location.replaceURL(lastURL);
+      };
+
+      router.replaceURL = function(path) {
+        lastURL = path;
+        Ember.run.once(doReplaceURL);
+      };
+    }
+
+    router.didTransition = function(infos) {
+      emberRouter.didTransition(infos);
+    };
+  },
+
+  _doTransition: function(method, args) {
+    // Normalize blank route to root URL.
+    args = slice.call(args);
+    args[0] = args[0] || '/';
+
+    var passedName = args[0], name, self = this,
+      isQueryParamsOnly = false;
+
+    
+    if (!isQueryParamsOnly &amp;&amp; passedName.charAt(0) === '/') {
+      name = passedName;
+    } else if (!isQueryParamsOnly) {
+      if (!this.router.hasRoute(passedName)) {
+        name = args[0] = passedName + '.index';
+      } else {
+        name = passedName;
+      }
+
+      Ember.assert(&quot;The route &quot; + passedName + &quot; was not found&quot;, this.router.hasRoute(name));
+    }
+
+    var transitionPromise = this.router[method].apply(this.router, args);
+
+    transitionPromise.then(null, function(error) {
+      if (error.name === &quot;UnrecognizedURLError&quot;) {
+        Ember.assert(&quot;The URL '&quot; + error.message + &quot;' did not match any routes in your application&quot;);
+      }
+    }, 'Ember: Check for Router unrecognized URL error');
+
+    // We want to return the configurable promise object
+    // so that callers of this function can use `.method()` on it,
+    // which obviously doesn't exist for normal RSVP promises.
+    return transitionPromise;
+  },
+
+  _scheduleLoadingEvent: function(transition, originRoute) {
+    this._cancelLoadingEvent();
+    this._loadingStateTimer = Ember.run.scheduleOnce('routerTransitions', this, '_fireLoadingEvent', transition, originRoute);
+  },
+
+  _fireLoadingEvent: function(transition, originRoute) {
+    if (!this.router.activeTransition) {
+      // Don't fire an event if we've since moved on from
+      // the transition that put us in a loading state.
+      return;
+    }
+
+    transition.trigger(true, 'loading', transition, originRoute);
+  },
+
+  _cancelLoadingEvent: function () {
+    if (this._loadingStateTimer) {
+      Ember.run.cancel(this._loadingStateTimer);
+    }
+    this._loadingStateTimer = null;
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-function getHandlerFunction(router) {
-  var seen = {}, container = router.container;
</del><ins>+/**
+  Helper function for iterating root-ward, starting
+  from (but not including) the provided `originRoute`.
</ins><span class="cx"> 
</span><del>-  return function(name) {
-    var handler = container.lookup('route:' + name);
-    if (seen[name]) { return handler; }
</del><ins>+  Returns true if the last callback fired requested
+  to bubble upward.
</ins><span class="cx"> 
</span><del>-    seen[name] = true;
</del><ins>+  @private
+ */
+function forEachRouteAbove(originRoute, transition, callback) {
+  var handlerInfos = transition.handlerInfos,
+      originRouteFound = false;
</ins><span class="cx"> 
</span><del>-    if (!handler) {
-      if (name === 'loading') { return {}; }
-      if (name === 'failure') { return router.constructor.defaultFailureHandler; }
</del><ins>+  for (var i = handlerInfos.length - 1; i &gt;= 0; --i) {
+    var handlerInfo = handlerInfos[i],
+        route = handlerInfo.handler;
</ins><span class="cx"> 
</span><del>-      container.register('route', name, Ember.Route.extend());
-      handler = container.lookup('route:' + name);
</del><ins>+    if (!originRouteFound) {
+      if (originRoute === route) {
+        originRouteFound = true;
+      }
+      continue;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    handler.routeName = name;
-    return handler;
-  };
</del><ins>+    if (callback(route, handlerInfos[i + 1].handler) !== true) {
+      return false;
+    }
+  }
+  return true;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-function handlerIsActive(router, handlerName) {
-  var handler = router.container.lookup('route:' + handlerName),
-      currentHandlerInfos = router.router.currentHandlerInfos,
-      handlerInfo;
</del><ins>+// These get invoked when an action bubbles above ApplicationRoute
+// and are not meant to be overridable.
+var defaultActionHandlers = {
</ins><span class="cx"> 
</span><del>-  for (var i=0, l=currentHandlerInfos.length; i&lt;l; i++) {
-    handlerInfo = currentHandlerInfos[i];
-    if (handlerInfo.handler === handler) { return true; }
-  }
</del><ins>+  willResolveModel: function(transition, originRoute) {
+    originRoute.router._scheduleLoadingEvent(transition, originRoute);
+  },
</ins><span class="cx"> 
</span><del>-  return false;
-}
</del><ins>+  error: function(error, transition, originRoute) {
+    // Attempt to find an appropriate error substate to enter.
+    var router = originRoute.router;
</ins><span class="cx"> 
</span><del>-function routePath(handlerInfos) {
-  var path = [];
</del><ins>+    var tryTopLevel = forEachRouteAbove(originRoute, transition, function(route, childRoute) {
+      var childErrorRouteName = findChildRouteName(route, childRoute, 'error');
+      if (childErrorRouteName) {
+        router.intermediateTransitionTo(childErrorRouteName, error);
+        return;
+      }
+      return true;
+    });
</ins><span class="cx"> 
</span><del>-  for (var i=1, l=handlerInfos.length; i&lt;l; i++) {
-    var name = handlerInfos[i].name,
-        nameParts = name.split(&quot;.&quot;);
</del><ins>+    if (tryTopLevel) {
+      // Check for top-level error state to enter.
+      if (routeHasBeenDefined(originRoute.router, 'application_error')) {
+        router.intermediateTransitionTo('application_error', error);
+        return;
+      }
+    } else {
+      // Don't fire an assertion if we found an error substate.
+      return;
+    }
</ins><span class="cx"> 
</span><del>-    path.push(nameParts[nameParts.length - 1]);
</del><ins>+    Ember.Logger.error('Error while loading route: ' + error.stack);
+  },
+
+  loading: function(transition, originRoute) {
+    // Attempt to find an appropriate loading substate to enter.
+    var router = originRoute.router;
+
+    var tryTopLevel = forEachRouteAbove(originRoute, transition, function(route, childRoute) {
+      var childLoadingRouteName = findChildRouteName(route, childRoute, 'loading');
+
+      if (childLoadingRouteName) {
+        router.intermediateTransitionTo(childLoadingRouteName);
+        return;
+      }
+
+      // Don't bubble above pivot route.
+      if (transition.pivotHandler !== route) {
+        return true;
+      }
+    });
+
+    if (tryTopLevel) {
+      // Check for top-level loading state to enter.
+      if (routeHasBeenDefined(originRoute.router, 'application_loading')) {
+        router.intermediateTransitionTo('application_loading');
+        return;
+      }
+    }
</ins><span class="cx">   }
</span><ins>+};
</ins><span class="cx"> 
</span><del>-  return path.join(&quot;.&quot;);
</del><ins>+function findChildRouteName(parentRoute, originatingChildRoute, name) {
+  var router = parentRoute.router,
+      childName,
+      targetChildRouteName = originatingChildRoute.routeName.split('.').pop(),
+      namespace = parentRoute.routeName === 'application' ? '' : parentRoute.routeName + '.';
+
+  
+  // Second, try general loading state, e.g. 'loading'
+  childName = namespace + name;
+  if (routeHasBeenDefined(router, childName)) {
+    return childName;
+  }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-function setupRouter(emberRouter, router, location) {
-  var lastURL;
</del><ins>+function routeHasBeenDefined(router, name) {
+  var container = router.container;
+  return router.hasRoute(name) &amp;&amp;
+         (container.has('template:' + name) || container.has('route:' + name));
+}
</ins><span class="cx"> 
</span><del>-  router.getHandler = getHandlerFunction(emberRouter);
</del><ins>+function triggerEvent(handlerInfos, ignoreFailure, args) {
+  var name = args.shift();
</ins><span class="cx"> 
</span><del>-  var doUpdateURL = function() {
-    location.setURL(lastURL);
-  };
</del><ins>+  if (!handlerInfos) {
+    if (ignoreFailure) { return; }
+    throw new Ember.Error(&quot;Can't trigger action '&quot; + name + &quot;' because your app hasn't finished transitioning into its first route. To trigger an action on destination routes during a transition, you can call `.send()` on the `Transition` object passed to the `model/beforeModel/afterModel` hooks.&quot;);
+  }
</ins><span class="cx"> 
</span><del>-  router.updateURL = function(path) {
-    lastURL = path;
-    Ember.run.once(doUpdateURL);
-  };
</del><ins>+  var eventWasHandled = false;
</ins><span class="cx"> 
</span><del>-  if (location.replaceURL) {
-    var doReplaceURL = function() {
-      location.replaceURL(lastURL);
-    };
</del><ins>+  for (var i = handlerInfos.length - 1; i &gt;= 0; i--) {
+    var handlerInfo = handlerInfos[i],
+        handler = handlerInfo.handler;
</ins><span class="cx"> 
</span><del>-    router.replaceURL = function(path) {
-      lastURL = path;
-      Ember.run.once(doReplaceURL);
-    };
</del><ins>+    if (handler._actions &amp;&amp; handler._actions[name]) {
+      if (handler._actions[name].apply(handler, args) === true) {
+        eventWasHandled = true;
+      } else {
+        return;
+      }
+    }
</ins><span class="cx">   }
</span><span class="cx"> 
</span><del>-  router.didTransition = function(infos) {
-    emberRouter.didTransition(infos);
-  };
</del><ins>+  if (defaultActionHandlers[name]) {
+    defaultActionHandlers[name].apply(null, args);
+    return;
+  }
+
+  if (!eventWasHandled &amp;&amp; !ignoreFailure) {
+    throw new Ember.Error(&quot;Nothing handled the action '&quot; + name + &quot;'. If you did handle the action, this error can be caused by returning true from an action handler in a controller, causing the action to bubble.&quot;);
+  }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-function doTransition(router, method, args) {
-  var passedName = args[0], name;
</del><ins>+function updatePaths(router) {
+  var appController = router.container.lookup('controller:application');
</ins><span class="cx"> 
</span><del>-  if (!router.router.hasRoute(args[0])) {
-    name = args[0] = passedName + '.index';
-  } else {
-    name = passedName;
</del><ins>+  if (!appController) {
+    // appController might not exist when top-level loading/error
+    // substates have been entered since ApplicationRoute hasn't
+    // actually been entered at that point.
+    return;
</ins><span class="cx">   }
</span><span class="cx"> 
</span><del>-  Ember.assert(&quot;The route &quot; + passedName + &quot; was not found&quot;, router.router.hasRoute(name));
</del><ins>+  var infos = router.router.currentHandlerInfos,
+      path = Ember.Router._routePath(infos);
</ins><span class="cx"> 
</span><del>-  router.router[method].apply(router.router, args);
-  router.notifyPropertyChange('url');
</del><ins>+  if (!('currentPath' in appController)) {
+    defineProperty(appController, 'currentPath');
+  }
+
+  set(appController, 'currentPath', path);
+
+  if (!('currentRouteName' in appController)) {
+    defineProperty(appController, 'currentRouteName');
+  }
+
+  set(appController, 'currentRouteName', infos[infos.length - 1].name);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ember.Router.reopenClass({
</span><ins>+  router: null,
</ins><span class="cx">   map: function(callback) {
</span><del>-    var router = this.router = new Router();
</del><ins>+    var router = this.router;
+    if (!router) {
+      router = new Router();
+      router.callbacks = [];
+      router.triggerEvent = triggerEvent;
+      this.reopenClass({ router: router });
+    }
</ins><span class="cx"> 
</span><span class="cx">     var dsl = Ember.RouterDSL.map(function() {
</span><span class="cx">       this.resource('application', { path: &quot;/&quot; }, function() {
</span><ins>+        for (var i=0; i &lt; router.callbacks.length; i++) {
+          router.callbacks[i].call(this);
+        }
</ins><span class="cx">         callback.call(this);
</span><span class="cx">       });
</span><span class="cx">     });
</span><span class="cx"> 
</span><ins>+    router.callbacks.push(callback);
</ins><span class="cx">     router.map(dsl.generate());
</span><span class="cx">     return router;
</span><ins>+  },
+
+  _routePath: function(handlerInfos) {
+    var path = [];
+
+    // We have to handle coalescing resource names that
+    // are prefixed with their parent's names, e.g.
+    // ['foo', 'foo.bar.baz'] =&gt; 'foo.bar.baz', not 'foo.foo.bar.baz'
+
+    function intersectionMatches(a1, a2) {
+      for (var i = 0, len = a1.length; i &lt; len; ++i) {
+        if (a1[i] !== a2[i]) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    for (var i=1, l=handlerInfos.length; i&lt;l; i++) {
+      var name = handlerInfos[i].name,
+          nameParts = name.split(&quot;.&quot;),
+          oldNameParts = slice.call(path);
+
+      while (oldNameParts.length) {
+        if (intersectionMatches(oldNameParts, nameParts)) {
+          break;
+        }
+        oldNameParts.shift();
+      }
+
+      path.push.apply(path, nameParts.slice(oldNameParts.length));
+    }
+
+    return path.join(&quot;.&quot;);
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><ins>+Router.Transition.prototype.send = Router.Transition.prototype.trigger;
+
+
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -22996,9 +34118,13 @@
</span><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> var get = Ember.get, set = Ember.set,
</span><ins>+    getProperties = Ember.getProperties,
</ins><span class="cx">     classify = Ember.String.classify,
</span><del>-    decamelize = Ember.String.decamelize;
</del><ins>+    fmt = Ember.String.fmt,
+    a_forEach = Ember.EnumerableUtils.forEach,
+    a_replace = Ember.EnumerableUtils.replace;
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx"> /**
</span><span class="cx">   The `Ember.Route` class is used to define individual routes. Refer to
</span><span class="cx">   the [routing guide](http://emberjs.com/guides/routing/) for documentation.
</span><span class="lines">@@ -23006,8 +34132,10 @@
</span><span class="cx">   @class Route
</span><span class="cx">   @namespace Ember
</span><span class="cx">   @extends Ember.Object
</span><ins>+  @uses Ember.ActionHandler
</ins><span class="cx"> */
</span><del>-Ember.Route = Ember.Object.extend({
</del><ins>+Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
+
</ins><span class="cx">   /**
</span><span class="cx">     @private
</span><span class="cx"> 
</span><span class="lines">@@ -23015,7 +34143,7 @@
</span><span class="cx">   */
</span><span class="cx">   exit: function() {
</span><span class="cx">     this.deactivate();
</span><del>-    teardownView(this);
</del><ins>+    this.teardownViews();
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -23028,25 +34156,227 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    The collection of functions keyed by name available on this route as
</del><ins>+    The collection of functions, keyed by name, available on this route as
</ins><span class="cx">     action targets.
</span><span class="cx"> 
</span><span class="cx">     These functions will be invoked when a matching `{{action}}` is triggered
</span><span class="cx">     from within a template and the application's current route is this route.
</span><span class="cx"> 
</span><del>-    Events can also be invoked from other parts of your application via `Route#send`.
</del><ins>+    Actions can also be invoked from other parts of your application via `Route#send`
+    or `Controller#send`.
</ins><span class="cx"> 
</span><del>-    The context of event will be the this route.
</del><ins>+    The `actions` hash will inherit action handlers from
+    the `actions` hash defined on extended Route parent classes
+    or mixins rather than just replace the entire hash, e.g.:
</ins><span class="cx"> 
</span><del>-    @see {Ember.Route#send}
-    @see {Handlebars.helpers.action}
</del><ins>+    ```js
+    App.CanDisplayBanner = Ember.Mixin.create({
+      actions: {
+        displayBanner: function(msg) {
+          // ...
+        }
+      }
+    });
</ins><span class="cx"> 
</span><del>-    @property events
</del><ins>+    App.WelcomeRoute = Ember.Route.extend(App.CanDisplayBanner, {
+      actions: {
+        playMusic: function() {
+          // ...
+        }
+      }
+    });
+
+    // `WelcomeRoute`, when active, will be able to respond
+    // to both actions, since the actions hash is merged rather
+    // then replaced when extending mixins / parent classes.
+    this.send('displayBanner');
+    this.send('playMusic');
+    ```
+
+    Within a route's action handler, the value of the `this` context
+    is the Route object:
+
+    ```js
+    App.SongRoute = Ember.Route.extend({
+      actions: {
+        myAction: function() {
+          this.controllerFor(&quot;song&quot;);
+          this.transitionTo(&quot;other.route&quot;);
+          ...
+        }
+      }
+    });
+    ```
+
+    It is also possible to call `this._super()` from within an
+    action handler if it overrides a handler defined on a parent
+    class or mixin:
+
+    Take for example the following routes:
+
+    ```js
+    App.DebugRoute = Ember.Mixin.create({
+      actions: {
+        debugRouteInformation: function() {
+          console.debug(&quot;trololo&quot;);
+        }
+      }
+    });
+
+    App.AnnoyingDebugRoute = Ember.Route.extend(App.DebugRoute, {
+      actions: {
+        debugRouteInformation: function() {
+          // also call the debugRouteInformation of mixed in App.DebugRoute
+          this._super();
+
+          // show additional annoyance
+          window.alert(...);
+        }
+      }
+    });
+    ```
+
+    ## Bubbling
+
+    By default, an action will stop bubbling once a handler defined
+    on the `actions` hash handles it. To continue bubbling the action,
+    you must return `true` from the handler:
+
+    ```js
+    App.Router.map(function() {
+      this.resource(&quot;album&quot;, function() {
+        this.route(&quot;song&quot;);
+      });
+    });
+
+    App.AlbumRoute = Ember.Route.extend({
+      actions: {
+        startPlaying: function() {
+        }
+      }
+    });
+
+    App.AlbumSongRoute = Ember.Route.extend({
+      actions: {
+        startPlaying: function() {
+          // ...
+
+          if (actionShouldAlsoBeTriggeredOnParentRoute) {
+            return true;
+          }
+        }
+      }
+    });
+    ```
+
+    ## Built-in actions
+
+    There are a few built-in actions pertaining to transitions that you
+    can use to customize transition behavior: `willTransition` and
+    `error`.
+
+    ### `willTransition`
+
+    The `willTransition` action is fired at the beginning of any
+    attempted transition with a `Transition` object as the sole
+    argument. This action can be used for aborting, redirecting,
+    or decorating the transition from the currently active routes.
+
+    A good example is preventing navigation when a form is
+    half-filled out:
+
+    ```js
+    App.ContactFormRoute = Ember.Route.extend({
+      actions: {
+        willTransition: function(transition) {
+          if (this.controller.get('userHasEnteredData')) {
+            this.controller.displayNavigationConfirm();
+            transition.abort();
+          }
+        }
+      }
+    });
+    ```
+
+    You can also redirect elsewhere by calling
+    `this.transitionTo('elsewhere')` from within `willTransition`.
+    Note that `willTransition` will not be fired for the
+    redirecting `transitionTo`, since `willTransition` doesn't
+    fire when there is already a transition underway. If you want
+    subsequent `willTransition` actions to fire for the redirecting
+    transition, you must first explicitly call
+    `transition.abort()`.
+
+    ### `error`
+
+    When attempting to transition into a route, any of the hooks
+    may return a promise that rejects, at which point an `error`
+    action will be fired on the partially-entered routes, allowing
+    for per-route error handling logic, or shared error handling
+    logic defined on a parent route.
+
+    Here is an example of an error handler that will be invoked
+    for rejected promises from the various hooks on the route,
+    as well as any unhandled errors from child routes:
+
+    ```js
+    App.AdminRoute = Ember.Route.extend({
+      beforeModel: function() {
+        return Ember.RSVP.reject(&quot;bad things!&quot;);
+      },
+
+      actions: {
+        error: function(error, transition) {
+          // Assuming we got here due to the error in `beforeModel`,
+          // we can expect that error === &quot;bad things!&quot;,
+          // but a promise model rejecting would also
+          // call this hook, as would any errors encountered
+          // in `afterModel`.
+
+          // The `error` hook is also provided the failed
+          // `transition`, which can be stored and later
+          // `.retry()`d if desired.
+
+          this.transitionTo('login');
+        }
+      }
+    });
+    ```
+
+    `error` actions that bubble up all the way to `ApplicationRoute`
+    will fire a default error handler that logs the error. You can
+    specify your own global default error handler by overriding the
+    `error` handler on `ApplicationRoute`:
+
+    ```js
+    App.ApplicationRoute = Ember.Route.extend({
+      actions: {
+        error: function(error, transition) {
+          this.controllerFor('banner').displayError(error.message);
+        }
+      }
+    });
+    ```
+
+    @property actions
</ins><span class="cx">     @type Hash
</span><span class="cx">     @default null
</span><span class="cx">   */
</span><ins>+  _actions: {
+    finalizeQueryParamChange: function(params, finalParams) {
+          }
+  },
+
+  /**
+    @deprecated
+
+    Please use `actions` instead.
+    @method events
+  */
</ins><span class="cx">   events: null,
</span><span class="cx"> 
</span><ins>+  mergedProperties: ['events'],
+
</ins><span class="cx">   /**
</span><span class="cx">     This hook is executed when the router completely exits this route. It is
</span><span class="cx">     not executed when the model for the route changes.
</span><span class="lines">@@ -23056,79 +34386,213 @@
</span><span class="cx">   deactivate: Ember.K,
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    This hook is executed when the router enters the route for the first time.
-    It is not executed when the model for the route changes.
</del><ins>+    This hook is executed when the router enters the route. It is not executed
+    when the model for the route changes.
</ins><span class="cx"> 
</span><span class="cx">     @method activate
</span><span class="cx">   */
</span><span class="cx">   activate: Ember.K,
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Transition into another route. Optionally supply a model for the
-    route in question. The model will be serialized into the URL
-    using the `serialize` hook.
</del><ins>+    Transition into another route. Optionally supply model(s) for the
+    route in question. If multiple models are supplied they will be applied
+    last to first recursively up the resource tree (see Multiple Models Example
+    below). The model(s) will be serialized into the URL using the appropriate
+    route's `serialize` hook. See also 'replaceWith'.
</ins><span class="cx"> 
</span><ins>+    Simple Transition Example
+
+    ```javascript
+    App.Router.map(function() {
+      this.route(&quot;index&quot;);
+      this.route(&quot;secret&quot;);
+      this.route(&quot;fourOhFour&quot;, { path: &quot;*:&quot;});
+    });
+
+    App.IndexRoute = Ember.Route.extend({
+      actions: {
+        moveToSecret: function(context){
+          if (authorized()){
+            this.transitionTo('secret', context);
+          }
+            this.transitionTo('fourOhFour');
+        }
+      }
+    });
+    ```
+
+   Transition to a nested route
+
+   ```javascript
+   App.Router.map(function() {
+     this.resource('articles', { path: '/articles' }, function() {
+       this.route('new');
+     });
+   });
+
+   App.IndexRoute = Ember.Route.extend({
+     actions: {
+       transitionToNewArticle: function() {
+         this.transitionTo('articles.new');
+       }
+     }
+   });
+   ```
+
+    Multiple Models Example
+
+    ```javascript
+    App.Router.map(function() {
+      this.route(&quot;index&quot;);
+      this.resource('breakfast', {path:':breakfastId'}, function(){
+        this.resource('cereal', {path: ':cerealId'});
+      });
+    });
+
+    App.IndexRoute = Ember.Route.extend({
+      actions: {
+        moveToChocolateCereal: function(){
+          var cereal = { cerealId: &quot;ChocolateYumminess&quot;},
+              breakfast = {breakfastId: &quot;CerealAndMilk&quot;};
+
+          this.transitionTo('cereal', breakfast, cereal);
+        }
+      }
+    });
+
</ins><span class="cx">     @method transitionTo
</span><span class="cx">     @param {String} name the name of the route
</span><del>-    @param {...Object} models the
</del><ins>+    @param {...Object} models the model(s) to be used while transitioning
+    to the route.
</ins><span class="cx">   */
</span><del>-  transitionTo: function() {
-    if (this._checkingRedirect) { this.redirected = true; }
-    return this.router.transitionTo.apply(this.router, arguments);
</del><ins>+  transitionTo: function(name, context) {
+    var router = this.router;
+    return router.transitionTo.apply(router, arguments);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Transition into another route while replacing the current URL if
-    possible. Identical to `transitionTo` in all other respects.
</del><ins>+    Perform a synchronous transition into another route with out attempting
+    to resolve promises, update the URL, or abort any currently active
+    asynchronous transitions (i.e. regular transitions caused by
+    `transitionTo` or URL changes).
</ins><span class="cx"> 
</span><ins>+    This method is handy for performing intermediate transitions on the
+    way to a final destination route, and is called internally by the
+    default implementations of the `error` and `loading` handlers.
+
+    @method intermediateTransitionTo
+    @param {String} name the name of the route
+    @param {...Object} models the model(s) to be used while transitioning
+    to the route.
+   */
+  intermediateTransitionTo: function() {
+    var router = this.router;
+    router.intermediateTransitionTo.apply(router, 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 `transitionTo` in all other respects. See
+    'transitionTo' for additional information regarding multiple models.
+
+    Example
+
+    ```javascript
+    App.Router.map(function() {
+      this.route(&quot;index&quot;);
+      this.route(&quot;secret&quot;);
+    });
+
+    App.SecretRoute = Ember.Route.extend({
+      afterModel: function() {
+        if (!authorized()){
+          this.replaceWith('index');
+        }
+      }
+    });
+    ```
+
</ins><span class="cx">     @method replaceWith
</span><span class="cx">     @param {String} name the name of the route
</span><del>-    @param {...Object} models the
</del><ins>+    @param {...Object} models the model(s) to be used while transitioning
+    to the route.
</ins><span class="cx">   */
</span><span class="cx">   replaceWith: function() {
</span><del>-    if (this._checkingRedirect) { this.redirected = true; }
-    return this.router.replaceWith.apply(this.router, arguments);
</del><ins>+    var router = this.router;
+    return router.replaceWith.apply(router, arguments);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    Sends an action to the router, which will delegate it to the currently
+    active route hierarchy per the bubbling rules explained under `actions`.
+
+    Example
+
+    ```javascript
+    App.Router.map(function() {
+      this.route(&quot;index&quot;);
+    });
+
+    App.ApplicationRoute = Ember.Route.extend({
+      actions: {
+        track: function(arg) {
+          console.log(arg, 'was clicked');
+        }
+      }
+    });
+
+    App.IndexRoute = Ember.Route.extend({
+      actions: {
+        trackIfDebug: function(arg) {
+          if (debug) {
+            this.send('track', arg);
+          }
+        }
+      }
+    });
+    ```
+
+    @method send
+    @param {String} name the name of the action to trigger
+    @param {...*} args
+  */
</ins><span class="cx">   send: function() {
</span><span class="cx">     return this.router.send.apply(this.router, arguments);
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     This hook is the entry point for router.js
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method setup
</span><span class="cx">   */
</span><del>-  setup: function(context) {
-    this.redirected = false;
-    this._checkingRedirect = true;
</del><ins>+  setup: function(context, queryParams) {
+    var controllerName = this.controllerName || this.routeName,
+        controller = this.controllerFor(controllerName, true);
+    if (!controller) {
+      controller =  this.generateController(controllerName, context);
+    }
</ins><span class="cx"> 
</span><del>-    this.redirect(context);
</del><ins>+    // Assign the route's controller so that it can more easily be
+    // referenced in action handlers
+    this.controller = controller;
</ins><span class="cx"> 
</span><del>-    this._checkingRedirect = false;
-    if (this.redirected) { return false; }
</del><ins>+    var args = [controller, context];
</ins><span class="cx"> 
</span><del>-    var controller = this.controllerFor(this.routeName, context);
-
-    if (controller) {
-      this.controller = controller;
-      set(controller, 'model', context);
-    }
-
</del><ins>+    
</ins><span class="cx">     if (this.setupControllers) {
</span><span class="cx">       Ember.deprecate(&quot;Ember.Route.setupControllers is deprecated. Please use Ember.Route.setupController(controller, model) instead.&quot;);
</span><span class="cx">       this.setupControllers(controller, context);
</span><span class="cx">     } else {
</span><del>-      this.setupController(controller, context);
</del><ins>+      this.setupController.apply(this, args);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (this.renderTemplates) {
</span><span class="cx">       Ember.deprecate(&quot;Ember.Route.renderTemplates is deprecated. Please use Ember.Route.renderTemplate(controller, model) instead.&quot;);
</span><span class="cx">       this.renderTemplates(context);
</span><span class="cx">     } else {
</span><del>-      this.renderTemplate(controller, context);
</del><ins>+      this.renderTemplate.apply(this, args);
</ins><span class="cx">     }
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="lines">@@ -23138,28 +34602,137 @@
</span><span class="cx">     If you call `this.transitionTo` from inside of this hook, this route
</span><span class="cx">     will not be entered in favor of the other hook.
</span><span class="cx"> 
</span><ins>+    Note that this hook is called by the default implementation of
+    `afterModel`, so if you override `afterModel`, you must either
+    explicitly call `redirect` or just put your redirecting
+    `this.transitionTo()` call within `afterModel`.
+
</ins><span class="cx">     @method redirect
</span><span class="cx">     @param {Object} model the model for this route
</span><span class="cx">   */
</span><span class="cx">   redirect: Ember.K,
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
</del><ins>+    This hook is the first of the route entry validation hooks
+    called when an attempt is made to transition into a route
+    or one of its children. It is called before `model` and
+    `afterModel`, and is appropriate for cases when:
</ins><span class="cx"> 
</span><del>-    The hook called by `router.js` to convert parameters into the context
-    for this handler. The public Ember hook is `model`.
</del><ins>+    1) A decision can be made to redirect elsewhere without
+       needing to resolve the model first.
+    2) Any async operations need to occur first before the
+       model is attempted to be resolved.
</ins><span class="cx"> 
</span><del>-    @method deserialize
</del><ins>+    This hook is provided the current `transition` attempt
+    as a parameter, which can be used to `.abort()` the transition,
+    save it for a later `.retry()`, or retrieve values set
+    on it from a previous hook. You can also just call
+    `this.transitionTo` to another route to implicitly
+    abort the `transition`.
+
+    You can return a promise from this hook to pause the
+    transition until the promise resolves (or rejects). This could
+    be useful, for instance, for retrieving async code from
+    the server that is required to enter a route.
+
+    ```js
+    App.PostRoute = Ember.Route.extend({
+      beforeModel: function(transition) {
+        if (!App.Post) {
+          return Ember.$.getScript('/models/post.js');
+        }
+      }
+    });
+    ```
+
+    If `App.Post` doesn't exist in the above example,
+    `beforeModel` will use jQuery's `getScript`, which
+    returns a promise that resolves after the server has
+    successfully retrieved and executed the code from the
+    server. Note that if an error were to occur, it would
+    be passed to the `error` hook on `Ember.Route`, but
+    it's also possible to handle errors specific to
+    `beforeModel` right from within the hook (to distinguish
+    from the shared error handling behavior of the `error`
+    hook):
+
+    ```js
+    App.PostRoute = Ember.Route.extend({
+      beforeModel: function(transition) {
+        if (!App.Post) {
+          var self = this;
+          return Ember.$.getScript('post.js').then(null, function(e) {
+            self.transitionTo('help');
+
+            // Note that the above transitionTo will implicitly
+            // halt the transition. If you were to return
+            // nothing from this promise reject handler,
+            // according to promise semantics, that would
+            // convert the reject into a resolve and the
+            // transition would continue. To propagate the
+            // error so that it'd be handled by the `error`
+            // hook, you would have to either
+            return Ember.RSVP.reject(e);
+            // or
+            throw e;
+          });
+        }
+      }
+    });
+    ```
+
+    @method beforeModel
+    @param {Transition} transition
+    @param {Object} queryParams the active query params for this route
+    @return {Promise} if the value returned from this hook is
+      a promise, the transition will pause until the transition
+      resolves. Otherwise, non-promise return values are not
+      utilized in any way.
</ins><span class="cx">   */
</span><del>-  deserialize: function(params) {
-    var model = this.model(params);
-    return this.currentModel = model;
</del><ins>+  beforeModel: Ember.K,
+
+  /**
+    This hook is called after this route's model has resolved.
+    It follows identical async/promise semantics to `beforeModel`
+    but is provided the route's resolved model in addition to
+    the `transition`, and is therefore suited to performing
+    logic that can only take place after the model has already
+    resolved.
+
+    ```js
+    App.PostsRoute = Ember.Route.extend({
+      afterModel: function(posts, transition) {
+        if (posts.length === 1) {
+          this.transitionTo('post.show', posts[0]);
+        }
+      }
+    });
+    ```
+
+    Refer to documentation for `beforeModel` for a description
+    of transition-pausing semantics when a promise is returned
+    from this hook.
+
+    @method afterModel
+    @param {Object} resolvedModel the value returned from `model`,
+      or its resolved value if it was a promise
+    @param {Transition} transition
+    @param {Object} queryParams the active query params for this handler
+    @return {Promise} if the value returned from this hook is
+      a promise, the transition will pause until the transition
+      resolves. Otherwise, non-promise return values are not
+      utilized in any way.
+   */
+  afterModel: function(resolvedModel, transition, queryParams) {
+    this.redirect(resolvedModel, transition);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">   /**
</span><ins>+    Called when the context is changed by router.js.
+
</ins><span class="cx">     @private
</span><del>-
-    Called when the context is changed by router.js.
</del><ins>+    @method contextDidChange
</ins><span class="cx">   */
</span><span class="cx">   contextDidChange: function() {
</span><span class="cx">     this.currentModel = this.context;
</span><span class="lines">@@ -23170,8 +34743,8 @@
</span><span class="cx">     this route.
</span><span class="cx"> 
</span><span class="cx">     ```js
</span><del>-    App.Route.map(function(match) {
-      match(&quot;/posts/:post_id&quot;).to(&quot;post&quot;);
</del><ins>+    App.Router.map(function() {
+      this.resource('post', {path: '/posts/:post_id'});
</ins><span class="cx">     });
</span><span class="cx">     ```
</span><span class="cx"> 
</span><span class="lines">@@ -23184,10 +34757,38 @@
</span><span class="cx">     * The find method is called on the model class with the value of
</span><span class="cx">       the dynamic segment.
</span><span class="cx"> 
</span><ins>+    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);
+      }
+    });
+    ```
+
</ins><span class="cx">     @method model
</span><span class="cx">     @param {Object} params the parameters extracted from the URL
</span><ins>+    @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.
</ins><span class="cx">   */
</span><del>-  model: function(params) {
</del><ins>+  model: function(params, transition) {
</ins><span class="cx">     var match, name, sawParams, value;
</span><span class="cx"> 
</span><span class="cx">     for (var prop in params) {
</span><span class="lines">@@ -23201,21 +34802,59 @@
</span><span class="cx">     if (!name &amp;&amp; sawParams) { return params; }
</span><span class="cx">     else if (!name) { return; }
</span><span class="cx"> 
</span><del>-    var className = classify(name),
-        namespace = this.router.namespace,
-        modelClass = namespace[className];
</del><ins>+    return this.findModel(name, value);
+  },
</ins><span class="cx"> 
</span><del>-    Ember.assert(&quot;You used the dynamic segment &quot; + name + &quot;_id in your router, but &quot; + namespace + &quot;.&quot; + className + &quot; did not exist and you did not override your state's `model` hook.&quot;, modelClass);
-    return modelClass.find(value);
</del><ins>+  /**
+
+    @method findModel
+    @param {String} type the model type
+    @param {Object} value the value passed to find
+  */
+  findModel: function(){
+    var store = get(this, 'store');
+    return store.find.apply(store, arguments);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+    Store property provides a hook for data persistence libraries to inject themselves.
+
+    By default, this store property provides the exact same functionality previously
+    in the model hook.
+
+    Currently, the required interface is:
+
+    `store.find(modelName, findArguments)`
+
+    @method store
+    @param {Object} store
+  */
+  store: Ember.computed(function(){
+    var container = this.container;
+    var routeName = this.routeName;
+    var namespace = get(this, 'router.namespace');
+
+    return {
+      find: function(name, value) {
+        var modelClass = container.lookupFactory('model:' + name);
+
+        Ember.assert(&quot;You used the dynamic segment &quot; + name + &quot;_id in your route &quot; +
+                     routeName + &quot;, but &quot; + namespace + &quot;.&quot; + classify(name) +
+                     &quot; did not exist and you did not override your route's `model` &quot; +
+                     &quot;hook.&quot;, modelClass);
+
+        return modelClass.find(value);
+      }
+    };
+  }),
+
+  /**
</ins><span class="cx">     A hook you can implement to convert the route's model into parameters
</span><span class="cx">     for the URL.
</span><span class="cx"> 
</span><span class="cx">     ```js
</span><del>-    App.Route.map(function(match) {
-      match(&quot;/posts/:post_id&quot;).to(&quot;post&quot;);
</del><ins>+    App.Router.map(function() {
+      this.resource('post', {path: '/posts/:post_id'});
</ins><span class="cx">     });
</span><span class="cx"> 
</span><span class="cx">     App.PostRoute = Ember.Route.extend({
</span><span class="lines">@@ -23231,8 +34870,10 @@
</span><span class="cx">     });
</span><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    The default `serialize` method inserts the model's `id` into the
-    route's dynamic segment (in this case, `:post_id`).
</del><ins>+    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)`
</ins><span class="cx"> 
</span><span class="cx">     This method is called when `transitionTo` is called with a context
</span><span class="cx">     in order to populate the URL.
</span><span class="lines">@@ -23244,14 +34885,15 @@
</span><span class="cx">     @return {Object} the serialized parameters
</span><span class="cx">   */
</span><span class="cx">   serialize: function(model, params) {
</span><del>-    if (params.length !== 1) { return; }
</del><ins>+    if (params.length &lt; 1) { return; }
+    if (!model) { return; }
</ins><span class="cx"> 
</span><span class="cx">     var name = params[0], object = {};
</span><span class="cx"> 
</span><del>-    if (/_id$/.test(name)) {
-      object[name] = get(model, 'id');
</del><ins>+    if (/_id$/.test(name) &amp;&amp; params.length === 1) {
+      object[name] = get(model, &quot;id&quot;);
</ins><span class="cx">     } else {
</span><del>-      object[name] = model;
</del><ins>+      object = getProperties(model, params);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return object;
</span><span class="lines">@@ -23263,34 +34905,60 @@
</span><span class="cx">     This method is called with the controller for the current route and the
</span><span class="cx">     model supplied by the `model` hook.
</span><span class="cx"> 
</span><del>-    ```js
-    App.Route.map(function(match) {
-      match(&quot;/posts/:post_id&quot;).to(&quot;post&quot;);
-    });
-    ```
-
-    For the `post` route, the controller is `App.PostController`.
-
</del><span class="cx">     By default, the `setupController` hook sets the `content` property of
</span><span class="cx">     the controller to the `model`.
</span><span class="cx"> 
</span><del>-    If no explicit controller is defined, the route will automatically create
-    an appropriate controller for the model:
</del><ins>+    This means that your template will get a proxy for the model as its
+    context, and you can act as though the model itself was the context.
</ins><span class="cx"> 
</span><ins>+    The provided controller will be one resolved based on the name
+    of this route.
+
+    If no explicit controller is defined, Ember will automatically create
+    an appropriate controller for the model.
+
</ins><span class="cx">     * if the model is an `Ember.Array` (including record arrays from Ember
</span><span class="cx">       Data), the controller is an `Ember.ArrayController`.
</span><span class="cx">     * otherwise, the controller is an `Ember.ObjectController`.
</span><span class="cx"> 
</span><del>-    This means that your template will get a proxy for the model as its
-    context, and you can act as though the model itself was the context.
</del><ins>+    As an example, consider the router:
</ins><span class="cx"> 
</span><ins>+    ```js
+    App.Router.map(function() {
+      this.resource('post', {path: '/posts/:post_id'});
+    });
+    ```
+
+    For the `post` route, a controller named `App.PostController` would
+    be used if it is defined. If it is not defined, an `Ember.ObjectController`
+    instance would be used.
+
+    Example
+
+    ```js
+    App.PostRoute = Ember.Route.extend({
+      setupController: function(controller, model) {
+        controller.set('model', model);
+      }
+    });
+    ```
+
</ins><span class="cx">     @method setupController
</span><ins>+    @param {Controller} controller instance
+    @param {Object} model
</ins><span class="cx">   */
</span><del>-  setupController: Ember.K,
</del><ins>+  setupController: function(controller, context) {
+    if (controller &amp;&amp; (context !== undefined)) {
+      set(controller, 'model', context);
+    }
+  },
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Returns the controller for a particular route.
</del><ins>+    Returns the controller for a particular route or name.
</ins><span class="cx"> 
</span><ins>+    The controller instance must already have been created, either through entering the
+    associated route or using `generateController`.
+
</ins><span class="cx">     ```js
</span><span class="cx">     App.PostRoute = Ember.Route.extend({
</span><span class="cx">       setupController: function(controller, post) {
</span><span class="lines">@@ -23300,41 +34968,105 @@
</span><span class="cx">     });
</span><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    By default, the controller for `post` is the shared instance of
-    `App.PostController`.
-
</del><span class="cx">     @method controllerFor
</span><del>-    @param {String} name the name of the route
-    @param {Object} model the model associated with the route (optional)
</del><ins>+    @param {String} name the name of the route or controller
</ins><span class="cx">     @return {Ember.Controller}
</span><span class="cx">   */
</span><del>-  controllerFor: function(name, model) {
-    var container = this.router.container,
-        controller = container.lookup('controller:' + name);
</del><ins>+  controllerFor: function(name, _skipAssert) {
+    var container = this.container,
+        route = container.lookup('route:'+name),
+        controller;
</ins><span class="cx"> 
</span><del>-    if (!controller) {
-      model = model || this.modelFor(name);
</del><ins>+    if (route &amp;&amp; route.controllerName) {
+      name = route.controllerName;
+    }
</ins><span class="cx"> 
</span><del>-      Ember.assert(&quot;You are trying to look up a controller that you did not define, and for which Ember does not know the model.\n\nThis is not a controller for a route, so you must explicitly define the controller (&quot;+this.router.namespace.toString() + &quot;.&quot; + Ember.String.capitalize(Ember.String.camelize(name))+&quot;Controller) or pass a model as the second parameter to `controllerFor`, so that Ember knows which type of controller to create for you.&quot;, model || this.container.lookup('route:' + name));
</del><ins>+    controller = container.lookup('controller:' + name);
</ins><span class="cx"> 
</span><del>-      controller = Ember.generateController(container, name, model);
-    }
</del><ins>+    // 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(&quot;The controller named '&quot;+name+&quot;' could not be found. Make sure &quot; +
+                 &quot;that this route exists and has already been entered at least &quot; +
+                 &quot;once. If you are accessing a controller not associated with a &quot; +
+                 &quot;route, make sure the controller class is explicitly defined.&quot;,
+                 controller || _skipAssert === true);
</ins><span class="cx"> 
</span><span class="cx">     return controller;
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Returns the current model for a given route.
</del><ins>+    Generates a controller for a route.
</ins><span class="cx"> 
</span><del>-    This is the object returned by the `model` hook of the route
-    in question.
</del><ins>+    If the optional model is passed then the controller type is determined automatically,
+    e.g., an ArrayController for arrays.
</ins><span class="cx"> 
</span><ins>+    Example
+
+    ```js
+    App.PostRoute = Ember.Route.extend({
+      setupController: function(controller, post) {
+        this._super(controller, post);
+        this.generateController('posts', post);
+      }
+    });
+    ```
+
+    @method generateController
+    @param {String} name the name of the controller
+    @param {Object} model the model to infer the type of the controller (optional)
+  */
+  generateController: function(name, model) {
+    var container = this.container;
+
+    model = model || this.modelFor(name);
+
+    return Ember.generateController(container, name, model);
+  },
+
+  /**
+    Returns the model of a parent (or any ancestor) route
+    in a route hierarchy.  During a transition, all routes
+    must resolve a model object, and if a route
+    needs access to a parent route's model in order to
+    resolve a model (or just reuse the model from a parent),
+    it can call `this.modelFor(theNameOfParentRoute)` to
+    retrieve it.
+
+    Example
+
+    ```js
+    App.Router.map(function() {
+        this.resource('post', { path: '/post/:post_id' }, function() {
+            this.resource('comments');
+        });
+    });
+
+    App.CommentsRoute = Ember.Route.extend({
+        afterModel: function() {
+            this.set('post', this.modelFor('post'));
+        }
+    });
+    ```
+
</ins><span class="cx">     @method modelFor
</span><span class="cx">     @param {String} name the name of the route
</span><span class="cx">     @return {Object} the model object
</span><span class="cx">   */
</span><span class="cx">   modelFor: function(name) {
</span><del>-    var route = this.container.lookup('route:' + name);
</del><ins>+
+    var route = this.container.lookup('route:' + name),
+        transition = this.router.router.activeTransition;
+
+    // If we are mid-transition, we want to try and look up
+    // resolved parent contexts on the current transitionEvent.
+    if (transition) {
+      var modelLookupName = (route &amp;&amp; route.routeName) || name;
+      if (transition.resolvedModels.hasOwnProperty(modelLookupName)) {
+        return transition.resolvedModels[modelLookupName];
+      }
+    }
+
</ins><span class="cx">     return route &amp;&amp; route.currentModel;
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="lines">@@ -23348,6 +35080,22 @@
</span><span class="cx">     This method can be overridden to set up and render additional or
</span><span class="cx">     alternative templates.
</span><span class="cx"> 
</span><ins>+    ```js
+    App.PostsRoute = Ember.Route.extend({
+      renderTemplate: function(controller, model) {
+        var favController = this.controllerFor('favoritePost');
+
+        // Render the `favoritePost` template into
+        // the outlet `posts`, and display the `favoritePost`
+        // controller.
+        this.render('favoritePost', {
+          outlet: 'posts',
+          controller: favController
+        });
+      }
+    });
+    ```
+
</ins><span class="cx">     @method renderTemplate
</span><span class="cx">     @param {Object} controller the route's controller
</span><span class="cx">     @param {Object} model the route's model
</span><span class="lines">@@ -23365,9 +35113,9 @@
</span><span class="cx">     For example:
</span><span class="cx"> 
</span><span class="cx">     ```js
</span><del>-    App.Router.map(function(match) {
-      match(&quot;/&quot;).to(&quot;index&quot;);
-      match(&quot;/posts/:post_id&quot;).to(&quot;post&quot;);
</del><ins>+    App.Router.map(function() {
+      this.route('index');
+      this.resource('post', {path: '/posts/:post_id'});
</ins><span class="cx">     });
</span><span class="cx"> 
</span><span class="cx">     App.PostRoute = App.Route.extend({
</span><span class="lines">@@ -23408,19 +35156,45 @@
</span><span class="cx">     @param {Object} options the options
</span><span class="cx">   */
</span><span class="cx">   render: function(name, options) {
</span><ins>+    Ember.assert(&quot;The name in the given arguments is undefined&quot;, arguments.length &gt; 0 ? !Ember.isNone(arguments[0]) : true);
+
+    var namePassed = !!name;
+
</ins><span class="cx">     if (typeof name === 'object' &amp;&amp; !options) {
</span><span class="cx">       options = name;
</span><span class="cx">       name = this.routeName;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    name = name ? name.replace(/\//g, '.') : this.routeName;
</del><ins>+    options = options || {};
</ins><span class="cx"> 
</span><ins>+    var templateName;
+
+    if (name) {
+      name = name.replace(/\//g, '.');
+      templateName = name;
+    } else {
+      name = this.routeName;
+      templateName = this.templateName || name;
+    }
+
+    var viewName = options.view || this.viewName || name;
+
</ins><span class="cx">     var container = this.container,
</span><del>-        view = container.lookup('view:' + name),
-        template = container.lookup('template:' + name);
</del><ins>+        view = container.lookup('view:' + viewName),
+        template = view ? view.get('template') : null;
</ins><span class="cx"> 
</span><del>-    if (!view &amp;&amp; !template) { return; }
</del><ins>+    if (!template) {
+      template = container.lookup('template:' + templateName);
+    }
</ins><span class="cx"> 
</span><ins>+    if (!view &amp;&amp; !template) {
+      Ember.assert(&quot;Could not find \&quot;&quot; + name + &quot;\&quot; template or view.&quot;, !namePassed);
+      if (get(this.router, 'namespace.LOG_VIEW_LOOKUPS')) {
+        Ember.Logger.info(&quot;Could not find \&quot;&quot; + name + &quot;\&quot; template or view. Nothing will be rendered&quot;, { fullName: 'template:' + name });
+      }
+      return;
+    }
+
</ins><span class="cx">     options = normalizeOptions(this, name, template, options);
</span><span class="cx">     view = setupView(view, container, options);
</span><span class="cx"> 
</span><span class="lines">@@ -23429,14 +35203,78 @@
</span><span class="cx">     appendView(this, view, options);
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    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'
+          });
+        }
+      }
+    });
+    ```
+
+    @method disconnectOutlet
+    @param {Object} options the options
+  */
+  disconnectOutlet: function(options) {
+    options = options || {};
+    options.parentView = options.parentView ? options.parentView.replace(/\//g, '.') : parentTemplate(this);
+    options.outlet = options.outlet || 'main';
+
+    var parentView = this.router._lookupActiveView(options.parentView);
+    parentView.disconnectOutlet(options.outlet);
+  },
+
</ins><span class="cx">   willDestroy: function() {
</span><del>-    teardownView(this);
</del><ins>+    this.teardownViews();
+  },
+
+  /**
+    @private
+
+    @method teardownViews
+  */
+  teardownViews: function() {
+    // Tear down the top level view
+    if (this.teardownTopLevelView) { this.teardownTopLevelView(); }
+
+    // Tear down any outlets rendered with 'into'
+    var teardownOutletViews = this.teardownOutletViews || [];
+    a_forEach(teardownOutletViews, function(teardownOutletView) {
+      teardownOutletView();
+    });
+
+    delete this.teardownTopLevelView;
+    delete this.teardownOutletViews;
+    delete this.lastRenderedTemplate;
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> function parentRoute(route) {
</span><del>-  var handlerInfos = route.router.router.currentHandlerInfos;
</del><ins>+  var handlerInfos = route.router.router.targetHandlerInfos;
</ins><span class="cx"> 
</span><ins>+  if (!handlerInfos) { return; }
+
</ins><span class="cx">   var parent, current;
</span><span class="cx"> 
</span><span class="cx">   for (var i=0, l=handlerInfos.length; i&lt;l; i++) {
</span><span class="lines">@@ -23446,17 +35284,15 @@
</span><span class="cx">   }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function parentTemplate(route, isRecursive) {
</del><ins>+function parentTemplate(route) {
</ins><span class="cx">   var parent = parentRoute(route), template;
</span><span class="cx"> 
</span><span class="cx">   if (!parent) { return; }
</span><span class="cx"> 
</span><del>-  Ember.warn(&quot;The immediate parent route did not render into the main outlet and the default 'into' option may not be expected&quot;, !isRecursive);
-
</del><span class="cx">   if (template = parent.lastRenderedTemplate) {
</span><span class="cx">     return template;
</span><span class="cx">   } else {
</span><del>-    return parentTemplate(parent, true);
</del><ins>+    return parentTemplate(parent);
</ins><span class="cx">   }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -23466,8 +35302,9 @@
</span><span class="cx">   options.outlet = options.outlet || 'main';
</span><span class="cx">   options.name = name;
</span><span class="cx">   options.template = template;
</span><ins>+  options.LOG_VIEW_LOOKUPS = get(route.router, 'namespace.LOG_VIEW_LOOKUPS');
</ins><span class="cx"> 
</span><del>-  Ember.assert(&quot;An outlet (&quot;+options.outlet+&quot;) was specified but this view will render at the root level.&quot;, options.outlet === 'main' || options.into);
</del><ins>+  Ember.assert(&quot;An outlet (&quot;+options.outlet+&quot;) was specified but was not found.&quot;, options.outlet === 'main' || options.into);
</ins><span class="cx"> 
</span><span class="cx">   var controller = options.controller, namedController;
</span><span class="cx"> 
</span><span class="lines">@@ -23476,7 +35313,7 @@
</span><span class="cx">   } else if (namedController = route.container.lookup('controller:' + name)) {
</span><span class="cx">     controller = namedController;
</span><span class="cx">   } else {
</span><del>-    controller = route.routeName;
</del><ins>+    controller = route.controllerName || route.routeName;
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   if (typeof controller === 'string') {
</span><span class="lines">@@ -23489,10 +35326,18 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function setupView(view, container, options) {
</span><del>-  var defaultView = options.into ? 'view:default' : 'view:toplevel';
</del><ins>+  if (view) {
+    if (options.LOG_VIEW_LOOKUPS) {
+      Ember.Logger.info(&quot;Rendering &quot; + options.name + &quot; with &quot; + view, { fullName: 'view:' + options.name });
+    }
+  } else {
+    var defaultView = options.into ? 'view:default' : 'view:toplevel';
+    view = container.lookup(defaultView);
+    if (options.LOG_VIEW_LOOKUPS) {
+      Ember.Logger.info(&quot;Rendering &quot; + options.name + &quot; with default view &quot; + view, { fullName: 'view:' + options.name });
+    }
+  }
</ins><span class="cx"> 
</span><del>-  view = view || container.lookup(defaultView);
-
</del><span class="cx">   if (!get(view, 'templateName')) {
</span><span class="cx">     set(view, 'template', options.template);
</span><span class="cx"> 
</span><span class="lines">@@ -23508,37 +35353,85 @@
</span><span class="cx"> function appendView(route, view, options) {
</span><span class="cx">   if (options.into) {
</span><span class="cx">     var parentView = route.router._lookupActiveView(options.into);
</span><del>-    route.teardownView = teardownOutlet(parentView, options.outlet);
</del><ins>+    var teardownOutletView = generateOutletTeardown(parentView, options.outlet);
+    if (!route.teardownOutletViews) { route.teardownOutletViews = []; }
+    a_replace(route.teardownOutletViews, 0, 0, [teardownOutletView]);
</ins><span class="cx">     parentView.connectOutlet(options.outlet, view);
</span><span class="cx">   } else {
</span><span class="cx">     var rootElement = get(route, 'router.namespace.rootElement');
</span><ins>+    // tear down view if one is already rendered
+    if (route.teardownTopLevelView) {
+      route.teardownTopLevelView();
+    }
</ins><span class="cx">     route.router._connectActiveView(options.name, view);
</span><del>-    route.teardownView = teardownTopLevel(view);
</del><ins>+    route.teardownTopLevelView = generateTopLevelTeardown(view);
</ins><span class="cx">     view.appendTo(rootElement);
</span><span class="cx">   }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function teardownTopLevel(view) {
</del><ins>+function generateTopLevelTeardown(view) {
</ins><span class="cx">   return function() { view.destroy(); };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function teardownOutlet(parentView, outlet) {
</del><ins>+function generateOutletTeardown(parentView, outlet) {
</ins><span class="cx">   return function() { parentView.disconnectOutlet(outlet); };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function teardownView(route) {
-  if (route.teardownView) { route.teardownView(); }
</del><ins>+})();
</ins><span class="cx"> 
</span><del>-  delete route.teardownView;
-  delete route.lastRenderedTemplate;
-}
</del><span class="cx"> 
</span><ins>+
+(function() {
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><ins>+Ember.onLoad('Ember.Handlebars', function() {
+  var handlebarsResolve = Ember.Handlebars.resolveParams,
+      map = Ember.ArrayPolyfills.map,
+      get = Ember.get,
+      handlebarsGet = Ember.Handlebars.get;
</ins><span class="cx"> 
</span><ins>+  function resolveParams(context, params, options) {
+    return map.call(resolvePaths(context, params, options), function(path, i) {
+      if (null === path) {
+        // Param was string/number, not a path, so just return raw string/number.
+        return params[i];
+      } else {
+        return handlebarsGet(context, path, options);
+      }
+    });
+  }
+
+  function resolvePaths(context, params, options) {
+    var resolved = handlebarsResolve(context, params, options),
+        types = options.types;
+
+    return map.call(resolved, function(object, i) {
+      if (types[i] === 'ID') {
+        return unwrap(object, params[i]);
+      } else {
+        return null;
+      }
+    });
+
+    function unwrap(object, path) {
+      if (path === 'controller') { return path; }
+
+      if (Ember.ControllerMixin.detect(object)) {
+        return unwrap(get(object, 'model'), path ? path + '.model' : 'model');
+      } else {
+        return path;
+      }
+    }
+  }
+
+  Ember.Router.resolveParams = resolveParams;
+  Ember.Router.resolvePaths = resolvePaths;
+});
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -23549,106 +35442,741 @@
</span><span class="cx"> @submodule ember-routing
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var get = Ember.get, set = Ember.set;
</del><ins>+var get = Ember.get, set = Ember.set, fmt = Ember.String.fmt;
</ins><span class="cx"> Ember.onLoad('Ember.Handlebars', function(Handlebars) {
</span><span class="cx"> 
</span><del>-  var resolveParams = Ember.Handlebars.resolveParams,
</del><ins>+  var resolveParams = Ember.Router.resolveParams,
+      resolvePaths  = Ember.Router.resolvePaths,
</ins><span class="cx">       isSimpleClick = Ember.ViewUtils.isSimpleClick;
</span><span class="cx"> 
</span><span class="cx">   function fullRouteName(router, name) {
</span><ins>+    var nameWithIndex;
</ins><span class="cx">     if (!router.hasRoute(name)) {
</span><del>-      name = name + '.index';
</del><ins>+      nameWithIndex = name + '.index';
+      Ember.assert(fmt(&quot;The attempt to link-to route '%@' failed (also tried '%@'). &quot; +
+                       &quot;The router did not find '%@' in its possible routes: '%@'&quot;,
+                       [name, nameWithIndex, name, Ember.keys(router.router.recognizer.names).join(&quot;', '&quot;)]),
+                       router.hasRoute(nameWithIndex));
+      name = nameWithIndex;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return name;
</span><span class="cx">   }
</span><span class="cx"> 
</span><del>-  function resolvedPaths(options) {
-    var types = options.options.types.slice(1),
</del><ins>+  function getResolvedPaths(options) {
+
+    var types = options.options.types,
</ins><span class="cx">         data = options.options.data;
</span><span class="cx"> 
</span><del>-    return resolveParams(options.context, options.params, { types: types, data: data });
</del><ins>+    return resolvePaths(options.context, options.params, { types: types, data: data });
</ins><span class="cx">   }
</span><span class="cx"> 
</span><del>-  function args(linkView, router, route) {
-    var passedRouteName = route || linkView.namedRoute, routeName;
</del><ins>+  /**
+    `Ember.LinkView` renders an element whose `click` event triggers a
+    transition of the application's instance of `Ember.Router` to
+    a supplied route by name.
</ins><span class="cx"> 
</span><del>-    routeName = fullRouteName(router, passedRouteName);
</del><ins>+    Instances of `LinkView` will most likely be created through
+    the `link-to` Handlebars helper, but properties of this class
+    can be overridden to customize application-wide behavior.
</ins><span class="cx"> 
</span><del>-    Ember.assert(&quot;The route &quot; + passedRouteName + &quot; was not found&quot;, router.hasRoute(routeName));
</del><ins>+    @class LinkView
+    @namespace Ember
+    @extends Ember.View
+    @see {Handlebars.helpers.link-to}
+  **/
+  var LinkView = Ember.LinkView = Ember.View.extend({
+    tagName: 'a',
+    currentWhen: null,
</ins><span class="cx"> 
</span><del>-    var ret = [ routeName ];
-    return ret.concat(resolvedPaths(linkView.parameters));
-  }
</del><ins>+    /**
+      Sets the `title` attribute of the `LinkView`'s HTML element.
</ins><span class="cx"> 
</span><del>-  var LinkView = Ember.View.extend({
-    tagName: 'a',
-    namedRoute: null,
-    currentWhen: null,
</del><ins>+      @property title
+      @default null
+    **/
</ins><span class="cx">     title: null,
</span><ins>+
+    /**
+      Sets the `rel` attribute of the `LinkView`'s HTML element.
+
+      @property rel
+      @default null
+    **/
+    rel: null,
+
+    /**
+      The CSS class to apply to `LinkView`'s element when its `active`
+      property is `true`.
+
+      @property activeClass
+      @type String
+      @default active
+    **/
</ins><span class="cx">     activeClass: 'active',
</span><ins>+
+    /**
+      The CSS class to apply to `LinkView`'s element when its `loading`
+      property is `true`.
+
+      @property loadingClass
+      @type String
+      @default loading
+    **/
+    loadingClass: 'loading',
+
+    /**
+      The CSS class to apply to a `LinkView`'s element when its `disabled`
+      property is `true`.
+
+      @property disabledClass
+      @type String
+      @default disabled
+    **/
+    disabledClass: 'disabled',
+    _isDisabled: false,
+
+    /**
+      Determines whether the `LinkView` will trigger routing via
+      the `replaceWith` routing strategy.
+
+      @property replace
+      @type Boolean
+      @default false
+    **/
</ins><span class="cx">     replace: false,
</span><del>-    attributeBindings: ['href', 'title'],
-    classNameBindings: 'active',
</del><span class="cx"> 
</span><del>-    // Even though this isn't a virtual view, we want to treat it as if it is
-    // so that you can access the parent with {{view.prop}}
</del><ins>+    /**
+      By default the `{{link-to}}` helper will bind to the `href` and
+      `title` attributes. It's discourage that you override these defaults,
+      however you can push onto the array if needed.
+
+      @property attributeBindings
+      @type Array | String
+      @default ['href', 'title', 'rel']
+     **/
+    attributeBindings: ['href', 'title', 'rel'],
+
+    /**
+      By default the `{{link-to}}` helper will bind to the `active`, `loading`, and
+      `disabled` classes. It is discouraged to override these directly.
+
+      @property classNameBindings
+      @type Array
+      @default ['active', 'loading', 'disabled']
+     **/
+    classNameBindings: ['active', 'loading', 'disabled'],
+
+    /**
+      By default the `{{link-to}}` helper responds to the `click` event. You
+      can override this globally by setting this property to your custom
+      event name.
+
+      This is particularly useful on mobile when one wants to avoid the 300ms
+      click delay using some sort of custom `tap` event.
+
+      @property eventName
+      @type String
+      @default click
+    */
+    eventName: 'click',
+
+    // this is doc'ed here so it shows up in the events
+    // section of the API documentation, which is where
+    // people will likely go looking for it.
+    /**
+      Triggers the `LinkView`'s routing behavior. If
+      `eventName` is changed to a value other than `click`
+      the routing behavior will trigger on that custom event
+      instead.
+
+      @event click
+    **/
+
+    /**
+      An overridable method called when LinkView objects are instantiated.
+
+      Example:
+
+      ```javascript
+      App.MyLinkView = Ember.LinkView.extend({
+        init: function() {
+          this._super();
+          Ember.Logger.log('Event is ' + this.get('eventName'));
+        }
+      });
+      ```
+
+      NOTE: If you do override `init` for a framework class like `Ember.View` or
+      `Ember.ArrayController`, be sure to call `this._super()` in your
+      `init` declaration! If you don't, Ember may not have an opportunity to
+      do important setup work, and you'll see strange behavior in your
+      application.
+
+      @method init
+    */
+    init: function() {
+      this._super.apply(this, arguments);
+
+      // Map desired event name to invoke function
+      var eventName = get(this, 'eventName'), i;
+      this.on(eventName, this, this._invoke);
+
+          },
+
+    /**
+      This method is invoked by observers installed during `init` that fire
+      whenever the params change
+
+      @private
+      @method _paramsChanged
+     */
+    _paramsChanged: function() {
+      this.notifyPropertyChange('resolvedParams');
+    },
+
+    /**
+     This is called to setup observers that will trigger a rerender.
+
+     @private
+     @method _setupPathObservers
+    **/
+    _setupPathObservers: 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 &lt; 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);
+      }
+    },
+
+    afterRender: function(){
+      this._super.apply(this, arguments);
+      this._setupPathObservers();
+    },
+
+    /**
+      This method is invoked by observers installed during `init` that fire
+      whenever the query params change
+      @private
+     */
+    _queryParamsChanged: function (object, path) {
+      this.notifyPropertyChange('queryParams');
+    },
+
+
+    /**
+      Even though this isn't a virtual view, we want to treat it as if it is
+      so that you can access the parent with {{view.prop}}
+
+      @private
+      @method concreteView
+    **/
</ins><span class="cx">     concreteView: Ember.computed(function() {
</span><span class="cx">       return get(this, 'parentView');
</span><del>-    }).property('parentView').volatile(),
</del><ins>+    }).property('parentView'),
</ins><span class="cx"> 
</span><del>-    active: Ember.computed(function() {
-      var router = this.get('router'),
-          params = resolvedPaths(this.parameters),
-          currentWithIndex = this.currentWhen + '.index',
-          isActive = router.isActive.apply(router, [this.currentWhen].concat(params)) ||
-                     router.isActive.apply(router, [currentWithIndex].concat(params));
</del><ins>+    /**
</ins><span class="cx"> 
</span><ins>+      Accessed as a classname binding to apply the `LinkView`'s `disabledClass`
+      CSS `class` to the element when the link is disabled.
+
+      When `true` interactions with the element will not trigger route changes.
+      @property disabled
+    */
+    disabled: Ember.computed(function computeLinkViewDisabled(key, value) {
+      if (value !== undefined) { this.set('_isDisabled', value); }
+
+      return value ? get(this, 'disabledClass') : false;
+    }),
+
+    /**
+      Accessed as a classname binding to apply the `LinkView`'s `activeClass`
+      CSS `class` to the element when the link is active.
+
+      A `LinkView` is considered active when its `currentWhen` property is `true`
+      or the application's current route is the route the `LinkView` would trigger
+      transitions into.
+
+      @property active
+    **/
+    active: Ember.computed(function computeLinkViewActive() {
+      if (get(this, 'loading')) { return false; }
+
+      var router = get(this, 'router'),
+          routeArgs = get(this, 'routeArgs'),
+          contexts = routeArgs.slice(1),
+          resolvedParams = get(this, 'resolvedParams'),
+          currentWhen = this.currentWhen || resolvedParams[0],
+          currentWithIndex = currentWhen + '.index',
+          isActive = router.isActive.apply(router, [currentWhen].concat(contexts)) ||
+                     router.isActive.apply(router, [currentWithIndex].concat(contexts));
+
</ins><span class="cx">       if (isActive) { return get(this, 'activeClass'); }
</span><del>-    }).property('namedRoute', 'router.url'),
</del><ins>+    }).property('resolvedParams', 'routeArgs', 'router.url'),
</ins><span class="cx"> 
</span><ins>+    /**
+      Accessed as a classname binding to apply the `LinkView`'s `loadingClass`
+      CSS `class` to the element when the link is loading.
+
+      A `LinkView` is considered loading when it has at least one
+      parameter whose value is currently null or undefined. During
+      this time, clicking the link will perform no transition and
+      emit a warning that the link is still in a loading state.
+
+      @property loading
+    **/
+    loading: Ember.computed(function computeLinkViewLoading() {
+      if (!get(this, 'routeArgs')) { return get(this, 'loadingClass'); }
+    }).property('routeArgs'),
+
+    /**
+      Returns the application's main router from the container.
+
+      @private
+      @property router
+    **/
</ins><span class="cx">     router: Ember.computed(function() {
</span><del>-      return this.get('controller').container.lookup('router:main');
</del><ins>+      return get(this, 'controller').container.lookup('router:main');
</ins><span class="cx">     }),
</span><span class="cx"> 
</span><del>-    click: function(event) {
</del><ins>+    /**
+      Event handler that invokes the link, activating the associated route.
+
+      @private
+      @method _invoke
+      @param {Event} event
+    */
+    _invoke: function(event) {
</ins><span class="cx">       if (!isSimpleClick(event)) { return true; }
</span><span class="cx"> 
</span><del>-      event.preventDefault();
</del><ins>+      if (this.preventDefault !== false) { event.preventDefault(); }
</ins><span class="cx">       if (this.bubbles === false) { event.stopPropagation(); }
</span><span class="cx"> 
</span><del>-      var router = this.get('router');
</del><ins>+      if (get(this, '_isDisabled')) { return false; }
</ins><span class="cx"> 
</span><del>-      if (this.get('replace')) {
-        router.replaceWith.apply(router, args(this, router));
</del><ins>+      if (get(this, 'loading')) {
+        Ember.Logger.warn(&quot;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.&quot;);
+        return false;
+      }
+
+      var router = get(this, 'router'),
+          routeArgs = get(this, 'routeArgs');
+
+      if (get(this, 'replace')) {
+        router.replaceWith.apply(router, routeArgs);
</ins><span class="cx">       } else {
</span><del>-        router.transitionTo.apply(router, args(this, router));
</del><ins>+        router.transitionTo.apply(router, routeArgs);
</ins><span class="cx">       }
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    href: Ember.computed(function() {
-      var router = this.get('router');
-      return router.generate.apply(router, args(this, router));
-    })
</del><ins>+    /**
+      Computed property that returns the resolved parameters.
+
+      @private
+      @property
+      @return {Array}
+     */
+    resolvedParams: Ember.computed(function() {
+      var parameters = this.parameters,
+          options = parameters.options,
+          types = options.types,
+          data = options.data;
+
+      
+      // Original implementation if query params not enabled
+      return resolveParams(parameters.context, parameters.params, { types: types, data: data });
+    }).property(),
+
+    /**
+      Computed property that returns the current route name and
+      any dynamic segments.
+
+      @private
+      @property
+      @return {Array} An array with the route name and any dynamic segments
+     */
+    routeArgs: Ember.computed(function computeLinkViewRouteArgs() {
+      var resolvedParams = get(this, 'resolvedParams').slice(0),
+          router = get(this, 'router'),
+          namedRoute = resolvedParams[0];
+
+      if (!namedRoute) { return; }
+
+      namedRoute = fullRouteName(router, namedRoute);
+      resolvedParams[0] = namedRoute;
+
+      for (var i = 1, len = resolvedParams.length; i &lt; len; ++i) {
+        var param = resolvedParams[i];
+        if (param === null || typeof param === 'undefined') {
+          // If contexts aren't present, consider the linkView unloaded.
+          return;
+        }
+      }
+
+      
+      return resolvedParams;
+    }).property('resolvedParams', 'queryParams', 'router.url'),
+
+
+    _potentialQueryParams: Ember.computed(function () {
+      var namedRoute = get(this, 'resolvedParams')[0];
+      if (!namedRoute) { return null; }
+      var router          = get(this, 'router');
+
+      namedRoute = fullRouteName(router, namedRoute);
+
+      return router.router.queryParamsForHandler(namedRoute);
+    }).property('resolvedParams'),
+
+    queryParams: Ember.computed(function () {
+      var self              = this,
+        queryParams         = null,
+        allowedQueryParams  = get(this, '_potentialQueryParams');
+
+      if (!allowedQueryParams) { return null; }
+      allowedQueryParams.forEach(function (param) {
+        var value = get(self, param);
+        if (typeof value !== 'undefined') {
+          queryParams = queryParams || {};
+          queryParams[param] = value;
+        }
+      });
+
+
+      return queryParams;
+    }).property('_potentialQueryParams.[]'),
+
+    /**
+      Sets the element's `href` attribute to the url for
+      the `LinkView`'s targeted route.
+
+      If the `LinkView`'s `tagName` is changed to a value other
+      than `a`, this property will be ignored.
+
+      @property href
+    **/
+    href: Ember.computed(function computeLinkViewHref() {
+      if (get(this, 'tagName') !== 'a') { return; }
+
+      var router = get(this, 'router'),
+          routeArgs = get(this, 'routeArgs');
+
+      return routeArgs ? router.generate.apply(router, routeArgs) : get(this, 'loadingHref');
+    }).property('routeArgs'),
+
+    /**
+      The default href value to use while a link-to is loading.
+      Only applies when tagName is 'a'
+
+      @property loadingHref
+      @type String
+      @default #
+    */
+    loadingHref: '#'
</ins><span class="cx">   });
</span><span class="cx"> 
</span><span class="cx">   LinkView.toString = function() { return &quot;LinkView&quot;; };
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @method linkTo
</del><ins>+    The `{{link-to}}` helper renders a link to the supplied
+    `routeName` passing an optionally supplied model to the
+    route as its `model` context of the route. The block
+    for `{{link-to}}` becomes the innerHTML of the rendered
+    element:
+
+    ```handlebars
+    {{#link-to 'photoGallery'}}
+      Great Hamster Photos
+    {{/link-to}}
+    ```
+
+    ```html
+    &lt;a href=&quot;/hamster-photos&quot;&gt;
+      Great Hamster Photos
+    &lt;/a&gt;
+    ```
+
+    ### Supplying a tagName
+    By default `{{link-to}}` renders an `&lt;a&gt;` element. This can
+    be overridden for a single use of `{{link-to}}` by supplying
+    a `tagName` option:
+
+    ```handlebars
+    {{#link-to 'photoGallery' tagName=&quot;li&quot;}}
+      Great Hamster Photos
+    {{/link-to}}
+    ```
+
+    ```html
+    &lt;li&gt;
+      Great Hamster Photos
+    &lt;/li&gt;
+    ```
+
+    To override this option for your entire application, see
+    &quot;Overriding Application-wide Defaults&quot;.
+
+    ### Disabling the `link-to` helper
+    By default `{{link-to}}` is enabled.
+    any passed value to `disabled` helper property will disable the `link-to` helper.
+
+    static use: the `disabled` option:
+
+    ```handlebars
+    {{#link-to 'photoGallery' disabled=true}}
+      Great Hamster Photos
+    {{/link-to}}
+    ```
+
+    dynamic use: the `disabledWhen` option:
+
+    ```handlebars
+    {{#link-to 'photoGallery' disabledWhen=controller.someProperty}}
+      Great Hamster Photos
+    {{/link-to}}
+    ```
+
+    any passed value to `disabled` will disable it except `undefined`.
+    to ensure that only `true` disable the `link-to` helper you can
+    override the global behaviour of `Ember.LinkView`.
+
+    ```javascript
+    Ember.LinkView.reopen({
+      disabled: Ember.computed(function(key, value) {
+        if (value !== undefined) {
+          this.set('_isDisabled', value === true);
+        }
+        return value === true ? get(this, 'disabledClass') : false;
+      })
+    });
+    ```
+
+    see &quot;Overriding Application-wide Defaults&quot; for more.
+
+    ### Handling `href`
+    `{{link-to}}` will use your application's Router to
+    fill the element's `href` property with a url that
+    matches the path to the supplied `routeName` for your
+    routers's configured `Location` scheme, which defaults
+    to Ember.HashLocation.
+
+    ### Handling current route
+    `{{link-to}}` will apply a CSS class name of 'active'
+    when the application's current route matches
+    the supplied routeName. For example, if the application's
+    current route is 'photoGallery.recent' the following
+    use of `{{link-to}}`:
+
+    ```handlebars
+    {{#link-to 'photoGallery.recent'}}
+      Great Hamster Photos from the last week
+    {{/link-to}}
+    ```
+
+    will result in
+
+    ```html
+    &lt;a href=&quot;/hamster-photos/this-week&quot; class=&quot;active&quot;&gt;
+      Great Hamster Photos
+    &lt;/a&gt;
+    ```
+
+    The CSS class name used for active classes can be customized
+    for a single use of `{{link-to}}` by passing an `activeClass`
+    option:
+
+    ```handlebars
+    {{#link-to 'photoGallery.recent' activeClass=&quot;current-url&quot;}}
+      Great Hamster Photos from the last week
+    {{/link-to}}
+    ```
+
+    ```html
+    &lt;a href=&quot;/hamster-photos/this-week&quot; class=&quot;current-url&quot;&gt;
+      Great Hamster Photos
+    &lt;/a&gt;
+    ```
+
+    To override this option for your entire application, see
+    &quot;Overriding Application-wide Defaults&quot;.
+
+    ### Supplying a model
+    An optional model argument can be used for routes whose
+    paths contain dynamic segments. This argument will become
+    the model context of the linked route:
+
+    ```javascript
+    App.Router.map(function() {
+      this.resource(&quot;photoGallery&quot;, {path: &quot;hamster-photos/:photo_id&quot;});
+    });
+    ```
+
+    ```handlebars
+    {{#link-to 'photoGallery' aPhoto}}
+      {{aPhoto.title}}
+    {{/link-to}}
+    ```
+
+    ```html
+    &lt;a href=&quot;/hamster-photos/42&quot;&gt;
+      Tomster
+    &lt;/a&gt;
+    ```
+
+    ### Supplying multiple models
+    For deep-linking to route paths that contain multiple
+    dynamic segments, multiple model arguments can be used.
+    As the router transitions through the route path, each
+    supplied model argument will become the context for the
+    route with the dynamic segments:
+
+    ```javascript
+    App.Router.map(function() {
+      this.resource(&quot;photoGallery&quot;, {path: &quot;hamster-photos/:photo_id&quot;}, function() {
+        this.route(&quot;comment&quot;, {path: &quot;comments/:comment_id&quot;});
+      });
+    });
+    ```
+    This argument will become the model context of the linked route:
+
+    ```handlebars
+    {{#link-to 'photoGallery.comment' aPhoto comment}}
+      {{comment.body}}
+    {{/link-to}}
+    ```
+
+    ```html
+    &lt;a href=&quot;/hamster-photos/42/comment/718&quot;&gt;
+      A+++ would snuggle again.
+    &lt;/a&gt;
+    ```
+
+    ### Supplying an explicit dynamic segment value
+    If you don't have a model object available to pass to `{{link-to}}`,
+    an optional string or integer argument can be passed for routes whose
+    paths contain dynamic segments. This argument will become the value
+    of the dynamic segment:
+
+    ```javascript
+    App.Router.map(function() {
+      this.resource(&quot;photoGallery&quot;, {path: &quot;hamster-photos/:photo_id&quot;});
+    });
+    ```
+
+    ```handlebars
+    {{#link-to 'photoGallery' aPhotoId}}
+      {{aPhoto.title}}
+    {{/link-to}}
+    ```
+
+    ```html
+    &lt;a href=&quot;/hamster-photos/42&quot;&gt;
+      Tomster
+    &lt;/a&gt;
+    ```
+
+    When transitioning into the linked route, the `model` hook will
+    be triggered with parameters including this passed identifier.
+
+    ### Allowing Default Action
+
+   By default the `{{link-to}}` helper prevents the default browser action
+   by calling `preventDefault()` as this sort of action bubbling is normally
+   handled internally and we do not want to take the browser to a new URL (for
+   example).
+
+   If you need to override this behavior specify `preventDefault=false` in
+   your template:
+
+    ```handlebars
+    {{#link-to 'photoGallery' aPhotoId preventDefault=false}}
+      {{aPhotoId.title}}
+    {{/link-to}}
+    ```
+
+    ### Overriding attributes
+    You can override any given property of the Ember.LinkView
+    that is generated by the `{{link-to}}` helper by passing
+    key/value pairs, like so:
+
+    ```handlebars
+    {{#link-to  aPhoto tagName='li' title='Following this link will change your life' classNames='pic sweet'}}
+      Uh-mazing!
+    {{/link-to}}
+    ```
+
+    See [Ember.LinkView](/api/classes/Ember.LinkView.html) for a
+    complete list of overrideable properties. Be sure to also
+    check out inherited properties of `LinkView`.
+
+    ### Overriding Application-wide Defaults
+    ``{{link-to}}`` creates an instance of Ember.LinkView
+    for rendering. To override options for your entire
+    application, reopen Ember.LinkView and supply the
+    desired values:
+
+    ``` javascript
+    Ember.LinkView.reopen({
+      activeClass: &quot;is-active&quot;,
+      tagName: 'li'
+    })
+    ```
+
+    It is also possible to override the default event in
+    this manner:
+
+    ``` javascript
+    Ember.LinkView.reopen({
+      eventName: 'customEventName'
+    });
+    ```
+
+    @method link-to
</ins><span class="cx">     @for Ember.Handlebars.helpers
</span><span class="cx">     @param {String} routeName
</span><span class="cx">     @param {Object} [context]*
</span><ins>+    @param [options] {Object} Handlebars key/value pairs of options, you can override any property of Ember.LinkView
</ins><span class="cx">     @return {String} HTML string
</span><ins>+    @see {Ember.LinkView}
</ins><span class="cx">   */
</span><del>-  Ember.Handlebars.registerHelper('linkTo', function(name) {
-    var options = [].slice.call(arguments, -1)[0];
-    var params = [].slice.call(arguments, 1, -1);
</del><ins>+  Ember.Handlebars.registerHelper('link-to', function linkToHelper(name) {
+    var options = [].slice.call(arguments, -1)[0],
+        params = [].slice.call(arguments, 0, -1),
+        hash = options.hash;
</ins><span class="cx"> 
</span><del>-    var hash = options.hash;
</del><ins>+    hash.disabledBinding = hash.disabledWhen;
</ins><span class="cx"> 
</span><del>-    hash.namedRoute = name;
-    hash.currentWhen = hash.currentWhen || name;
</del><ins>+    if (!options.fn) {
+      var linkTitle = params.shift();
+      var linkType = options.types.shift();
+      var context = this;
+      if (linkType === 'ID') {
+        options.linkTextPath = linkTitle;
+        options.fn = function() {
+          return Ember.Handlebars.get(context, linkTitle, options);
+        };
+      } else {
+        options.fn = function() {
+          return linkTitle;
+        };
+      }
+    }
</ins><span class="cx"> 
</span><span class="cx">     hash.parameters = {
</span><span class="cx">       context: this,
</span><span class="lines">@@ -23659,9 +36187,24 @@
</span><span class="cx">     return Ember.Handlebars.helpers.view.call(this, LinkView, options);
</span><span class="cx">   });
</span><span class="cx"> 
</span><ins>+  /**
+    See [link-to](/api/classes/Ember.Handlebars.helpers.html#method_link-to)
+
+    @method linkTo
+    @for Ember.Handlebars.helpers
+    @deprecated
+    @param {String} routeName
+    @param {Object} [context]*
+    @return {String} HTML string
+  */
+  Ember.Handlebars.registerHelper('linkTo', function linkToHelper() {
+    Ember.warn(&quot;The 'linkTo' view helper is deprecated in favor of 'link-to'&quot;);
+    return Ember.Handlebars.helpers['link-to'].apply(this, arguments);
+  });
</ins><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -23676,66 +36219,109 @@
</span><span class="cx"> Ember.onLoad('Ember.Handlebars', function(Handlebars) {
</span><span class="cx">   /**
</span><span class="cx">   @module ember
</span><del>-  @submodule ember-handlebars
</del><ins>+  @submodule ember-routing
</ins><span class="cx">   */
</span><span class="cx"> 
</span><span class="cx">   Handlebars.OutletView = Ember.ContainerView.extend(Ember._Metamorph);
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    The `outlet` helper allows you to specify that the current
-    view's controller will fill in the view for a given area.
</del><ins>+    The `outlet` helper is a placeholder that the router will fill in with
+    the appropriate template based on the current state of the application.
</ins><span class="cx"> 
</span><span class="cx">     ``` handlebars
</span><span class="cx">     {{outlet}}
</span><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    By default, when the the current controller's `view` property changes, the
-    outlet will replace its current view with the new view. You can set the
-    `view` property directly, but it's normally best to use `connectOutlet`.
</del><ins>+    By default, a template based on Ember's naming conventions will be rendered
+    into the `outlet` (e.g. `App.PostsRoute` will render the `posts` template).
</ins><span class="cx"> 
</span><ins>+    You can render a different template by using the `render()` method in the
+    route's `renderTemplate` hook. The following will render the `favoritePost`
+    template into the `outlet`.
+
</ins><span class="cx">     ``` javascript
</span><del>-    # Instantiate App.PostsView and assign to `view`, so as to render into outlet.
-    controller.connectOutlet('posts');
</del><ins>+    App.PostsRoute = Ember.Route.extend({
+      renderTemplate: function() {
+        this.render('favoritePost');
+      }
+    });
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    You can also specify a particular name other than `view`:
</del><ins>+    You can create custom named outlets for more control.
</ins><span class="cx"> 
</span><span class="cx">     ``` handlebars
</span><del>-    {{outlet masterView}}
-    {{outlet detailView}}
</del><ins>+    {{outlet 'favoritePost'}}
+    {{outlet 'posts'}}
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    Then, you can control several outlets from a single controller.
</del><ins>+    Then you can define what template is rendered into each outlet in your
+    route.
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">     ``` javascript
</span><del>-    # Instantiate App.PostsView and assign to controller.masterView.
-    controller.connectOutlet('masterView', 'posts');
-    # Also, instantiate App.PostInfoView and assign to controller.detailView.
-    controller.connectOutlet('detailView', 'postInfo');
</del><ins>+    App.PostsRoute = Ember.Route.extend({
+      renderTemplate: function() {
+        this.render('favoritePost', { outlet: 'favoritePost' });
+        this.render('posts', { outlet: 'posts' });
+      }
+    });
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><ins>+    You can specify the view that the outlet uses to contain and manage the
+    templates rendered into it.
+
+    ``` handlebars
+    {{outlet view='sectionContainer'}}
+    ```
+
+    ``` javascript
+    App.SectionContainer = Ember.ContainerView.extend({
+      tagName: 'section',
+      classNames: ['special']
+    });
+    ```
+
</ins><span class="cx">     @method outlet
</span><span class="cx">     @for Ember.Handlebars.helpers
</span><span class="cx">     @param {String} property the property on the controller
</span><span class="cx">       that holds the view for this outlet
</span><ins>+    @return {String} HTML string
</ins><span class="cx">   */
</span><del>-  Handlebars.registerHelper('outlet', function(property, options) {
-    var outletSource;
</del><ins>+  Handlebars.registerHelper('outlet', function outletHelper(property, options) {
+   
+    var outletSource,
+        container,
+        viewName,
+        viewClass,
+        viewFullName;
</ins><span class="cx"> 
</span><span class="cx">     if (property &amp;&amp; property.data &amp;&amp; property.data.isRenderData) {
</span><span class="cx">       options = property;
</span><span class="cx">       property = 'main';
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    container = options.data.view.container;
+
</ins><span class="cx">     outletSource = options.data.view;
</span><del>-    while (!(outletSource.get('template.isTop'))){
</del><ins>+    while (!outletSource.get('template.isTop')) {
</ins><span class="cx">       outletSource = outletSource.get('_parentView');
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // provide controller override
+    viewName = options.hash.view;
+
+    if (viewName) {
+      viewFullName = 'view:' + viewName;
+      Ember.assert(&quot;Using a quoteless view parameter with {{outlet}} is not supported. Please update to quoted usage '{{outlet \&quot;&quot; + viewName + &quot;\&quot;}}.&quot;, options.hashTypes.view !== 'ID');
+      Ember.assert(&quot;The view name you supplied '&quot; + viewName + &quot;' did not resolve to a view.&quot;, container.has(viewFullName));
+    }
+
+    viewClass = viewName ? container.lookupFactory(viewFullName) : options.hash.viewClass || Handlebars.OutletView;
+
</ins><span class="cx">     options.data.view.set('outletSource', outletSource);
</span><span class="cx">     options.hash.currentViewBinding = '_view.outletSource._outlets.' + property;
</span><span class="cx"> 
</span><del>-    return Handlebars.helpers.view.call(this, Handlebars.OutletView, options);
</del><ins>+    return Handlebars.helpers.view.call(this, viewClass, options);
</ins><span class="cx">   });
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -23753,51 +36339,132 @@
</span><span class="cx"> Ember.onLoad('Ember.Handlebars', function(Handlebars) {
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Renders the named template in the current context using the singleton
-    instance of the same-named controller.
</del><ins>+    Calling ``{{render}}`` from within a template will insert another
+    template that matches the provided name. The inserted template will
+    access its properties on its own controller (rather than the controller
+    of the parent template).
</ins><span class="cx"> 
</span><del>-    If a view class with the same name exists, uses the view class.
</del><ins>+    If a view class with the same name exists, the view class also will be used.
</ins><span class="cx"> 
</span><del>-    If a `model` is specified, it becomes the model for that controller.
</del><ins>+    Note: A given controller may only be used *once* in your app in this manner.
+    A singleton instance of the controller will be created for you.
</ins><span class="cx"> 
</span><del>-    The default target for `{{action}}`s in the rendered template is the
-    named controller.
</del><ins>+    Example:
</ins><span class="cx"> 
</span><del>-    @method action
</del><ins>+    ```javascript
+    App.NavigationController = Ember.Controller.extend({
+      who: &quot;world&quot;
+    });
+    ```
+
+    ```handlebars
+    &lt;!-- navigation.hbs --&gt;
+    Hello, {{who}}.
+    ```
+
+    ```handelbars
+    &lt;!-- application.hbs --&gt;
+    &lt;h1&gt;My great app&lt;/h1&gt;
+    {{render navigation}}
+    ```
+
+    ```html
+    &lt;h1&gt;My great app&lt;/h1&gt;
+    &lt;div class='ember-view'&gt;
+      Hello, world.
+    &lt;/div&gt;
+    ```
+
+    Optionally you may provide a second argument: a property path
+    that will be bound to the `model` property of the controller.
+
+    If a `model` property path is specified, then a new instance of the
+    controller will be created and `{{render}}` can be used multiple times
+    with the same name.
+
+   For example if you had this `author` template.
+
+   ```handlebars
+&lt;div class=&quot;author&quot;&gt;
+  Written by {{firstName}} {{lastName}}.
+  Total Posts: {{postCount}}
+&lt;/div&gt;
+  ```
+
+  You could render it inside the `post` template using the `render` helper.
+
+  ```handlebars
+&lt;div class=&quot;post&quot;&gt;
+  &lt;h1&gt;{{title}}&lt;/h1&gt;
+  &lt;div&gt;{{body}}&lt;/div&gt;
+  {{render &quot;author&quot; author}}
+&lt;/div&gt;
+   ```
+
+    @method render
</ins><span class="cx">     @for Ember.Handlebars.helpers
</span><del>-    @param {String} actionName
-    @param {Object?} model
</del><ins>+    @param {String} name
+    @param {Object?} contextString
</ins><span class="cx">     @param {Hash} options
</span><ins>+    @return {String} HTML string
</ins><span class="cx">   */
</span><del>-  Ember.Handlebars.registerHelper('render', function(name, contextString, options) {
-    Ember.assert(&quot;You must pass a template to render&quot;, arguments.length &gt;= 2);
-    var container, router, controller, view, context;
</del><ins>+  Ember.Handlebars.registerHelper('render', function renderHelper(name, contextString, options) {
+    var length = arguments.length;
+    Ember.assert(&quot;You must pass a template to render&quot;, length &gt;= 2);
+    var contextProvided = length === 3,
+        container, router, controller, view, context, lookupOptions;
</ins><span class="cx"> 
</span><del>-    if (arguments.length === 2) {
</del><ins>+    container = (options || contextString).data.keywords.controller.container;
+    router = container.lookup('router:main');
+
+    if (length === 2) {
+      // use the singleton controller
</ins><span class="cx">       options = contextString;
</span><span class="cx">       contextString = undefined;
</span><del>-    }
-
-    if (typeof contextString === 'string') {
</del><ins>+      Ember.assert(&quot;You can only use the {{render}} helper once without a model object as its second argument, as in {{render \&quot;post\&quot; post}}.&quot;, !router || !router._lookupActiveView(name));
+    } else if (length === 3) {
+      // create a new controller
</ins><span class="cx">       context = Ember.Handlebars.get(options.contexts[1], contextString, options);
</span><ins>+    } else {
+      throw Ember.Error(&quot;You must pass a templateName to render&quot;);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // # legacy namespace
</ins><span class="cx">     name = name.replace(/\//g, '.');
</span><del>-    container = options.data.keywords.controller.container;
-    router = container.lookup('router:main');
</del><ins>+    // \ legacy slash as namespace support
</ins><span class="cx"> 
</span><del>-    Ember.assert(&quot;This view is already rendered&quot;, !router || !router._lookupActiveView(name));
</del><span class="cx"> 
</span><span class="cx">     view = container.lookup('view:' + name) || container.lookup('view:default');
</span><span class="cx"> 
</span><del>-    if (controller = options.hash.controller) {
-      controller = container.lookup('controller:' + controller);
-    } else {
-      controller = Ember.controllerFor(container, name, context);
</del><ins>+    // provide controller override
+    var controllerName = options.hash.controller || name;
+    var controllerFullName = 'controller:' + controllerName;
+
+    if (options.hash.controller) {
+      Ember.assert(&quot;The controller name you supplied '&quot; + controllerName + &quot;' did not resolve to a controller.&quot;, container.has(controllerFullName));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (controller &amp;&amp; context) {
-      controller.set('model', context);
</del><ins>+    var parentController = options.data.keywords.controller;
+
+    // choose name
+    if (length &gt; 2) {
+      var factory = container.lookupFactory(controllerFullName) ||
+                    Ember.generateControllerFactory(container, controllerName, context);
+
+      controller = factory.create({
+        model: context,
+        parentController: parentController,
+        target: parentController
+      });
+
+    } else {
+      controller = container.lookup(controllerFullName) ||
+                   Ember.generateController(container, controllerName);
+
+      controller.setProperties({
+        target: parentController,
+        parentController: parentController
+      });
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     var root = options.contexts[1];
</span><span class="lines">@@ -23808,19 +36475,20 @@
</span><span class="cx">       });
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    controller.set('target', options.data.keywords.controller);
</del><ins>+    options.hash.viewName = Ember.String.camelize(name);
</ins><span class="cx"> 
</span><del>-    options.hash.viewName = Ember.String.camelize(name);
-    options.hash.template = container.lookup('template:' + name);
</del><ins>+    var templateName = 'template:' + name;
+    Ember.assert(&quot;You used `{{render '&quot; + name + &quot;'}}`, but '&quot; + name + &quot;' can not be found as either a template or a view.&quot;, container.has(&quot;view:&quot; + name) || container.has(templateName));
+    options.hash.template = container.lookup(templateName);
+
</ins><span class="cx">     options.hash.controller = controller;
</span><span class="cx"> 
</span><del>-    if (router) {
</del><ins>+    if (router &amp;&amp; !context) {
</ins><span class="cx">       router._connectActiveView(name, view);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     Ember.Handlebars.helpers.view.call(this, view, options);
</span><span class="cx">   });
</span><del>-
</del><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> })();
</span><span class="lines">@@ -23834,12 +36502,13 @@
</span><span class="cx"> */
</span><span class="cx"> Ember.onLoad('Ember.Handlebars', function(Handlebars) {
</span><span class="cx"> 
</span><del>-  var resolveParams = Ember.Handlebars.resolveParams,
</del><ins>+  var resolveParams = Ember.Router.resolveParams,
</ins><span class="cx">       isSimpleClick = Ember.ViewUtils.isSimpleClick;
</span><span class="cx"> 
</span><span class="cx">   var EmberHandlebars = Ember.Handlebars,
</span><span class="cx">       handlebarsGet = EmberHandlebars.get,
</span><span class="cx">       SafeString = EmberHandlebars.SafeString,
</span><ins>+      forEach = Ember.ArrayPolyfills.forEach,
</ins><span class="cx">       get = Ember.get,
</span><span class="cx">       a_slice = Array.prototype.slice;
</span><span class="cx"> 
</span><span class="lines">@@ -23857,22 +36526,51 @@
</span><span class="cx">     registeredActions: {}
</span><span class="cx">   };
</span><span class="cx"> 
</span><del>-  ActionHelper.registerAction = function(actionName, options) {
</del><ins>+  var keys = [&quot;alt&quot;, &quot;shift&quot;, &quot;meta&quot;, &quot;ctrl&quot;];
+
+  var POINTER_EVENT_TYPE_REGEX = /^click|mouse|touch/;
+
+  var isAllowedEvent = function(event, allowedKeys) {
+    if (typeof allowedKeys === &quot;undefined&quot;) {
+      if (POINTER_EVENT_TYPE_REGEX.test(event.type)) {
+        return isSimpleClick(event);
+      } else {
+        allowedKeys = '';
+      }
+    }
+
+    if (allowedKeys.indexOf(&quot;any&quot;) &gt;= 0) {
+      return true;
+    }
+
+    var allowed = true;
+
+    forEach.call(keys, function(key) {
+      if (event[key + &quot;Key&quot;] &amp;&amp; allowedKeys.indexOf(key) === -1) {
+        allowed = false;
+      }
+    });
+
+    return allowed;
+  };
+
+  ActionHelper.registerAction = function(actionName, options, allowedKeys) {
</ins><span class="cx">     var actionId = (++Ember.uuid).toString();
</span><span class="cx"> 
</span><span class="cx">     ActionHelper.registeredActions[actionId] = {
</span><span class="cx">       eventName: options.eventName,
</span><del>-      handler: function(event) {
-        if (!isSimpleClick(event)) { return true; }
-        event.preventDefault();
</del><ins>+      handler: function handleRegisteredAction(event) {
+        if (!isAllowedEvent(event, allowedKeys)) { return true; }
</ins><span class="cx"> 
</span><ins>+        if (options.preventDefault !== false) {
+          event.preventDefault();
+        }
+
</ins><span class="cx">         if (options.bubbles === false) {
</span><span class="cx">           event.stopPropagation();
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        var view = options.view,
-            contexts = options.contexts,
-            target = options.target;
</del><ins>+        var target = options.target;
</ins><span class="cx"> 
</span><span class="cx">         if (target.target) {
</span><span class="cx">           target = handlebarsGet(target.root, target.target, target.options);
</span><span class="lines">@@ -23880,7 +36578,7 @@
</span><span class="cx">           target = target.root;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        Ember.run(function() {
</del><ins>+        Ember.run(function runRegisteredAction() {
</ins><span class="cx">           if (target.send) {
</span><span class="cx">             target.send.apply(target, args(options.parameters, actionName));
</span><span class="cx">           } else {
</span><span class="lines">@@ -23900,42 +36598,35 @@
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">     The `{{action}}` helper registers an HTML element within a template for DOM
</span><del>-    event handling and forwards that interaction to the view's controller
</del><ins>+    event handling and forwards that interaction to the templates's controller
</ins><span class="cx">     or supplied `target` option (see 'Specifying a Target').
</span><span class="cx"> 
</span><del>-    If the view's controller does not implement the event, the event is sent
</del><ins>+    If the controller does not implement the event, the event is sent
</ins><span class="cx">     to the current route, and it bubbles up the route hierarchy from there.
</span><span class="cx"> 
</span><span class="cx">     User interaction with that element will invoke the supplied action name on
</span><span class="cx">     the appropriate target.
</span><span class="cx"> 
</span><del>-    Given the following Handlebars template on the page
</del><ins>+    Given the following application Handlebars template on the page
</ins><span class="cx"> 
</span><span class="cx">     ```handlebars
</span><del>-    &lt;script type=&quot;text/x-handlebars&quot; data-template-name='a-template'&gt;
-      &lt;div {{action anActionName}}&gt;
-        click me
-      &lt;/div&gt;
-    &lt;/script&gt;
</del><ins>+    &lt;div {{action 'anActionName'}}&gt;
+      click me
+    &lt;/div&gt;
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><span class="cx">     And application code
</span><span class="cx"> 
</span><span class="cx">     ```javascript
</span><del>-    AController = Ember.Controller.extend({
-      anActionName: function() {}
</del><ins>+    App.ApplicationController = Ember.Controller.extend({
+      actions: {
+        anActionName: function() {
+        }
+      }
</ins><span class="cx">     });
</span><del>-
-    AView = Ember.View.extend({
-      controller: AController.create(),
-      templateName: 'a-template'
-    });
-
-    aView = AView.create();
-    aView.appendTo('body');
</del><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    Will results in the following rendered HTML
</del><ins>+    Will result in the following rendered HTML
</ins><span class="cx"> 
</span><span class="cx">     ```html
</span><span class="cx">     &lt;div class=&quot;ember-view&quot;&gt;
</span><span class="lines">@@ -23945,8 +36636,8 @@
</span><span class="cx">     &lt;/div&gt;
</span><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    Clicking &quot;click me&quot; will trigger the `anActionName` method of the
-    `AController`. In this case, no additional parameters will be passed.
</del><ins>+    Clicking &quot;click me&quot; will trigger the `anActionName` action of the
+    `App.ApplicationController`. In this case, no additional parameters will be passed.
</ins><span class="cx"> 
</span><span class="cx">     If you provide additional parameters to the helper:
</span><span class="cx"> 
</span><span class="lines">@@ -23961,16 +36652,24 @@
</span><span class="cx"> 
</span><span class="cx">     Events triggered through the action helper will automatically have
</span><span class="cx">     `.preventDefault()` called on them. You do not need to do so in your event
</span><del>-    handlers.
</del><ins>+    handlers. If you need to allow event propagation (to handle file inputs for
+    example) you can supply the `preventDefault=false` option to the `{{action}}` helper:
</ins><span class="cx"> 
</span><del>-    To also disable bubbling, pass `bubbles=false` to the helper:
</del><ins>+    ```handlebars
+    &lt;div {{action &quot;sayHello&quot; preventDefault=false}}&gt;
+      &lt;input type=&quot;file&quot; /&gt;
+      &lt;input type=&quot;checkbox&quot; /&gt;
+    &lt;/div&gt;
+    ```
</ins><span class="cx"> 
</span><ins>+    To disable bubbling, pass `bubbles=false` to the helper:
+
</ins><span class="cx">     ```handlebars
</span><span class="cx">     &lt;button {{action 'edit' post bubbles=false}}&gt;Edit&lt;/button&gt;
</span><span class="cx">     ```
</span><span class="cx"> 
</span><span class="cx">     If you need the default handler to trigger you should either register your
</span><del>-    own event handler, or use event methods on your view class. See `Ember.View`
</del><ins>+    own event handler, or use event methods on your view class. See [Ember.View](/api/classes/Ember.View.html)
</ins><span class="cx">     'Responding to Browser Events' for more information.
</span><span class="cx"> 
</span><span class="cx">     ### Specifying DOM event type
</span><span class="lines">@@ -23979,11 +36678,9 @@
</span><span class="cx">     supply an `on` option to the helper to specify a different DOM event name:
</span><span class="cx"> 
</span><span class="cx">     ```handlebars
</span><del>-    &lt;script type=&quot;text/x-handlebars&quot; data-template-name='a-template'&gt;
-      &lt;div {{action anActionName on=&quot;doubleClick&quot;}}&gt;
-        click me
-      &lt;/div&gt;
-    &lt;/script&gt;
</del><ins>+    &lt;div {{action &quot;anActionName&quot; on=&quot;doubleClick&quot;}}&gt;
+      click me
+    &lt;/div&gt;
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><span class="cx">     See `Ember.View` 'Responding to Browser Events' for a list of
</span><span class="lines">@@ -23995,6 +36692,27 @@
</span><span class="cx">     is created. Having an instance of `Ember.Application` will satisfy this
</span><span class="cx">     requirement.
</span><span class="cx"> 
</span><ins>+    ### Specifying whitelisted modifier keys
+
+    By default the `{{action}}` helper will ignore click event with pressed modifier
+    keys. You can supply an `allowedKeys` option to specify which keys should not be ignored.
+
+    ```handlebars
+    &lt;div {{action &quot;anActionName&quot; allowedKeys=&quot;alt&quot;}}&gt;
+      click me
+    &lt;/div&gt;
+    ```
+
+    This way the `{{action}}` will fire when clicking with the alt key pressed down.
+
+    Alternatively, supply &quot;any&quot; to the `allowedKeys` option to accept any combination of modifier keys.
+
+    ```handlebars
+    &lt;div {{action &quot;anActionName&quot; allowedKeys=&quot;any&quot;}}&gt;
+      click me with any key pressed
+    &lt;/div&gt;
+    ```
+
</ins><span class="cx">     ### Specifying a Target
</span><span class="cx"> 
</span><span class="cx">     There are several possible target objects for `{{action}}` helpers:
</span><span class="lines">@@ -24005,46 +36723,24 @@
</span><span class="cx"> 
</span><span class="cx">     Alternatively, a `target` option can be provided to the helper to change
</span><span class="cx">     which object will receive the method call. This option must be a path
</span><del>-    path to an object, accessible in the current context:
</del><ins>+    to an object, accessible in the current context:
</ins><span class="cx"> 
</span><span class="cx">     ```handlebars
</span><del>-    &lt;script type=&quot;text/x-handlebars&quot; data-template-name='a-template'&gt;
-      &lt;div {{action anActionName target=&quot;MyApplication.someObject&quot;}}&gt;
-        click me
-      &lt;/div&gt;
-    &lt;/script&gt;
</del><ins>+    {{! the application template }}
+    &lt;div {{action &quot;anActionName&quot; target=view}}&gt;
+      click me
+    &lt;/div&gt;
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    Clicking &quot;click me&quot; in the rendered HTML of the above template will trigger
-    the  `anActionName` method of the object at `MyApplication.someObject`.
-
-    If an action's target does not implement a method that matches the supplied
-    action name an error will be thrown.
-
-    ```handlebars
-    &lt;script type=&quot;text/x-handlebars&quot; data-template-name='a-template'&gt;
-      &lt;div {{action aMethodNameThatIsMissing}}&gt;
-        click me
-      &lt;/div&gt;
-    &lt;/script&gt;
-    ```
-
-    With the following application code
-
</del><span class="cx">     ```javascript
</span><del>-    AView = Ember.View.extend({
-      templateName; 'a-template',
-      // note: no method 'aMethodNameThatIsMissing'
-      anActionName: function(event) {}
</del><ins>+    App.ApplicationView = Ember.View.extend({
+      actions: {
+        anActionName: function(){}
+      }
</ins><span class="cx">     });
</span><span class="cx"> 
</span><del>-    aView = AView.create();
-    aView.appendTo('body');
</del><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    Will throw `Uncaught TypeError: Cannot call method 'call' of undefined` when
-    &quot;click me&quot; is clicked.
-
</del><span class="cx">     ### Additional Parameters
</span><span class="cx"> 
</span><span class="cx">     You may specify additional parameters to the `{{action}}` helper. These
</span><span class="lines">@@ -24052,17 +36748,15 @@
</span><span class="cx">     implementing the action.
</span><span class="cx"> 
</span><span class="cx">     ```handlebars
</span><del>-    &lt;script type=&quot;text/x-handlebars&quot; data-template-name='a-template'&gt;
-      {{#each person in people}}
-        &lt;div {{action edit person}}&gt;
-          click me
-        &lt;/div&gt;
-      {{/each}}
-    &lt;/script&gt;
</del><ins>+    {{#each person in people}}
+      &lt;div {{action &quot;edit&quot; person}}&gt;
+        click me
+      &lt;/div&gt;
+    {{/each}}
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><del>-    Clicking &quot;click me&quot; will trigger the `edit` method on the current view's
-    controller with the current person as a parameter.
</del><ins>+    Clicking &quot;click me&quot; will trigger the `edit` method on the current controller
+    with the value of `person` as a parameter.
</ins><span class="cx"> 
</span><span class="cx">     @method action
</span><span class="cx">     @for Ember.Handlebars.helpers
</span><span class="lines">@@ -24070,13 +36764,12 @@
</span><span class="cx">     @param {Object} [context]*
</span><span class="cx">     @param {Hash} options
</span><span class="cx">   */
</span><del>-  EmberHandlebars.registerHelper('action', function(actionName) {
</del><ins>+  EmberHandlebars.registerHelper('action', function actionHelper(actionName) {
</ins><span class="cx">     var options = arguments[arguments.length - 1],
</span><span class="cx">         contexts = a_slice.call(arguments, 1, -1);
</span><span class="cx"> 
</span><span class="cx">     var hash = options.hash,
</span><del>-        view = options.data.view,
-        controller, link;
</del><ins>+        controller;
</ins><span class="cx"> 
</span><span class="cx">     // create a hash to pass along to registerAction
</span><span class="cx">     var action = {
</span><span class="lines">@@ -24089,7 +36782,7 @@
</span><span class="cx">       params: contexts
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    action.view = view = get(view, 'concreteView');
</del><ins>+    action.view = options.data.view;
</ins><span class="cx"> 
</span><span class="cx">     var root, target;
</span><span class="cx"> 
</span><span class="lines">@@ -24102,8 +36795,9 @@
</span><span class="cx"> 
</span><span class="cx">     action.target = { root: root, target: target, options: options };
</span><span class="cx">     action.bubbles = hash.bubbles;
</span><ins>+    action.preventDefault = hash.preventDefault;
</ins><span class="cx"> 
</span><del>-    var actionId = ActionHelper.registerAction(actionName, action);
</del><ins>+    var actionId = ActionHelper.registerAction(actionName, action, hash.allowedKeys);
</ins><span class="cx">     return new SafeString('data-ember-action=&quot;' + actionId + '&quot;');
</span><span class="cx">   });
</span><span class="cx"> 
</span><span class="lines">@@ -24114,100 +36808,56 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><ins>+
+})();
+
+
+
+(function() {
</ins><span class="cx"> /**
</span><span class="cx"> @module ember
</span><span class="cx"> @submodule ember-routing
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-if (Ember.ENV.EXPERIMENTAL_CONTROL_HELPER) {
-  var get = Ember.get, set = Ember.set;
</del><ins>+var get = Ember.get, set = Ember.set;
</ins><span class="cx"> 
</span><ins>+Ember.ControllerMixin.reopen({
</ins><span class="cx">   /**
</span><del>-    The control helper is currently under development and is considered experimental.
-    To enable it, set `ENV.EXPERIMENTAL_CONTROL_HELPER = true` before requiring Ember.
</del><ins>+    Transition the application into another route. The route may
+    be either a single route or route path:
</ins><span class="cx"> 
</span><del>-    @method control
-    @for Ember.Handlebars.helpers
-    @param {String} path
-    @param {String} modelPath
-    @param {Hash} options
-    @return {String} HTML string
-  */
-  Ember.Handlebars.registerHelper('control', function(path, modelPath, options) {
-    if (arguments.length === 2) {
-      options = modelPath;
-      modelPath = undefined;
-    }
</del><ins>+    ```javascript
+    aController.transitionToRoute('blogPosts');
+    aController.transitionToRoute('blogPosts.recentEntries');
+    ```
</ins><span class="cx"> 
</span><del>-    var model;
</del><ins>+    Optionally supply a model for the route in question. The model
+    will be serialized into the URL using the `serialize` hook of
+    the route:
</ins><span class="cx"> 
</span><del>-    if (modelPath) {
-      model = Ember.Handlebars.get(this, modelPath, options);
-    }
</del><ins>+    ```javascript
+    aController.transitionToRoute('blogPost', aPost);
+    ```
</ins><span class="cx"> 
</span><del>-    var controller = options.data.keywords.controller,
-        view = options.data.keywords.view,
-        children = get(controller, '_childContainers'),
-        controlID = options.hash.controlID,
-        container, subContainer;
</del><ins>+    Multiple models will be applied last to first recursively up the
+    resource tree.
</ins><span class="cx"> 
</span><del>-    if (children.hasOwnProperty(controlID)) {
-      subContainer = children[controlID];
-    } else {
-      container = get(controller, 'container'),
-      subContainer = container.child();
-      children[controlID] = subContainer;
-    }
-
-    var normalizedPath = path.replace(/\//g, '.');
-
-    var childView = subContainer.lookup('view:' + normalizedPath) || subContainer.lookup('view:default'),
-        childController = subContainer.lookup('controller:' + normalizedPath),
-        childTemplate = subContainer.lookup('template:' + path);
-
-    Ember.assert(&quot;Could not find controller for path: &quot; + normalizedPath, childController);
-    Ember.assert(&quot;Could not find view for path: &quot; + normalizedPath, childView);
-
-    set(childController, 'target', controller);
-    set(childController, 'model', model);
-
-    options.hash.template = childTemplate;
-    options.hash.controller = childController;
-
-    function observer() {
-      var model = Ember.Handlebars.get(this, modelPath, options);
-      set(childController, 'model', model);
-      childView.rerender();
-    }
-
-    Ember.addObserver(this, modelPath, observer);
-    childView.one('willDestroyElement', this, function() {
-      Ember.removeObserver(this, modelPath, observer);
</del><ins>+    ```javascript
+    this.resource('blogPost', {path:':blogPostId'}, function(){
+      this.resource('blogComment', {path: ':blogCommentId'});
</ins><span class="cx">     });
</span><span class="cx"> 
</span><del>-    Ember.Handlebars.helpers.view.call(this, childView, options);
-  });
-}
</del><ins>+    aController.transitionToRoute('blogComment', aPost, aComment);
+    ```
</ins><span class="cx"> 
</span><del>-})();
</del><ins>+    See also 'replaceRoute'.
</ins><span class="cx"> 
</span><del>-
-
-(function() {
-
-})();
-
-
-
-(function() {
-/**
-@module ember
-@submodule ember-routing
-*/
-
-var get = Ember.get, set = Ember.set;
-
-Ember.ControllerMixin.reopen({
</del><ins>+    @param {String} name the name of the route
+    @param {...Object} models the model(s) to be used while transitioning
+    to the route.
+    @for Ember.ControllerMixin
+    @method transitionToRoute
+  */
</ins><span class="cx">   transitionToRoute: function() {
</span><span class="cx">     // target may be either another controller or a router
</span><span class="cx">     var target = get(this, 'target'),
</span><span class="lines">@@ -24215,11 +36865,51 @@
</span><span class="cx">     return method.apply(target, arguments);
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    @deprecated
+    @for Ember.ControllerMixin
+    @method transitionTo
+  */
</ins><span class="cx">   transitionTo: function() {
</span><span class="cx">     Ember.deprecate(&quot;transitionTo is deprecated. Please use transitionToRoute.&quot;);
</span><span class="cx">     return this.transitionToRoute.apply(this, arguments);
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    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);
+    ```
+
+    Multiple models will be applied last to first recursively up the
+    resource tree.
+
+    ```javascript
+    this.resource('blogPost', {path:':blogPostId'}, function(){
+      this.resource('blogComment', {path: ':blogCommentId'});
+    });
+
+    aController.replaceRoute('blogComment', aPost, aComment);
+    ```
+
+    @param {String} name the name of the route
+    @param {...Object} models the model(s) to be used while transitioning
+    to the route.
+    @for Ember.ControllerMixin
+    @method replaceRoute
+  */
</ins><span class="cx">   replaceRoute: function() {
</span><span class="cx">     // target may be either another controller or a router
</span><span class="cx">     var target = get(this, 'target'),
</span><span class="lines">@@ -24227,6 +36917,11 @@
</span><span class="cx">     return method.apply(target, arguments);
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    @deprecated
+    @for Ember.ControllerMixin
+    @method replaceWith
+  */
</ins><span class="cx">   replaceWith: function() {
</span><span class="cx">     Ember.deprecate(&quot;replaceWith is deprecated. Please use replaceRoute.&quot;);
</span><span class="cx">     return this.replaceRoute.apply(this, arguments);
</span><span class="lines">@@ -24246,12 +36941,56 @@
</span><span class="cx"> var get = Ember.get, set = Ember.set;
</span><span class="cx"> 
</span><span class="cx"> Ember.View.reopen({
</span><ins>+
+  /**
+    Sets the private `_outlets` object on the view.
+
+    @method init
+   */
</ins><span class="cx">   init: function() {
</span><span class="cx">     set(this, '_outlets', {});
</span><span class="cx">     this._super();
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    Manually fill any of a view's `{{outlet}}` areas with the
+    supplied view.
+
+    Example
+
+    ```javascript
+    var MyView = Ember.View.extend({
+      template: Ember.Handlebars.compile('Child view: {{outlet &quot;main&quot;}} ')
+    });
+    var myView = MyView.create();
+    myView.appendTo('body');
+    // The html for myView now looks like:
+    // &lt;div id=&quot;ember228&quot; class=&quot;ember-view&quot;&gt;Child view: &lt;/div&gt;
+
+    var FooView = Ember.View.extend({
+      template: Ember.Handlebars.compile('&lt;h1&gt;Foo&lt;/h1&gt; ')
+    });
+    var fooView = FooView.create();
+    myView.connectOutlet('main', fooView);
+    // The html for myView now looks like:
+    // &lt;div id=&quot;ember228&quot; class=&quot;ember-view&quot;&gt;Child view:
+    //   &lt;div id=&quot;ember234&quot; class=&quot;ember-view&quot;&gt;&lt;h1&gt;Foo&lt;/h1&gt; &lt;/div&gt;
+    // &lt;/div&gt;
+    ```
+    @method connectOutlet
+    @param  {String} outletName A unique name for the outlet
+    @param  {Object} view       An Ember.View
+   */
</ins><span class="cx">   connectOutlet: function(outletName, view) {
</span><ins>+    if (this._pendingDisconnections) {
+      delete this._pendingDisconnections[outletName];
+    }
+
+    if (this._hasEquivalentView(outletName, view)) {
+      view.destroy();
+      return;
+    }
+
</ins><span class="cx">     var outlets = get(this, '_outlets'),
</span><span class="cx">         container = get(this, 'container'),
</span><span class="cx">         router = container &amp;&amp; container.lookup('router:main'),
</span><span class="lines">@@ -24264,10 +37003,80 @@
</span><span class="cx">     }
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    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}
+   */
+  _hasEquivalentView: function(outletName, view) {
+    var existingView = get(this, '_outlets.'+outletName);
+    return existingView &amp;&amp;
+      existingView.constructor === view.constructor &amp;&amp;
+      existingView.get('template') === view.get('template') &amp;&amp;
+      existingView.get('context') === view.get('context');
+  },
+
+  /**
+    Removes an outlet from the view.
+
+    Example
+
+    ```javascript
+    var MyView = Ember.View.extend({
+      template: Ember.Handlebars.compile('Child view: {{outlet &quot;main&quot;}} ')
+    });
+    var myView = MyView.create();
+    myView.appendTo('body');
+    // myView's html:
+    // &lt;div id=&quot;ember228&quot; class=&quot;ember-view&quot;&gt;Child view: &lt;/div&gt;
+
+    var FooView = Ember.View.extend({
+      template: Ember.Handlebars.compile('&lt;h1&gt;Foo&lt;/h1&gt; ')
+    });
+    var fooView = FooView.create();
+    myView.connectOutlet('main', fooView);
+    // myView's html:
+    // &lt;div id=&quot;ember228&quot; class=&quot;ember-view&quot;&gt;Child view:
+    //   &lt;div id=&quot;ember234&quot; class=&quot;ember-view&quot;&gt;&lt;h1&gt;Foo&lt;/h1&gt; &lt;/div&gt;
+    // &lt;/div&gt;
+
+    myView.disconnectOutlet('main');
+    // myView's html:
+    // &lt;div id=&quot;ember228&quot; class=&quot;ember-view&quot;&gt;Child view: &lt;/div&gt;
+    ```
+
+    @method disconnectOutlet
+    @param  {String} outletName The name of the outlet to be removed
+   */
</ins><span class="cx">   disconnectOutlet: function(outletName) {
</span><ins>+    if (!this._pendingDisconnections) {
+      this._pendingDisconnections = {};
+    }
+    this._pendingDisconnections[outletName] = true;
+    Ember.run.once(this, '_finishDisconnections');
+  },
+
+  /**
+    Gets an outlet that is pending disconnection and then
+    nullifys the object on the `_outlet` object.
+
+    @private
+    @method _finishDisconnections
+   */
+  _finishDisconnections: function() {
</ins><span class="cx">     var outlets = get(this, '_outlets');
</span><ins>+    var pendingDisconnections = this._pendingDisconnections;
+    this._pendingDisconnections = null;
</ins><span class="cx"> 
</span><del>-    set(outlets, outletName, null);
</del><ins>+    for (var outletName in pendingDisconnections) {
+      set(outlets, outletName, null);
+    }
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -24276,7 +37085,20 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><ins>+/**
+@module ember
+@submodule ember-views
+*/
</ins><span class="cx"> 
</span><ins>+// Add a new named queue after the 'actions' queue (where RSVP promises
+// resolve), which is used in router transitions to prevent unnecessary
+// loading state entry if all context promises resolve on the 
+// 'actions' queue first.
+
+var queues = Ember.run.queues,
+    indexOf = Ember.ArrayPolyfills.indexOf;
+queues.splice(indexOf.call(queues, 'actions') + 1, 0, 'routerTransitions');
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -24289,34 +37111,102 @@
</span><span class="cx"> 
</span><span class="cx"> var get = Ember.get, set = Ember.set;
</span><span class="cx"> 
</span><del>-/*
-  This file implements the `location` API used by Ember's router.
</del><ins>+/**
+  Ember.Location returns an instance of the correct implementation of
+  the `location` API.
</ins><span class="cx"> 
</span><del>-  That API is:
</del><ins>+  ## Implementations
</ins><span class="cx"> 
</span><del>-  getURL: returns the current URL
-  setURL(path): sets the current URL
-  replaceURL(path): replace the current URL (optional)
-  onUpdateURL(callback): triggers the callback when the URL changes
-  formatURL(url): formats `url` to be placed into `href` attribute
</del><ins>+  You can pass an implementation name (`hash`, `history`, `none`) to force a
+  particular implementation to be used in your application.
</ins><span class="cx"> 
</span><del>-  Calling setURL or replaceURL will not trigger onUpdateURL callbacks.
</del><ins>+  ### HashLocation
</ins><span class="cx"> 
</span><del>-  TODO: This should perhaps be moved so that it's visible in the doc output.
-*/
</del><ins>+  Using `HashLocation` results in URLs with a `#` (hash sign) separating the
+  server side URL portion of the URL from the portion that is used by Ember.
+  This relies upon the `hashchange` event existing in the browser.
</ins><span class="cx"> 
</span><del>-/**
-  Ember.Location returns an instance of the correct implementation of
-  the `location` API.
</del><ins>+  Example:
</ins><span class="cx"> 
</span><del>-  You can pass it a `implementation` ('hash', 'history', 'none') to force a
-  particular implementation.
</del><ins>+  ```javascript
+  App.Router.map(function() {
+    this.resource('posts', function() {
+      this.route('new');
+    });
+  });
</ins><span class="cx"> 
</span><ins>+  App.Router.reopen({
+    location: 'hash'
+  });
+  ```
+
+  This will result in a posts.new url of `/#/posts/new`.
+
+  ### HistoryLocation
+
+  Using `HistoryLocation` results in URLs that are indistinguishable from a
+  standard URL. This relies upon the browser's `history` API.
+
+  Example:
+
+  ```javascript
+  App.Router.map(function() {
+    this.resource('posts', function() {
+      this.route('new');
+    });
+  });
+
+  App.Router.reopen({
+    location: 'history'
+  });
+  ```
+
+  This will result in a posts.new url of `/posts/new`.
+
+  ### NoneLocation
+
+  Using `NoneLocation` causes Ember to not store the applications URL state
+  in the actual URL. This is generally used for testing purposes, and is one
+  of the changes made when calling `App.setupForTesting()`.
+
+  ## Location API
+
+  Each location implementation must provide the following methods:
+
+  * implementation: returns the string name used to reference the implementation.
+  * getURL: returns the current URL.
+  * setURL(path): sets the current URL.
+  * replaceURL(path): replace the current URL (optional).
+  * onUpdateURL(callback): triggers the callback when the URL changes.
+  * formatURL(url): formats `url` to be placed into `href` attribute.
+
+  Calling setURL or replaceURL will not trigger onUpdateURL callbacks.
+
</ins><span class="cx">   @class Location
</span><span class="cx">   @namespace Ember
</span><span class="cx">   @static
</span><span class="cx"> */
</span><span class="cx"> Ember.Location = {
</span><ins>+  /**
+   This is deprecated in favor of using the container to lookup the location
+   implementation as desired.
+
+   For example:
+
+   ```javascript
+   // Given a location registered as follows:
+   container.register('location:history-test', HistoryTestLocation);
+
+   // You could create a new instance via:
+   container.lookup('location:history-test');
+   ```
+
+    @method create
+    @param {Object} options
+    @return {Object} an instance of an implementation of the `location` API
+    @deprecated Use the container to lookup the location implementation that you
+    need.
+  */
</ins><span class="cx">   create: function(options) {
</span><span class="cx">     var implementation = options &amp;&amp; options.implementation;
</span><span class="cx">     Ember.assert(&quot;Ember.Location.create: you must specify a 'implementation' option&quot;, !!implementation);
</span><span class="lines">@@ -24327,6 +37217,28 @@
</span><span class="cx">     return implementationClass.create.apply(implementationClass, arguments);
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+   This is deprecated in favor of using the container to register the
+   location implementation as desired.
+
+   Example:
+
+   ```javascript
+   Application.initializer({
+    name: &quot;history-test-location&quot;,
+
+    initialize: function(container, application) {
+      application.register('location:history-test', HistoryTestLocation);
+    }
+   });
+   ```
+
+   @method registerImplementation
+   @param {String} name
+   @param {Object} implementation of the `location` API
+   @deprecated Register your custom location implementation with the
+   container directly.
+  */
</ins><span class="cx">   registerImplementation: function(name, implementation) {
</span><span class="cx">     this.implementations[name] = implementation;
</span><span class="cx">   },
</span><span class="lines">@@ -24359,23 +37271,66 @@
</span><span class="cx"> Ember.NoneLocation = Ember.Object.extend({
</span><span class="cx">   path: '',
</span><span class="cx"> 
</span><ins>+  /**
+    Returns the current path.
+
+    @private
+    @method getURL
+    @return {String} path
+  */
</ins><span class="cx">   getURL: function() {
</span><span class="cx">     return get(this, 'path');
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    Set the path and remembers what was set. Using this method
+    to change the path will not invoke the `updateURL` callback.
+
+    @private
+    @method setURL
+    @param path {String}
+  */
</ins><span class="cx">   setURL: function(path) {
</span><span class="cx">     set(this, 'path', path);
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    Register a callback to be invoked when the path changes. These
+    callbacks will execute when the user presses the back or forward
+    button, but not after `setURL` is invoked.
+
+    @private
+    @method onUpdateURL
+    @param callback {Function}
+  */
</ins><span class="cx">   onUpdateURL: function(callback) {
</span><span class="cx">     this.updateCallback = callback;
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    Sets the path and calls the `updateURL` callback.
+
+    @private
+    @method handleURL
+    @param callback {Function}
+  */
</ins><span class="cx">   handleURL: function(url) {
</span><span class="cx">     set(this, 'path', url);
</span><span class="cx">     this.updateCallback(url);
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    Given a URL, formats it to be placed into the page as part
+    of an element's `href` attribute.
+
+    This is used, for example, when using the {{action}} helper
+    to generate a URL based on an event.
+
+    @private
+    @method formatURL
+    @param url {String}
+    @return {String} url
+  */
</ins><span class="cx">   formatURL: function(url) {
</span><span class="cx">     // The return value is not overly meaningful, but we do not want to throw
</span><span class="cx">     // errors when test code renders templates containing {{action href=true}}
</span><span class="lines">@@ -24399,8 +37354,8 @@
</span><span class="cx"> var get = Ember.get, set = Ember.set;
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  Ember.HashLocation implements the location API using the browser's
-  hash. At present, it relies on a hashchange event existing in the
</del><ins>+  `Ember.HashLocation` implements the location API using the browser's
+  hash. At present, it relies on a `hashchange` event existing in the
</ins><span class="cx">   browser.
</span><span class="cx"> 
</span><span class="cx">   @class HashLocation
</span><span class="lines">@@ -24414,23 +37369,22 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Returns the current `location.hash`, minus the '#' at the front.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method getURL
</span><span class="cx">   */
</span><span class="cx">   getURL: function() {
</span><ins>+        // Default implementation without feature flag enabled
</ins><span class="cx">     return get(this, 'location').hash.substr(1);
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Set the `location.hash` and remembers what was set. This prevents
</span><span class="cx">     `onUpdateURL` callbacks from triggering when the hash was set by
</span><span class="cx">     `HashLocation`.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method setURL
</span><span class="cx">     @param path {String}
</span><span class="cx">   */
</span><span class="lines">@@ -24440,12 +37394,23 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+    Uses location.replace to update the url without a page reload
+    or history modification.
+
</ins><span class="cx">     @private
</span><ins>+    @method replaceURL
+    @param path {String}
+  */
+  replaceURL: function(path) {
+    get(this, 'location').replace('#' + path);
+  },
</ins><span class="cx"> 
</span><ins>+  /**
</ins><span class="cx">     Register a callback to be invoked when the hash changes. These
</span><span class="cx">     callbacks will execute when the user presses the back or forward
</span><span class="cx">     button, but not after `setURL` is invoked.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method onUpdateURL
</span><span class="cx">     @param callback {Function}
</span><span class="cx">   */
</span><span class="lines">@@ -24453,27 +37418,26 @@
</span><span class="cx">     var self = this;
</span><span class="cx">     var guid = Ember.guidFor(this);
</span><span class="cx"> 
</span><del>-    Ember.$(window).bind('hashchange.ember-location-'+guid, function() {
</del><ins>+    Ember.$(window).on('hashchange.ember-location-'+guid, function() {
</ins><span class="cx">       Ember.run(function() {
</span><span class="cx">         var path = location.hash.substr(1);
</span><span class="cx">         if (get(self, 'lastSetURL') === path) { return; }
</span><span class="cx"> 
</span><span class="cx">         set(self, 'lastSetURL', null);
</span><span class="cx"> 
</span><del>-        callback(location.hash.substr(1));
</del><ins>+        callback(path);
</ins><span class="cx">       });
</span><span class="cx">     });
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Given a URL, formats it to be placed into the page as part
</span><span class="cx">     of an element's `href` attribute.
</span><span class="cx"> 
</span><span class="cx">     This is used, for example, when using the {{action}} helper
</span><span class="cx">     to generate a URL based on an event.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method formatURL
</span><span class="cx">     @param url {String}
</span><span class="cx">   */
</span><span class="lines">@@ -24481,10 +37445,16 @@
</span><span class="cx">     return '#'+url;
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    Cleans up the HashLocation event listener.
+
+    @private
+    @method willDestroy
+  */
</ins><span class="cx">   willDestroy: function() {
</span><span class="cx">     var guid = Ember.guidFor(this);
</span><span class="cx"> 
</span><del>-    Ember.$(window).unbind('hashchange.ember-location-'+guid);
</del><ins>+    Ember.$(window).off('hashchange.ember-location-'+guid);
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -24501,7 +37471,8 @@
</span><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> var get = Ember.get, set = Ember.set;
</span><del>-var popstateReady = false;
</del><ins>+var popstateFired = false;
+var supportsHistoryState = window.history &amp;&amp; 'state' in window.history;
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><span class="cx">   Ember.HistoryLocation implements the location API using the browser's
</span><span class="lines">@@ -24515,19 +37486,17 @@
</span><span class="cx"> 
</span><span class="cx">   init: function() {
</span><span class="cx">     set(this, 'location', get(this, 'location') || window.location);
</span><del>-    this.initState();
</del><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Used to set state on first call to setURL
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method initState
</span><span class="cx">   */
</span><span class="cx">   initState: function() {
</span><ins>+    set(this, 'history', get(this, 'history') || window.history);
</ins><span class="cx">     this.replaceState(this.formatURL(this.getURL()));
</span><del>-    set(this, 'history', window.history);
</del><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -24539,98 +37508,117 @@
</span><span class="cx">   rootURL: '/',
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+    Returns the current `location.pathname` without `rootURL`.
+
</ins><span class="cx">     @private
</span><del>-
-    Returns the current `location.pathname` without rootURL
-
</del><span class="cx">     @method getURL
</span><ins>+    @return url {String}
</ins><span class="cx">   */
</span><span class="cx">   getURL: function() {
</span><span class="cx">     var rootURL = get(this, 'rootURL'),
</span><del>-        url = get(this, 'location').pathname;
</del><ins>+        location = get(this, 'location'),
+        path = location.pathname;
</ins><span class="cx"> 
</span><span class="cx">     rootURL = rootURL.replace(/\/$/, '');
</span><del>-    url = url.replace(rootURL, '');
</del><ins>+    var url = path.replace(rootURL, '');
</ins><span class="cx"> 
</span><ins>+    
</ins><span class="cx">     return url;
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Uses `history.pushState` to update the url without a page reload.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method setURL
</span><span class="cx">     @param path {String}
</span><span class="cx">   */
</span><span class="cx">   setURL: function(path) {
</span><ins>+    var state = this.getState();
</ins><span class="cx">     path = this.formatURL(path);
</span><span class="cx"> 
</span><del>-    if (this.getState() &amp;&amp; this.getState().path !== path) {
-      popstateReady = true;
</del><ins>+    if (state &amp;&amp; state.path !== path) {
</ins><span class="cx">       this.pushState(path);
</span><span class="cx">     }
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Uses `history.replaceState` to update the url without a page reload
</span><span class="cx">     or history modification.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method replaceURL
</span><span class="cx">     @param path {String}
</span><span class="cx">   */
</span><span class="cx">   replaceURL: function(path) {
</span><ins>+    var state = this.getState();
</ins><span class="cx">     path = this.formatURL(path);
</span><span class="cx"> 
</span><del>-    if (this.getState() &amp;&amp; this.getState().path !== path) {
-      popstateReady = true;
</del><ins>+    if (state &amp;&amp; state.path !== path) {
</ins><span class="cx">       this.replaceState(path);
</span><span class="cx">     }
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   @private
-
</del><span class="cx">    Get the current `history.state`
</span><ins>+   Polyfill checks for native browser support and falls back to retrieving
+   from a private _historyState variable
</ins><span class="cx"> 
</span><ins>+   @private
</ins><span class="cx">    @method getState
</span><ins>+   @return state {Object}
</ins><span class="cx">   */
</span><span class="cx">   getState: function() {
</span><del>-    return get(this, 'history').state;
</del><ins>+    return supportsHistoryState ? get(this, 'history').state : this._historyState;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+   Pushes a new state.
+
</ins><span class="cx">    @private
</span><del>-
-   Pushes a new state
-
</del><span class="cx">    @method pushState
</span><span class="cx">    @param path {String}
</span><span class="cx">   */
</span><span class="cx">   pushState: function(path) {
</span><del>-    window.history.pushState({ path: path }, null, path);
</del><ins>+    var state = { path: path };
+
+    get(this, 'history').pushState(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();
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+   Replaces the current state.
+
</ins><span class="cx">    @private
</span><del>-
-   Replaces the current state
-
</del><span class="cx">    @method replaceState
</span><span class="cx">    @param path {String}
</span><span class="cx">   */
</span><span class="cx">   replaceState: function(path) {
</span><del>-    window.history.replaceState({ path: path }, null, path);
</del><ins>+    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();
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Register a callback to be invoked whenever the browser
</span><span class="cx">     history changes, including using forward and back buttons.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method onUpdateURL
</span><span class="cx">     @param callback {Function}
</span><span class="cx">   */
</span><span class="lines">@@ -24638,21 +37626,23 @@
</span><span class="cx">     var guid = Ember.guidFor(this),
</span><span class="cx">         self = this;
</span><span class="cx"> 
</span><del>-    Ember.$(window).bind('popstate.ember-location-'+guid, function(e) {
-      if(!popstateReady) {
-        return;
</del><ins>+    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; }
</ins><span class="cx">       }
</span><span class="cx">       callback(self.getURL());
</span><span class="cx">     });
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Used when using `{{action}}` helper.  The url is always appended to the rootURL.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method formatURL
</span><span class="cx">     @param url {String}
</span><ins>+    @return formatted url {String}
</ins><span class="cx">   */
</span><span class="cx">   formatURL: function(url) {
</span><span class="cx">     var rootURL = get(this, 'rootURL');
</span><span class="lines">@@ -24664,10 +37654,16 @@
</span><span class="cx">     return rootURL + url;
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    Cleans up the HistoryLocation event listener.
+
+    @private
+    @method willDestroy
+  */
</ins><span class="cx">   willDestroy: function() {
</span><span class="cx">     var guid = Ember.guidFor(this);
</span><span class="cx"> 
</span><del>-    Ember.$(window).unbind('popstate.ember-location-'+guid);
</del><ins>+    Ember.$(window).off('popstate.ember-location-'+guid);
</ins><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -24689,7 +37685,6 @@
</span><span class="cx"> 
</span><span class="cx"> @module ember
</span><span class="cx"> @submodule ember-routing
</span><del>-@requires ember-states
</del><span class="cx"> @requires ember-views
</span><span class="cx"> */
</span><span class="cx"> 
</span><span class="lines">@@ -24752,7 +37747,7 @@
</span><span class="cx">   }
</span><span class="cx">   function checkCycle(vertex, path) {
</span><span class="cx">     if (vertex.name === toName) {
</span><del>-      throw new Error(&quot;cycle detected: &quot; + toName + &quot; &lt;- &quot; + path.join(&quot; &lt;- &quot;));
</del><ins>+      throw new Ember.Error(&quot;cycle detected: &quot; + toName + &quot; &lt;- &quot; + path.join(&quot; &lt;- &quot;));
</ins><span class="cx">     }
</span><span class="cx">   }
</span><span class="cx">   visit(from, checkCycle);
</span><span class="lines">@@ -24810,11 +37805,341 @@
</span><span class="cx"> @submodule ember-application
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var get = Ember.get, set = Ember.set,
</del><ins>+var get = Ember.get,
</ins><span class="cx">     classify = Ember.String.classify,
</span><ins>+    capitalize = Ember.String.capitalize,
</ins><span class="cx">     decamelize = Ember.String.decamelize;
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+  The DefaultResolver defines the default lookup rules to resolve
+  container lookups before consulting the container for registered
+  items:
+
+* templates are looked up on `Ember.TEMPLATES`
+* other names are looked up on the application after converting
+  the name. For example, `controller:post` looks up
+  `App.PostController` by default.
+* there are some nuances (see examples below)
+
+  ### How Resolving Works
+
+  The container calls this object's `resolve` method with the
+  `fullName` argument.
+
+  It first parses the fullName into an object using `parseName`.
+
+  Then it checks for the presence of a type-specific instance
+  method of the form `resolve[Type]` and calls it if it exists.
+  For example if it was resolving 'template:post', it would call
+  the `resolveTemplate` method.
+
+  Its last resort is to call the `resolveOther` method.
+
+  The methods of this object are designed to be easy to override
+  in a subclass. For example, you could enhance how a template
+  is resolved like so:
+
+  ```javascript
+  App = Ember.Application.create({
+    Resolver: Ember.DefaultResolver.extend({
+      resolveTemplate: function(parsedName) {
+        var resolvedTemplate = this._super(parsedName);
+        if (resolvedTemplate) { return resolvedTemplate; }
+        return Ember.TEMPLATES['not_found'];
+      }
+    })
+  });
+  ```
+
+  Some examples of how names are resolved:
+
+  ```
+  'template:post' //=&gt; Ember.TEMPLATES['post']
+  'template:posts/byline' //=&gt; Ember.TEMPLATES['posts/byline']
+  'template:posts.byline' //=&gt; Ember.TEMPLATES['posts/byline']
+  'template:blogPost' //=&gt; Ember.TEMPLATES['blogPost']
+                      //   OR
+                      //   Ember.TEMPLATES['blog_post']
+  'controller:post' //=&gt; App.PostController
+  'controller:posts.index' //=&gt; App.PostsIndexController
+  'controller:blog/post' //=&gt; Blog.PostController
+  'controller:basic' //=&gt; Ember.Controller
+  'route:post' //=&gt; App.PostRoute
+  'route:posts.index' //=&gt; App.PostsIndexRoute
+  'route:blog/post' //=&gt; Blog.PostRoute
+  'route:basic' //=&gt; Ember.Route
+  'view:post' //=&gt; App.PostView
+  'view:posts.index' //=&gt; App.PostsIndexView
+  'view:blog/post' //=&gt; Blog.PostView
+  'view:basic' //=&gt; Ember.View
+  'foo:post' //=&gt; App.PostFoo
+  'model:post' //=&gt; App.Post
+  ```
+
+  @class DefaultResolver
+  @namespace Ember
+  @extends Ember.Object
+*/
+Ember.DefaultResolver = Ember.Object.extend({
+  /**
+    This will be set to the Application instance when it is
+    created.
+
+    @property namespace
+  */
+  namespace: null,
+
+  normalize: function(fullName) {
+    var split = fullName.split(':', 2),
+        type = split[0],
+        name = split[1];
+
+    Ember.assert(&quot;Tried to normalize a container name without a colon (:) in &quot; +
+                 &quot;it. You probably tried to lookup a name that did not contain &quot; +
+                 &quot;a type, a colon, and a name. A proper lookup name would be &quot; +
+                 &quot;`view:post`.&quot;, split.length === 2);
+
+    if (type !== 'template') {
+      var result = name;
+
+      if (result.indexOf('.') &gt; -1) {
+        result = result.replace(/\.(.)/g, function(m) { return m.charAt(1).toUpperCase(); });
+      }
+
+      if (name.indexOf('_') &gt; -1) {
+        result = result.replace(/_(.)/g, function(m) { return m.charAt(1).toUpperCase(); });
+      }
+
+      return type + ':' + result;
+    } else {
+      return fullName;
+    }
+  },
+
+
+  /**
+    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
+  */
+  resolve: function(fullName) {
+    var parsedName = this.parseName(fullName),
+        typeSpecificResolveMethod = this[parsedName.resolveMethodName];
+
+    if (!parsedName.name || !parsedName.type) {
+      throw new TypeError(&quot;Invalid fullName: `&quot; + fullName + &quot;`, must be of the form `type:name` &quot;);
+    }
+
+    if (typeSpecificResolveMethod) {
+      var resolved = typeSpecificResolveMethod.call(this, parsedName);
+      if (resolved) { return resolved; }
+    }
+    return this.resolveOther(parsedName);
+  },
+  /**
+    Convert the string name of the form &quot;type:name&quot; to
+    a Javascript object with the parsed aspects of the name
+    broken out.
+
+    @protected
+    @param {String} fullName the lookup string
+    @method parseName
+  */
+  parseName: function(fullName) {
+    var nameParts = fullName.split(&quot;:&quot;),
+        type = nameParts[0], fullNameWithoutType = nameParts[1],
+        name = fullNameWithoutType,
+        namespace = get(this, 'namespace'),
+        root = namespace;
+
+    if (type !== 'template' &amp;&amp; name.indexOf('/') !== -1) {
+      var parts = name.split('/');
+      name = parts[parts.length - 1];
+      var namespaceName = capitalize(parts.slice(0, -1).join('.'));
+      root = Ember.Namespace.byName(namespaceName);
+
+      Ember.assert('You are looking for a ' + name + ' ' + type + ' in the ' + namespaceName + ' namespace, but the namespace could not be found', root);
+    }
+
+    return {
+      fullName: fullName,
+      type: type,
+      fullNameWithoutType: fullNameWithoutType,
+      name: name,
+      root: root,
+      resolveMethodName: &quot;resolve&quot; + classify(type)
+    };
+  },
+  /**
+    Look up the template in Ember.TEMPLATES
+
+    @protected
+    @param {Object} parsedName a parseName object with the parsed
+      fullName lookup string
+    @method resolveTemplate
+  */
+  resolveTemplate: 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];
+    }
+  },
+  /**
+    Given a parseName object (output from `parseName`), apply
+    the conventions expected by `Ember.Router`
+
+    @protected
+    @param {Object} parsedName a parseName object with the parsed
+      fullName lookup string
+    @method useRouterNaming
+  */
+  useRouterNaming: function(parsedName) {
+    parsedName.name = parsedName.name.replace(/\./g, '_');
+    if (parsedName.name === 'basic') {
+      parsedName.name = '';
+    }
+  },
+  /**
+    Lookup the controller using `resolveOther`
+
+    @protected
+    @param {Object} parsedName a parseName object with the parsed
+      fullName lookup string
+    @method resolveController
+  */
+  resolveController: function(parsedName) {
+    this.useRouterNaming(parsedName);
+    return this.resolveOther(parsedName);
+  },
+  /**
+    Lookup the route using `resolveOther`
+
+    @protected
+    @param {Object} parsedName a parseName object with the parsed
+      fullName lookup string
+    @method resolveRoute
+  */
+  resolveRoute: function(parsedName) {
+    this.useRouterNaming(parsedName);
+    return this.resolveOther(parsedName);
+  },
+  /**
+    Lookup the view using `resolveOther`
+
+    @protected
+    @param {Object} parsedName a parseName object with the parsed
+      fullName lookup string
+    @method resolveView
+  */
+  resolveView: function(parsedName) {
+    this.useRouterNaming(parsedName);
+    return this.resolveOther(parsedName);
+  },
+
+  resolveHelper: function(parsedName) {
+    return this.resolveOther(parsedName) || Ember.Handlebars.helpers[parsedName.fullNameWithoutType];
+  },
+
+  /**
+    Lookup the model on the Application namespace
+
+    @protected
+    @param {Object} parsedName a parseName object with the parsed
+      fullName lookup string
+    @method resolveModel
+  */
+  resolveModel: function(parsedName) {
+    var className = classify(parsedName.name),
+        factory = get(parsedName.root, className);
+
+     if (factory) { return factory; }
+  },
+  /**
+    Look up the specified object (from parsedName) on the appropriate
+    namespace (usually on the Application)
+
+    @protected
+    @param {Object} parsedName a parseName object with the parsed
+      fullName lookup string
+    @method resolveOther
+  */
+  resolveOther: function(parsedName) {
+    var className = classify(parsedName.name) + classify(parsedName.type),
+        factory = get(parsedName.root, className);
+    if (factory) { return factory; }
+  },
+
+  /**
+    Returns a human-readable description for a fullName. Used by the
+    Application namespace in assertions to describe the
+    precise name of the class that Ember is looking for, rather than
+    container keys.
+
+    @protected
+    @param {String} fullName the lookup string
+    @method lookupDescription
+  */
+  lookupDescription: function(fullName) {
+    var parsedName = this.parseName(fullName);
+
+    if (parsedName.type === 'template') {
+      return &quot;template at &quot; + parsedName.fullNameWithoutType.replace(/\./g, '/');
+    }
+
+    var description = parsedName.root + &quot;.&quot; + classify(parsedName.name);
+    if (parsedName.type !== 'model') { description += classify(parsedName.type); }
+
+    return description;
+  },
+
+  makeToString: function(factory, fullName) {
+    return factory.toString();
+  }
+});
+
+})();
+
+
+
+(function() {
+/**
+@module ember
+@submodule ember-application
+*/
+
+var get = Ember.get, set = Ember.set;
+
+function DeprecatedContainer(container) {
+  this._container = container;
+}
+
+DeprecatedContainer.deprecate = function(method) {
+  return function() {
+    var container = this._container;
+
+    Ember.deprecate('Using the defaultContainer is no longer supported. [defaultContainer#' + method + '] see: http://git.io/EKPpnA', false);
+    return container[method].apply(container, arguments);
+  };
+};
+
+DeprecatedContainer.prototype = {
+  _container: null,
+  lookup: DeprecatedContainer.deprecate('lookup'),
+  resolve: DeprecatedContainer.deprecate('resolve'),
+  register: DeprecatedContainer.deprecate('register')
+};
+
+/**
</ins><span class="cx">   An instance of `Ember.Application` is the starting point for every Ember
</span><span class="cx">   application. It helps to instantiate, initialize and coordinate the many
</span><span class="cx">   objects that make up your app.
</span><span class="lines">@@ -24837,11 +38162,14 @@
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   By default, calling `Ember.Application.create()` will automatically initialize
</span><del>-  your  application by calling the `Ember.Application.initialize()` method. If
</del><ins>+  your application by calling the `Ember.Application.initialize()` method. If
</ins><span class="cx">   you need to delay initialization, you can call your app's `deferReadiness()`
</span><span class="cx">   method. When you are ready for your app to be initialized, call its
</span><span class="cx">   `advanceReadiness()` method.
</span><span class="cx"> 
</span><ins>+  You can define a `ready` method on the `Ember.Application` instance, which
+  will be run by Ember when the application is initialized.
+
</ins><span class="cx">   Because `Ember.Application` inherits from `Ember.Namespace`, any classes
</span><span class="cx">   you create will have useful string representations when calling `toString()`.
</span><span class="cx">   See the `Ember.Namespace` documentation for more information.
</span><span class="lines">@@ -24867,16 +38195,15 @@
</span><span class="cx">   example, the `keypress` event causes the `keyPress` method on the view to be
</span><span class="cx">   called, the `dblclick` event causes `doubleClick` to be called, and so on.
</span><span class="cx"> 
</span><del>-  If there is a browser event that Ember does not listen for by default, you
-  can specify custom events and their corresponding view method names by
-  setting the application's `customEvents` property:
</del><ins>+  If there is a bubbling browser event that Ember does not listen for by
+  default, you can specify custom events and their corresponding view method
+  names by setting the application's `customEvents` property:
</ins><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="cx">   App = Ember.Application.create({
</span><span class="cx">     customEvents: {
</span><del>-      // add support for the loadedmetadata media
-      // player event
-      'loadedmetadata': &quot;loadedMetadata&quot;
</del><ins>+      // add support for the paste event
+      paste: &quot;paste&quot;
</ins><span class="cx">     }
</span><span class="cx">   });
</span><span class="cx">   ```
</span><span class="lines">@@ -24902,7 +38229,7 @@
</span><span class="cx"> 
</span><span class="cx">   To learn more about the advantages of event delegation and the Ember view
</span><span class="cx">   layer, and a list of the event listeners that are setup by default, visit the
</span><del>-  [Ember View Layer guide](http://emberjs.com/guides/view_layer#toc_event-delegation).
</del><ins>+  [Ember View Layer guide](http://emberjs.com/guides/understanding-ember/the-view-layer/#toc_event-delegation).
</ins><span class="cx"> 
</span><span class="cx">   ### Initializers
</span><span class="cx"> 
</span><span class="lines">@@ -24913,7 +38240,7 @@
</span><span class="cx">     name: &quot;store&quot;,
</span><span class="cx"> 
</span><span class="cx">     initialize: function(container, application) {
</span><del>-      container.register('store', 'main', application.Store);
</del><ins>+      container.register('store:main', application.Store);
</ins><span class="cx">     }
</span><span class="cx">   });
</span><span class="cx">   ```
</span><span class="lines">@@ -24922,11 +38249,14 @@
</span><span class="cx"> 
</span><span class="cx">   In addition to creating your application's router, `Ember.Application` is
</span><span class="cx">   also responsible for telling the router when to start routing. Transitions
</span><del>-  between routes can be logged with the LOG_TRANSITIONS flag:
</del><ins>+  between routes can be logged with the `LOG_TRANSITIONS` flag, and more
+  detailed intra-transition logging can be logged with
+  the `LOG_TRANSITIONS_INTERNAL` flag:
</ins><span class="cx"> 
</span><span class="cx">   ```javascript
</span><span class="cx">   window.App = Ember.Application.create({
</span><del>-    LOG_TRANSITIONS: true
</del><ins>+    LOG_TRANSITIONS: true, // basic logging of successful transitions
+    LOG_TRANSITIONS_INTERNAL: true // detailed logging of all routing steps
</ins><span class="cx">   });
</span><span class="cx">   ```
</span><span class="cx"> 
</span><span class="lines">@@ -24938,25 +38268,15 @@
</span><span class="cx">   If there is any setup required before routing begins, you can implement a
</span><span class="cx">   `ready()` method on your app that will be invoked immediately before routing
</span><span class="cx">   begins.
</span><del>-
-  To begin routing, you must have at a minimum a top-level controller and view.
-  You define these as `App.ApplicationController` and `App.ApplicationView`,
-  respectively. Your application will not work if you do not define these two
-  mandatory classes. For example:
-
-  ```javascript
-  App.ApplicationView = Ember.View.extend({
-    templateName: 'application'
-  });
-  App.ApplicationController = Ember.Controller.extend();
</del><span class="cx">   ```
</span><span class="cx"> 
</span><span class="cx">   @class Application
</span><span class="cx">   @namespace Ember
</span><span class="cx">   @extends Ember.Namespace
</span><span class="cx"> */
</span><del>-var Application = Ember.Application = Ember.Namespace.extend({
</del><span class="cx"> 
</span><ins>+var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin, {
+
</ins><span class="cx">   /**
</span><span class="cx">     The root DOM element of the Application. This can be specified as an
</span><span class="cx">     element or a
</span><span class="lines">@@ -24996,7 +38316,7 @@
</span><span class="cx">     `keyup`, and delegates them to your application's `Ember.View`
</span><span class="cx">     instances.
</span><span class="cx"> 
</span><del>-    If you would like additional events to be delegated to your
</del><ins>+    If you would like additional bubbling events to be delegated to your
</ins><span class="cx">     views, set your `Ember.Application`'s `customEvents` property
</span><span class="cx">     to a hash containing the DOM event name as the key and the
</span><span class="cx">     corresponding view method name as the value. For example:
</span><span class="lines">@@ -25004,9 +38324,8 @@
</span><span class="cx">     ```javascript
</span><span class="cx">     App = Ember.Application.create({
</span><span class="cx">       customEvents: {
</span><del>-        // add support for the loadedmetadata media
-        // player event
-        'loadedmetadata': &quot;loadedMetadata&quot;
</del><ins>+        // add support for the paste event
+        paste: &quot;paste&quot;
</ins><span class="cx">       }
</span><span class="cx">     });
</span><span class="cx">     ```
</span><span class="lines">@@ -25017,8 +38336,6 @@
</span><span class="cx">   */
</span><span class="cx">   customEvents: null,
</span><span class="cx"> 
</span><del>-  isInitialized: false,
-
</del><span class="cx">   // Start off the number of deferrals at 1. This will be
</span><span class="cx">   // decremented by the Application's own `initialize` method.
</span><span class="cx">   _readinessDeferrals: 1,
</span><span class="lines">@@ -25027,29 +38344,35 @@
</span><span class="cx">     if (!this.$) { this.$ = Ember.$; }
</span><span class="cx">     this.__container__ = this.buildContainer();
</span><span class="cx"> 
</span><del>-    this.Router = this.Router || this.defaultRouter();
-    if (this.Router) { this.Router.namespace = this; }
</del><ins>+    this.Router = this.defaultRouter();
</ins><span class="cx"> 
</span><span class="cx">     this._super();
</span><span class="cx"> 
</span><del>-    this.deferUntilDOMReady();
</del><span class="cx">     this.scheduleInitialize();
</span><span class="cx"> 
</span><del>-    Ember.debug('-------------------------------');
-    Ember.debug('Ember.VERSION : ' + Ember.VERSION);
-    Ember.debug('Handlebars.VERSION : ' + Ember.Handlebars.VERSION);
-    Ember.debug('jQuery.VERSION : ' + Ember.$().jquery);
-    Ember.debug('-------------------------------');
</del><ins>+    Ember.libraries.registerCoreLibrary('Handlebars', Ember.Handlebars.VERSION);
+    Ember.libraries.registerCoreLibrary('jQuery', Ember.$().jquery);
+
+    if ( Ember.LOG_VERSION ) {
+      Ember.LOG_VERSION = false; // we only need to see this once per Application#init
+      var maxNameLength = Math.max.apply(this, Ember.A(Ember.libraries).mapBy(&quot;name.length&quot;));
+
+      Ember.debug('-------------------------------');
+      Ember.libraries.each(function(name, version) {
+        var spaces = new Array(maxNameLength - name.length + 1).join(&quot; &quot;);
+        Ember.debug([name, spaces, ' : ', version].join(&quot;&quot;));
+      });
+      Ember.debug('-------------------------------');
+    }
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Build the container for the current application.
</span><span class="cx"> 
</span><span class="cx">     Also register a default application view in case the application
</span><span class="cx">     itself does not.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method buildContainer
</span><span class="cx">     @return {Ember.Container} the configured container
</span><span class="cx">   */
</span><span class="lines">@@ -25060,8 +38383,6 @@
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     If the application has not opted out of routing and has not explicitly
</span><span class="cx">     defined a router, supply a default router for the application author
</span><span class="cx">     to configure.
</span><span class="lines">@@ -25069,50 +38390,35 @@
</span><span class="cx">     This allows application developers to do:
</span><span class="cx"> 
</span><span class="cx">     ```javascript
</span><del>-    App = Ember.Application.create();
</del><ins>+    var App = Ember.Application.create();
</ins><span class="cx"> 
</span><del>-    App.Router.map(function(match) {
-      match(&quot;/&quot;).to(&quot;index&quot;);
</del><ins>+    App.Router.map(function() {
+      this.resource('posts');
</ins><span class="cx">     });
</span><span class="cx">     ```
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method defaultRouter
</span><span class="cx">     @return {Ember.Router} the default router
</span><span class="cx">   */
</span><ins>+
</ins><span class="cx">   defaultRouter: function() {
</span><del>-    // Create a default App.Router if one was not supplied to make
-    // it possible to do App.Router.map(...) without explicitly
-    // creating a router first.
-    if (this.router === undefined) {
-      return Ember.Router.extend();
</del><ins>+    if (this.Router === false) { return; }
+    var container = this.__container__;
+
+    if (this.Router) {
+      container.unregister('router:main');
+      container.register('router:main', this.Router);
</ins><span class="cx">     }
</span><del>-  },
</del><span class="cx"> 
</span><del>-  /**
-    @private
-
-    Defer Ember readiness until DOM readiness. By default, Ember
-    will wait for both DOM readiness and application initialization,
-    as well as any deferrals registered by initializers.
-
-    @method deferUntilDOMReady
-  */
-  deferUntilDOMReady: function() {
-    this.deferReadiness();
-
-    var self = this;
-    this.$().ready(function() {
-      self.advanceReadiness();
-    });
</del><ins>+    return container.lookupFactory('router:main');
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Automatically initialize the application once the DOM has
</span><span class="cx">     become ready.
</span><span class="cx"> 
</span><del>-    The initialization itself is deferred using Ember.run.once,
</del><ins>+    The initialization itself is scheduled on the actions queue
</ins><span class="cx">     which ensures that application loading finishes before
</span><span class="cx">     booting.
</span><span class="cx"> 
</span><span class="lines">@@ -25121,14 +38427,19 @@
</span><span class="cx">     `advanceReadiness()` once all of your code has finished
</span><span class="cx">     loading.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method scheduleInitialize
</span><span class="cx">   */
</span><span class="cx">   scheduleInitialize: function() {
</span><span class="cx">     var self = this;
</span><del>-    this.$().ready(function() {
-      if (self.isDestroyed || self.isInitialized) return;
-      Ember.run.once(self, 'initialize');
-    });
</del><ins>+
+    if (!this.$ || this.$.isReady) {
+      Ember.run.schedule('actions', self, '_initialize');
+    } else {
+      this.$().ready(function runInitialize() {
+        Ember.run(self, '_initialize');
+      });
+    }
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -25155,15 +38466,21 @@
</span><span class="cx">     @method deferReadiness
</span><span class="cx">   */
</span><span class="cx">   deferReadiness: function() {
</span><ins>+    Ember.assert(&quot;You must call deferReadiness on an instance of Ember.Application&quot;, this instanceof Ember.Application);
</ins><span class="cx">     Ember.assert(&quot;You cannot defer readiness since the `ready()` hook has already been called.&quot;, this._readinessDeferrals &gt; 0);
</span><span class="cx">     this._readinessDeferrals++;
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+    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.
+
</ins><span class="cx">     @method advanceReadiness
</span><span class="cx">     @see {Ember.Application#deferReadiness}
</span><span class="cx">   */
</span><span class="cx">   advanceReadiness: function() {
</span><ins>+    Ember.assert(&quot;You must call advanceReadiness on an instance of Ember.Application&quot;, this instanceof Ember.Application);
</ins><span class="cx">     this._readinessDeferrals--;
</span><span class="cx"> 
</span><span class="cx">     if (this._readinessDeferrals === 0) {
</span><span class="lines">@@ -25179,19 +38496,20 @@
</span><span class="cx">     ```javascript
</span><span class="cx">     App = Ember.Application.create();
</span><span class="cx"> 
</span><del>-    App.Person = Ember.Object.extend({});
-    App.Orange = Ember.Object.extend({});
-    App.Email  = Ember.Object.extend({});
</del><ins>+    App.Person  = Ember.Object.extend({});
+    App.Orange  = Ember.Object.extend({});
+    App.Email   = Ember.Object.extend({});
+    App.session = Ember.Object.create({});
</ins><span class="cx"> 
</span><span class="cx">     App.register('model:user', App.Person, {singleton: false });
</span><span class="cx">     App.register('fruit:favorite', App.Orange);
</span><span class="cx">     App.register('communication:main', App.Email, {singleton: false});
</span><ins>+    App.register('session', App.session, {instantiate: false});
</ins><span class="cx">     ```
</span><span class="cx"> 
</span><span class="cx">     @method register
</span><del>-    @param  type {String}
-    @param  name {String}
-    @param  factory {String}
</del><ins>+    @param  fullName {String} type:name (e.g., 'model:user')
+    @param  factory {Function} (e.g., App.Person)
</ins><span class="cx">     @param  options {String} (optional)
</span><span class="cx">   **/
</span><span class="cx">   register: function() {
</span><span class="lines">@@ -25214,29 +38532,43 @@
</span><span class="cx">     @param  property {String}
</span><span class="cx">     @param  injectionName {String}
</span><span class="cx">   **/
</span><del>-  inject: function(){
</del><ins>+  inject: function() {
</ins><span class="cx">     var container = this.__container__;
</span><span class="cx">     container.injection.apply(container, arguments);
</span><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+    Calling initialize manually is not supported.
+
+    Please see Ember.Application#advanceReadiness and
+    Ember.Application#deferReadiness.
+
</ins><span class="cx">     @private
</span><del>-
</del><ins>+    @deprecated
+    @method initialize
+   **/
+  initialize: function() {
+    Ember.deprecate('Calling initialize manually is not supported. Please see Ember.Application#advanceReadiness and Ember.Application#deferReadiness');
+  },
+  /**
</ins><span class="cx">     Initialize the application. This happens automatically.
</span><span class="cx"> 
</span><span class="cx">     Run any initializers and run the application load hook. These hooks may
</span><span class="cx">     choose to defer readiness. For example, an authentication hook might want
</span><span class="cx">     to defer readiness until the auth token has been retrieved.
</span><span class="cx"> 
</span><del>-    @method initialize
</del><ins>+    @private
+    @method _initialize
</ins><span class="cx">   */
</span><del>-  initialize: function() {
-    Ember.assert(&quot;Application initialize may only be called once&quot;, !this.isInitialized);
-    Ember.assert(&quot;Cannot initialize a destroyed application&quot;, !this.isDestroyed);
-    this.isInitialized = true;
</del><ins>+  _initialize: function() {
+    if (this.isDestroyed) { return; }
</ins><span class="cx"> 
</span><span class="cx">     // At this point, the App.Router must already be assigned
</span><del>-    this.__container__.register('router', 'main', this.Router);
</del><ins>+    if (this.Router) {
+      var container = this.__container__;
+      container.unregister('router:main');
+      container.register('router:main', this.Router);
+    }
</ins><span class="cx"> 
</span><span class="cx">     this.runInitializers();
</span><span class="cx">     Ember.runLoadHooks('application', this);
</span><span class="lines">@@ -25249,13 +38581,92 @@
</span><span class="cx">     return this;
</span><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    Reset the application. This is typically used only in tests. It cleans up
+    the application in the following order:
+
+    1. Deactivate existing routes
+    2. Destroy all objects in the container
+    3. Create a new application container
+    4. Re-route to the existing url
+
+    Typical Example:
+
+    ```javascript
+
+    var App;
+
+    Ember.run(function() {
+      App = Ember.Application.create();
+    });
+
+    module(&quot;acceptance test&quot;, {
+      setup: function() {
+        App.reset();
+      }
+    });
+
+    test(&quot;first test&quot;, function() {
+      // App is freshly reset
+    });
+
+    test(&quot;first test&quot;, function() {
+      // App is again freshly reset
+    });
+    ```
+
+    Advanced Example:
+
+    Occasionally you may want to prevent the app from initializing during
+    setup. This could enable extra configuration, or enable asserting prior
+    to the app becoming ready.
+
+    ```javascript
+
+    var App;
+
+    Ember.run(function() {
+      App = Ember.Application.create();
+    });
+
+    module(&quot;acceptance test&quot;, {
+      setup: function() {
+        Ember.run(function() {
+          App.reset();
+          App.deferReadiness();
+        });
+      }
+    });
+
+    test(&quot;first test&quot;, function() {
+      ok(true, 'something before app is initialized');
+
+      Ember.run(function() {
+        App.advanceReadiness();
+      });
+      ok(true, 'something after app is initialized');
+    });
+    ```
+
+    @method reset
+  **/
</ins><span class="cx">   reset: function() {
</span><del>-    get(this, '__container__').destroy();
-    this.buildContainer();
</del><ins>+    this._readinessDeferrals = 1;
</ins><span class="cx"> 
</span><del>-    this.isInitialized = false;
-    this.initialize();
-    this.startRouting();
</del><ins>+    function handleReset() {
+      var router = this.__container__.lookup('router:main');
+      router.reset();
+
+      Ember.run(this.__container__, 'destroy');
+
+      this.buildContainer();
+
+      Ember.run.schedule('actions', this, function() {
+        this._initialize();
+      });
+    }
+
+    Ember.run.join(this, handleReset);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -25267,15 +38678,16 @@
</span><span class="cx">         container = this.__container__,
</span><span class="cx">         graph = new Ember.DAG(),
</span><span class="cx">         namespace = this,
</span><del>-        properties, i, initializer;
</del><ins>+        name, initializer;
</ins><span class="cx"> 
</span><del>-    for (i=0; i&lt;initializers.length; i++) {
-      initializer = initializers[i];
</del><ins>+    for (name in initializers) {
+      initializer = initializers[name];
</ins><span class="cx">       graph.addEdges(initializer.name, initializer.initialize, initializer.before, initializer.after);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     graph.topsort(function (vertex) {
</span><span class="cx">       var initializer = vertex.value;
</span><ins>+      Ember.assert(&quot;No application initializer named '&quot;+vertex.name+&quot;'&quot;, initializer);
</ins><span class="cx">       initializer(container, namespace);
</span><span class="cx">     });
</span><span class="cx">   },
</span><span class="lines">@@ -25294,47 +38706,32 @@
</span><span class="cx">       Ember.Namespace.processAll();
</span><span class="cx">       Ember.BOOTED = true;
</span><span class="cx">     }
</span><ins>+
+    this.resolve(this);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     Setup up the event dispatcher to receive events on the
</span><span class="cx">     application's `rootElement` with any registered
</span><span class="cx">     `customEvents`.
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method setupEventDispatcher
</span><span class="cx">   */
</span><span class="cx">   setupEventDispatcher: function() {
</span><del>-    var eventDispatcher = this.createEventDispatcher(),
-        customEvents    = get(this, 'customEvents');
</del><ins>+    var customEvents = get(this, 'customEvents'),
+        rootElement = get(this, 'rootElement'),
+        dispatcher = this.__container__.lookup('event_dispatcher:main');
</ins><span class="cx"> 
</span><del>-    eventDispatcher.setup(customEvents);
</del><ins>+    set(this, 'eventDispatcher', dispatcher);
+    dispatcher.setup(customEvents, rootElement);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
</del><ins>+    trigger a new call to `route` whenever the URL changes.
+    If the application has a router, use it to route to the current URL, and
</ins><span class="cx"> 
</span><del>-    Create an event dispatcher for the application's `rootElement`.
-
-    @method createEventDispatcher
-  */
-  createEventDispatcher: function() {
-    var rootElement = get(this, 'rootElement'),
-        eventDispatcher = Ember.EventDispatcher.create({
-          rootElement: rootElement
-        });
-
-    set(this, 'eventDispatcher', eventDispatcher);
-    return eventDispatcher;
-  },
-
-  /**
</del><span class="cx">     @private
</span><del>-
-    If the application has a router, use it to route to the current URL, and
-    trigger a new call to `route` whenever the URL changes.
-
</del><span class="cx">     @method startRouting
</span><span class="cx">     @property router {Ember.Router}
</span><span class="cx">   */
</span><span class="lines">@@ -25359,13 +38756,26 @@
</span><span class="cx">   */
</span><span class="cx">   ready: Ember.K,
</span><span class="cx"> 
</span><ins>+  /**
+    @deprecated Use 'Resolver' instead
+    Set this to provide an alternate class to `Ember.DefaultResolver`
+
+
+    @property resolver
+  */
+  resolver: null,
+
+  /**
+    Set this to provide an alternate class to `Ember.DefaultResolver`
+
+    @property resolver
+  */
+  Resolver: null,
+
</ins><span class="cx">   willDestroy: function() {
</span><span class="cx">     Ember.BOOTED = false;
</span><span class="cx"> 
</span><del>-    var eventDispatcher = get(this, 'eventDispatcher');
-    if (eventDispatcher) { eventDispatcher.destroy(); }
-
-    get(this, '__container__').destroy();
</del><ins>+    this.__container__.destroy();
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   initializer: function(options) {
</span><span class="lines">@@ -25374,21 +38784,26 @@
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> Ember.Application.reopenClass({
</span><del>-  concatenatedProperties: ['initializers'],
-  initializers: Ember.A(),
</del><ins>+  initializers: {},
</ins><span class="cx">   initializer: function(initializer) {
</span><del>-    var initializers = get(this, 'initializers');
</del><ins>+    // If this is the first initializer being added to a subclass, we are going to reopen the class
+    // to make sure we have a new `initializers` object, which extends from the parent class' using
+    // prototypal inheritance. Without this, attempting to add initializers to the subclass would
+    // pollute the parent class as well as other subclasses.
+    if (this.superclass.initializers !== undefined &amp;&amp; this.superclass.initializers === this.initializers) {
+      this.reopenClass({
+        initializers: Ember.create(this.initializers)
+      });
+    }
</ins><span class="cx"> 
</span><del>-    Ember.assert(&quot;The initializer '&quot; + initializer.name + &quot;' has already been registered&quot;, !initializers.findProperty('name', initializers.name));
-    Ember.assert(&quot;An injection cannot be registered with both a before and an after&quot;, !(initializer.before &amp;&amp; initializer.after));
-    Ember.assert(&quot;An injection cannot be registered without an injection function&quot;, Ember.canInvoke(initializer, 'initialize'));
</del><ins>+    Ember.assert(&quot;The initializer '&quot; + initializer.name + &quot;' has already been registered&quot;, !this.initializers[initializer.name]);
+    Ember.assert(&quot;An initializer cannot be registered with both a before and an after&quot;, !(initializer.before &amp;&amp; initializer.after));
+    Ember.assert(&quot;An initializer cannot be registered without an initialize function&quot;, Ember.canInvoke(initializer, 'initialize'));
</ins><span class="cx"> 
</span><del>-    initializers.push(initializer);
</del><ins>+    this.initializers[initializer.name] = initializer;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
-
</del><span class="cx">     This creates a container with the default Ember naming conventions.
</span><span class="cx"> 
</span><span class="cx">     It also configures the container:
</span><span class="lines">@@ -25406,6 +38821,7 @@
</span><span class="cx">     * the application view receives the application template as its
</span><span class="cx">       `defaultTemplate` property
</span><span class="cx"> 
</span><ins>+    @private
</ins><span class="cx">     @method buildContainer
</span><span class="cx">     @static
</span><span class="cx">     @param {Ember.Application} namespace the application to build the
</span><span class="lines">@@ -25414,27 +38830,41 @@
</span><span class="cx">   */
</span><span class="cx">   buildContainer: function(namespace) {
</span><span class="cx">     var container = new Ember.Container();
</span><del>-    Ember.Container.defaultContainer = Ember.Container.defaultContainer || container;
</del><span class="cx"> 
</span><ins>+    Ember.Container.defaultContainer = new DeprecatedContainer(container);
+
</ins><span class="cx">     container.set = Ember.set;
</span><del>-    container.resolver = resolverFor(namespace);
</del><ins>+    container.resolver  = resolverFor(namespace);
+    container.normalize = container.resolver.normalize;
+    container.describe  = container.resolver.describe;
+    container.makeToString = container.resolver.makeToString;
+
+    container.optionsForType('component', { singleton: false });
</ins><span class="cx">     container.optionsForType('view', { singleton: false });
</span><span class="cx">     container.optionsForType('template', { instantiate: false });
</span><del>-    container.register('application', 'main', namespace, { instantiate: false });
</del><ins>+    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);
</ins><span class="cx">     container.injection('router:main', 'namespace', 'application:main');
</span><span class="cx"> 
</span><del>-    container.typeInjection('controller', 'target', 'router:main');
-    container.typeInjection('controller', 'namespace', 'application:main');
</del><ins>+    container.injection('controller', 'target', 'router:main');
+    container.injection('controller', 'namespace', 'application:main');
</ins><span class="cx"> 
</span><del>-    container.typeInjection('route', 'router', 'router:main');
</del><ins>+    container.injection('route', 'router', 'router:main');
</ins><span class="cx"> 
</span><span class="cx">     return container;
</span><span class="cx">   }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> /**
</span><del>-  @private
-
</del><span class="cx">   This function defines the default lookup rules for container lookups:
</span><span class="cx"> 
</span><span class="cx">   * templates are looked up on `Ember.TEMPLATES`
</span><span class="lines">@@ -25445,40 +38875,47 @@
</span><span class="cx">   This allows the application to register default injections in the container
</span><span class="cx">   that could be overridden by the normal naming convention.
</span><span class="cx"> 
</span><ins>+  @private
+  @method resolverFor
</ins><span class="cx">   @param {Ember.Namespace} namespace the namespace to look for classes
</span><del>-  @return {any} the resolved value for a given lookup
</del><ins>+  @return {*} the resolved value for a given lookup
</ins><span class="cx"> */
</span><span class="cx"> function resolverFor(namespace) {
</span><del>-  return function(fullName) {
-    var nameParts = fullName.split(&quot;:&quot;),
-        type = nameParts[0], name = nameParts[1];
</del><ins>+  if (namespace.get('resolver')) {
+    Ember.deprecate('Application.resolver is deprecated in favor of Application.Resolver', false);
+  }
</ins><span class="cx"> 
</span><del>-    if (type === 'template') {
-      var templateName = name.replace(/\./g, '/');
-      if (Ember.TEMPLATES[templateName]) {
-        return Ember.TEMPLATES[templateName];
-      }
</del><ins>+  var ResolverClass = namespace.get('resolver') || namespace.get('Resolver') || Ember.DefaultResolver;
+  var resolver = ResolverClass.create({
+    namespace: namespace
+  });
</ins><span class="cx"> 
</span><del>-      templateName = decamelize(templateName);
-      if (Ember.TEMPLATES[templateName]) {
-        return Ember.TEMPLATES[templateName];
-      }
-    }
</del><ins>+  function resolve(fullName) {
+    return resolver.resolve(fullName);
+  }
</ins><span class="cx"> 
</span><del>-    if (type === 'controller' || type === 'route' || type === 'view') {
-      name = name.replace(/\./g, '_');
-    }
</del><ins>+  resolve.describe = function(fullName) {
+    return resolver.lookupDescription(fullName);
+  };
</ins><span class="cx"> 
</span><del>-    var className = classify(name) + classify(type);
-    var factory = get(namespace, className);
</del><ins>+  resolve.makeToString = function(factory, fullName) {
+    return resolver.makeToString(factory, fullName);
+  };
</ins><span class="cx"> 
</span><del>-    if (factory) { return factory; }
</del><ins>+  resolve.normalize = function(fullName) {
+    if (resolver.normalize) {
+      return resolver.normalize(fullName);
+    } else {
+      Ember.deprecate('The Resolver should now provide a \'normalize\' function', false);
+      return fullName;
+    }
</ins><span class="cx">   };
</span><ins>+
+  return resolve;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ember.runLoadHooks('Ember.Application', Ember.Application);
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -25492,70 +38929,165 @@
</span><span class="cx"> (function() {
</span><span class="cx"> /**
</span><span class="cx"> @module ember
</span><del>-@submodule ember-routing
</del><ins>+@submodule ember-application
</ins><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> var get = Ember.get, set = Ember.set;
</span><del>-var ControllersProxy = Ember.Object.extend({
-  controller: null,
</del><span class="cx"> 
</span><del>-  unknownProperty: function(controllerName) {
-    var controller = get(this, 'controller'),
-      needs = get(controller, 'needs'),
-      container = controller.get('container'),
-      dependency;
</del><ins>+function verifyNeedsDependencies(controller, container, needs) {
+  var dependency, i, l, missing = [];
</ins><span class="cx"> 
</span><del>-    for (var i=0, l=needs.length; i&lt;l; i++) {
-      dependency = needs[i];
-      if (dependency === controllerName) {
-        return container.lookup('controller:' + controllerName);
-      }
-    }
-  }
-});
</del><ins>+  for (i=0, l=needs.length; i&lt;l; i++) {
+    dependency = needs[i];
</ins><span class="cx"> 
</span><del>-function verifyDependencies(controller) {
-  var needs = get(controller, 'needs'),
-      container = get(controller, 'container'),
-      dependency, satisfied = true;
</del><ins>+    Ember.assert(Ember.inspect(controller) + &quot;#needs must not specify dependencies with periods in their names (&quot; + dependency + &quot;)&quot;, dependency.indexOf('.') === -1);
</ins><span class="cx"> 
</span><del>-  for (var i=0, l=needs.length; i&lt;l; i++) {
-    dependency = needs[i];
</del><span class="cx">     if (dependency.indexOf(':') === -1) {
</span><span class="cx">       dependency = &quot;controller:&quot; + dependency;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // Structure assert to still do verification but not string concat in production
</ins><span class="cx">     if (!container.has(dependency)) {
</span><del>-      satisfied = false;
-      Ember.assert(controller + &quot; needs &quot; + dependency + &quot; but it does not exist&quot;, false);
</del><ins>+      missing.push(dependency);
</ins><span class="cx">     }
</span><span class="cx">   }
</span><del>-
-  return satisfied;
</del><ins>+  if (missing.length) {
+    throw new Ember.Error(Ember.inspect(controller) + &quot; needs [ &quot; + missing.join(', ') + &quot; ] but &quot; + (missing.length &gt; 1 ? 'they' : 'it') + &quot; could not be found&quot;);
+  }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+var defaultControllersComputedProperty = Ember.computed(function() {
+  var controller = this;
+
+  return {
+    needs: get(controller, 'needs'),
+    container: get(controller, 'container'),
+    unknownProperty: function(controllerName) {
+      var needs = this.needs,
+        dependency, i, l;
+      for (i=0, l=needs.length; i&lt;l; i++) {
+        dependency = needs[i];
+        if (dependency === controllerName) {
+          return this.container.lookup('controller:' + controllerName);
+        }
+      }
+
+      var errorMessage = Ember.inspect(controller) + '#needs does not include `' + controllerName + '`. To access the ' + controllerName + ' controller from ' + Ember.inspect(controller) + ', ' + Ember.inspect(controller) + ' should have a `needs` property that is an array of the controllers it has access to.';
+      throw new ReferenceError(errorMessage);
+    },
+    setUnknownProperty: function (key, value) {
+      throw new Error(&quot;You cannot overwrite the value of `controllers.&quot; + key + &quot;` of &quot; + Ember.inspect(controller));
+    }
+  };
+});
+
+/**
+  @class ControllerMixin
+  @namespace Ember
+*/
</ins><span class="cx"> Ember.ControllerMixin.reopen({
</span><span class="cx">   concatenatedProperties: ['needs'],
</span><ins>+
+  /**
+    An array of other controller objects available inside
+    instances of this controller via the `controllers`
+    property:
+
+    For example, when you define a controller:
+
+    ```javascript
+    App.CommentsController = Ember.ArrayController.extend({
+      needs: ['post']
+    });
+    ```
+
+    The application's single instance of these other
+    controllers are accessible by name through the
+    `controllers` property:
+
+    ```javascript
+    this.get('controllers.post'); // instance of App.PostController
+    ```
+
+    Given that you have a nested controller (nested resource):
+
+    ```javascript
+    App.CommentsNewController = Ember.ObjectController.extend({
+    });
+    ```
+
+    When you define a controller that requires access to a nested one:
+
+    ```javascript
+    App.IndexController = Ember.ObjectController.extend({
+      needs: ['commentsNew']
+    });
+    ```
+
+    You will be able to get access to it:
+
+    ```javascript
+    this.get('controllers.commentsNew'); // instance of App.CommentsNewController
+    ```
+
+    This is only available for singleton controllers.
+
+    @property {Array} needs
+    @default []
+  */
</ins><span class="cx">   needs: [],
</span><span class="cx"> 
</span><span class="cx">   init: function() {
</span><del>-    this._super.apply(this, arguments);
</del><ins>+    var needs = get(this, 'needs'),
+    length = get(needs, 'length');
</ins><span class="cx"> 
</span><del>-    // Structure asserts to still do verification but not string concat in production
-    if(!verifyDependencies(this)) {
-      Ember.assert(&quot;Missing dependencies&quot;, false);
</del><ins>+    if (length &gt; 0) {
+      Ember.assert(' `' + Ember.inspect(this) + ' specifies `needs`, but does ' +
+                   &quot;not have a container. Please ensure this controller was &quot; +
+                   &quot;instantiated with a container.&quot;,
+                   this.container || Ember.meta(this, false).descs.controllers !== defaultControllersComputedProperty);
+
+      if (this.container) {
+        verifyNeedsDependencies(this, this.container, needs);
+      }
+
+      // if needs then initialize controllers proxy
+      get(this, 'controllers');
</ins><span class="cx">     }
</span><ins>+
+    this._super.apply(this, arguments);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><ins>+  /**
+    @method controllerFor
+    @see {Ember.Route#controllerFor}
+    @deprecated Use `needs` instead
+  */
</ins><span class="cx">   controllerFor: function(controllerName) {
</span><del>-    Ember.deprecate(&quot;Controller#controllerFor is depcrecated, please use Controller#needs instead&quot;);
-    var container = get(this, 'container');
-    return container.lookup('controller:' + controllerName);
</del><ins>+    Ember.deprecate(&quot;Controller#controllerFor is deprecated, please use Controller#needs instead&quot;);
+    return Ember.controllerFor(get(this, 'container'), controllerName);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  controllers: Ember.computed(function() {
-    return ControllersProxy.create({ controller: this });
-  })
</del><ins>+  /**
+    Stores the instances of other controllers available from within
+    this controller. Any controller listed by name in the `needs`
+    property will be accessible by name through this property.
+
+    ```javascript
+    App.CommentsController = Ember.ArrayController.extend({
+      needs: ['post'],
+      postTitle: function(){
+        var currentPost = this.get('controllers.post'); // instance of App.PostController
+        return currentPost.get('title');
+      }.property('controllers.post.title')
+    });
+    ```
+
+    @see {Ember.ControllerMixin#needs}
+    @property {Object} controllers
+    @default null
+  */
+  controllers: defaultControllersComputedProperty
</ins><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> })();
</span><span class="lines">@@ -25574,1260 +39106,1437 @@
</span><span class="cx"> 
</span><span class="cx"> @module ember
</span><span class="cx"> @submodule ember-application
</span><del>-@requires ember-views, ember-states, ember-routing
</del><ins>+@requires ember-views, ember-routing
</ins><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><del>-var get = Ember.get, set = Ember.set;
-
</del><span class="cx"> /**
</span><span class="cx"> @module ember
</span><del>-@submodule ember-states
</del><ins>+@submodule ember-extension-support
</ins><span class="cx"> */
</span><ins>+/**
+  The `DataAdapter` helps a data persistence library
+  interface with tools that debug Ember such
+  as the [Ember Extension](https://github.com/tildeio/ember-extension)
+  for Chrome and Firefox.
</ins><span class="cx"> 
</span><del>-/**
-  @class State
</del><ins>+  This class will be extended by a persistence library
+  which will override some of the methods with
+  library-specific code.
+
+  The methods likely to be overridden are:
+
+  * `getFilters`
+  * `detect`
+  * `columnsForType`
+  * `getRecords`
+  * `getRecordColumnValues`
+  * `getRecordKeywords`
+  * `getRecordFilterValues`
+  * `getRecordColor`
+  * `observeRecord`
+
+  The adapter will need to be registered
+  in the application's container as `dataAdapter:main`
+
+  Example:
+
+  ```javascript
+  Application.initializer({
+    name: &quot;dataAdapter&quot;,
+
+    initialize: function(container, application) {
+      application.register('dataAdapter:main', DS.DataAdapter);
+    }
+  });
+  ```
+
+  @class DataAdapter
</ins><span class="cx">   @namespace Ember
</span><span class="cx">   @extends Ember.Object
</span><del>-  @uses Ember.Evented
</del><span class="cx"> */
</span><del>-Ember.State = Ember.Object.extend(Ember.Evented,
-/** @scope Ember.State.prototype */{
-  isState: true,
</del><ins>+Ember.DataAdapter = Ember.Object.extend({
+  init: function() {
+    this._super();
+    this.releaseMethods = Ember.A();
+  },
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    A reference to the parent state.
</del><ins>+    The container of the application being debugged.
+    This property will be injected
+    on creation.
</ins><span class="cx"> 
</span><del>-    @property parentState
-    @type Ember.State
</del><ins>+    @property container
+    @default null
</ins><span class="cx">   */
</span><del>-  parentState: null,
-  start: null,
</del><ins>+  container: null,
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    The name of this state.
</del><ins>+    Number of attributes to send
+    as columns. (Enough to make the record
+    identifiable).
</ins><span class="cx"> 
</span><del>-    @property name
-    @type String
</del><ins>+    @private
+    @property attributeLimit
+    @default 3
</ins><span class="cx">   */
</span><del>-  name: null,
</del><ins>+  attributeLimit: 3,
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    The full path to this state.
</del><ins>+    Stores all methods that clear observers.
+    These methods will be called on destruction.
</ins><span class="cx"> 
</span><del>-    @property path
-    @type String
</del><ins>+    @private
+    @property releaseMethods
</ins><span class="cx">   */
</span><del>-  path: Ember.computed(function() {
-    var parentPath = get(this, 'parentState.path'),
-        path = get(this, 'name');
</del><ins>+  releaseMethods: Ember.A(),
</ins><span class="cx"> 
</span><del>-    if (parentPath) {
-      path = parentPath + '.' + path;
-    }
</del><ins>+  /**
+    Specifies how records can be filtered.
+    Records returned will need to have a `filterValues`
+    property with a key for every name in the returned array.
</ins><span class="cx"> 
</span><del>-    return path;
-  }),
</del><ins>+    @public
+    @method getFilters
+    @return {Array} List of objects defining filters.
+     The object should have a `name` and `desc` property.
+  */
+  getFilters: function() {
+    return Ember.A();
+  },
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    @private
</del><ins>+    Fetch the model types and observe them for changes.
</ins><span class="cx"> 
</span><del>-    Override the default event firing from `Ember.Evented` to
-    also call methods with the given name.
</del><ins>+    @public
+    @method watchModelTypes
</ins><span class="cx"> 
</span><del>-    @method trigger
-    @param name
</del><ins>+    @param {Function} typesAdded Callback to call to add types.
+    Takes an array of objects containing wrapped types (returned from `wrapModelType`).
+
+    @param {Function} typesUpdated Callback to call when a type has changed.
+    Takes an array of objects containing wrapped types.
+
+    @return {Function} Method to call to remove all observers
</ins><span class="cx">   */
</span><del>-  trigger: function(name) {
-    if (this[name]) {
-      this[name].apply(this, [].slice.call(arguments, 1));
-    }
-    this._super.apply(this, arguments);
</del><ins>+  watchModelTypes: function(typesAdded, typesUpdated) {
+    var modelTypes = this.getModelTypes(),
+        self = this, typesToSend, releaseMethods = Ember.A();
+
+    typesToSend = modelTypes.map(function(type) {
+      var wrapped = self.wrapModelType(type);
+      releaseMethods.push(self.observeModelType(type, typesUpdated));
+      return wrapped;
+    });
+
+    typesAdded(typesToSend);
+
+    var release = function() {
+      releaseMethods.forEach(function(fn) { fn(); });
+      self.releaseMethods.removeObject(release);
+    };
+    this.releaseMethods.pushObject(release);
+    return release;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  init: function() {
-    var states = get(this, 'states'), foundStates;
-    set(this, 'childStates', Ember.A());
-    set(this, 'eventTransitions', get(this, 'eventTransitions') || {});
</del><ins>+  /**
+    Fetch the records of a given type and observe them for changes.
</ins><span class="cx"> 
</span><del>-    var name, value, transitionTarget;
</del><ins>+    @public
+    @method watchRecords
</ins><span class="cx"> 
</span><del>-    // As a convenience, loop over the properties
-    // of this state and look for any that are other
-    // Ember.State instances or classes, and move them
-    // to the `states` hash. This avoids having to
-    // create an explicit separate hash.
</del><ins>+    @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
</ins><span class="cx"> 
</span><del>-    if (!states) {
-      states = {};
</del><ins>+    @param {Function} recordsUpdated Callback to call when a record has changed.
+    Takes an array of objects containing wrapped records.
</ins><span class="cx"> 
</span><del>-      for (name in this) {
-        if (name === &quot;constructor&quot;) { continue; }
</del><ins>+    @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
</ins><span class="cx"> 
</span><del>-        if (value = this[name]) {
-          if (transitionTarget = value.transitionTarget) {
-            this.eventTransitions[name] = transitionTarget;
-          }
</del><ins>+    @return {Function} Method to call to remove all observers
+  */
+  watchRecords: function(type, recordsAdded, recordsUpdated, recordsRemoved) {
+    var self = this, releaseMethods = Ember.A(), records = this.getRecords(type), release;
</ins><span class="cx"> 
</span><del>-          this.setupChild(states, name, value);
-        }
</del><ins>+    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 &lt; idx + addedCount; i++) {
+        var record = array.objectAt(i);
+        var wrapped = self.wrapRecord(record);
+        releaseMethods.push(self.observeRecord(record, recordUpdated));
+        recordsAdded([wrapped]);
</ins><span class="cx">       }
</span><span class="cx"> 
</span><del>-      set(this, 'states', states);
-    } else {
-      for (name in states) {
-        this.setupChild(states, name, states[name]);
</del><ins>+      if (removedCount) {
+        recordsRemoved(idx, removedCount);
</ins><span class="cx">       }
</span><del>-    }
</del><ins>+    };
</ins><span class="cx"> 
</span><del>-    set(this, 'pathsCache', {});
-    set(this, 'pathsCacheNoContext', {});
-  },
</del><ins>+    var observer = { didChange: contentDidChange, willChange: Ember.K };
+    records.addArrayObserver(self, observer);
</ins><span class="cx"> 
</span><del>-  setupChild: function(states, name, value) {
-    if (!value) { return false; }
</del><ins>+    release = function() {
+      releaseMethods.forEach(function(fn) { fn(); });
+      records.removeArrayObserver(self, observer);
+      self.releaseMethods.removeObject(release);
+    };
</ins><span class="cx"> 
</span><del>-    if (value.isState) {
-      set(value, 'name', name);
-    } else if (Ember.State.detect(value)) {
-      value = value.create({
-        name: name
-      });
-    }
</del><ins>+    recordsAdded(recordsToSend);
</ins><span class="cx"> 
</span><del>-    if (value.isState) {
-      set(value, 'parentState', this);
-      get(this, 'childStates').pushObject(value);
-      states[name] = value;
-      return value;
-    }
</del><ins>+    this.releaseMethods.pushObject(release);
+    return release;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><del>-  lookupEventTransition: function(name) {
-    var path, state = this;
</del><ins>+  /**
+    Clear all observers before destruction
+    @private
+  */
+  willDestroy: function() {
+    this._super();
+    this.releaseMethods.forEach(function(fn) {
+      fn();
+    });
+  },
</ins><span class="cx"> 
</span><del>-    while(state &amp;&amp; !path) {
-      path = state.eventTransitions[name];
-      state = state.get('parentState');
-    }
</del><ins>+  /**
+    Detect whether a class is a model.
</ins><span class="cx"> 
</span><del>-    return path;
</del><ins>+    Test that against the model class
+    of your persistence library
+
+    @private
+    @method detect
+    @param {Class} klass The class to test
+    @return boolean Whether the class is a model class or not
+  */
+  detect: function(klass) {
+    return false;
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    A Boolean value indicating whether the state is a leaf state
-    in the state hierarchy. This is `false` if the state has child
-    states; otherwise it is true.
</del><ins>+    Get the columns for a given model type.
</ins><span class="cx"> 
</span><del>-    @property isLeaf
-    @type Boolean
</del><ins>+    @private
+    @method columnsForType
+    @param {Class} type The model type
+    @return {Array} An array of columns of the following format:
+     name: {String} name of the column
+     desc: {String} Humanized description (what would show in a table column name)
</ins><span class="cx">   */
</span><del>-  isLeaf: Ember.computed(function() {
-    return !get(this, 'childStates').length;
-  }),
</del><ins>+  columnsForType: function(type) {
+    return Ember.A();
+  },
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    A boolean value indicating whether the state takes a context.
-    By default we assume all states take contexts.
</del><ins>+    Adds observers to a model type class.
</ins><span class="cx"> 
</span><del>-    @property hasContext
-    @default true
</del><ins>+    @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
</ins><span class="cx">   */
</span><del>-  hasContext: true,
</del><span class="cx"> 
</span><ins>+  observeModelType: 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;
+  },
+
+
</ins><span class="cx">   /**
</span><del>-    This is the default transition event.
</del><ins>+    Wraps a given model type and observes changes to it.
</ins><span class="cx"> 
</span><del>-    @event setup
-    @param {Ember.StateManager} manager
-    @param context
-    @see Ember.StateManager#transitionEvent
</del><ins>+    @private
+    @method wrapModelType
+    @param {Class} type A model class
+    @param {Function} typesUpdated callback to call when the type changes
+    @return {Object} contains the wrapped type and the function to remove observers
+    Format:
+      type: {Object} the wrapped type
+        The wrapped type has the following format:
+          name: {String} name of the type
+          count: {Integer} number of records available
+          columns: {Columns} array of columns to describe the record
+          object: {Class} the actual Model type class
+      release: {Function} The function to remove observers
</ins><span class="cx">   */
</span><del>-  setup: Ember.K,
</del><ins>+  wrapModelType: function(type, typesUpdated) {
+    var release, records = this.getRecords(type),
+        typeToSend, self = this;
</ins><span class="cx"> 
</span><ins>+    typeToSend = {
+      name: type.toString(),
+      count: Ember.get(records, 'length'),
+      columns: this.columnsForType(type),
+      object: type
+    };
+
+
+    return typeToSend;
+  },
+
+
</ins><span class="cx">   /**
</span><del>-    This event fires when the state is entered.
</del><ins>+    Fetches all models defined in the application.
</ins><span class="cx"> 
</span><del>-    @event enter
-    @param {Ember.StateManager} manager
</del><ins>+    @private
+    @method getModelTypes
+    @return {Array} Array of model types
</ins><span class="cx">   */
</span><del>-  enter: Ember.K,
</del><span class="cx"> 
</span><ins>+ // TODO: Use the resolver instead of looping over namespaces.
+  getModelTypes: function() {
+    var namespaces = Ember.A(Ember.Namespace.NAMESPACES), types = Ember.A(), self = this;
+
+    namespaces.forEach(function(namespace) {
+      for (var key in namespace) {
+        if (!namespace.hasOwnProperty(key)) { continue; }
+        var klass = namespace[key];
+        if (self.detect(klass)) {
+          types.push(klass);
+        }
+      }
+    });
+    return types;
+  },
+
</ins><span class="cx">   /**
</span><del>-    This event fires when the state is exited.
</del><ins>+    Fetches all loaded records for a given type.
</ins><span class="cx"> 
</span><del>-    @event exit
-    @param {Ember.StateManager} manager
</del><ins>+    @private
+    @method getRecords
+    @return {Array} An array of records.
+     This array will be observed for changes,
+     so it should update when new records are added/removed.
</ins><span class="cx">   */
</span><del>-  exit: Ember.K
-});
</del><ins>+  getRecords: function(type) {
+    return Ember.A();
+  },
</ins><span class="cx"> 
</span><del>-Ember.State.reopenClass({
-
</del><span class="cx">   /**
</span><del>-    Creates an action function for transitioning to the named state while
-    preserving context.
</del><ins>+    Wraps a record and observers changes to it.
</ins><span class="cx"> 
</span><del>-    The following example StateManagers are equivalent:
</del><ins>+    @private
+    @method wrapRecord
+    @param {Object} record The record instance.
+    @return {Object} The wrapped record. Format:
+    columnValues: {Array}
+    searchKeywords: {Array}
+  */
+  wrapRecord: function(record) {
+    var recordToSend = { object: record }, columnValues = {}, self = this;
</ins><span class="cx"> 
</span><del>-    ```javascript
-    aManager = Ember.StateManager.create({
-      stateOne: Ember.State.create({
-        changeToStateTwo: Ember.State.transitionTo('stateTwo')
-      }),
-      stateTwo: Ember.State.create({})
-    })
</del><ins>+    recordToSend.columnValues = this.getRecordColumnValues(record);
+    recordToSend.searchKeywords = this.getRecordKeywords(record);
+    recordToSend.filterValues = this.getRecordFilterValues(record);
+    recordToSend.color = this.getRecordColor(record);
</ins><span class="cx"> 
</span><del>-    bManager = Ember.StateManager.create({
-      stateOne: Ember.State.create({
-        changeToStateTwo: function(manager, context){
-          manager.transitionTo('stateTwo', context)
-        }
-      }),
-      stateTwo: Ember.State.create({})
-    })
-    ```
</del><ins>+    return recordToSend;
+  },
</ins><span class="cx"> 
</span><del>-    @method transitionTo
-    @static
-    @param {String} target
</del><ins>+  /**
+    Gets the values for each column.
+
+    @private
+    @method getRecordColumnValues
+    @return {Object} Keys should match column names defined
+    by the model type.
</ins><span class="cx">   */
</span><ins>+  getRecordColumnValues: function(record) {
+    return {};
+  },
</ins><span class="cx"> 
</span><del>-  transitionTo: function(target) {
</del><ins>+  /**
+    Returns keywords to match when searching records.
</ins><span class="cx"> 
</span><del>-    var transitionFunction = function(stateManager, contextOrEvent) {
-      var contexts = [], transitionArgs,
-          Event = Ember.$ &amp;&amp; Ember.$.Event;
</del><ins>+    @private
+    @method getRecordKeywords
+    @return {Array} Relevant keywords for search.
+  */
+  getRecordKeywords: function(record) {
+    return Ember.A();
+  },
</ins><span class="cx"> 
</span><del>-      if (contextOrEvent &amp;&amp; (Event &amp;&amp; contextOrEvent instanceof Event)) {
-        if (contextOrEvent.hasOwnProperty('contexts')) {
-          contexts = contextOrEvent.contexts.slice();
-        }
-      }
-      else {
-        contexts = [].slice.call(arguments, 1);
-      }
</del><ins>+  /**
+    Returns the values of filters defined by `getFilters`.
</ins><span class="cx"> 
</span><del>-      contexts.unshift(target);
-      stateManager.transitionTo.apply(stateManager, contexts);
-    };
</del><ins>+    @private
+    @method getRecordFilterValues
+    @param {Object} record The record instance
+    @return {Object} The filter values
+  */
+  getRecordFilterValues: function(record) {
+    return {};
+  },
</ins><span class="cx"> 
</span><del>-    transitionFunction.transitionTarget = target;
</del><ins>+  /**
+    Each record can have a color that represents its state.
</ins><span class="cx"> 
</span><del>-    return transitionFunction;
</del><ins>+    @private
+    @method getRecordColor
+    @param {Object} record The record instance
+    @return {String} The record's color
+      Possible options: black, red, blue, green
+  */
+  getRecordColor: function(record) {
+    return null;
+  },
+
+  /**
+    Observes all relevant properties and re-sends the wrapped record
+    when a change occurs.
+
+    @private
+    @method observerRecord
+    @param {Object} record The record instance
+    @param {Function} recordUpdated The callback to call when a record is updated.
+    @return {Function} The function to call to remove all observers.
+  */
+  observeRecord: function(record, recordUpdated) {
+    return function(){};
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx"> });
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><span class="cx"> /**
</span><ins>+Ember Extension Support
+
</ins><span class="cx"> @module ember
</span><del>-@submodule ember-states
</del><ins>+@submodule ember-extension-support
+@requires ember-application
</ins><span class="cx"> */
</span><span class="cx"> 
</span><del>-var get = Ember.get, set = Ember.set, fmt = Ember.String.fmt;
-var arrayForEach = Ember.ArrayPolyfills.forEach;
</del><ins>+})();
+
+(function() {
</ins><span class="cx"> /**
</span><del>-  A Transition takes the enter, exit and resolve states and normalizes
-  them:
</del><ins>+  @module ember
+  @submodule ember-testing
+ */
+var slice = [].slice,
+    helpers = {},
+    injectHelpersCallbacks = [];
</ins><span class="cx"> 
</span><del>-  * takes any passed in contexts into consideration
-  * adds in `initialState`s
</del><ins>+/**
+  This is a container for an assortment of testing related functionality:
</ins><span class="cx"> 
</span><del>-  @class Transition
-  @private
</del><ins>+  * Choose your default test adapter (for your framework of choice).
+  * Register/Unregister additional test helpers.
+  * Setup callbacks to be fired when the test helpers are injected into
+    your application.
+
+  @class Test
+  @namespace Ember
</ins><span class="cx"> */
</span><del>-var Transition = function(raw) {
-  this.enterStates = raw.enterStates.slice();
-  this.exitStates = raw.exitStates.slice();
-  this.resolveState = raw.resolveState;
</del><ins>+Ember.Test = {
</ins><span class="cx"> 
</span><del>-  this.finalState = raw.enterStates[raw.enterStates.length - 1] || raw.resolveState;
-};
-
-Transition.prototype = {
</del><span class="cx">   /**
</span><del>-    Normalize the passed in enter, exit and resolve states.
</del><ins>+    `registerHelper` is used to register a test helper that will be injected
+    when `App.injectTestHelpers` is called.
</ins><span class="cx"> 
</span><del>-    This process also adds `finalState` and `contexts` to the Transition object.
</del><ins>+    The helper method will always be called with the current Application as
+    the first parameter.
</ins><span class="cx"> 
</span><del>-    @method normalize
-    @param {Ember.StateManager} manager the state manager running the transition
-    @param {Array} contexts a list of contexts passed into `transitionTo`
</del><ins>+    For example:
+
+    ```javascript
+    Ember.Test.registerHelper('boot', function(app) {
+      Ember.run(app, app.advanceReadiness);
+    });
+    ```
+
+    This helper can later be called without arguments because it will be
+    called with `app` as the first parameter.
+
+    ```javascript
+    App = Ember.Application.create();
+    App.injectTestHelpers();
+    boot();
+    ```
+
+    @public
+    @method registerHelper
+    @param {String} name The name of the helper method to add.
+    @param {Function} helperMethod
+    @param options {Object}
</ins><span class="cx">   */
</span><del>-  normalize: function(manager, contexts) {
-    this.matchContextsToStates(contexts);
-    this.addInitialStates();
-    this.removeUnchangedContexts(manager);
-    return this;
</del><ins>+  registerHelper: function(name, helperMethod) {
+    helpers[name] = {
+      method: helperMethod,
+      meta: { wait: false }
+    };
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Match each of the contexts passed to `transitionTo` to a state.
-    This process may also require adding additional enter and exit
-    states if there are more contexts than enter states.
</del><ins>+    `registerAsyncHelper` is used to register an async test helper that will be injected
+    when `App.injectTestHelpers` is called.
</ins><span class="cx"> 
</span><del>-    @method matchContextsToStates
-    @param {Array} contexts a list of contexts passed into `transitionTo`
-  */
-  matchContextsToStates: function(contexts) {
-    var stateIdx = this.enterStates.length - 1,
-        matchedContexts = [],
-        state,
-        context;
</del><ins>+    The helper method will always be called with the current Application as
+    the first parameter.
</ins><span class="cx"> 
</span><del>-    // Next, we will match the passed in contexts to the states they
-    // represent.
-    //
-    // First, assign a context to each enter state in reverse order. If
-    // any contexts are left, add a parent state to the list of states
-    // to enter and exit, and assign a context to the parent state.
-    //
-    // If there are still contexts left when the state manager is
-    // reached, raise an exception.
-    //
-    // This allows the following:
-    //
-    // |- root
-    // | |- post
-    // | | |- comments
-    // | |- about (* current state)
-    //
-    // For `transitionTo('post.comments', post, post.get('comments')`,
-    // the first context (`post`) will be assigned to `root.post`, and
-    // the second context (`post.get('comments')`) will be assigned
-    // to `root.post.comments`.
-    //
-    // For the following:
-    //
-    // |- root
-    // | |- post
-    // | | |- index (* current state)
-    // | | |- comments
-    //
-    // For `transitionTo('post.comments', otherPost, otherPost.get('comments')`,
-    // the `&lt;root.post&gt;` state will be added to the list of enter and exit
-    // states because its context has changed.
</del><ins>+    For example:
</ins><span class="cx"> 
</span><del>-    while (contexts.length &gt; 0) {
-      if (stateIdx &gt;= 0) {
-        state = this.enterStates[stateIdx--];
-      } else {
-        if (this.enterStates.length) {
-          state = get(this.enterStates[0], 'parentState');
-          if (!state) { throw &quot;Cannot match all contexts to states&quot;; }
-        } else {
-          // If re-entering the current state with a context, the resolve
-          // state will be the current state.
-          state = this.resolveState;
-        }
</del><ins>+    ```javascript
+    Ember.Test.registerAsyncHelper('boot', function(app) {
+      Ember.run(app, app.advanceReadiness);
+    });
+    ```
</ins><span class="cx"> 
</span><del>-        this.enterStates.unshift(state);
-        this.exitStates.unshift(state);
-      }
</del><ins>+    The advantage of an async helper is that it will not run
+    until the last async helper has completed.  All async helpers
+    after it will wait for it complete before running.
</ins><span class="cx"> 
</span><del>-      // in routers, only states with dynamic segments have a context
-      if (get(state, 'hasContext')) {
-        context = contexts.pop();
-      } else {
-        context = null;
-      }
</del><span class="cx"> 
</span><del>-      matchedContexts.unshift(context);
-    }
</del><ins>+    For example:
</ins><span class="cx"> 
</span><del>-    this.contexts = matchedContexts;
</del><ins>+    ```javascript
+    Ember.Test.registerAsyncHelper('deletePost', function(app, postId) {
+      click('.delete-' + postId);
+    });
+
+    // ... in your test
+    visit('/post/2');
+    deletePost(2);
+    visit('/post/3');
+    deletePost(3);
+    ```
+
+    @public
+    @method registerAsyncHelper
+    @param {String} name The name of the helper method to add.
+    @param {Function} helperMethod
+  */
+  registerAsyncHelper: function(name, helperMethod) {
+    helpers[name] = {
+      method: helperMethod,
+      meta: { wait: true }
+    };
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Add any `initialState`s to the list of enter states.
</del><ins>+    Remove a previously added helper method.
</ins><span class="cx"> 
</span><del>-    @method addInitialStates
</del><ins>+    Example:
+
+    ```
+    Ember.Test.unregisterHelper('wait');
+    ```
+
+    @public
+    @method unregisterHelper
+    @param {String} name The helper to remove.
</ins><span class="cx">   */
</span><del>-  addInitialStates: function() {
-    var finalState = this.finalState, initialState;
</del><ins>+  unregisterHelper: function(name) {
+    delete helpers[name];
+    delete Ember.Test.Promise.prototype[name];
+  },
</ins><span class="cx"> 
</span><del>-    while(true) {
-      initialState = get(finalState, 'initialState') || 'start';
-      finalState = get(finalState, 'states.' + initialState);
</del><ins>+  /**
+    Used to register callbacks to be fired whenever `App.injectTestHelpers`
+    is called.
</ins><span class="cx"> 
</span><del>-      if (!finalState) { break; }
</del><ins>+    The callback will receive the current application as an argument.
</ins><span class="cx"> 
</span><del>-      this.finalState = finalState;
-      this.enterStates.push(finalState);
-      this.contexts.push(undefined);
-    }
</del><ins>+    Example:
+    ```
+    Ember.Test.onInjectHelpers(function() {
+      Ember.$(document).ajaxStart(function() {
+        Test.pendingAjaxRequests++;
+      });
+
+      Ember.$(document).ajaxStop(function() {
+        Test.pendingAjaxRequests--;
+      });
+    });
+    ```
+
+    @public
+    @method onInjectHelpers
+    @param {Function} callback The function to be called.
+  */
+  onInjectHelpers: function(callback) {
+    injectHelpersCallbacks.push(callback);
</ins><span class="cx">   },
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-    Remove any states that were added because the number of contexts
-    exceeded the number of explicit enter states, but the context has
-    not changed since the last time the state was entered.
</del><ins>+    This returns a thenable tailored for testing.  It catches failed
+    `onSuccess` callbacks and invokes the `Ember.Test.adapter.exception`
+    callback in the last chained then.
</ins><span class="cx"> 
</span><del>-    @method removeUnchangedContexts
-    @param {Ember.StateManager} manager passed in to look up the last
-      context for a states
</del><ins>+    This method should be returned by async helpers such as `wait`.
+
+    @public
+    @method promise
+    @param {Function} resolver The function used to resolve the promise.
</ins><span class="cx">   */
</span><del>-  removeUnchangedContexts: function(manager) {
-    // Start from the beginning of the enter states. If the state was added
-    // to the list during the context matching phase, make sure the context
-    // has actually changed since the last time the state was entered.
-    while (this.enterStates.length &gt; 0) {
-      if (this.enterStates[0] !== this.exitStates[0]) { break; }
</del><ins>+  promise: function(resolver) {
+    return new Ember.Test.Promise(resolver);
+  },
</ins><span class="cx"> 
</span><del>-      if (this.enterStates.length === this.contexts.length) {
-        if (manager.getStateMeta(this.enterStates[0], 'context') !== this.contexts[0]) { break; }
-        this.contexts.shift();
-      }
</del><ins>+  /**
+   Used to allow ember-testing to communicate with a specific testing
+   framework.
</ins><span class="cx"> 
</span><del>-      this.resolveState = this.enterStates.shift();
-      this.exitStates.shift();
-    }
-  }
-};
</del><ins>+   You can manually set it before calling `App.setupForTesting()`.
</ins><span class="cx"> 
</span><del>-var sendRecursively = function(event, currentState, isUnhandledPass) {
-  var log = this.enableLogging,
-      eventName = isUnhandledPass ? 'unhandledEvent' : event,
-      action = currentState[eventName],
-      contexts, sendRecursiveArguments, actionArguments;
</del><ins>+   Example:
</ins><span class="cx"> 
</span><del>-  contexts = [].slice.call(arguments, 3);
</del><ins>+   ```
+   Ember.Test.adapter = MyCustomAdapter.create()
+   ```
</ins><span class="cx"> 
</span><del>-  // Test to see if the action is a method that
-  // can be invoked. Don't blindly check just for
-  // existence, because it is possible the state
-  // manager has a child state of the given name,
-  // and we should still raise an exception in that
-  // case.
-  if (typeof action === 'function') {
-    if (log) {
-      if (isUnhandledPass) {
-        Ember.Logger.log(fmt(&quot;STATEMANAGER: Unhandled event '%@' being sent to state %@.&quot;, [event, get(currentState, 'path')]));
-      } else {
-        Ember.Logger.log(fmt(&quot;STATEMANAGER: Sending event '%@' to state %@.&quot;, [event, get(currentState, 'path')]));
-      }
-    }
</del><ins>+   If you do not set it, ember-testing will default to `Ember.Test.QUnitAdapter`.
</ins><span class="cx"> 
</span><del>-    actionArguments = contexts;
-    if (isUnhandledPass) {
-      actionArguments.unshift(event);
-    }
-    actionArguments.unshift(this);
</del><ins>+   @public
+   @property adapter
+   @type {Class} The adapter to be used.
+   @default Ember.Test.QUnitAdapter
+  */
+  adapter: null,
</ins><span class="cx"> 
</span><del>-    return action.apply(currentState, actionArguments);
-  } else {
-    var parentState = get(currentState, 'parentState');
-    if (parentState) {
</del><ins>+  /**
+    Replacement for `Ember.RSVP.resolve`
+    The only difference is this uses
+    and instance of `Ember.Test.Promise`
</ins><span class="cx"> 
</span><del>-      sendRecursiveArguments = contexts;
-      sendRecursiveArguments.unshift(event, parentState, isUnhandledPass);
</del><ins>+    @public
+    @method resolve
+    @param {Mixed} The value to resolve
+  */
+  resolve: function(val) {
+    return Ember.Test.promise(function(resolve) {
+      return resolve(val);
+    });
+  },
</ins><span class="cx"> 
</span><del>-      return sendRecursively.apply(this, sendRecursiveArguments);
-    } else if (!isUnhandledPass) {
-      return sendEvent.call(this, event, contexts, true);
</del><ins>+  /**
+     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
+  */
+  registerWaiter: function(context, callback) {
+    if (arguments.length === 1) {
+      callback = context;
+      context = null;
</ins><span class="cx">     }
</span><ins>+    if (!this.waiters) {
+      this.waiters = Ember.A();
+    }
+    this.waiters.push([context, callback]);
+  },
+  /**
+     `unregisterWaiter` is used to unregister a callback that was
+     registered with `registerWaiter`.
+
+     @public
+     @method unregisterWaiter
+     @param {Object} context (optional)
+     @param {Function} callback
+  */
+  unregisterWaiter: 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;
+    }));
</ins><span class="cx">   }
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-var sendEvent = function(eventName, sendRecursiveArguments, isUnhandledPass) {
-  sendRecursiveArguments.unshift(eventName, get(this, 'currentState'), isUnhandledPass);
-  return sendRecursively.apply(this, sendRecursiveArguments);
-};
</del><ins>+function helper(app, name) {
+  var fn = helpers[name].method,
+      meta = helpers[name].meta;
</ins><span class="cx"> 
</span><del>-/**
-  StateManager is part of Ember's implementation of a finite state machine. A
-  StateManager instance manages a number of properties that are instances of
-  `Ember.State`,
-  tracks the current active state, and triggers callbacks when states have changed.
</del><ins>+  return function() {
+    var args = slice.call(arguments),
+        lastPromise = Ember.Test.lastPromise;
</ins><span class="cx"> 
</span><del>-  ## Defining States
</del><ins>+    args.unshift(app);
</ins><span class="cx"> 
</span><del>-  The states of StateManager can be declared in one of two ways. First, you can
-  define a `states` property that contains all the states:
</del><ins>+    // some helpers are not async and
+    // need to return a value immediately.
+    // example: `find`
+    if (!meta.wait) {
+      return fn.apply(app, args);
+    }
</ins><span class="cx"> 
</span><del>-  ```javascript
-  managerA = Ember.StateManager.create({
-    states: {
-      stateOne: Ember.State.create(),
-      stateTwo: Ember.State.create()
</del><ins>+    if (!lastPromise) {
+      // It's the first async helper in current context
+      lastPromise = fn.apply(app, args);
+    } else {
+      // wait for last helper's promise to resolve
+      // and then execute
+      run(function() {
+        lastPromise = Ember.Test.resolve(lastPromise).then(function() {
+          return fn.apply(app, args);
+        });
+      });
</ins><span class="cx">     }
</span><del>-  })
</del><span class="cx"> 
</span><del>-  managerA.get('states')
-  // {
-  //   stateOne: Ember.State.create(),
-  //   stateTwo: Ember.State.create()
-  // }
-  ```
</del><ins>+    return lastPromise;
+  };
+}
</ins><span class="cx"> 
</span><del>-  You can also add instances of `Ember.State` (or an `Ember.State` subclass)
-  directly as properties of a StateManager. These states will be collected into
-  the `states` property for you.
</del><ins>+function run(fn) {
+  if (!Ember.run.currentRunLoop) {
+    Ember.run(fn);
+  } else {
+    fn();
+  }
+}
</ins><span class="cx"> 
</span><del>-  ```javascript
-  managerA = Ember.StateManager.create({
-    stateOne: Ember.State.create(),
-    stateTwo: Ember.State.create()
-  })
</del><ins>+Ember.Application.reopen({
+  /**
+   This property contains the testing helpers for the current application. These
+   are created once you call `injectTestHelpers` on your `Ember.Application`
+   instance. The included helpers are also available on the `window` object by
+   default, but can be used from this object on the individual application also.
</ins><span class="cx"> 
</span><del>-  managerA.get('states')
-  // {
-  //   stateOne: Ember.State.create(),
-  //   stateTwo: Ember.State.create()
-  // }
-  ```
</del><ins>+    @property testHelpers
+    @type {Object}
+    @default {}
+  */
+  testHelpers: {},
</ins><span class="cx"> 
</span><del>-  ## The Initial State
</del><ins>+  /**
+   This property will contain the original methods that were registered
+   on the `helperContainer` before `injectTestHelpers` is called.
</ins><span class="cx"> 
</span><del>-  When created a StateManager instance will immediately enter into the state
-  defined as its `start` property or the state referenced by name in its
-  `initialState` property:
</del><ins>+   When `removeTestHelpers` is called, these methods are restored to the
+   `helperContainer`.
</ins><span class="cx"> 
</span><del>-  ```javascript
-  managerA = Ember.StateManager.create({
-    start: Ember.State.create({})
-  })
</del><ins>+    @property originalMethods
+    @type {Object}
+    @default {}
+    @private
+  */
+  originalMethods: {},
</ins><span class="cx"> 
</span><del>-  managerA.get('currentState.name') // 'start'
</del><span class="cx"> 
</span><del>-  managerB = Ember.StateManager.create({
-    initialState: 'beginHere',
-    beginHere: Ember.State.create({})
-  })
</del><ins>+  /**
+  This property indicates whether or not this application is currently in
+  testing mode. This is set when `setupForTesting` is called on the current
+  application.
</ins><span class="cx"> 
</span><del>-  managerB.get('currentState.name') // 'beginHere'
-  ```
</del><ins>+  @property testing
+  @type {Boolean}
+  @default false
+  */
+  testing: false,
</ins><span class="cx"> 
</span><del>-  Because it is a property you may also provide a computed function if you wish
-  to derive an `initialState` programmatically:
</del><ins>+  /**
+   This hook defers the readiness of the application, so that you can start
+   the app when your tests are ready to run. It also sets the router's
+   location to 'none', so that the window's location will not be modified
+   (preventing both accidental leaking of state between tests and interference
+   with your testing framework).
</ins><span class="cx"> 
</span><del>-  ```javascript
-  managerC = Ember.StateManager.create({
-    initialState: function(){
-      if (someLogic) {
-        return 'active';
-      } else {
-        return 'passive';
-      }
-    }.property(),
-    active: Ember.State.create({}),
-    passive: Ember.State.create({})
-  })
</del><ins>+   Example:
+
</ins><span class="cx">   ```
</span><ins>+  App.setupForTesting();
+  ```
</ins><span class="cx"> 
</span><del>-  ## Moving Between States
</del><ins>+    @method setupForTesting
+  */
+  setupForTesting: function() {
+    Ember.testing = true;
</ins><span class="cx"> 
</span><del>-  A StateManager can have any number of `Ember.State` objects as properties
-  and can have a single one of these states as its current state.
</del><ins>+    this.testing = true;
</ins><span class="cx"> 
</span><del>-  Calling `transitionTo` transitions between states:
</del><ins>+    this.Router.reopen({
+      location: 'none'
+    });
</ins><span class="cx"> 
</span><del>-  ```javascript
-  robotManager = Ember.StateManager.create({
-    initialState: 'poweredDown',
-    poweredDown: Ember.State.create({}),
-    poweredUp: Ember.State.create({})
-  })
</del><ins>+    // if adapter is not manually set default to QUnit
+    if (!Ember.Test.adapter) {
+       Ember.Test.adapter = Ember.Test.QUnitAdapter.create();
+    }
</ins><span class="cx"> 
</span><del>-  robotManager.get('currentState.name') // 'poweredDown'
-  robotManager.transitionTo('poweredUp')
-  robotManager.get('currentState.name') // 'poweredUp'
-  ```
</del><ins>+      },
</ins><span class="cx"> 
</span><del>-  Before transitioning into a new state the existing `currentState` will have
-  its `exit` method called with the StateManager instance as its first argument
-  and an object representing the transition as its second argument.
</del><ins>+  /**
+    This will be used as the container to inject the test helpers into. By
+    default the helpers are injected into `window`.
</ins><span class="cx"> 
</span><del>-  After transitioning into a new state the new `currentState` will have its
-  `enter` method called with the StateManager instance as its first argument
-  and an object representing the transition as its second argument.
</del><ins>+    @property helperContainer
+   @type {Object} The object to be used for test helpers.
+   @default window
+  */
+  helperContainer: window,
</ins><span class="cx"> 
</span><del>-  ```javascript
-  robotManager = Ember.StateManager.create({
-    initialState: 'poweredDown',
-    poweredDown: Ember.State.create({
-      exit: function(stateManager){
-        console.log(&quot;exiting the poweredDown state&quot;)
-      }
-    }),
-    poweredUp: Ember.State.create({
-      enter: function(stateManager){
-        console.log(&quot;entering the poweredUp state. Destroy all humans.&quot;)
-      }
-    })
-  })
</del><ins>+  /**
+    This injects the test helpers into the `helperContainer` object. If an object is provided
+    it will be used as the helperContainer. If `helperContainer` is not set it will default
+    to `window`. If a function of the same name has already been defined it will be cached
+    (so that it can be reset if the helper is removed with `unregisterHelper` or
+    `removeTestHelpers`).
</ins><span class="cx"> 
</span><del>-  robotManager.get('currentState.name') // 'poweredDown'
-  robotManager.transitionTo('poweredUp')
</del><ins>+   Any callbacks registered with `onInjectHelpers` will be called once the
+   helpers have been injected.
</ins><span class="cx"> 
</span><del>-  // will log
-  // 'exiting the poweredDown state'
-  // 'entering the poweredUp state. Destroy all humans.'
</del><ins>+  Example:
</ins><span class="cx">   ```
</span><ins>+  App.injectTestHelpers();
+  ```
</ins><span class="cx"> 
</span><del>-  Once a StateManager is already in a state, subsequent attempts to enter that
-  state will not trigger enter or exit method calls. Attempts to transition
-  into a state that the manager does not have will result in no changes in the
-  StateManager's current state:
</del><ins>+    @method injectTestHelpers
+  */
+  injectTestHelpers: function(helperContainer) {
+    if (helperContainer) { this.helperContainer = helperContainer; }
</ins><span class="cx"> 
</span><del>-  ```javascript
-  robotManager = Ember.StateManager.create({
-    initialState: 'poweredDown',
-    poweredDown: Ember.State.create({
-      exit: function(stateManager){
-        console.log(&quot;exiting the poweredDown state&quot;)
-      }
-    }),
-    poweredUp: Ember.State.create({
-      enter: function(stateManager){
-        console.log(&quot;entering the poweredUp state. Destroy all humans.&quot;)
-      }
-    })
-  })
</del><ins>+    this.testHelpers = {};
+    for (var name in helpers) {
+      this.originalMethods[name] = this.helperContainer[name];
+      this.testHelpers[name] = this.helperContainer[name] = helper(this, name);
+      protoWrap(Ember.Test.Promise.prototype, name, helper(this, name), helpers[name].meta.wait);
+    }
</ins><span class="cx"> 
</span><del>-  robotManager.get('currentState.name') // 'poweredDown'
-  robotManager.transitionTo('poweredUp')
-  // will log
-  // 'exiting the poweredDown state'
-  // 'entering the poweredUp state. Destroy all humans.'
-  robotManager.transitionTo('poweredUp') // no logging, no state change
</del><ins>+    for(var i = 0, l = injectHelpersCallbacks.length; i &lt; l; i++) {
+      injectHelpersCallbacks[i](this);
+    }
+  },
</ins><span class="cx"> 
</span><del>-  robotManager.transitionTo('someUnknownState') // silently fails
-  robotManager.get('currentState.name') // 'poweredUp'
-  ```
</del><ins>+  /**
+    This removes all helpers that have been registered, and resets and functions
+    that were overridden by the helpers.
</ins><span class="cx"> 
</span><del>-  Each state property may itself contain properties that are instances of
-  `Ember.State`. The StateManager can transition to specific sub-states in a
-  series of transitionTo method calls or via a single transitionTo with the
-  full path to the specific state. The StateManager will also keep track of the
-  full path to its currentState
</del><ins>+    Example:
</ins><span class="cx"> 
</span><del>-  ```javascript
-  robotManager = Ember.StateManager.create({
-    initialState: 'poweredDown',
-    poweredDown: Ember.State.create({
-      charging: Ember.State.create(),
-      charged: Ember.State.create()
-    }),
-    poweredUp: Ember.State.create({
-      mobile: Ember.State.create(),
-      stationary: Ember.State.create()
-    })
-  })
</del><ins>+    ```javascript
+    App.removeTestHelpers();
+    ```
</ins><span class="cx"> 
</span><del>-  robotManager.get('currentState.name') // 'poweredDown'
</del><ins>+    @public
+    @method removeTestHelpers
+  */
+  removeTestHelpers: function() {
+    for (var name in helpers) {
+      this.helperContainer[name] = this.originalMethods[name];
+      delete this.testHelpers[name];
+      delete this.originalMethods[name];
+    }
+  }
+});
</ins><span class="cx"> 
</span><del>-  robotManager.transitionTo('poweredUp')
-  robotManager.get('currentState.name') // 'poweredUp'
</del><ins>+// This method is no longer needed
+// But still here for backwards compatibility
+// of helper chaining
+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);
+      });
+    }
+  };
+}
</ins><span class="cx"> 
</span><del>-  robotManager.transitionTo('mobile')
-  robotManager.get('currentState.name') // 'mobile'
</del><ins>+Ember.Test.Promise = function() {
+  Ember.RSVP.Promise.apply(this, arguments);
+  Ember.Test.lastPromise = this;
+};
</ins><span class="cx"> 
</span><del>-  // transition via a state path
-  robotManager.transitionTo('poweredDown.charging')
-  robotManager.get('currentState.name') // 'charging'
</del><ins>+Ember.Test.Promise.prototype = Ember.create(Ember.RSVP.Promise.prototype);
+Ember.Test.Promise.prototype.constructor = Ember.Test.Promise;
</ins><span class="cx"> 
</span><del>-  robotManager.get('currentState.path') // 'poweredDown.charging'
-  ```
</del><ins>+// Patch `then` to isolate async methods
+// specifically `Ember.Test.lastPromise`
+var originalThen = Ember.RSVP.Promise.prototype.then;
+Ember.Test.Promise.prototype.then = function(onSuccess, onFailure) {
+  return originalThen.call(this, function(val) {
+    return isolate(onSuccess, val);
+  }, onFailure);
+};
</ins><span class="cx"> 
</span><del>-  Enter transition methods will be called for each state and nested child state
-  in their hierarchical order. Exit methods will be called for each state and
-  its nested states in reverse hierarchical order.
</del><ins>+// This method isolates nested async methods
+// so that they don't conflict with other last promises.
+//
+// 1. Set `Ember.Test.lastPromise` to null
+// 2. Invoke method
+// 3. Return the last promise created during method
+// 4. Restore `Ember.Test.lastPromise` to original value
+function isolate(fn, val) {
+  var value, lastPromise;
</ins><span class="cx"> 
</span><del>-  Exit transitions for a parent state are not called when entering into one of
-  its child states, only when transitioning to a new section of possible states
-  in the hierarchy.
</del><ins>+  // Reset lastPromise for nested helpers
+  Ember.Test.lastPromise = null;
</ins><span class="cx"> 
</span><del>-  ```javascript
-  robotManager = Ember.StateManager.create({
-    initialState: 'poweredDown',
-    poweredDown: Ember.State.create({
-      enter: function(){},
-      exit: function(){
-        console.log(&quot;exited poweredDown state&quot;)
-      },
-      charging: Ember.State.create({
-        enter: function(){},
-        exit: function(){}
-      }),
-      charged: Ember.State.create({
-        enter: function(){
-          console.log(&quot;entered charged state&quot;)
-        },
-        exit: function(){
-          console.log(&quot;exited charged state&quot;)
-        }
-      })
-    }),
-    poweredUp: Ember.State.create({
-      enter: function(){
-        console.log(&quot;entered poweredUp state&quot;)
-      },
-      exit: function(){},
-      mobile: Ember.State.create({
-        enter: function(){
-          console.log(&quot;entered mobile state&quot;)
-        },
-        exit: function(){}
-      }),
-      stationary: Ember.State.create({
-        enter: function(){},
-        exit: function(){}
-      })
-    })
-  })
</del><ins>+  value = fn.call(null, val);
</ins><span class="cx"> 
</span><ins>+  lastPromise = Ember.Test.lastPromise;
</ins><span class="cx"> 
</span><del>-  robotManager.get('currentState.path') // 'poweredDown'
-  robotManager.transitionTo('charged')
-  // logs 'entered charged state'
-  // but does *not* log  'exited poweredDown state'
-  robotManager.get('currentState.name') // 'charged
</del><ins>+  // If the method returned a promise
+  // return that promise. If not,
+  // return the last async helper's promise
+  if ((value &amp;&amp; (value instanceof Ember.Test.Promise)) || !lastPromise) {
+    return value;
+  } else {
+    run(function() {
+      lastPromise = Ember.Test.resolve(lastPromise).then(function() {
+        return value;
+      });
+    });
+    return lastPromise;
+  }
+}
</ins><span class="cx"> 
</span><del>-  robotManager.transitionTo('poweredUp.mobile')
-  // logs
-  // 'exited charged state'
-  // 'exited poweredDown state'
-  // 'entered poweredUp state'
-  // 'entered mobile state'
-  ```
</del><ins>+})();
</ins><span class="cx"> 
</span><del>-  During development you can set a StateManager's `enableLogging` property to
-  `true` to receive console messages of state transitions.
</del><span class="cx"> 
</span><del>-  ```javascript
-  robotManager = Ember.StateManager.create({
-    enableLogging: true
-  })
-  ```
</del><span class="cx"> 
</span><del>-  ## Managing currentState with Actions
</del><ins>+(function() {
+Ember.onLoad('Ember.Application', function(Application) {
+  Application.initializer({
+    name: 'deferReadiness in `testing` mode',
</ins><span class="cx"> 
</span><del>-  To control which transitions are possible for a given state, and
-  appropriately handle external events, the StateManager can receive and
-  route action messages to its states via the `send` method. Calling to
-  `send` with an action name will begin searching for a method with the same
-  name starting at the current state and moving up through the parent states
-  in a state hierarchy until an appropriate method is found or the StateManager
-  instance itself is reached.
</del><ins>+    initialize: function(container, application){
+      if (application.testing) {
+        application.deferReadiness();
+      }
+    }
+  });
</ins><span class="cx"> 
</span><del>-  If an appropriately named method is found it will be called with the state
-  manager as the first argument and an optional `context` object as the second
-  argument.
</del><ins>+  });
</ins><span class="cx"> 
</span><del>-  ```javascript
-  managerA = Ember.StateManager.create({
-    initialState: 'stateOne.substateOne.subsubstateOne',
-    stateOne: Ember.State.create({
-      substateOne: Ember.State.create({
-        anAction: function(manager, context){
-          console.log(&quot;an action was called&quot;)
-        },
-        subsubstateOne: Ember.State.create({})
-      })
-    })
-  })
</del><ins>+})();
</ins><span class="cx"> 
</span><del>-  managerA.get('currentState.name') // 'subsubstateOne'
-  managerA.send('anAction')
-  // 'stateOne.substateOne.subsubstateOne' has no anAction method
-  // so the 'anAction' method of 'stateOne.substateOne' is called
-  // and logs &quot;an action was called&quot;
-  // with managerA as the first argument
-  // and no second argument
</del><span class="cx"> 
</span><del>-  someObject = {}
-  managerA.send('anAction', someObject)
-  // the 'anAction' method of 'stateOne.substateOne' is called again
-  // with managerA as the first argument and
-  // someObject as the second argument.
-  ```
</del><span class="cx"> 
</span><del>-  If the StateManager attempts to send an action but does not find an appropriately named
-  method in the current state or while moving upwards through the state hierarchy, it will
-  repeat the process looking for a `unhandledEvent` method. If an `unhandledEvent` method is
-  found, it will be called with the original event name as the second argument. If an
-  `unhandledEvent` method is not found, the StateManager will throw a new Ember.Error.
</del><ins>+(function() {
+/**
+  @module ember
+  @submodule ember-testing
+ */
</ins><span class="cx"> 
</span><del>-  ```javascript
-  managerB = Ember.StateManager.create({
-    initialState: 'stateOne.substateOne.subsubstateOne',
-    stateOne: Ember.State.create({
-      substateOne: Ember.State.create({
-        subsubstateOne: Ember.State.create({}),
-        unhandledEvent: function(manager, eventName, context) {
-          console.log(&quot;got an unhandledEvent with name &quot; + eventName);
-        }
-      })
-    })
-  })
</del><ins>+var $ = Ember.$;
</ins><span class="cx"> 
</span><del>-  managerB.get('currentState.name') // 'subsubstateOne'
-  managerB.send('anAction')
-  // neither `stateOne.substateOne.subsubstateOne` nor any of it's
-  // parent states have a handler for `anAction`. `subsubstateOne`
-  // also does not have a `unhandledEvent` method, but its parent
-  // state, `substateOne`, does, and it gets fired. It will log
-  // &quot;got an unhandledEvent with name anAction&quot;
-  ```
</del><ins>+/**
+  This method creates a checkbox and triggers the click event to fire the
+  passed in handler. It is used to correct for a bug in older versions
+  of jQuery (e.g 1.8.3).
</ins><span class="cx"> 
</span><del>-  Action detection only moves upwards through the state hierarchy from the current state.
-  It does not search in other portions of the hierarchy.
</del><ins>+  @private
+  @method testCheckboxClick
+*/
+function testCheckboxClick(handler) {
+  $('&lt;input type=&quot;checkbox&quot;&gt;')
+    .css({ position: 'absolute', left: '-1000px', top: '-1000px' })
+    .appendTo('body')
+    .on('click', handler)
+    .trigger('click')
+    .remove();
+}
</ins><span class="cx"> 
</span><del>-  ```javascript
-  managerC = Ember.StateManager.create({
-    initialState: 'stateOne.substateOne.subsubstateOne',
-    stateOne: Ember.State.create({
-      substateOne: Ember.State.create({
-        subsubstateOne: Ember.State.create({})
-      })
-    }),
-    stateTwo: Ember.State.create({
-     anAction: function(manager, context){
-       // will not be called below because it is
-       // not a parent of the current state
-     }
-    })
-  })
</del><ins>+$(function() {
+  /*
+    Determine whether a checkbox checked using jQuery's &quot;click&quot; method will have
+    the correct value for its checked property.
</ins><span class="cx"> 
</span><del>-  managerC.get('currentState.name') // 'subsubstateOne'
-  managerC.send('anAction')
-  // Error: &lt;Ember.StateManager:ember132&gt; could not
-  // respond to event anAction in state stateOne.substateOne.subsubstateOne.
-  ```
-
-  Inside of an action method the given state should delegate `transitionTo` calls on its
-  StateManager.
-
-  ```javascript
-  robotManager = Ember.StateManager.create({
-    initialState: 'poweredDown.charging',
-    poweredDown: Ember.State.create({
-      charging: Ember.State.create({
-        chargeComplete: function(manager, context){
-          manager.transitionTo('charged')
</del><ins>+    If we determine that the current jQuery version exhibits this behavior,
+    patch it to work correctly as in the commit for the actual fix:
+    https://github.com/jquery/jquery/commit/1fb2f92.
+  */
+  testCheckboxClick(function() {
+    if (!this.checked &amp;&amp; !$.event.special.click) {
+      $.event.special.click = {
+        // For checkbox, fire native event so checked state will be right
+        trigger: function() {
+          if ($.nodeName( this, &quot;input&quot; ) &amp;&amp; this.type === &quot;checkbox&quot; &amp;&amp; this.click) {
+            this.click();
+            return false;
+          }
</ins><span class="cx">         }
</span><del>-      }),
-      charged: Ember.State.create({
-        boot: function(manager, context){
-          manager.transitionTo('poweredUp')
-        }
-      })
-    }),
-    poweredUp: Ember.State.create({
-      beginExtermination: function(manager, context){
-        manager.transitionTo('rampaging')
-      },
-      rampaging: Ember.State.create()
-    })
-  })
</del><ins>+      };
+    }
+  });
</ins><span class="cx"> 
</span><del>-  robotManager.get('currentState.name') // 'charging'
-  robotManager.send('boot') // throws error, no boot action
-                            // in current hierarchy
-  robotManager.get('currentState.name') // remains 'charging'
</del><ins>+  // Try again to verify that the patch took effect or blow up.
+  testCheckboxClick(function() {
+    Ember.warn(&quot;clicked checkboxes should be checked! the jQuery patch didn't work&quot;, this.checked);
+  });
+});
</ins><span class="cx"> 
</span><del>-  robotManager.send('beginExtermination') // throws error, no beginExtermination
-                                          // action in current hierarchy
-  robotManager.get('currentState.name')   // remains 'charging'
</del><ins>+})();
</ins><span class="cx"> 
</span><del>-  robotManager.send('chargeComplete')
-  robotManager.get('currentState.name')   // 'charged'
</del><span class="cx"> 
</span><del>-  robotManager.send('boot')
-  robotManager.get('currentState.name')   // 'poweredUp'
</del><span class="cx"> 
</span><del>-  robotManager.send('beginExtermination', allHumans)
-  robotManager.get('currentState.name')   // 'rampaging'
-  ```
</del><ins>+(function() {
+/**
+ @module ember
+ @submodule ember-testing
+*/
</ins><span class="cx"> 
</span><del>-  Transition actions can also be created using the `transitionTo` method of the `Ember.State` class. The
-  following example StateManagers are equivalent:
</del><ins>+var Test = Ember.Test;
</ins><span class="cx"> 
</span><del>-  ```javascript
-  aManager = Ember.StateManager.create({
-    stateOne: Ember.State.create({
-      changeToStateTwo: Ember.State.transitionTo('stateTwo')
-    }),
-    stateTwo: Ember.State.create({})
-  })
</del><ins>+/**
+  The primary purpose of this class is to create hooks that can be implemented
+  by an adapter for various test frameworks.
</ins><span class="cx"> 
</span><del>-  bManager = Ember.StateManager.create({
-    stateOne: Ember.State.create({
-      changeToStateTwo: function(manager, context){
-        manager.transitionTo('stateTwo', context)
-      }
-    }),
-    stateTwo: Ember.State.create({})
-  })
-  ```
-
-  @class StateManager
-  @namespace Ember
-  @extends Ember.State
-**/
-Ember.StateManager = Ember.State.extend({
</del><ins>+  @class Adapter
+  @namespace Ember.Test
+*/
+Test.Adapter = Ember.Object.extend({
</ins><span class="cx">   /**
</span><del>-    @private
</del><ins>+    This callback will be called whenever an async operation is about to start.
</ins><span class="cx"> 
</span><del>-    When creating a new statemanager, look for a default state to transition
-    into. This state can either be named `start`, or can be specified using the
-    `initialState` property.
</del><ins>+    Override this to call your framework's methods that handle async
+    operations.
</ins><span class="cx"> 
</span><del>-    @method init
</del><ins>+    @public
+    @method asyncStart
</ins><span class="cx">   */
</span><del>-  init: function() {
-    this._super();
</del><ins>+  asyncStart: Ember.K,
</ins><span class="cx"> 
</span><del>-    set(this, 'stateMeta', Ember.Map.create());
</del><ins>+  /**
+    This callback will be called whenever an async operation has completed.
</ins><span class="cx"> 
</span><del>-    var initialState = get(this, 'initialState');
</del><ins>+    @public
+    @method asyncEnd
+  */
+  asyncEnd: Ember.K,
</ins><span class="cx"> 
</span><del>-    if (!initialState &amp;&amp; get(this, 'states.start')) {
-      initialState = 'start';
-    }
</del><ins>+  /**
+    Override this method with your testing framework's false assertion.
+    This function is called whenever an exception occurs causing the testing
+    promise to fail.
</ins><span class="cx"> 
</span><del>-    if (initialState) {
-      this.transitionTo(initialState);
-      Ember.assert('Failed to transition to initial state &quot;' + initialState + '&quot;', !!get(this, 'currentState'));
-    }
-  },
</del><ins>+    QUnit example:
</ins><span class="cx"> 
</span><del>-  stateMetaFor: function(state) {
-    var meta = get(this, 'stateMeta'),
-        stateMeta = meta.get(state);
</del><ins>+    ```javascript
+      exception: function(error) {
+        ok(false, error);
+      };
+    ```
</ins><span class="cx"> 
</span><del>-    if (!stateMeta) {
-      stateMeta = {};
-      meta.set(state, stateMeta);
-    }
</del><ins>+    @public
+    @method exception
+    @param {String} error The exception to be raised.
+  */
+  exception: function(error) {
+    throw error;
+  }
+});
</ins><span class="cx"> 
</span><del>-    return stateMeta;
-  },
</del><ins>+/**
+  This class implements the methods defined by Ember.Test.Adapter for the
+  QUnit testing framework.
</ins><span class="cx"> 
</span><del>-  setStateMeta: function(state, key, value) {
-    return set(this.stateMetaFor(state), key, value);
</del><ins>+  @class QUnitAdapter
+  @namespace Ember.Test
+  @extends Ember.Test.Adapter
+*/
+Test.QUnitAdapter = Test.Adapter.extend({
+  asyncStart: function() {
+    stop();
</ins><span class="cx">   },
</span><del>-
-  getStateMeta: function(state, key) {
-    return get(this.stateMetaFor(state), key);
</del><ins>+  asyncEnd: function() {
+    start();
</ins><span class="cx">   },
</span><ins>+  exception: function(error) {
+    ok(false, Ember.inspect(error));
+  }
+});
</ins><span class="cx"> 
</span><del>-  /**
-    The current state from among the manager's possible states. This property should
-    not be set directly. Use `transitionTo` to move between states by name.
</del><ins>+})();
</ins><span class="cx"> 
</span><del>-    @property currentState
-    @type Ember.State
-  */
-  currentState: null,
</del><span class="cx"> 
</span><del>-  /**
-   The path of the current state. Returns a string representation of the current
-   state.
</del><span class="cx"> 
</span><del>-   @property currentPath
-   @type String
-  */
-  currentPath: Ember.computed.alias('currentState.path'),
</del><ins>+(function() {
+/**
+* @module ember
+* @submodule ember-testing
+*/
</ins><span class="cx"> 
</span><del>-  /**
-    The name of transitionEvent that this stateManager will dispatch
</del><ins>+var get = Ember.get,
+    Test = Ember.Test,
+    helper = Test.registerHelper,
+    asyncHelper = Test.registerAsyncHelper,
+    countAsync = 0;
</ins><span class="cx"> 
</span><del>-    @property transitionEvent
-    @type String
-    @default 'setup'
-  */
-  transitionEvent: 'setup',
</del><ins>+Test.pendingAjaxRequests = 0;
</ins><span class="cx"> 
</span><del>-  /**
-    If set to true, `errorOnUnhandledEvents` will cause an exception to be
-    raised if you attempt to send an event to a state manager that is not
-    handled by the current state or any of its parent states.
</del><ins>+Test.onInjectHelpers(function() {
+  Ember.$(document).ajaxStart(function() {
+    Test.pendingAjaxRequests++;
+  });
</ins><span class="cx"> 
</span><del>-    @property errorOnUnhandledEvents
-    @type Boolean
-    @default true
-  */
-  errorOnUnhandledEvent: true,
</del><ins>+  Ember.$(document).ajaxStop(function() {
+    Ember.assert(&quot;An ajaxStop event which would cause the number of pending AJAX &quot; +
+                 &quot;requests to be negative has been triggered. This is most likely &quot; +
+                 &quot;caused by AJAX events that were started before calling &quot; +
+                 &quot;`injectTestHelpers()`.&quot;, Test.pendingAjaxRequests !== 0);
+    Test.pendingAjaxRequests--;
+  });
+});
</ins><span class="cx"> 
</span><del>-  send: function(event) {
-    var contexts = [].slice.call(arguments, 1);
-    Ember.assert('Cannot send event &quot;' + event + '&quot; while currentState is ' + get(this, 'currentState'), get(this, 'currentState'));
-    return sendEvent.call(this, event, contexts, false);
-  },
-  unhandledEvent: function(manager, event) {
-    if (get(this, 'errorOnUnhandledEvent')) {
-      throw new Ember.Error(this.toString() + &quot; could not respond to event &quot; + event + &quot; in state &quot; + get(this, 'currentState.path') + &quot;.&quot;);
-    }
-  },
</del><ins>+function currentRouteName(app){
+  var appController = app.__container__.lookup('controller:application');
</ins><span class="cx"> 
</span><del>-  /**
-    Finds a state by its state path.
</del><ins>+  return get(appController, 'currentRouteName');
+}
</ins><span class="cx"> 
</span><del>-    Example:
</del><ins>+function currentPath(app){
+  var appController = app.__container__.lookup('controller:application');
</ins><span class="cx"> 
</span><del>-    ```javascript
-    manager = Ember.StateManager.create({
-      root: Ember.State.create({
-        dashboard: Ember.State.create()
-      })
-    });
</del><ins>+  return get(appController, 'currentPath');
+}
</ins><span class="cx"> 
</span><del>-    manager.getStateByPath(manager, &quot;root.dashboard&quot;)
</del><ins>+function currentURL(app){
+  var router = app.__container__.lookup('router:main');
</ins><span class="cx"> 
</span><del>-    // returns the dashboard state
-    ```
</del><ins>+  return get(router, 'location').getURL();
+}
</ins><span class="cx"> 
</span><del>-    @method getStateByPath
-    @param {Ember.State} root the state to start searching from
-    @param {String} path the state path to follow
-    @return {Ember.State} the state at the end of the path
-  */
-  getStateByPath: function(root, path) {
-    var parts = path.split('.'),
-        state = root;
</del><ins>+function visit(app, url) {
+  Ember.run(app, 'advanceReadiness');
</ins><span class="cx"> 
</span><del>-    for (var i=0, len=parts.length; i&lt;len; i++) {
-      state = get(get(state, 'states'), parts[i]);
-      if (!state) { break; }
</del><ins>+  app.__container__.lookup('router:main').location.setURL(url);
+  Ember.run(app, app.handleURL, url);
+  return wait(app);
+}
+
+function click(app, selector, context) {
+  var $el = findWithAssert(app, selector, context);
+  Ember.run($el, 'mousedown');
+
+  if ($el.is(':input')) {
+    var type = $el.prop('type');
+    if (type !== 'checkbox' &amp;&amp; type !== 'radio' &amp;&amp; type !== 'hidden') {
+      Ember.run($el, function(){
+        // Firefox does not trigger the `focusin` event if the window
+        // does not have focus. If the document doesn't have focus just
+        // use trigger('focusin') instead.
+        if (!document.hasFocus || document.hasFocus()) {
+          this.focus();
+        } else {
+          this.trigger('focusin');
+        }
+      });
</ins><span class="cx">     }
</span><ins>+  }
</ins><span class="cx"> 
</span><del>-    return state;
-  },
</del><ins>+  Ember.run($el, 'mouseup');
+  Ember.run($el, 'click');
</ins><span class="cx"> 
</span><del>-  findStateByPath: function(state, path) {
-    var possible;
</del><ins>+  return wait(app);
+}
</ins><span class="cx"> 
</span><del>-    while (!possible &amp;&amp; state) {
-      possible = this.getStateByPath(state, path);
-      state = get(state, 'parentState');
-    }
</del><ins>+function triggerEvent(app, selector, context, event){
+  if (typeof method === 'undefined') {
+    event = context;
+    context = null;
+  }
</ins><span class="cx"> 
</span><del>-    return possible;
-  },
</del><ins>+  var $el = findWithAssert(app, selector, context);
</ins><span class="cx"> 
</span><del>-  /**
-    A state stores its child states in its `states` hash.
-    This code takes a path like `posts.show` and looks
-    up `root.states.posts.states.show`.
</del><ins>+  Ember.run($el, 'trigger', event);
</ins><span class="cx"> 
</span><del>-    It returns a list of all of the states from the
-    root, which is the list of states to call `enter`
-    on.
</del><ins>+  return wait(app);
+}
</ins><span class="cx"> 
</span><del>-    @method getStatesInPath
-    @param root
-    @param path
-  */
-  getStatesInPath: function(root, path) {
-    if (!path || path === &quot;&quot;) { return undefined; }
-    var parts = path.split('.'),
-        result = [],
-        states,
-        state;
</del><ins>+function keyEvent(app, selector, context, type, keyCode) {
+  var $el;
+  if (typeof keyCode === 'undefined') {
+    keyCode = type;
+    type = context;
+    context = null;
+  }
+  $el = findWithAssert(app, selector, context);
+  var event = Ember.$.Event(type, { keyCode: keyCode });
+  Ember.run($el, 'trigger', event);
+  return wait(app);
+}
</ins><span class="cx"> 
</span><del>-    for (var i=0, len=parts.length; i&lt;len; i++) {
-      states = get(root, 'states');
-      if (!states) { return undefined; }
-      state = get(states, parts[i]);
-      if (state) { root = state; result.push(state); }
-      else { return undefined; }
</del><ins>+function fillIn(app, selector, context, text) {
+  var $el;
+  if (typeof text === 'undefined') {
+    text = context;
+    context = null;
+  }
+  $el = findWithAssert(app, selector, context);
+  Ember.run(function() {
+    $el.val(text).change();
+  });
+  return wait(app);
+}
+
+function findWithAssert(app, selector, context) {
+  var $el = find(app, selector, context);
+  if ($el.length === 0) {
+    throw new Ember.Error(&quot;Element &quot; + selector + &quot; not found.&quot;);
+  }
+  return $el;
+}
+
+function find(app, selector, context) {
+  var $el;
+  context = context || get(app, 'rootElement');
+  $el = app.$(selector, context);
+
+  return $el;
+}
+
+function andThen(app, callback) {
+  return wait(app, callback(app));
+}
+
+function wait(app, value) {
+  return Test.promise(function(resolve) {
+    // If this is the first async promise, kick off the async test
+    if (++countAsync === 1) {
+      Test.adapter.asyncStart();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return result;
-  },
</del><ins>+    // Every 10ms, poll for the async thing to have finished
+    var watcher = setInterval(function() {
+      // 1. If the router is loading, keep polling
+      var routerIsLoading = app.__container__.lookup('router:main').router.isLoading;
+      if (routerIsLoading) { return; }
</ins><span class="cx"> 
</span><del>-  goToState: function() {
-    // not deprecating this yet so people don't constantly need to
-    // make trivial changes for little reason.
-    return this.transitionTo.apply(this, arguments);
-  },
</del><ins>+      // 2. If there are pending Ajax requests, keep polling
+      if (Test.pendingAjaxRequests) { return; }
</ins><span class="cx"> 
</span><del>-  transitionTo: function(path, context) {
-    // XXX When is transitionTo called with no path
-    if (Ember.isEmpty(path)) { return; }
</del><ins>+      // 3. If there are scheduled timers or we are inside of a run loop, keep polling
+      if (Ember.run.hasScheduledTimers() || Ember.run.currentRunLoop) { return; }
+      if (Test.waiters &amp;&amp; Test.waiters.any(function(waiter) {
+        var context = waiter[0];
+        var callback = waiter[1];
+        return !callback.call(context);
+      })) { return; }
+      // Stop polling
+      clearInterval(watcher);
</ins><span class="cx"> 
</span><del>-    // The ES6 signature of this function is `path, ...contexts`
-    var contexts = context ? Array.prototype.slice.call(arguments, 1) : [],
-        currentState = get(this, 'currentState') || this;
</del><ins>+      // If this is the last async promise, end the async test
+      if (--countAsync === 0) {
+        Test.adapter.asyncEnd();
+      }
</ins><span class="cx"> 
</span><del>-    // First, get the enter, exit and resolve states for the current state
-    // and specified path. If possible, use an existing cache.
-    var hash = this.contextFreeTransition(currentState, path);
</del><ins>+      // Synchronously resolve the promise
+      Ember.run(null, resolve, value);
+    }, 10);
+  });
</ins><span class="cx"> 
</span><del>-    // Next, process the raw state information for the contexts passed in.
-    var transition = new Transition(hash).normalize(this, contexts);
</del><ins>+}
</ins><span class="cx"> 
</span><del>-    this.enterState(transition);
-    this.triggerSetupContext(transition);
-  },
</del><span class="cx"> 
</span><del>-  contextFreeTransition: function(currentState, path) {
-    var cache = currentState.pathsCache[path];
-    if (cache) { return cache; }
</del><ins>+/**
+* Loads a route, sets up any controllers, and renders any templates associated
+* with the route as though a real user had triggered the route change while
+* using your app.
+*
+* Example:
+*
+* ```javascript
+* visit('posts/index').then(function() {
+*   // assert something
+* });
+* ```
+*
+* @method visit
+* @param {String} url the name of the route
+* @return {RSVP.Promise}
+*/
+asyncHelper('visit', visit);
</ins><span class="cx"> 
</span><del>-    var enterStates = this.getStatesInPath(currentState, path),
-        exitStates = [],
-        resolveState = currentState;
</del><ins>+/**
+* Clicks an element and triggers any actions triggered by the element's `click`
+* event.
+*
+* Example:
+*
+* ```javascript
+* click('.some-jQuery-selector').then(function() {
+*  // assert something
+* });
+* ```
+*
+* @method click
+* @param {String} selector jQuery selector for finding element on the DOM
+* @return {RSVP.Promise}
+*/
+asyncHelper('click', click);
</ins><span class="cx"> 
</span><del>-    // Walk up the states. For each state, check whether a state matching
-    // the `path` is nested underneath. This will find the closest
-    // parent state containing `path`.
-    //
-    // This allows the user to pass in a relative path. For example, for
-    // the following state hierarchy:
-    //
-    //    | |root
-    //    | |- posts
-    //    | | |- show (* current)
-    //    | |- comments
-    //    | | |- show
-    //
-    // If the current state is `&lt;root.posts.show&gt;`, an attempt to
-    // transition to `comments.show` will match `&lt;root.comments.show&gt;`.
-    //
-    // First, this code will look for root.posts.show.comments.show.
-    // Next, it will look for root.posts.comments.show. Finally,
-    // it will look for `root.comments.show`, and find the state.
-    //
-    // After this process, the following variables will exist:
-    //
-    // * resolveState: a common parent state between the current
-    //   and target state. In the above example, `&lt;root&gt;` is the
-    //   `resolveState`.
-    // * enterStates: a list of all of the states represented
-    //   by the path from the `resolveState`. For example, for
-    //   the path `root.comments.show`, `enterStates` would have
-    //   `[&lt;root.comments&gt;, &lt;root.comments.show&gt;]`
-    // * exitStates: a list of all of the states from the
-    //   `resolveState` to the `currentState`. In the above
-    //   example, `exitStates` would have
-    //   `[&lt;root.posts&gt;`, `&lt;root.posts.show&gt;]`.
-    while (resolveState &amp;&amp; !enterStates) {
-      exitStates.unshift(resolveState);
</del><ins>+/**
+* Simulates a key event, e.g. `keypress`, `keydown`, `keyup` with the desired keyCode
+*
+* Example:
+*
+* ```javascript
+* keyEvent('.some-jQuery-selector', 'keypress', 13).then(function() {
+*  // assert something
+* });
+* ```
+*
+* @method keyEvent
+* @param {String} selector jQuery selector for finding element on the DOM
+* @param {String} the type of key event, e.g. `keypress`, `keydown`, `keyup`
+* @param {Number} the keyCode of the simulated key event
+* @return {RSVP.Promise}
+*/
+asyncHelper('keyEvent', keyEvent);
</ins><span class="cx"> 
</span><del>-      resolveState = get(resolveState, 'parentState');
-      if (!resolveState) {
-        enterStates = this.getStatesInPath(this, path);
-        if (!enterStates) {
-          Ember.assert('Could not find state for path: &quot;'+path+'&quot;');
-          return;
-        }
-      }
-      enterStates = this.getStatesInPath(resolveState, path);
-    }
</del><ins>+/**
+* Fills in an input element with some text.
+*
+* Example:
+*
+* ```javascript
+* fillIn('#email', 'you@example.com').then(function() {
+*   // assert something
+* });
+* ```
+*
+* @method fillIn
+* @param {String} selector jQuery selector finding an input element on the DOM
+* to fill text with
+* @param {String} text text to place inside the input element
+* @return {RSVP.Promise}
+*/
+asyncHelper('fillIn', fillIn);
</ins><span class="cx"> 
</span><del>-    // If the path contains some states that are parents of both the
-    // current state and the target state, remove them.
-    //
-    // For example, in the following hierarchy:
-    //
-    // |- root
-    // | |- post
-    // | | |- index (* current)
-    // | | |- show
-    //
-    // If the `path` is `root.post.show`, the three variables will
-    // be:
-    //
-    // * resolveState: `&lt;state manager&gt;`
-    // * enterStates: `[&lt;root&gt;, &lt;root.post&gt;, &lt;root.post.show&gt;]`
-    // * exitStates: `[&lt;root&gt;, &lt;root.post&gt;, &lt;root.post.index&gt;]`
-    //
-    // The goal of this code is to remove the common states, so we
-    // have:
-    //
-    // * resolveState: `&lt;root.post&gt;`
-    // * enterStates: `[&lt;root.post.show&gt;]`
-    // * exitStates: `[&lt;root.post.index&gt;]`
-    //
-    // This avoid unnecessary calls to the enter and exit transitions.
-    while (enterStates.length &gt; 0 &amp;&amp; enterStates[0] === exitStates[0]) {
-      resolveState = enterStates.shift();
-      exitStates.shift();
-    }
</del><ins>+/**
+* Finds an element in the context of the app's container element. A simple alias
+* for `app.$(selector)`.
+*
+* Example:
+*
+* ```javascript
+* var $el = find('.my-selector);
+* ```
+*
+* @method find
+* @param {String} selector jQuery string selector for element lookup
+* @return {Object} jQuery object representing the results of the query
+*/
+helper('find', find);
</ins><span class="cx"> 
</span><del>-    // Cache the enterStates, exitStates, and resolveState for the
-    // current state and the `path`.
-    var transitions = currentState.pathsCache[path] = {
-      exitStates: exitStates,
-      enterStates: enterStates,
-      resolveState: resolveState
-    };
</del><ins>+/**
+* Like `find`, but throws an error if the element selector returns no results.
+*
+* Example:
+*
+* ```javascript
+* var $el = findWithAssert('.doesnt-exist'); // throws error
+* ```
+*
+* @method findWithAssert
+* @param {String} selector jQuery selector string for finding an element within
+* the DOM
+* @return {Object} jQuery object representing the results of the query
+* @throws {Error} throws error if jQuery object returned has a length of 0
+*/
+helper('findWithAssert', findWithAssert);
</ins><span class="cx"> 
</span><del>-    return transitions;
-  },
</del><ins>+/**
+  Causes the run loop to process any pending events. This is used to ensure that
+  any async operations from other helpers (or your assertions) have been processed.
</ins><span class="cx"> 
</span><del>-  triggerSetupContext: function(transitions) {
-    var contexts = transitions.contexts,
-        offset = transitions.enterStates.length - contexts.length,
-        enterStates = transitions.enterStates,
-        transitionEvent = get(this, 'transitionEvent');
</del><ins>+  This is most often used as the return value for the helper functions (see 'click',
+  'fillIn','visit',etc).
</ins><span class="cx"> 
</span><del>-    Ember.assert(&quot;More contexts provided than states&quot;, offset &gt;= 0);
</del><ins>+  Example:
</ins><span class="cx"> 
</span><del>-    arrayForEach.call(enterStates, function(state, idx) {
-      state.trigger(transitionEvent, this, contexts[idx-offset]);
-    }, this);
-  },
</del><ins>+  ```javascript
+  Ember.Test.registerAsyncHelper('loginUser', function(app, username, password) {
+    visit('secured/path/here')
+    .fillIn('#username', username)
+    .fillIn('#password', username)
+    .click('.submit')
</ins><span class="cx"> 
</span><del>-  getState: function(name) {
-    var state = get(this, name),
-        parentState = get(this, 'parentState');
</del><ins>+    return wait();
+  });
</ins><span class="cx"> 
</span><del>-    if (state) {
-      return state;
-    } else if (parentState) {
-      return parentState.getState(name);
-    }
-  },
</del><ins>+  @method wait
+  @param {Object} value The value to be returned.
+  @return {RSVP.Promise}
+*/
+asyncHelper('wait', wait);
+asyncHelper('andThen', andThen);
</ins><span class="cx"> 
</span><del>-  enterState: function(transition) {
-    var log = this.enableLogging;
</del><span class="cx"> 
</span><del>-    var exitStates = transition.exitStates.slice(0).reverse();
-    arrayForEach.call(exitStates, function(state) {
-      state.trigger('exit', this);
-    }, this);
</del><span class="cx"> 
</span><del>-    arrayForEach.call(transition.enterStates, function(state) {
-      if (log) { Ember.Logger.log(&quot;STATEMANAGER: Entering &quot; + get(state, 'path')); }
-      state.trigger('enter', this);
-    }, this);
</del><span class="cx"> 
</span><del>-    set(this, 'currentState', transition.finalState);
-  }
-});
-
</del><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> (function() {
</span><span class="cx"> /**
</span><del>-Ember States
</del><ins>+  Ember Testing
</ins><span class="cx"> 
</span><del>-@module ember
-@submodule ember-states
-@requires ember-runtime
</del><ins>+  @module ember
+  @submodule ember-testing
+  @requires ember-application
</ins><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> })();
</span><span class="cx"> 
</span><del>-
-})();
-// Version: v1.0.0-rc.1
-// Last commit: 8b061b4 (2013-02-15 12:10:22 -0800)
-
-
</del><span class="cx"> (function() {
</span><span class="cx"> /**
</span><span class="cx"> Ember
</span><span class="lines">@@ -26835,5 +40544,40 @@
</span><span class="cx"> @module ember
</span><span class="cx"> */
</span><span class="cx"> 
</span><ins>+function throwWithMessage(msg) {
+  return function() {
+    throw new Ember.Error(msg);
+  };
+}
+
+function generateRemovedClass(className) {
+  var msg = &quot; has been moved into a plugin: https://github.com/emberjs/ember-states&quot;;
+
+  return {
+    extend: throwWithMessage(className + msg),
+    create: throwWithMessage(className + msg)
+  };
+}
+
+Ember.StateManager = generateRemovedClass(&quot;Ember.StateManager&quot;);
+
+/**
+  This was exported to ember-states plugin for v 1.0.0 release. See: https://github.com/emberjs/ember-states
+  
+  @class StateManager
+  @namespace Ember
+*/
+
+Ember.State = generateRemovedClass(&quot;Ember.State&quot;);
+
+/**
+  This was exported to ember-states plugin for v 1.0.0 release. See: https://github.com/emberjs/ember-states
+  
+  @class State
+  @namespace Ember
+*/
+
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><ins>+
+})();
</ins></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbower_componentsemberdataemberdatajs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember-data/ember-data.js (0 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember-data/ember-data.js                                (rev 0)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember-data/ember-data.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -0,0 +1,10620 @@
</span><ins>+/*!
+ * @overview  Ember Data
+ * @copyright Copyright 2011-2014 Tilde Inc. and contributors.
+ *            Portions Copyright 2011 LivingSocial Inc.
+ * @license   Licensed under MIT license (see license.js)
+ * @version   1.0.0-beta.6
+ */
+
+
+(function() {
+var define, requireModule;
+
+(function() {
+  var registry = {}, seen = {};
+
+  define = function(name, deps, callback) {
+    registry[name] = { deps: deps, callback: callback };
+  };
+
+  requireModule = function(name) {
+    if (seen[name]) { return seen[name]; }
+    seen[name] = {};
+
+    var mod, deps, callback, reified , exports;
+
+    mod = registry[name];
+
+    if (!mod) {
+      throw new Error(&quot;Module '&quot; + name + &quot;' not found.&quot;);
+    }
+
+    deps = mod.deps;
+    callback = mod.callback;
+    reified = [];
+    exports;
+
+    for (var i=0, l=deps.length; i&lt;l; i++) {
+      if (deps[i] === 'exports') {
+        reified.push(exports = {});
+      } else {
+        reified.push(requireModule(deps[i]));
+      }
+    }
+
+    var value = callback.apply(this, reified);
+    return seen[name] = exports || value;
+  };
+})();
+(function() {
+/**
+  @module ember-data
+*/
+
+/**
+  All Ember Data methods and functions are defined inside of this namespace.
+
+  @class DS
+  @static
+*/
+var DS;
+if ('undefined' === typeof DS) {
+  /**
+    @property VERSION
+    @type String
+    @default '1.0.0-beta.6'
+    @static
+  */
+  DS = Ember.Namespace.create({
+    VERSION: '1.0.0-beta.6'
+  });
+
+  if ('undefined' !== typeof window) {
+    window.DS = DS;
+  }
+
+  if (Ember.libraries) {
+    Ember.libraries.registerCoreLibrary('Ember Data', DS.VERSION);
+  }
+}
+
+})();
+
+
+
+(function() {
+/**
+  This is used internally to enable deprecation of container paths and provide
+  a decent message to the user indicating how to fix the issue.
+
+  @class ContainerProxy
+  @namespace DS
+  @private
+*/
+var ContainerProxy = function (container){
+  this.container = container;
+};
+
+ContainerProxy.prototype.aliasedFactory = function(path, preLookup) {
+  var _this = this;
+
+  return {create: function(){ 
+    if (preLookup) { preLookup(); }
+
+    return _this.container.lookup(path); 
+  }};
+};
+
+ContainerProxy.prototype.registerAlias = function(source, dest, preLookup) {
+  var factory = this.aliasedFactory(dest, preLookup);
+
+  return this.container.register(source, factory);
+};
+
+ContainerProxy.prototype.registerDeprecation = function(deprecated, valid) {
+  var preLookupCallback = function(){
+    Ember.deprecate(&quot;You tried to look up '&quot; + deprecated + &quot;', &quot; +
+                    &quot;but this has been deprecated in favor of '&quot; + valid + &quot;'.&quot;, false);
+  };
+
+  return this.registerAlias(deprecated, valid, preLookupCallback);
+};
+
+ContainerProxy.prototype.registerDeprecations = function(proxyPairs) {
+  for (var i = proxyPairs.length; i &gt; 0; i--) {
+    var proxyPair = proxyPairs[i - 1],
+        deprecated = proxyPair['deprecated'],
+        valid = proxyPair['valid'];
+
+    this.registerDeprecation(deprecated, valid);
+  }
+};
+
+DS.ContainerProxy = ContainerProxy;
+
+})();
+
+
+
+(function() {
+var get = Ember.get, set = Ember.set, isNone = Ember.isNone;
+
+// Simple dispatcher to support overriding the aliased
+// method in subclasses.
+function aliasMethod(methodName) {
+  return function() {
+    return this[methodName].apply(this, arguments);
+  };
+}
+
+/**
+  In Ember Data a Serializer is used to serialize and deserialize
+  records when they are transferred in and out of an external source.
+  This process involves normalizing property names, transforming
+  attribute values and serializing relationships.
+
+  For maximum performance Ember Data recommends you use the
+  [RESTSerializer](DS.RESTSerializer.html) or one of its subclasses.
+
+  `JSONSerializer` is useful for simpler or legacy backends that may
+  not support the http://jsonapi.org/ spec.
+
+  @class JSONSerializer
+  @namespace DS
+*/
+DS.JSONSerializer = Ember.Object.extend({
+  /**
+    The primaryKey is used when serializing and deserializing
+    data. Ember Data always uses the `id` property to store the id of
+    the record. The external source may not always follow this
+    convention. In these cases it is useful to override the
+    primaryKey property to match the primaryKey of your external
+    store.
+
+    Example
+
+    ```javascript
+    App.ApplicationSerializer = DS.JSONSerializer.extend({
+      primaryKey: '_id'
+    });
+    ```
+
+    @property primaryKey
+    @type {String}
+    @default 'id'
+  */
+  primaryKey: 'id',
+
+  /**
+   Given a subclass of `DS.Model` and a JSON object this method will
+   iterate through each attribute of the `DS.Model` and invoke the
+   `DS.Transform#deserialize` method on the matching property of the
+   JSON object.  This method is typically called after the
+   serializer's `normalize` method.
+
+   @method applyTransforms
+   @private
+   @param {subclass of DS.Model} type
+   @param {Object} data The data to transform
+   @return {Object} data The transformed data object
+  */
+  applyTransforms: function(type, data) {
+    type.eachTransformedAttribute(function(key, type) {
+      var transform = this.transformFor(type);
+      data[key] = transform.deserialize(data[key]);
+    }, this);
+
+    return data;
+  },
+
+  /**
+    Normalizes a part of the JSON payload returned by
+    the server. You should override this method, munge the hash
+    and call super if you have generic normalization to do.
+
+    It takes the type of the record that is being normalized
+    (as a DS.Model class), the property where the hash was
+    originally found, and the hash to normalize.
+
+    You can use this method, for example, to normalize underscored keys to camelized
+    or other general-purpose normalizations.
+
+    Example
+
+    ```javascript
+    App.ApplicationSerializer = DS.JSONSerializer.extend({
+      normalize: function(type, hash) {
+        var fields = Ember.get(type, 'fields');
+        fields.forEach(function(field) {
+          var payloadField = Ember.String.underscore(field);
+          if (field === payloadField) { return; }
+
+          hash[field] = hash[payloadField];
+          delete hash[payloadField];
+        });
+        return this._super.apply(this, arguments);
+      }
+    });
+    ```
+
+    @method normalize
+    @param {subclass of DS.Model} type
+    @param {Object} hash
+    @return {Object}
+  */
+  normalize: function(type, hash) {
+    if (!hash) { return hash; }
+
+    this.applyTransforms(type, hash);
+    return hash;
+  },
+
+  // 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
+    {
+      &quot;title&quot;: &quot;Rails is unagi&quot;,
+      &quot;body&quot;: &quot;Rails? Omakase? O_O&quot;,
+      &quot;author&quot;: 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()) + &quot;_IDS&quot;;
+    }
+    ```
+
+    This serializer will generate JSON that looks like this:
+
+    ```javascript
+    {
+      &quot;TITLE&quot;: &quot;Rails is omakase&quot;,
+      &quot;BODY&quot;: &quot;Yep. Omakase.&quot;,
+      &quot;COMMENT_IDS&quot;: [ 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: function(record, options) {
+    var json = {};
+
+    if (options &amp;&amp; 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;
+  },
+
+  /**
+   `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: 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 &amp;&amp; attrs[key] || (this.keyForAttribute ? this.keyForAttribute(key) : key);
+
+    json[key] = value;
+  },
+
+  /**
+   `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, &quot;belongsTo&quot;) : key;
+
+       json[key] = Ember.isNone(belongsTo) ? belongsTo : belongsTo.toJSON();
+     }
+   });
+   ```
+
+   @method serializeBelongsTo
+   @param {DS.Model} record
+   @param {Object} json
+   @param {Object} relationship
+  */
+  serializeBelongsTo: function(record, json, relationship) {
+    var key = relationship.key;
+
+    var belongsTo = get(record, key);
+
+    key = this.keyForRelationship ? this.keyForRelationship(key, &quot;belongsTo&quot;) : key;
+
+    if (isNone(belongsTo)) {
+      json[key] = belongsTo;
+    } else {
+      json[key] = get(belongsTo, 'id');
+    }
+
+    if (relationship.options.polymorphic) {
+      this.serializePolymorphicType(record, json, relationship);
+    }
+  },
+
+  /**
+   `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: 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
+    }
+  },
+
+  /**
+    You can use this method to customize how polymorphic objects are
+    serialized. Objects are considered to be polymorphic if
+    `{polymorphic: true}` is pass as the second argument to the
+    `DS.belongsTo` function.
+
+    Example
+
+    ```javascript
+    App.CommentSerializer = DS.JSONSerializer.extend({
+      serializePolymorphicType: function(record, json, relationship) {
+        var key = relationship.key,
+            belongsTo = get(record, key);
+        key = this.keyForAttribute ? this.keyForAttribute(key) : key;
+        json[key + &quot;_type&quot;] = belongsTo.constructor.typeKey;
+      }
+    });
+   ```
+
+    @method serializePolymorphicType
+    @param {DS.Model} record
+    @param {Object} json
+    @param {Object} relationship
+  */
+  serializePolymorphicType: Ember.K,
+
+  // 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 delegates 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: function(store, type, payload, id, requestType) {
+    this.extractMeta(store, type, payload);
+
+    var specificExtract = &quot;extract&quot; + requestType.charAt(0).toUpperCase() + requestType.substr(1);
+    return this[specificExtract](store, type, payload, id, requestType);
+  },
+
+  /**
+    `extractFindAll` is a hook into the extract method used when a
+    call is made to `DS.Store#findAll`. By default this method is an
+    alias for [extractArray](#method_extractArray).
+
+    @method extractFindAll
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} payload
+    @return {Array} array An array of deserialized objects
+  */
+  extractFindAll: aliasMethod('extractArray'),
+  /**
+    `extractFindQuery` is a hook into the extract method used when a
+    call is made to `DS.Store#findQuery`. By default this method is an
+    alias for [extractArray](#method_extractArray).
+
+    @method extractFindQuery
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} payload
+    @return {Array} array An array of deserialized objects
+  */
+  extractFindQuery: aliasMethod('extractArray'),
+  /**
+    `extractFindMany` is a hook into the extract method used when a
+    call is made to `DS.Store#findMany`. By default this method is
+    alias for [extractArray](#method_extractArray).
+
+    @method extractFindMany
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} payload
+    @return {Array} array An array of deserialized objects
+  */
+  extractFindMany: aliasMethod('extractArray'),
+  /**
+    `extractFindHasMany` is a hook into the extract method used when a
+    call is made to `DS.Store#findHasMany`. By default this method is
+    alias for [extractArray](#method_extractArray).
+
+    @method extractFindHasMany
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} payload
+    @return {Array} array An array of deserialized objects
+  */
+  extractFindHasMany: aliasMethod('extractArray'),
+
+  /**
+    `extractCreateRecord` is a hook into the extract method used when a
+    call is made to `DS.Store#createRecord`. By default this method is
+    alias for [extractSave](#method_extractSave).
+
+    @method extractCreateRecord
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} payload
+    @return {Object} json The deserialized payload
+  */
+  extractCreateRecord: aliasMethod('extractSave'),
+  /**
+    `extractUpdateRecord` is a hook into the extract method used when
+    a call is made to `DS.Store#update`. By default this method is alias
+    for [extractSave](#method_extractSave).
+
+    @method extractUpdateRecord
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} payload
+    @return {Object} json The deserialized payload
+  */
+  extractUpdateRecord: aliasMethod('extractSave'),
+  /**
+    `extractDeleteRecord` is a hook into the extract method used when
+    a call is made to `DS.Store#deleteRecord`. By default this method is
+    alias for [extractSave](#method_extractSave).
+
+    @method extractDeleteRecord
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} payload
+    @return {Object} json The deserialized payload
+  */
+  extractDeleteRecord: aliasMethod('extractSave'),
+
+  /**
+    `extractFind` is a hook into the extract method used when
+    a call is made to `DS.Store#find`. By default this method is
+    alias for [extractSingle](#method_extractSingle).
+
+    @method extractFind
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} payload
+    @return {Object} json The deserialized payload
+  */
+  extractFind: aliasMethod('extractSingle'),
+  /**
+    `extractFindBelongsTo` is a hook into the extract method used when
+    a call is made to `DS.Store#findBelongsTo`. By default this method is
+    alias for [extractSingle](#method_extractSingle).
+
+    @method extractFindBelongsTo
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} payload
+    @return {Object} json The deserialized payload
+  */
+  extractFindBelongsTo: aliasMethod('extractSingle'),
+  /**
+    `extractSave` is a hook into the extract method used when a call
+    is made to `DS.Model#save`. By default this method is alias
+    for [extractSingle](#method_extractSingle).
+
+    @method extractSave
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} payload
+    @return {Object} json The deserialized payload
+  */
+  extractSave: aliasMethod('extractSingle'),
+
+  /**
+    `extractSingle` is used to deserialize a single record returned
+    from the adapter.
+
+    Example
+
+    ```javascript
+    App.PostSerializer = DS.JSONSerializer.extend({
+      extractSingle: function(store, type, payload) {
+        payload.comments = payload._embedded.comment;
+        delete payload._embedded;
+
+        return this._super(store, type, payload);
+      },
+    });
+    ```
+
+    @method extractSingle
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} payload
+    @return {Object} json The deserialized payload
+  */
+  extractSingle: function(store, type, payload) {
+    return this.normalize(type, payload);
+  },
+
+  /**
+    `extractArray` is used to deserialize an array of records
+    returned from the adapter.
+
+    Example
+
+    ```javascript
+    App.PostSerializer = DS.JSONSerializer.extend({
+      extractArray: function(store, type, payload) {
+        return payload.map(function(json) {
+          return this.extractSingle(json);
+        }, this);
+      }
+    });
+    ```
+
+    @method extractArray
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} payload
+    @return {Array} array An array of deserialized objects
+  */
+  extractArray: function(store, type, payload) {
+    return this.normalize(type, 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.
+
+    Example
+
+    ```javascript
+    App.PostSerializer = DS.JSONSerializer.extend({
+      extractMeta: function(store, type, payload) {
+        if (payload &amp;&amp; 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: function(store, type, payload) {
+    if (payload &amp;&amp; payload.meta) {
+      store.metaForType(type, payload.meta);
+      delete payload.meta;
+    }
+  },
+
+  /**
+   `keyForAttribute` can be used to define rules for how to convert an
+   attribute name in your model to a key in your JSON.
+
+   Example
+
+   ```javascript
+   App.ApplicationSerializer = DS.RESTSerializer.extend({
+     keyForAttribute: function(attr) {
+       return Ember.String.underscore(attr).toUpperCase();
+     }
+   });
+   ```
+
+   @method keyForAttribute
+   @param {String} key
+   @return {String} normalized key
+  */
+
+
+  /**
+   `keyForRelationship` can be used to define a custom key when
+   serializing relationship properties. By default `JSONSerializer`
+   does not provide an implementation of this method.
+
+   Example
+
+    ```javascript
+    App.PostSerializer = DS.JSONSerializer.extend({
+      keyForRelationship: function(key, relationship) {
+         return 'rel_' + Ember.String.underscore(key);
+      }
+    });
+    ```
+
+   @method keyForRelationship
+   @param {String} key
+   @param {String} relationship type
+   @return {String} normalized key
+  */
+
+  // HELPERS
+
+  /**
+   @method transformFor
+   @private
+   @param {String} attributeType
+   @param {Boolean} skipAssertion
+   @return {DS.Transform} transform
+  */
+  transformFor: function(attributeType, skipAssertion) {
+    var transform = this.container.lookup('transform:' + attributeType);
+    Ember.assert(&quot;Unable to find transform for '&quot; + attributeType + &quot;'&quot;, skipAssertion || !!transform);
+    return transform;
+  }
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+var get = Ember.get, capitalize = Ember.String.capitalize, underscore = Ember.String.underscore, DS = window.DS ;
+
+/**
+  Extend `Ember.DataAdapter` with ED specific code.
+
+  @class DebugAdapter
+  @namespace DS
+  @extends Ember.DataAdapter
+  @private
+*/
+DS.DebugAdapter = Ember.DataAdapter.extend({
+  getFilters: function() {
+    return [
+      { name: 'isNew', desc: 'New' },
+      { name: 'isModified', desc: 'Modified' },
+      { name: 'isClean', desc: 'Clean' }
+    ];
+  },
+
+  detect: function(klass) {
+    return klass !== DS.Model &amp;&amp; DS.Model.detect(klass);
+  },
+
+  columnsForType: function(type) {
+    var columns = [{ name: 'id', desc: 'Id' }], count = 0, self = this;
+    get(type, 'attributes').forEach(function(name, meta) {
+        if (count++ &gt; self.attributeLimit) { return false; }
+        var desc = capitalize(underscore(name).replace('_', ' '));
+        columns.push({ name: name, desc: desc });
+    });
+    return columns;
+  },
+
+  getRecords: function(type) {
+    return this.get('store').all(type);
+  },
+
+  getRecordColumnValues: function(record) {
+    var self = this, count = 0,
+        columnValues = { id: get(record, 'id') };
+
+    record.eachAttribute(function(key) {
+      if (count++ &gt; self.attributeLimit) {
+        return false;
+      }
+      var value = get(record, key);
+      columnValues[key] = value;
+    });
+    return columnValues;
+  },
+
+  getRecordKeywords: function(record) {
+    var keywords = [], keys = Ember.A(['id']);
+    record.eachAttribute(function(key) {
+      keys.push(key);
+    });
+    keys.forEach(function(key) {
+      keywords.push(get(record, key));
+    });
+    return keywords;
+  },
+
+  getRecordFilterValues: function(record) {
+    return {
+      isNew: record.get('isNew'),
+      isModified: record.get('isDirty') &amp;&amp; !record.get('isNew'),
+      isClean: !record.get('isDirty')
+    };
+  },
+
+  getRecordColor: function(record) {
+    var color = 'black';
+    if (record.get('isNew')) {
+      color = 'green';
+    } else if (record.get('isDirty')) {
+      color = 'blue';
+    }
+    return color;
+  },
+
+  observeRecord: function(record, recordUpdated) {
+    var releaseMethods = Ember.A(), self = this,
+        keysToObserve = Ember.A(['id', 'isNew', 'isDirty']);
+
+    record.eachAttribute(function(key) {
+      keysToObserve.push(key);
+    });
+
+    keysToObserve.forEach(function(key) {
+      var handler = function() {
+        recordUpdated(self.wrapRecord(record));
+      };
+      Ember.addObserver(record, key, handler);
+      releaseMethods.push(function() {
+        Ember.removeObserver(record, key, handler);
+      });
+    });
+
+    var release = function() {
+      releaseMethods.forEach(function(fn) { fn(); } );
+    };
+
+    return release;
+  }
+
+});
+
+})();
+
+
+
+(function() {
+/**
+  The `DS.Transform` class is used to serialize and deserialize model
+  attributes when they are saved or loaded from an
+  adapter. Subclassing `DS.Transform` is useful for creating custom
+  attributes. All subclasses of `DS.Transform` must implement a
+  `serialize` and a `deserialize` method.
+
+  Example
+
+  ```javascript
+  App.RawTransform = DS.Transform.extend({
+    deserialize: function(serialized) {
+      return serialized;
+    },
+    serialize: function(deserialized) {
+      return deserialized;
+    }
+  });
+  ```
+
+  Usage
+
+  ```javascript
+  var attr = DS.attr;
+  App.Requirement = DS.Model.extend({
+    name: attr('string'),
+    optionsArray: attr('raw')
+  });
+  ```
+
+  @class Transform
+  @namespace DS
+ */
+DS.Transform = Ember.Object.extend({
+  /**
+    When given a deserialized value from a record attribute this
+    method must return the serialized value.
+
+    Example
+
+    ```javascript
+    serialize: function(deserialized) {
+      return Ember.isEmpty(deserialized) ? null : Number(deserialized);
+    }
+    ```
+
+    @method serialize
+    @param deserialized The deserialized value
+    @return The serialized value
+  */
+  serialize: Ember.required(),
+
+  /**
+    When given a serialize value from a JSON object this method must
+    return the deserialized value for the record attribute.
+
+    Example
+
+    ```javascript
+    deserialize: function(serialized) {
+      return empty(serialized) ? null : Number(serialized);
+    }
+    ```
+
+    @method deserialize
+    @param serialized The serialized value
+    @return The deserialized value
+  */
+  deserialize: Ember.required()
+
+});
+
+})();
+
+
+
+(function() {
+
+/**
+  The `DS.BooleanTransform` class is used to serialize and deserialize
+  boolean attributes on Ember Data record objects. This transform is
+  used when `boolean` is passed as the type parameter to the
+  [DS.attr](../../data#method_attr) function.
+
+  Usage
+
+  ```javascript
+  var attr = DS.attr;
+  App.User = DS.Model.extend({
+    isAdmin: attr('boolean'),
+    name: attr('string'),
+    email: attr('string')
+  });
+  ```
+
+  @class BooleanTransform
+  @extends DS.Transform
+  @namespace DS
+ */
+DS.BooleanTransform = DS.Transform.extend({
+  deserialize: function(serialized) {
+    var type = typeof serialized;
+
+    if (type === &quot;boolean&quot;) {
+      return serialized;
+    } else if (type === &quot;string&quot;) {
+      return serialized.match(/^true$|^t$|^1$/i) !== null;
+    } else if (type === &quot;number&quot;) {
+      return serialized === 1;
+    } else {
+      return false;
+    }
+  },
+
+  serialize: function(deserialized) {
+    return Boolean(deserialized);
+  }
+});
+
+})();
+
+
+
+(function() {
+/**
+  The `DS.DateTransform` class is used to serialize and deserialize
+  date attributes on Ember Data record objects. This transform is used
+  when `date` is passed as the type parameter to the
+  [DS.attr](../../data#method_attr) function.
+
+  ```javascript
+  var attr = DS.attr;
+  App.Score = DS.Model.extend({
+    value: attr('number'),
+    player: DS.belongsTo('player'),
+    date: attr('date')
+  });
+  ```
+
+  @class DateTransform
+  @extends DS.Transform
+  @namespace DS
+ */
+DS.DateTransform = DS.Transform.extend({
+
+  deserialize: function(serialized) {
+    var type = typeof serialized;
+
+    if (type === &quot;string&quot;) {
+      return new Date(Ember.Date.parse(serialized));
+    } else if (type === &quot;number&quot;) {
+      return new Date(serialized);
+    } else if (serialized === null || serialized === undefined) {
+      // if the value is not present in the data,
+      // return undefined, not null.
+      return serialized;
+    } else {
+      return null;
+    }
+  },
+
+  serialize: function(date) {
+    if (date instanceof Date) {
+      // Serialize it as a number to maintain millisecond precision
+      return Number(date);
+    } else {
+      return null;
+    }
+  }
+
+});
+
+})();
+
+
+
+(function() {
+var empty = Ember.isEmpty;
+/**
+  The `DS.NumberTransform` class is used to serialize and deserialize
+  numeric attributes on Ember Data record objects. This transform is
+  used when `number` is passed as the type parameter to the
+  [DS.attr](../../data#method_attr) function.
+
+  Usage
+
+  ```javascript
+  var attr = DS.attr;
+  App.Score = DS.Model.extend({
+    value: attr('number'),
+    player: DS.belongsTo('player'),
+    date: attr('date')
+  });
+  ```
+
+  @class NumberTransform
+  @extends DS.Transform
+  @namespace DS
+ */
+DS.NumberTransform = DS.Transform.extend({
+
+  deserialize: function(serialized) {
+    return empty(serialized) ? null : Number(serialized);
+  },
+
+  serialize: function(deserialized) {
+    return empty(deserialized) ? null : Number(deserialized);
+  }
+});
+
+})();
+
+
+
+(function() {
+var none = Ember.isNone;
+
+/**
+  The `DS.StringTransform` class is used to serialize and deserialize
+  string attributes on Ember Data record objects. This transform is
+  used when `string` is passed as the type parameter to the
+  [DS.attr](../../data#method_attr) function.
+
+  Usage
+
+  ```javascript
+  var attr = DS.attr;
+  App.User = DS.Model.extend({
+    isAdmin: attr('boolean'),
+    name: attr('string'),
+    email: attr('string')
+  });
+  ```
+
+  @class StringTransform
+  @extends DS.Transform
+  @namespace DS
+ */
+DS.StringTransform = DS.Transform.extend({
+
+  deserialize: function(serialized) {
+    return none(serialized) ? null : String(serialized);
+  },
+
+  serialize: function(deserialized) {
+    return none(deserialized) ? null : String(deserialized);
+  }
+
+});
+
+})();
+
+
+
+(function() {
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var set = Ember.set;
+
+/*
+  This code registers an injection for Ember.Application.
+
+  If an Ember.js developer defines a subclass of DS.Store on their application,
+  this code will automatically instantiate it and make it available on the
+  router.
+
+  Additionally, after an application's controllers have been injected, they will
+  each have the store made available to them.
+
+  For example, imagine an Ember.js application with the following classes:
+
+  App.Store = DS.Store.extend({
+    adapter: 'custom'
+  });
+
+  App.PostsController = Ember.ArrayController.extend({
+    // ...
+  });
+
+  When the application is initialized, `App.Store` will automatically be
+  instantiated, and the instance of `App.PostsController` will have its `store`
+  property set to that instance.
+
+  Note that this code will only be run if the `ember-application` package is
+  loaded. If Ember Data is being used in an environment other than a
+  typical application (e.g., node.js where only `ember-runtime` is available),
+  this code will be ignored.
+*/
+
+Ember.onLoad('Ember.Application', function(Application) {
+  Application.initializer({
+    name: &quot;store&quot;,
+
+    initialize: function(container, application) {
+      application.register('store:main', application.Store || DS.Store);
+
+      // allow older names to be looked up
+
+      var proxy = new DS.ContainerProxy(container);
+      proxy.registerDeprecations([
+        {deprecated: 'serializer:_default',  valid: 'serializer:-default'},
+        {deprecated: 'serializer:_rest',     valid: 'serializer:-rest'},
+        {deprecated: 'adapter:_rest',        valid: 'adapter:-rest'}
+      ]);
+
+      // new go forward paths
+      application.register('serializer:-default', DS.JSONSerializer);
+      application.register('serializer:-rest', DS.RESTSerializer);
+      application.register('adapter:-rest', DS.RESTAdapter);
+
+      // Eagerly generate the store so defaultStore is populated.
+      // TODO: Do this in a finisher hook
+      container.lookup('store:main');
+    }
+  });
+
+  Application.initializer({
+    name: &quot;transforms&quot;,
+    before: &quot;store&quot;,
+
+    initialize: function(container, application) {
+      application.register('transform:boolean', DS.BooleanTransform);
+      application.register('transform:date', DS.DateTransform);
+      application.register('transform:number', DS.NumberTransform);
+      application.register('transform:string', DS.StringTransform);
+    }
+  });
+
+  Application.initializer({
+    name: &quot;data-adapter&quot;,
+    before: &quot;store&quot;,
+
+    initialize: function(container, application) {
+      application.register('data-adapter:main', DS.DebugAdapter);
+    }
+  });
+
+  Application.initializer({
+    name: &quot;injectStore&quot;,
+    before: &quot;store&quot;,
+
+    initialize: function(container, application) {
+      application.inject('controller', 'store', 'store:main');
+      application.inject('route', 'store', 'store:main');
+      application.inject('serializer', 'store', 'store:main');
+      application.inject('data-adapter', 'store', 'store:main');
+    }
+  });
+
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+/**
+  Date.parse with progressive enhancement for ISO 8601 &lt;https://github.com/csnover/js-iso8601&gt;
+
+  © 2011 Colin Snover &lt;http://zetafleet.com&gt;
+
+  Released under MIT license.
+
+  @class Date
+  @namespace Ember
+  @static
+*/
+Ember.Date = Ember.Date || {};
+
+var origParse = Date.parse, numericKeys = [ 1, 4, 5, 6, 7, 10, 11 ];
+
+/**
+  @method parse
+  @param date
+*/
+Ember.Date.parse = function (date) {
+    var timestamp, struct, minutesOffset = 0;
+
+    // ES5 §15.9.4.2 states that the string should attempt to be parsed as a Date Time String Format string
+    // before falling back to any implementation-specific date parsing, so that’s what we do, even if native
+    // implementations could be faster
+    //              1 YYYY                2 MM       3 DD           4 HH    5 mm       6 ss        7 msec        8 Z 9 ±    10 tzHH    11 tzmm
+    if ((struct = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(date))) {
+        // avoid NaN timestamps caused by “undefined” values being passed to Date.UTC
+        for (var i = 0, k; (k = numericKeys[i]); ++i) {
+            struct[k] = +struct[k] || 0;
+        }
+
+        // allow undefined days and months
+        struct[2] = (+struct[2] || 1) - 1;
+        struct[3] = +struct[3] || 1;
+
+        if (struct[8] !== 'Z' &amp;&amp; struct[9] !== undefined) {
+            minutesOffset = struct[10] * 60 + struct[11];
+
+            if (struct[9] === '+') {
+                minutesOffset = 0 - minutesOffset;
+            }
+        }
+
+        timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
+    }
+    else {
+        timestamp = origParse ? origParse(date) : NaN;
+    }
+
+    return timestamp;
+};
+
+if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Date) {
+  Date.parse = Ember.Date.parse;
+}
+
+})();
+
+
+
+(function() {
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var get = Ember.get, set = Ember.set;
+
+/**
+  A record array is an array that contains records of a certain type. The record
+  array materializes records as needed when they are retrieved for the first
+  time. You should not create record arrays yourself. Instead, an instance of
+  `DS.RecordArray` or its subclasses will be returned by your application's store
+  in response to queries.
+
+  @class RecordArray
+  @namespace DS
+  @extends Ember.ArrayProxy
+  @uses Ember.Evented
+*/
+
+DS.RecordArray = Ember.ArrayProxy.extend(Ember.Evented, {
+  /**
+    The model type contained by this record array.
+
+    @property type
+    @type DS.Model
+  */
+  type: null,
+
+  /**
+    The array of client ids backing the record array. When a
+    record is requested from the record array, the record
+    for the client id at the same index is materialized, if
+    necessary, by the store.
+
+    @property content
+    @private
+    @type Ember.Array
+  */
+  content: null,
+
+  /**
+    The flag to signal a `RecordArray` is currently loading data.
+
+    Example
+
+    ```javascript
+    var people = store.all(App.Person);
+    people.get('isLoaded'); // true
+    ```
+
+    @property isLoaded
+    @type Boolean
+  */
+  isLoaded: false,
+  /**
+    The flag to signal a `RecordArray` is currently loading data.
+
+    Example
+
+    ```javascript
+    var people = store.all(App.Person);
+    people.get('isUpdating'); // false
+    people.update();
+    people.get('isUpdating'); // true
+    ```
+
+    @property isUpdating
+    @type Boolean
+  */
+  isUpdating: false,
+
+  /**
+    The store that created this record array.
+
+    @property store
+    @private
+    @type DS.Store
+  */
+  store: null,
+
+  /**
+    Retrieves an object from the content by index.
+
+    @method objectAtContent
+    @private
+    @param {Number} index
+    @return {DS.Model} record
+  */
+  objectAtContent: function(index) {
+    var content = get(this, 'content');
+
+    return content.objectAt(index);
+  },
+
+  /**
+    Used to get the latest version of all of the records in this array
+    from the adapter.
+
+    Example
+
+    ```javascript
+    var people = store.all(App.Person);
+    people.get('isUpdating'); // false
+    people.update();
+    people.get('isUpdating'); // true
+    ```
+
+    @method update
+  */
+  update: function() {
+    if (get(this, 'isUpdating')) { return; }
+
+    var store = get(this, 'store'),
+        type = get(this, 'type');
+
+    return store.fetchAll(type, this);
+  },
+
+  /**
+    Adds a record to the `RecordArray`.
+
+    @method addRecord
+    @private
+    @param {DS.Model} record
+  */
+  addRecord: function(record) {
+    get(this, 'content').addObject(record);
+  },
+
+  /**
+    Removes a record to the `RecordArray`.
+
+    @method removeRecord
+    @private
+    @param {DS.Model} record
+  */
+  removeRecord: function(record) {
+    get(this, 'content').removeObject(record);
+  },
+
+  /**
+    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
+  */
+  save: function() {
+    var promiseLabel = &quot;DS: RecordArray#save &quot; + get(this, 'type');
+    var promise = Ember.RSVP.all(this.invoke(&quot;save&quot;), promiseLabel).then(function(array) {
+      return Ember.A(array);
+    }, null, &quot;DS: RecordArray#save apply Ember.NativeArray&quot;);
+
+    return DS.PromiseArray.create({ promise: promise });
+  }
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var get = Ember.get;
+
+/**
+  Represents a list of records whose membership is determined by the
+  store. As records are created, loaded, or modified, the store
+  evaluates them to determine if they should be part of the record
+  array.
+
+  @class FilteredRecordArray
+  @namespace DS
+  @extends DS.RecordArray
+*/
+DS.FilteredRecordArray = DS.RecordArray.extend({
+  /**
+    The filterFunction is a function used to test records from the store to
+    determine if they should be part of the record array.
+
+    Example
+
+    ```javascript
+    var allPeople = store.all('person');
+    allPeople.mapBy('name'); // [&quot;Tom Dale&quot;, &quot;Yehuda Katz&quot;, &quot;Trek Glowacki&quot;]
+
+    var people = store.filter('person', function(person) {
+      if (person.get('name').match(/Katz$/)) { return true; }
+    });
+    people.mapBy('name'); // [&quot;Yehuda Katz&quot;]
+
+    var notKatzFilter = function(person) {
+      return !person.get('name').match(/Katz$/);
+    };
+    people.set('filterFunction', notKatzFilter);
+    people.mapBy('name'); // [&quot;Tom Dale&quot;, &quot;Trek Glowacki&quot;]
+    ```
+
+    @method filterFunction
+    @param {DS.Model} record
+    @return {Boolean} `true` if the record should be in the array
+  */
+  filterFunction: null,
+  isLoaded: true,
+
+  replace: function() {
+    var type = get(this, 'type').toString();
+    throw new Error(&quot;The result of a client-side filter (on &quot; + type + &quot;) is immutable.&quot;);
+  },
+
+  /**
+    @method updateFilter
+    @private
+  */
+  updateFilter: Ember.observer(function() {
+    var manager = get(this, 'manager');
+    manager.updateFilter(this, get(this, 'type'), get(this, 'filterFunction'));
+  }, 'filterFunction')
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var get = Ember.get, set = Ember.set;
+
+/**
+  Represents an ordered list of records whose order and membership is
+  determined by the adapter. For example, a query sent to the adapter
+  may trigger a search on the server, whose results would be loaded
+  into an instance of the `AdapterPopulatedRecordArray`.
+
+  @class AdapterPopulatedRecordArray
+  @namespace DS
+  @extends DS.RecordArray
+*/
+DS.AdapterPopulatedRecordArray = DS.RecordArray.extend({
+  query: null,
+
+  replace: function() {
+    var type = get(this, 'type').toString();
+    throw new Error(&quot;The result of a server query (on &quot; + type + &quot;) is immutable.&quot;);
+  },
+
+  /**
+    @method load
+    @private
+    @param {Array} data
+  */
+  load: function(data) {
+    var store = get(this, 'store'),
+        type = get(this, 'type'),
+        records = store.pushMany(type, data),
+        meta = store.metadataFor(type);
+
+    this.setProperties({
+      content: Ember.A(records),
+      isLoaded: true,
+      meta: meta
+    });
+
+    // TODO: does triggering didLoad event should be the last action of the runLoop?
+    Ember.run.once(this, 'trigger', 'didLoad');
+  }
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var get = Ember.get, set = Ember.set;
+var map = Ember.EnumerableUtils.map;
+
+/**
+  A `ManyArray` is a `RecordArray` that represents the contents of a has-many
+  relationship.
+
+  The `ManyArray` is instantiated lazily the first time the relationship is
+  requested.
+
+  ### Inverses
+
+  Often, the relationships in Ember Data applications will have
+  an inverse. For example, imagine the following models are
+  defined:
+
+  ```javascript
+  App.Post = DS.Model.extend({
+    comments: DS.hasMany('comment')
+  });
+
+  App.Comment = DS.Model.extend({
+    post: DS.belongsTo('post')
+  });
+  ```
+
+  If you created a new instance of `App.Post` and added
+  a `App.Comment` record to its `comments` has-many
+  relationship, you would expect the comment's `post`
+  property to be set to the post that contained
+  the has-many.
+
+  We call the record to which a relationship belongs the
+  relationship's _owner_.
+
+  @class ManyArray
+  @namespace DS
+  @extends DS.RecordArray
+*/
+DS.ManyArray = DS.RecordArray.extend({
+  init: function() {
+    this._super.apply(this, arguments);
+    this._changesToSync = Ember.OrderedSet.create();
+  },
+
+  /**
+    The property name of the relationship
+
+    @property {String} name
+    @private
+  */
+  name: null,
+
+  /**
+    The record to which this relationship belongs.
+
+    @property {DS.Model} owner
+    @private
+  */
+  owner: null,
+
+  /**
+    `true` if the relationship is polymorphic, `false` otherwise.
+
+    @property {Boolean} isPolymorphic
+    @private
+  */
+  isPolymorphic: false,
+
+  // LOADING STATE
+
+  isLoaded: false,
+
+  /**
+    Used for async `hasMany` arrays
+    to keep track of when they will resolve.
+
+    @property {Ember.RSVP.Promise} promise
+    @private
+  */
+  promise: null,
+
+  /**
+    @method loadingRecordsCount
+    @param {Number} count
+    @private
+  */
+  loadingRecordsCount: function(count) {
+    this.loadingRecordsCount = count;
+  },
+
+  /**
+    @method loadedRecord
+    @private
+  */
+  loadedRecord: function() {
+    this.loadingRecordsCount--;
+    if (this.loadingRecordsCount === 0) {
+      set(this, 'isLoaded', true);
+      this.trigger('didLoad');
+    }
+  },
+
+  /**
+    @method fetch
+    @private
+  */
+  fetch: function() {
+    var records = get(this, 'content'),
+        store = get(this, 'store'),
+        owner = get(this, 'owner'),
+        resolver = Ember.RSVP.defer(&quot;DS: ManyArray#fetch &quot; + get(this, 'type'));
+
+    var unloadedRecords = records.filterProperty('isEmpty', true);
+    store.fetchMany(unloadedRecords, owner, resolver);
+  },
+
+  // Overrides Ember.Array's replace method to implement
+  replaceContent: function(index, removed, added) {
+    // Map the array of record objects into an array of  client ids.
+    added = map(added, function(record) {
+      Ember.assert(&quot;You cannot add '&quot; + record.constructor.typeKey + &quot;' records to this relationship (only '&quot; + this.type.typeKey + &quot;' allowed)&quot;, !this.type || record instanceof this.type);
+      return record;
+    }, this);
+
+    this._super(index, removed, added);
+  },
+
+  arrangedContentDidChange: function() {
+    Ember.run.once(this, 'fetch');
+  },
+
+  arrayContentWillChange: function(index, removed, added) {
+    var owner = get(this, 'owner'),
+        name = get(this, 'name');
+
+    if (!owner._suspendedRelationships) {
+      // This code is the first half of code that continues inside
+      // of arrayContentDidChange. It gets or creates a change from
+      // the child object, adds the current owner as the old
+      // parent if this is the first time the object was removed
+      // from a ManyArray, and sets `newParent` to null.
+      //
+      // Later, if the object is added to another ManyArray,
+      // the `arrayContentDidChange` will set `newParent` on
+      // the change.
+      for (var i=index; i&lt;index+removed; i++) {
+        var record = get(this, 'content').objectAt(i);
+
+        var change = DS.RelationshipChange.createChange(owner, record, get(this, 'store'), {
+          parentType: owner.constructor,
+          changeType: &quot;remove&quot;,
+          kind: &quot;hasMany&quot;,
+          key: name
+        });
+
+        this._changesToSync.add(change);
+      }
+    }
+
+    return this._super.apply(this, arguments);
+  },
+
+  arrayContentDidChange: function(index, removed, added) {
+    this._super.apply(this, arguments);
+
+    var owner = get(this, 'owner'),
+        name = get(this, 'name'),
+        store = get(this, 'store');
+
+    if (!owner._suspendedRelationships) {
+      // This code is the second half of code that started in
+      // `arrayContentWillChange`. It gets or creates a change
+      // from the child object, and adds the current owner as
+      // the new parent.
+      for (var i=index; i&lt;index+added; i++) {
+        var record = get(this, 'content').objectAt(i);
+
+        var change = DS.RelationshipChange.createChange(owner, record, store, {
+          parentType: owner.constructor,
+          changeType: &quot;add&quot;,
+          kind:&quot;hasMany&quot;,
+          key: name
+        });
+        change.hasManyName = name;
+
+        this._changesToSync.add(change);
+      }
+
+      // We wait until the array has finished being
+      // mutated before syncing the OneToManyChanges created
+      // in arrayContentWillChange, so that the array
+      // membership test in the sync() logic operates
+      // on the final results.
+      this._changesToSync.forEach(function(change) {
+        change.sync();
+      });
+
+      this._changesToSync.clear();
+    }
+  },
+
+  /**
+    Create a child record within the owner
+
+    @method createRecord
+    @private
+    @param {Object} hash
+    @return {DS.Model} record
+  */
+  createRecord: function(hash) {
+    var owner = get(this, 'owner'),
+        store = get(owner, 'store'),
+        type = get(this, 'type'),
+        record;
+
+    Ember.assert(&quot;You cannot add '&quot; + type.typeKey + &quot;' records to this polymorphic relationship.&quot;, !get(this, 'isPolymorphic'));
+
+    record = store.createRecord.call(store, type, hash);
+    this.pushObject(record);
+
+    return record;
+  }
+
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+})();
+
+
+
+(function() {
+/*globals Ember*/
+/*jshint eqnull:true*/
+/**
+  @module ember-data
+*/
+
+var get = Ember.get, set = Ember.set;
+var once = Ember.run.once;
+var isNone = Ember.isNone;
+var forEach = Ember.EnumerableUtils.forEach;
+var indexOf = Ember.EnumerableUtils.indexOf;
+var map = Ember.EnumerableUtils.map;
+var resolve = Ember.RSVP.resolve;
+var copy = Ember.copy;
+
+// Implementors Note:
+//
+//   The variables in this file are consistently named according to the following
+//   scheme:
+//
+//   * +id+ means an identifier managed by an external source, provided inside
+//     the data provided by that source. These are always coerced to be strings
+//     before being used internally.
+//   * +clientId+ means a transient numerical identifier generated at runtime by
+//     the data store. It is important primarily because newly created objects may
+//     not yet have an externally generated id.
+//   * +reference+ means a record reference object, which holds metadata about a
+//     record, even if it has not yet been fully materialized.
+//   * +type+ means a subclass of DS.Model.
+
+// Used by the store to normalize IDs entering the store.  Despite the fact
+// that developers may provide IDs as numbers (e.g., `store.find(Person, 1)`),
+// it is important that internally we use strings, since IDs may be serialized
+// and lose type information.  For example, Ember's router may put a record's
+// ID into the URL, and if we later try to deserialize that URL and find the
+// corresponding record, we will not know if it is a string or a number.
+var coerceId = function(id) {
+  return id == null ? null : id+'';
+};
+
+/**
+  The store contains all of the data for records loaded from the server.
+  It is also responsible for creating instances of `DS.Model` that wrap
+  the individual data for a record, so that they can be bound to in your
+  Handlebars templates.
+
+  Define your application's store like this:
+
+  ```javascript
+  MyApp.Store = DS.Store.extend();
+  ```
+
+  Most Ember.js applications will only have a single `DS.Store` that is
+  automatically created by their `Ember.Application`.
+
+  You can retrieve models from the store in several ways. To retrieve a record
+  for a specific id, use `DS.Store`'s `find()` method:
+
+  ```javascript
+  var person = store.find('person', 123);
+  ```
+
+  If your application has multiple `DS.Store` instances (an unusual case), you can
+  specify which store should be used:
+
+  ```javascript
+  var person = store.find(App.Person, 123);
+  ```
+
+  By default, the store will talk to your backend using a standard
+  REST mechanism. You can customize how the store talks to your
+  backend by specifying a custom adapter:
+
+  ```javascript
+   MyApp.store = DS.Store.create({
+     adapter: 'MyApp.CustomAdapter'
+   });
+   ```
+
+  You can learn more about writing a custom adapter by reading the `DS.Adapter`
+  documentation.
+
+  @class Store
+  @namespace DS
+  @extends Ember.Object
+*/
+DS.Store = Ember.Object.extend({
+
+  /**
+    @method init
+    @private
+  */
+  init: function() {
+    // internal bookkeeping; not observable
+    this.typeMaps = {};
+    this.recordArrayManager = DS.RecordArrayManager.create({
+      store: this
+    });
+    this._relationshipChanges = {};
+    this._pendingSave = [];
+  },
+
+  /**
+    The adapter to use to communicate to a backend server or other persistence layer.
+
+    This can be specified as an instance, class, or string.
+
+    If you want to specify `App.CustomAdapter` as a string, do:
+
+    ```js
+    adapter: 'custom'
+    ```
+
+    @property adapter
+    @default DS.RESTAdapter
+    @type {DS.Adapter|String}
+  */
+  adapter: '-rest',
+
+  /**
+    Returns a JSON representation of the record using a custom
+    type-specific serializer, if one exists.
+
+    The available options are:
+
+    * `includeId`: `true` if the record's ID should be included in
+      the JSON representation
+
+    @method serialize
+    @private
+    @param {DS.Model} record the record to serialize
+    @param {Object} options an options hash
+  */
+  serialize: function(record, options) {
+    return this.serializerFor(record.constructor.typeKey).serialize(record, options);
+  },
+
+  /**
+    This property returns the adapter, after resolving a possible
+    string key.
+
+    If the supplied `adapter` was a class, or a String property
+    path resolved to a class, this property will instantiate the
+    class.
+
+    This property is cacheable, so the same instance of a specified
+    adapter class should be used for the lifetime of the store.
+
+    @property defaultAdapter
+    @private
+    @returns DS.Adapter
+  */
+  defaultAdapter: Ember.computed('adapter', function() {
+    var adapter = get(this, 'adapter');
+
+    Ember.assert('You tried to set `adapter` property to an instance of `DS.Adapter`, where it should be a name or a factory', !(adapter instanceof DS.Adapter));
+
+    if (typeof adapter === 'string') {
+      adapter = this.container.lookup('adapter:' + adapter) || this.container.lookup('adapter:application') || this.container.lookup('adapter:-rest');
+    }
+
+    if (DS.Adapter.detect(adapter)) {
+      adapter = adapter.create({ container: this.container });
+    }
+
+    return adapter;
+  }),
+
+  // .....................
+  // . CREATE NEW RECORD .
+  // .....................
+
+  /**
+    Create a new record in the current store. The properties passed
+    to this method are set on the newly created record.
+
+    To create a new instance of `App.Post`:
+
+    ```js
+    store.createRecord('post', {
+      title: &quot;Rails is omakase&quot;
+    });
+    ```
+
+    @method createRecord
+    @param {String} type
+    @param {Object} properties a hash of properties to set on the
+      newly created record.
+    @returns {DS.Model} record
+  */
+  createRecord: function(type, properties) {
+    type = this.modelFor(type);
+
+    properties = copy(properties) || {};
+
+    // If the passed properties do not include a primary key,
+    // give the adapter an opportunity to generate one. Typically,
+    // client-side ID generators will use something like uuid.js
+    // to avoid conflicts.
+
+    if (isNone(properties.id)) {
+      properties.id = this._generateId(type);
+    }
+
+    // Coerce ID to a string
+    properties.id = coerceId(properties.id);
+
+    var record = this.buildRecord(type, properties.id);
+
+    // Move the record out of its initial `empty` state into
+    // the `loaded` state.
+    record.loadedData();
+
+    // Set the properties specified on the record.
+    record.setProperties(properties);
+
+    return record;
+  },
+
+  /**
+    If possible, this method asks the adapter to generate an ID for
+    a newly created record.
+
+    @method _generateId
+    @private
+    @param {String} type
+    @returns {String} if the adapter can generate one, an ID
+  */
+  _generateId: function(type) {
+    var adapter = this.adapterFor(type);
+
+    if (adapter &amp;&amp; adapter.generateIdForRecord) {
+      return adapter.generateIdForRecord(this);
+    }
+
+    return null;
+  },
+
+  // .................
+  // . DELETE RECORD .
+  // .................
+
+  /**
+    For symmetry, a record can be deleted via the store.
+
+    Example
+
+    ```javascript
+    var post = store.createRecord('post', {
+      title: &quot;Rails is omakase&quot;
+    });
+
+    store.deleteRecord(post);
+    ```
+
+    @method deleteRecord
+    @param {DS.Model} record
+  */
+  deleteRecord: function(record) {
+    record.deleteRecord();
+  },
+
+  /**
+    For symmetry, a record can be unloaded via the store. Only
+    non-dirty records can be unloaded.
+
+    Example
+
+    ```javascript
+    store.find('post', 1).then(function(post) {
+      store.unloadRecord(post);
+    });
+    ```
+
+    @method unloadRecord
+    @param {DS.Model} record
+  */
+  unloadRecord: function(record) {
+    record.unloadRecord();
+  },
+
+  // ................
+  // . FIND RECORDS .
+  // ................
+
+  /**
+    This is the main entry point into finding records. The first parameter to
+    this method is the model's name as a string.
+
+    ---
+
+    To find a record by ID, pass the `id` as the second parameter:
+
+    ```javascript
+    store.find('person', 1);
+    ```
+
+    The `find` method will always return a **promise** that will be resolved
+    with the record. If the record was already in the store, the promise will
+    be resolved immediately. Otherwise, the store will ask the adapter's `find`
+    method to find the necessary data.
+
+    The `find` method will always resolve its promise with the same object for
+    a given type and `id`.
+
+    ---
+
+    To find all records for a type, call `find` with no additional parameters:
+
+    ```javascript
+    store.find('person');
+    ```
+
+    This will ask the adapter's `findAll` method to find the records for the
+    given type, and return a promise that will be resolved once the server
+    returns the values.
+
+    ---
+
+    To find a record by a query, call `find` with a hash as the second
+    parameter:
+
+    ```javascript
+    store.find(App.Person, { page: 1 });
+    ```
+
+    This will ask the adapter's `findQuery` method to find the records for
+    the query, and return a promise that will be resolved once the server
+    responds.
+
+    @method find
+    @param {String or subclass of DS.Model} type
+    @param {Object|String|Integer|null} id
+    @return {Promise} promise
+  */
+  find: function(type, id) {
+    if (id === undefined) {
+      return this.findAll(type);
+    }
+
+    // We are passed a query instead of an id.
+    if (Ember.typeOf(id) === 'object') {
+      return this.findQuery(type, id);
+    }
+
+    return this.findById(type, coerceId(id));
+  },
+
+  /**
+    This method returns a record for a given type and id combination.
+
+    @method findById
+    @private
+    @param {String or subclass of DS.Model} type
+    @param {String|Integer} id
+    @return {Promise} promise
+  */
+  findById: function(type, id) {
+    type = this.modelFor(type);
+
+    var record = this.recordForId(type, id);
+
+    var promise = this.fetchRecord(record) || resolve(record, &quot;DS: Store#findById &quot; + type + &quot; with id: &quot; + id);
+    return promiseObject(promise);
+  },
+
+  /**
+    This method makes a series of requests to the adapter's `find` method
+    and returns a promise that resolves once they are all loaded.
+
+    @private
+    @method findByIds
+    @param {String} type
+    @param {Array} ids
+    @returns {Promise} promise
+  */
+  findByIds: function(type, ids) {
+    var store = this;
+    var promiseLabel = &quot;DS: Store#findByIds &quot; + type;
+    return promiseArray(Ember.RSVP.all(map(ids, function(id) {
+      return store.findById(type, id);
+    })).then(Ember.A, null, &quot;DS: Store#findByIds of &quot; + type + &quot; complete&quot;));
+  },
+
+  /**
+    This method is called by `findById` if it discovers that a particular
+    type/id pair hasn't been loaded yet to kick off a request to the
+    adapter.
+
+    @method fetchRecord
+    @private
+    @param {DS.Model} record
+    @returns {Promise} promise
+  */
+  fetchRecord: function(record) {
+    if (isNone(record)) { return null; }
+    if (record._loadingPromise) { return record._loadingPromise; }
+    if (!get(record, 'isEmpty')) { return null; }
+
+    var type = record.constructor,
+        id = get(record, 'id');
+
+    var adapter = this.adapterFor(type);
+
+    Ember.assert(&quot;You tried to find a record but you have no adapter (for &quot; + type + &quot;)&quot;, adapter);
+    Ember.assert(&quot;You tried to find a record but your adapter (for &quot; + type + &quot;) does not implement 'find'&quot;, adapter.find);
+
+    var promise = _find(adapter, this, type, id);
+    record.loadingData(promise);
+    return promise;
+  },
+
+  /**
+    Get a record by a given type and ID without triggering a fetch.
+
+    This method will synchronously return the record if it's available.
+    Otherwise, it will return null.
+
+    ```js
+    var post = store.getById('post', 1);
+    ```
+
+    @method getById
+    @param {String or subclass of DS.Model} type
+    @param {String|Integer} id
+    @param {DS.Model} record
+  */
+  getById: function(type, id) {
+    if (this.hasRecordForId(type, id)) {
+      return this.recordForId(type, id);
+    } else {
+      return null;
+    }
+  },
+
+  /**
+    This method is called by the record's `reload` method.
+
+    This method calls the adapter's `find` method, which returns a promise. When
+    **that** promise resolves, `reloadRecord` will resolve the promise returned
+    by the record's `reload`.
+
+    @method reloadRecord
+    @private
+    @param {DS.Model} record
+    @return {Promise} promise
+  */
+  reloadRecord: function(record) {
+    var type = record.constructor,
+        adapter = this.adapterFor(type),
+        id = get(record, 'id');
+
+    Ember.assert(&quot;You cannot reload a record without an ID&quot;, id);
+    Ember.assert(&quot;You tried to reload a record but you have no adapter (for &quot; + type + &quot;)&quot;, adapter);
+    Ember.assert(&quot;You tried to reload a record but your adapter does not implement `find`&quot;, adapter.find);
+
+    return _find(adapter, this, type, id);
+  },
+
+  /**
+    This method takes a list of records, groups the records by type,
+    converts the records into IDs, and then invokes the adapter's `findMany`
+    method.
+
+    The records are grouped by type to invoke `findMany` on adapters
+    for each unique type in records.
+
+    It is used both by a brand new relationship (via the `findMany`
+    method) or when the data underlying an existing relationship
+    changes.
+
+    @method fetchMany
+    @private
+    @param {Array} records
+    @param {DS.Model} owner
+    @param {Resolver} resolver
+  */
+  fetchMany: function(records, owner, resolver) {
+    if (!records.length) { return; }
+
+    // Group By Type
+    var recordsByTypeMap = Ember.MapWithDefault.create({
+      defaultValue: function() { return Ember.A(); }
+    });
+
+    forEach(records, function(record) {
+      recordsByTypeMap.get(record.constructor).push(record);
+    });
+
+    forEach(recordsByTypeMap, function(type, records) {
+      var ids = records.mapProperty('id'),
+          adapter = this.adapterFor(type);
+
+      Ember.assert(&quot;You tried to load many records but you have no adapter (for &quot; + type + &quot;)&quot;, adapter);
+      Ember.assert(&quot;You tried to load many records but your adapter does not implement `findMany`&quot;, adapter.findMany);
+
+      resolver.resolve(_findMany(adapter, this, type, ids, owner));
+    }, this);
+  },
+
+  /**
+    Returns true if a record for a given type and ID is already loaded.
+
+    @method hasRecordForId
+    @param {String or subclass of DS.Model} type
+    @param {String|Integer} id
+    @returns {Boolean}
+  */
+  hasRecordForId: function(type, id) {
+    id = coerceId(id);
+    type = this.modelFor(type);
+    return !!this.typeMapFor(type).idToRecord[id];
+  },
+
+  /**
+    Returns id record for a given type and ID. If one isn't already loaded,
+    it builds a new record and leaves it in the `empty` state.
+
+    @method recordForId
+    @private
+    @param {String or subclass of DS.Model} type
+    @param {String|Integer} id
+    @returns {DS.Model} record
+  */
+  recordForId: function(type, id) {
+    type = this.modelFor(type);
+
+    id = coerceId(id);
+
+    var record = this.typeMapFor(type).idToRecord[id];
+
+    if (!record) {
+      record = this.buildRecord(type, id);
+    }
+
+    return record;
+  },
+
+  /**
+    @method findMany
+    @private
+    @param {DS.Model} owner
+    @param {Array} records
+    @param {String or subclass of DS.Model} type
+    @param {Resolver} resolver
+    @return {DS.ManyArray} records
+  */
+  findMany: function(owner, records, type, resolver) {
+    type = this.modelFor(type);
+
+    records = Ember.A(records);
+
+    var unloadedRecords = records.filterProperty('isEmpty', true),
+        manyArray = this.recordArrayManager.createManyArray(type, records);
+
+    forEach(unloadedRecords, function(record) {
+      record.loadingData();
+    });
+
+    manyArray.loadingRecordsCount = unloadedRecords.length;
+
+    if (unloadedRecords.length) {
+      forEach(unloadedRecords, function(record) {
+        this.recordArrayManager.registerWaitingRecordArray(record, manyArray);
+      }, this);
+
+      this.fetchMany(unloadedRecords, owner, resolver);
+    } else {
+      if (resolver) { resolver.resolve(); }
+      manyArray.set('isLoaded', true);
+      Ember.run.once(manyArray, 'trigger', 'didLoad');
+    }
+
+    return manyArray;
+  },
+
+  /**
+    If a relationship was originally populated by the adapter as a link
+    (as opposed to a list of IDs), this method is called when the
+    relationship is fetched.
+
+    The link (which is usually a URL) is passed through unchanged, so the
+    adapter can make whatever request it wants.
+
+    The usual use-case is for the server to register a URL as a link, and
+    then use that URL in the future to make a request for the relationship.
+
+    @method findHasMany
+    @private
+    @param {DS.Model} owner
+    @param {any} link
+    @param {String or subclass of DS.Model} type
+    @param {Resolver} resolver
+    @return {DS.ManyArray}
+  */
+  findHasMany: function(owner, link, relationship, resolver) {
+    var adapter = this.adapterFor(owner.constructor);
+
+    Ember.assert(&quot;You tried to load a hasMany relationship but you have no adapter (for &quot; + owner.constructor + &quot;)&quot;, adapter);
+    Ember.assert(&quot;You tried to load a hasMany relationship from a specified `link` in the original payload but your adapter does not implement `findHasMany`&quot;, adapter.findHasMany);
+
+    var records = this.recordArrayManager.createManyArray(relationship.type, Ember.A([]));
+    resolver.resolve(_findHasMany(adapter, this, owner, link, relationship));
+    return records;
+  },
+
+  /**
+    @method findBelongsTo
+    @private
+    @param {DS.Model} owner
+    @param {any} link
+    @param {Relationship} relationship
+    @param {Resolver} resolver
+  */
+  findBelongsTo: function(owner, link, relationship, resolver) {
+    var adapter = this.adapterFor(owner.constructor);
+
+    Ember.assert(&quot;You tried to load a belongsTo relationship but you have no adapter (for &quot; + owner.constructor + &quot;)&quot;, adapter);
+    Ember.assert(&quot;You tried to load a belongsTo relationship from a specified `link` in the original payload but your adapter does not implement `findBelongsTo`&quot;, adapter.findBelongsTo);
+
+    resolver.resolve(_findBelongsTo(adapter, this, owner, link, relationship));
+  },
+
+  /**
+    This method delegates a query to the adapter. This is the one place where
+    adapter-level semantics are exposed to the application.
+
+    Exposing queries this way seems preferable to creating an abstract query
+    language for all server-side queries, and then require all adapters to
+    implement them.
+
+    This method returns a promise, which is resolved with a `RecordArray`
+    once the server returns.
+
+    @method findQuery
+    @private
+    @param {String or subclass of DS.Model} type
+    @param {any} query an opaque query to be used by the adapter
+    @return {Promise} promise
+  */
+  findQuery: function(type, query) {
+    type = this.modelFor(type);
+
+    var array = this.recordArrayManager
+      .createAdapterPopulatedRecordArray(type, query);
+
+    var adapter = this.adapterFor(type),
+        promiseLabel = &quot;DS: Store#findQuery &quot; + type,
+        resolver = Ember.RSVP.defer(promiseLabel);
+
+    Ember.assert(&quot;You tried to load a query but you have no adapter (for &quot; + type + &quot;)&quot;, adapter);
+    Ember.assert(&quot;You tried to load a query but your adapter does not implement `findQuery`&quot;, adapter.findQuery);
+
+    resolver.resolve(_findQuery(adapter, this, type, query, array));
+
+    return promiseArray(resolver.promise);
+  },
+
+  /**
+    This method returns an array of all records adapter can find.
+    It triggers the adapter's `findAll` method to give it an opportunity to populate
+    the array with records of that type.
+
+    @method findAll
+    @private
+    @param {String or subclass of DS.Model} type
+    @return {DS.AdapterPopulatedRecordArray}
+  */
+  findAll: function(type) {
+    type = this.modelFor(type);
+
+    return this.fetchAll(type, this.all(type));
+  },
+
+  /**
+    @method fetchAll
+    @private
+    @param {DS.Model} type
+    @param {DS.RecordArray} array
+    @returns {Promise} promise
+  */
+  fetchAll: function(type, array) {
+    var adapter = this.adapterFor(type),
+        sinceToken = this.typeMapFor(type).metadata.since;
+
+    set(array, 'isUpdating', true);
+
+    Ember.assert(&quot;You tried to load all records but you have no adapter (for &quot; + type + &quot;)&quot;, adapter);
+    Ember.assert(&quot;You tried to load all records but your adapter does not implement `findAll`&quot;, adapter.findAll);
+
+    return promiseArray(_findAll(adapter, this, type, sinceToken));
+  },
+
+  /**
+    @method didUpdateAll
+    @param {DS.Model} type
+  */
+  didUpdateAll: function(type) {
+    var findAllCache = this.typeMapFor(type).findAllCache;
+    set(findAllCache, 'isUpdating', false);
+  },
+
+  /**
+    This method returns a filtered array that contains all of the known records
+    for a given type.
+
+    Note that because it's just a filter, it will have any locally
+    created records of the type.
+
+    Also note that multiple calls to `all` for a given type will always
+    return the same RecordArray.
+
+    Example
+
+    ```javascript
+    var local_posts = store.all(App.Post);
+    ```
+
+    @method all
+    @param {String or subclass of DS.Model} type
+    @return {DS.RecordArray}
+  */
+  all: function(type) {
+    type = this.modelFor(type);
+
+    var typeMap = this.typeMapFor(type),
+        findAllCache = typeMap.findAllCache;
+
+    if (findAllCache) { return findAllCache; }
+
+    var array = this.recordArrayManager.createRecordArray(type);
+
+    typeMap.findAllCache = array;
+    return array;
+  },
+
+
+  /**
+    This method unloads all of the known records for a given type.
+
+    ```javascript
+    store.unloadAll(App.Post);
+    ```
+
+    @method unloadAll
+    @param {String or subclass of DS.Model} type
+  */
+  unloadAll: function(type) {
+    type = this.modelFor(type);
+
+    var typeMap = this.typeMapFor(type),
+        records = typeMap.records.splice(0), record;
+
+    while(record = records.pop()) {
+      record.unloadRecord();
+    }
+
+    typeMap.findAllCache = null;
+  },
+
+  /**
+    Takes a type and filter function, and returns a live RecordArray that
+    remains up to date as new records are loaded into the store or created
+    locally.
+
+    The callback function takes a materialized record, and returns true
+    if the record should be included in the filter and false if it should
+    not.
+
+    The filter function is called once on all records for the type when
+    it is created, and then once on each newly loaded or created record.
+
+    If any of a record's properties change, or if it changes state, the
+    filter function will be invoked again to determine whether it should
+    still be in the array.
+
+    Optionally you can pass a query which will be triggered at first. The
+    results returned by the server could then appear in the filter if they
+    match the filter function.
+
+    Example
+
+    ```javascript
+    store.filter(App.Post, {unread: true}, function(post) {
+      return post.get('unread');
+    }).then(function(unreadPosts) {
+      unreadPosts.get('length'); // 5
+      var unreadPost = unreadPosts.objectAt(0);
+      unreadPost.set('unread', false);
+      unreadPosts.get('length'); // 4
+    });
+    ```
+
+    @method filter
+    @param {String or subclass of DS.Model} type
+    @param {Object} query optional query
+    @param {Function} filter
+    @return {DS.PromiseArray}
+  */
+  filter: function(type, query, filter) {
+    var promise;
+
+    // allow an optional server query
+    if (arguments.length === 3) {
+      promise = this.findQuery(type, query);
+    } else if (arguments.length === 2) {
+      filter = query;
+    }
+
+    type = this.modelFor(type);
+
+    var array = this.recordArrayManager
+      .createFilteredRecordArray(type, filter);
+    promise = promise || resolve(array);
+
+    return promiseArray(promise.then(function() {
+      return array;
+    }, null, &quot;DS: Store#filter of &quot; + type));
+  },
+
+  /**
+    This method returns if a certain record is already loaded
+    in the store. Use this function to know beforehand if a find()
+    will result in a request or that it will be a cache hit.
+
+     Example
+
+    ```javascript
+    store.recordIsLoaded(App.Post, 1); // false
+    store.find(App.Post, 1).then(function() {
+      store.recordIsLoaded(App.Post, 1); // true
+    });
+    ```
+
+    @method recordIsLoaded
+    @param {String or subclass of DS.Model} type
+    @param {string} id
+    @return {boolean}
+  */
+  recordIsLoaded: function(type, id) {
+    if (!this.hasRecordForId(type, id)) { return false; }
+    return !get(this.recordForId(type, id), 'isEmpty');
+  },
+
+  /**
+    This method returns the metadata for a specific type.
+
+    @method metadataFor
+    @param {String or subclass of DS.Model} type
+    @return {object}
+  */
+  metadataFor: function(type) {
+    type = this.modelFor(type);
+    return this.typeMapFor(type).metadata;
+  },
+
+  // ............
+  // . UPDATING .
+  // ............
+
+  /**
+    If the adapter updates attributes or acknowledges creation
+    or deletion, the record will notify the store to update its
+    membership in any filters.
+    To avoid thrashing, this method is invoked only once per
+
+    run loop per record.
+
+    @method dataWasUpdated
+    @private
+    @param {Class} type
+    @param {DS.Model} record
+  */
+  dataWasUpdated: function(type, record) {
+    this.recordArrayManager.recordDidChange(record);
+  },
+
+  // ..............
+  // . PERSISTING .
+  // ..............
+
+  /**
+    This method is called by `record.save`, and gets passed a
+    resolver for the promise that `record.save` returns.
+
+    It schedules saving to happen at the end of the run loop.
+
+    @method scheduleSave
+    @private
+    @param {DS.Model} record
+    @param {Resolver} resolver
+  */
+  scheduleSave: function(record, resolver) {
+    record.adapterWillCommit();
+    this._pendingSave.push([record, resolver]);
+    once(this, 'flushPendingSave');
+  },
+
+  /**
+    This method is called at the end of the run loop, and
+    flushes any records passed into `scheduleSave`
+
+    @method flushPendingSave
+    @private
+  */
+  flushPendingSave: function() {
+    var pending = this._pendingSave.slice();
+    this._pendingSave = [];
+
+    forEach(pending, function(tuple) {
+      var record = tuple[0], resolver = tuple[1],
+          adapter = this.adapterFor(record.constructor),
+          operation;
+
+      if (get(record, 'isNew')) {
+        operation = 'createRecord';
+      } else if (get(record, 'isDeleted')) {
+        operation = 'deleteRecord';
+      } else {
+        operation = 'updateRecord';
+      }
+
+      resolver.resolve(_commit(adapter, this, operation, record));
+    }, this);
+  },
+
+  /**
+    This method is called once the promise returned by an
+    adapter's `createRecord`, `updateRecord` or `deleteRecord`
+    is resolved.
+
+    If the data provides a server-generated ID, it will
+    update the record and the store's indexes.
+
+    @method didSaveRecord
+    @private
+    @param {DS.Model} record the in-flight record
+    @param {Object} data optional data (see above)
+  */
+  didSaveRecord: function(record, data) {
+    if (data) {
+      // normalize relationship IDs into records
+      data = normalizeRelationships(this, record.constructor, data, record);
+
+      this.updateId(record, data);
+    }
+
+    record.adapterDidCommit(data);
+  },
+
+  /**
+    This method is called once the promise returned by an
+    adapter's `createRecord`, `updateRecord` or `deleteRecord`
+    is rejected with a `DS.InvalidError`.
+
+    @method recordWasInvalid
+    @private
+    @param {DS.Model} record
+    @param {Object} errors
+  */
+  recordWasInvalid: function(record, errors) {
+    record.adapterDidInvalidate(errors);
+  },
+
+  /**
+    This method is called once the promise returned by an
+    adapter's `createRecord`, `updateRecord` or `deleteRecord`
+    is rejected (with anything other than a `DS.InvalidError`).
+
+    @method recordWasError
+    @private
+    @param {DS.Model} record
+  */
+  recordWasError: function(record) {
+    record.adapterDidError();
+  },
+
+  /**
+    When an adapter's `createRecord`, `updateRecord` or `deleteRecord`
+    resolves with data, this method extracts the ID from the supplied
+    data.
+
+    @method updateId
+    @private
+    @param {DS.Model} record
+    @param {Object} data
+  */
+  updateId: function(record, data) {
+    var oldId = get(record, 'id'),
+        id = coerceId(data.id);
+
+    Ember.assert(&quot;An adapter cannot assign a new id to a record that already has an id. &quot; + record + &quot; had id: &quot; + oldId + &quot; and you tried to update it with &quot; + id + &quot;. This likely happened because your server returned data in response to a find or update that had a different id than the one you sent.&quot;, oldId === null || id === oldId);
+
+    this.typeMapFor(record.constructor).idToRecord[id] = record;
+
+    set(record, 'id', id);
+  },
+
+  /**
+    Returns a map of IDs to client IDs for a given type.
+
+    @method typeMapFor
+    @private
+    @param type
+    @return {Object} typeMap
+  */
+  typeMapFor: function(type) {
+    var typeMaps = get(this, 'typeMaps'),
+        guid = Ember.guidFor(type),
+        typeMap;
+
+    typeMap = typeMaps[guid];
+
+    if (typeMap) { return typeMap; }
+
+    typeMap = {
+      idToRecord: {},
+      records: [],
+      metadata: {}
+    };
+
+    typeMaps[guid] = typeMap;
+
+    return typeMap;
+  },
+
+  // ................
+  // . LOADING DATA .
+  // ................
+
+  /**
+    This internal method is used by `push`.
+
+    @method _load
+    @private
+    @param {String or subclass of DS.Model} type
+    @param {Object} data
+    @param {Boolean} partial the data should be merged into
+      the existing data, not replace it.
+  */
+  _load: function(type, data, partial) {
+    var id = coerceId(data.id),
+        record = this.recordForId(type, id);
+
+    record.setupData(data, partial);
+    this.recordArrayManager.recordDidChange(record);
+
+    return record;
+  },
+
+  /**
+    Returns a model class for a particular key. Used by
+    methods that take a type key (like `find`, `createRecord`,
+    etc.)
+
+    @method modelFor
+    @param {String or subclass of DS.Model} key
+    @returns {subclass of DS.Model}
+  */
+  modelFor: function(key) {
+    var factory;
+
+
+    if (typeof key === 'string') {
+      var normalizedKey = this.container.normalize('model:' + key);
+
+      factory = this.container.lookupFactory(normalizedKey);
+      if (!factory) { throw new Ember.Error(&quot;No model was found for '&quot; + key + &quot;'&quot;); }
+      factory.typeKey = normalizedKey.split(':', 2)[1];
+    } else {
+      // A factory already supplied.
+      factory = key;
+    }
+
+    factory.store = this;
+    return factory;
+  },
+
+  /**
+    Push some data for a given type into the store.
+
+    This method expects normalized data:
+
+    * The ID is a key named `id` (an ID is mandatory)
+    * The names of attributes are the ones you used in
+      your model's `DS.attr`s.
+    * Your relationships must be:
+      * represented as IDs or Arrays of IDs
+      * represented as model instances
+      * represented as URLs, under the `links` key
+
+    For this model:
+
+    ```js
+    App.Person = DS.Model.extend({
+      firstName: DS.attr(),
+      lastName: DS.attr(),
+
+      children: DS.hasMany('person')
+    });
+    ```
+
+    To represent the children as IDs:
+
+    ```js
+    {
+      id: 1,
+      firstName: &quot;Tom&quot;,
+      lastName: &quot;Dale&quot;,
+      children: [1, 2, 3]
+    }
+    ```
+
+    To represent the children relationship as a URL:
+
+    ```js
+    {
+      id: 1,
+      firstName: &quot;Tom&quot;,
+      lastName: &quot;Dale&quot;,
+      links: {
+        children: &quot;/people/1/children&quot;
+      }
+    }
+    ```
+
+    If you're streaming data or implementing an adapter,
+    make sure that you have converted the incoming data
+    into this form.
+
+    This method can be used both to push in brand new
+    records, as well as to update existing records.
+
+    @method push
+    @param {String or subclass of DS.Model} type
+    @param {Object} data
+    @returns {DS.Model} the record that was created or
+      updated.
+  */
+  push: function(type, data, _partial) {
+    // _partial is an internal param used by `update`.
+    // If passed, it means that the data should be
+    // merged into the existing data, not replace it.
+
+    Ember.assert(&quot;You must include an `id` in a hash passed to `push`&quot;, data.id != null);
+
+    type = this.modelFor(type);
+
+    // normalize relationship IDs into records
+    data = normalizeRelationships(this, type, data);
+
+    this._load(type, data, _partial);
+
+    return this.recordForId(type, data.id);
+  },
+
+  /**
+    Push some raw data into the store.
+
+    The data will be automatically deserialized using the
+    serializer for the `type` param.
+
+    This method can be used both to push in brand new
+    records, as well as to update existing records.
+
+    You can push in more than one type of object at once.
+    All objects should be in the format expected by the
+    serializer.
+
+    ```js
+    App.ApplicationSerializer = DS.ActiveModelSerializer;
+
+    var pushData = {
+      posts: [
+        {id: 1, post_title: &quot;Great post&quot;, comment_ids: [2]}
+      ],
+      comments: [
+        {id: 2, comment_body: &quot;Insightful comment&quot;}
+      ]
+    }
+
+    store.pushPayload('post', pushData);
+    ```
+
+    @method pushPayload
+    @param {String} type
+    @param {Object} payload
+    @return {DS.Model} the record that was created or updated.
+  */
+  pushPayload: function (type, payload) {
+    var serializer;
+    if (!payload) {
+      payload = type;
+      serializer = defaultSerializer(this.container);
+      Ember.assert(&quot;You cannot use `store#pushPayload` without a type unless your default serializer defines `pushPayload`&quot;, serializer.pushPayload);
+    } else {
+      serializer = this.serializerFor(type);
+    }
+    serializer.pushPayload(this, payload);
+  },
+
+  update: function(type, data) {
+    Ember.assert(&quot;You must include an `id` in a hash passed to `update`&quot;, data.id != null);
+
+    return this.push(type, data, true);
+  },
+
+  /**
+    If you have an Array of normalized data to push,
+    you can call `pushMany` with the Array, and it will
+    call `push` repeatedly for you.
+
+    @method pushMany
+    @param {String or subclass of DS.Model} type
+    @param {Array} datas
+    @return {Array}
+  */
+  pushMany: function(type, datas) {
+    return map(datas, function(data) {
+      return this.push(type, data);
+    }, this);
+  },
+
+  /**
+    If you have some metadata to set for a type
+    you can call `metaForType`.
+
+    @method metaForType
+    @param {String or subclass of DS.Model} type
+    @param {Object} metadata
+  */
+  metaForType: function(type, metadata) {
+    type = this.modelFor(type);
+
+    Ember.merge(this.typeMapFor(type).metadata, metadata);
+  },
+
+  /**
+    Build a brand new record for a given type, ID, and
+    initial data.
+
+    @method buildRecord
+    @private
+    @param {subclass of DS.Model} type
+    @param {String} id
+    @param {Object} data
+    @returns {DS.Model} record
+  */
+  buildRecord: function(type, id, data) {
+    var typeMap = this.typeMapFor(type),
+        idToRecord = typeMap.idToRecord;
+
+    Ember.assert('The id ' + id + ' has already been used with another record of type ' + type.toString() + '.', !id || !idToRecord[id]);
+
+    // lookupFactory should really return an object that creates
+    // instances with the injections applied
+    var record = type._create({
+      id: id,
+      store: this,
+      container: this.container
+    });
+
+    if (data) {
+      record.setupData(data);
+    }
+
+    // if we're creating an item, this process will be done
+    // later, once the object has been persisted.
+    if (id) {
+      idToRecord[id] = record;
+    }
+
+    typeMap.records.push(record);
+
+    return record;
+  },
+
+  // ...............
+  // . DESTRUCTION .
+  // ...............
+
+  /**
+    When a record is destroyed, this un-indexes it and
+    removes it from any record arrays so it can be GCed.
+
+    @method dematerializeRecord
+    @private
+    @param {DS.Model} record
+  */
+  dematerializeRecord: function(record) {
+    var type = record.constructor,
+        typeMap = this.typeMapFor(type),
+        id = get(record, 'id');
+
+    record.updateRecordArrays();
+
+    if (id) {
+      delete typeMap.idToRecord[id];
+    }
+
+    var loc = indexOf(typeMap.records, record);
+    typeMap.records.splice(loc, 1);
+  },
+
+  // ........................
+  // . RELATIONSHIP CHANGES .
+  // ........................
+
+  addRelationshipChangeFor: function(childRecord, childKey, parentRecord, parentKey, change) {
+    var clientId = childRecord.clientId,
+        parentClientId = parentRecord ? parentRecord : parentRecord;
+    var key = childKey + parentKey;
+    var changes = this._relationshipChanges;
+    if (!(clientId in changes)) {
+      changes[clientId] = {};
+    }
+    if (!(parentClientId in changes[clientId])) {
+      changes[clientId][parentClientId] = {};
+    }
+    if (!(key in changes[clientId][parentClientId])) {
+      changes[clientId][parentClientId][key] = {};
+    }
+    changes[clientId][parentClientId][key][change.changeType] = change;
+  },
+
+  removeRelationshipChangeFor: function(clientRecord, childKey, parentRecord, parentKey, type) {
+    var clientId = clientRecord.clientId,
+        parentClientId = parentRecord ? parentRecord.clientId : parentRecord;
+    var changes = this._relationshipChanges;
+    var key = childKey + parentKey;
+    if (!(clientId in changes) || !(parentClientId in changes[clientId]) || !(key in changes[clientId][parentClientId])){
+      return;
+    }
+    delete changes[clientId][parentClientId][key][type];
+  },
+
+  relationshipChangePairsFor: function(record){
+    var toReturn = [];
+
+    if( !record ) { return toReturn; }
+
+    //TODO(Igor) What about the other side
+    var changesObject = this._relationshipChanges[record.clientId];
+    for (var objKey in changesObject){
+      if(changesObject.hasOwnProperty(objKey)){
+        for (var changeKey in changesObject[objKey]){
+          if(changesObject[objKey].hasOwnProperty(changeKey)){
+            toReturn.push(changesObject[objKey][changeKey]);
+          }
+        }
+      }
+    }
+    return toReturn;
+  },
+
+  // ......................
+  // . PER-TYPE ADAPTERS
+  // ......................
+
+  /**
+    Returns the adapter for a given type.
+
+    @method adapterFor
+    @private
+    @param {subclass of DS.Model} type
+    @returns DS.Adapter
+  */
+  adapterFor: function(type) {
+    var container = this.container, adapter;
+
+    if (container) {
+      adapter = container.lookup('adapter:' + type.typeKey) || container.lookup('adapter:application');
+    }
+
+    return adapter || get(this, 'defaultAdapter');
+  },
+
+  // ..............................
+  // . RECORD CHANGE NOTIFICATION .
+  // ..............................
+
+  /**
+    Returns an instance of the serializer for a given type. For
+    example, `serializerFor('person')` will return an instance of
+    `App.PersonSerializer`.
+
+    If no `App.PersonSerializer` is found, this method will look
+    for an `App.ApplicationSerializer` (the default serializer for
+    your entire application).
+
+    If no `App.ApplicationSerializer` is found, it will fall back
+    to an instance of `DS.JSONSerializer`.
+
+    @method serializerFor
+    @private
+    @param {String} type the record to serialize
+    @return {DS.Serializer}
+  */
+  serializerFor: function(type) {
+    type = this.modelFor(type);
+    var adapter = this.adapterFor(type);
+
+    return serializerFor(this.container, type.typeKey, adapter &amp;&amp; adapter.defaultSerializer);
+  }
+});
+
+function normalizeRelationships(store, type, data, record) {
+  type.eachRelationship(function(key, relationship) {
+    // A link (usually a URL) was already provided in
+    // normalized form
+    if (data.links &amp;&amp; data.links[key]) {
+      if (record &amp;&amp; relationship.options.async) { record._relationships[key] = null; }
+      return;
+    }
+
+    var kind = relationship.kind,
+        value = data[key];
+
+    if (value == null) { return; }
+
+    if (kind === 'belongsTo') {
+      deserializeRecordId(store, data, key, relationship, value);
+    } else if (kind === 'hasMany') {
+      deserializeRecordIds(store, data, key, relationship, value);
+      addUnsavedRecords(record, key, value);
+    }
+  });
+
+  return data;
+}
+
+function deserializeRecordId(store, data, key, relationship, id) {
+  if (isNone(id) || id instanceof DS.Model) {
+    return;
+  }
+
+  var type;
+
+  if (typeof id === 'number' || typeof id === 'string') {
+    type = typeFor(relationship, key, data);
+    data[key] = store.recordForId(type, id);
+  } else if (typeof id === 'object') {
+    // polymorphic
+    data[key] = store.recordForId(id.type, id.id);
+  }
+}
+
+function typeFor(relationship, key, data) {
+  if (relationship.options.polymorphic) {
+    return data[key + &quot;Type&quot;];
+  } else {
+    return relationship.type;
+  }
+}
+
+function deserializeRecordIds(store, data, key, relationship, ids) {
+  for (var i=0, l=ids.length; i&lt;l; i++) {
+    deserializeRecordId(store, ids, i, relationship, ids[i]);
+  }
+}
+
+// If there are any unsaved records that are in a hasMany they won't be
+// in the payload, so add them back in manually.
+function addUnsavedRecords(record, key, data) {
+  if(record) {
+    data.pushObjects(record.get(key).filterBy('isNew'));
+  }
+}
+
+// Delegation to the adapter and promise management
+/**
+  A `PromiseArray` is an object that acts like both an `Ember.Array`
+  and a promise. When the promise is resolved the the resulting value
+  will be set to the `PromiseArray`'s `content` property. This makes
+  it easy to create data bindings with the `PromiseArray` that will be
+  updated when the promise resolves.
+
+  For more information see the [Ember.PromiseProxyMixin
+  documentation](/api/classes/Ember.PromiseProxyMixin.html).
+
+  Example
+
+  ```javascript
+  var promiseArray = DS.PromiseArray.create({
+    promise: $.getJSON('/some/remote/data.json')
+  });
+
+  promiseArray.get('length'); // 0
+
+  promiseArray.then(function() {
+    promiseArray.get('length'); // 100
+  });
+  ```
+
+  @class PromiseArray
+  @namespace DS
+  @extends Ember.ArrayProxy
+  @uses Ember.PromiseProxyMixin
+*/
+DS.PromiseArray = Ember.ArrayProxy.extend(Ember.PromiseProxyMixin);
+/**
+  A `PromiseObject` is an object that acts like both an `Ember.Object`
+  and a promise. When the promise is resolved the the resulting value
+  will be set to the `PromiseObject`'s `content` property. This makes
+  it easy to create data bindings with the `PromiseObject` that will
+  be updated when the promise resolves.
+
+  For more information see the [Ember.PromiseProxyMixin
+  documentation](/api/classes/Ember.PromiseProxyMixin.html).
+
+  Example
+
+  ```javascript
+  var promiseObject = DS.PromiseObject.create({
+    promise: $.getJSON('/some/remote/data.json')
+  });
+
+  promiseObject.get('name'); // null
+
+  promiseObject.then(function() {
+    promiseObject.get('name'); // 'Tomster'
+  });
+  ```
+
+  @class PromiseObject
+  @namespace DS
+  @extends Ember.ObjectProxy
+  @uses Ember.PromiseProxyMixin
+*/
+DS.PromiseObject = Ember.ObjectProxy.extend(Ember.PromiseProxyMixin);
+
+function promiseObject(promise) {
+  return DS.PromiseObject.create({ promise: promise });
+}
+
+function promiseArray(promise) {
+  return DS.PromiseArray.create({ promise: promise });
+}
+
+function isThenable(object) {
+  return object &amp;&amp; typeof object.then === 'function';
+}
+
+function serializerFor(container, type, defaultSerializer) {
+  return container.lookup('serializer:'+type) ||
+                 container.lookup('serializer:application') ||
+                 container.lookup('serializer:' + defaultSerializer) ||
+                 container.lookup('serializer:-default');
+}
+
+function defaultSerializer(container) {
+  return container.lookup('serializer:application') ||
+         container.lookup('serializer:-default');
+}
+
+function serializerForAdapter(adapter, type) {
+  var serializer = adapter.serializer,
+      defaultSerializer = adapter.defaultSerializer,
+      container = adapter.container;
+
+  if (container &amp;&amp; serializer === undefined) {
+    serializer = serializerFor(container, type.typeKey, defaultSerializer);
+  }
+
+  if (serializer === null || serializer === undefined) {
+    serializer = {
+      extract: function(store, type, payload) { return payload; }
+    };
+  }
+
+  return serializer;
+}
+
+function _find(adapter, store, type, id) {
+  var promise = adapter.find(store, type, id),
+      serializer = serializerForAdapter(adapter, type);
+
+  return resolve(promise, &quot;DS: Handle Adapter#find of &quot; + type + &quot; with id: &quot; + id).then(function(payload) {
+    Ember.assert(&quot;You made a request for a &quot; + type.typeKey + &quot; with id &quot; + id + &quot;, but the adapter's response did not have any data&quot;, payload);
+    payload = serializer.extract(store, type, payload, id, 'find');
+
+    return store.push(type, payload);
+  }, function(error) {
+    var record = store.getById(type, id);
+    record.notFound();
+    throw error;
+  }, &quot;DS: Extract payload of '&quot; + type + &quot;'&quot;);
+}
+
+function _findMany(adapter, store, type, ids, owner) {
+  var promise = adapter.findMany(store, type, ids, owner),
+      serializer = serializerForAdapter(adapter, type);
+
+  return resolve(promise, &quot;DS: Handle Adapter#findMany of &quot; + type).then(function(payload) {
+    payload = serializer.extract(store, type, payload, null, 'findMany');
+
+    Ember.assert(&quot;The response from a findMany must be an Array, not &quot; + Ember.inspect(payload), Ember.typeOf(payload) === 'array');
+
+    store.pushMany(type, payload);
+  }, null, &quot;DS: Extract payload of &quot; + type);
+}
+
+function _findHasMany(adapter, store, record, link, relationship) {
+  var promise = adapter.findHasMany(store, record, link, relationship),
+      serializer = serializerForAdapter(adapter, relationship.type);
+
+  return resolve(promise, &quot;DS: Handle Adapter#findHasMany of &quot; + record + &quot; : &quot; + relationship.type).then(function(payload) {
+    payload = serializer.extract(store, relationship.type, payload, null, 'findHasMany');
+
+    Ember.assert(&quot;The response from a findHasMany must be an Array, not &quot; + Ember.inspect(payload), Ember.typeOf(payload) === 'array');
+
+    var records = store.pushMany(relationship.type, payload);
+    record.updateHasMany(relationship.key, records);
+  }, null, &quot;DS: Extract payload of &quot; + record + &quot; : hasMany &quot; + relationship.type);
+}
+
+function _findBelongsTo(adapter, store, record, link, relationship) {
+  var promise = adapter.findBelongsTo(store, record, link, relationship),
+      serializer = serializerForAdapter(adapter, relationship.type);
+
+  return resolve(promise, &quot;DS: Handle Adapter#findBelongsTo of &quot; + record + &quot; : &quot; + relationship.type).then(function(payload) {
+    payload = serializer.extract(store, relationship.type, payload, null, 'findBelongsTo');
+
+    var record = store.push(relationship.type, payload);
+    record.updateBelongsTo(relationship.key, record);
+    return record;
+  }, null, &quot;DS: Extract payload of &quot; + record + &quot; : &quot; + relationship.type);
+}
+
+function _findAll(adapter, store, type, sinceToken) {
+  var promise = adapter.findAll(store, type, sinceToken),
+      serializer = serializerForAdapter(adapter, type);
+
+  return resolve(promise, &quot;DS: Handle Adapter#findAll of &quot; + type).then(function(payload) {
+    payload = serializer.extract(store, type, payload, null, 'findAll');
+
+    Ember.assert(&quot;The response from a findAll must be an Array, not &quot; + Ember.inspect(payload), Ember.typeOf(payload) === 'array');
+
+    store.pushMany(type, payload);
+    store.didUpdateAll(type);
+    return store.all(type);
+  }, null, &quot;DS: Extract payload of findAll &quot; + type);
+}
+
+function _findQuery(adapter, store, type, query, recordArray) {
+  var promise = adapter.findQuery(store, type, query, recordArray),
+      serializer = serializerForAdapter(adapter, type);
+
+  return resolve(promise, &quot;DS: Handle Adapter#findQuery of &quot; + type).then(function(payload) {
+    payload = serializer.extract(store, type, payload, null, 'findQuery');
+
+    Ember.assert(&quot;The response from a findQuery must be an Array, not &quot; + Ember.inspect(payload), Ember.typeOf(payload) === 'array');
+
+    recordArray.load(payload);
+    return recordArray;
+  }, null, &quot;DS: Extract payload of findQuery &quot; + type);
+}
+
+function _commit(adapter, store, operation, record) {
+  var type = record.constructor,
+      promise = adapter[operation](store, type, record),
+      serializer = serializerForAdapter(adapter, type);
+
+  Ember.assert(&quot;Your adapter's '&quot; + operation + &quot;' method must return a promise, but it returned &quot; + promise, isThenable(promise));
+
+  return promise.then(function(payload) {
+    if (payload) { payload = serializer.extract(store, type, payload, get(record, 'id'), operation); }
+    store.didSaveRecord(record, payload);
+    return record;
+  }, function(reason) {
+    if (reason instanceof DS.InvalidError) {
+      store.recordWasInvalid(record, reason.errors);
+    } else {
+      store.recordWasError(record, reason);
+    }
+
+    throw reason;
+  }, &quot;DS: Extract and notify about &quot; + operation + &quot; completion of &quot; + record);
+}
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var get = Ember.get, set = Ember.set;
+/*
+  This file encapsulates the various states that a record can transition
+  through during its lifecycle.
+*/
+/**
+  ### State
+
+  Each record has a `currentState` property that explicitly tracks what
+  state a record is in at any given time. For instance, if a record is
+  newly created and has not yet been sent to the adapter to be saved,
+  it would be in the `root.loaded.created.uncommitted` state.  If a
+  record has had local modifications made to it that are in the
+  process of being saved, the record would be in the
+  `root.loaded.updated.inFlight` state. (These state paths will be
+  explained in more detail below.)
+
+  Events are sent by the record or its store to the record's
+  `currentState` property. How the state reacts to these events is
+  dependent on which state it is in. In some states, certain events
+  will be invalid and will cause an exception to be raised.
+
+  States are hierarchical and every state is a substate of the
+  `RootState`. For example, a record can be in the
+  `root.deleted.uncommitted` state, then transition into the
+  `root.deleted.inFlight` state. If a child state does not implement
+  an event handler, the state manager will attempt to invoke the event
+  on all parent states until the root state is reached. The state
+  hierarchy of a record is described in terms of a path string. You
+  can determine a record's current state by getting the state's
+  `stateName` property:
+
+  ```javascript
+  record.get('currentState.stateName');
+  //=&gt; &quot;root.created.uncommitted&quot;
+   ```
+
+  The hierarchy of valid states that ship with ember data looks like
+  this:
+
+  ```text
+  * root
+    * deleted
+      * saved
+      * uncommitted
+      * inFlight
+    * empty
+    * loaded
+      * created
+        * uncommitted
+        * inFlight
+      * saved
+      * updated
+        * uncommitted
+        * inFlight
+    * loading
+  ```
+
+  The `DS.Model` states are themselves stateless. What we mean is
+  that, the hierarchical states that each of *those* points to is a
+  shared data structure. For performance reasons, instead of each
+  record getting its own copy of the hierarchy of states, each record
+  points to this global, immutable shared instance. How does a state
+  know which record it should be acting on? We pass the record
+  instance into the state's event handlers as the first argument.
+
+  The record passed as the first parameter is where you should stash
+  state about the record if needed; you should never store data on the state
+  object itself.
+
+  ### Events and Flags
+
+  A state may implement zero or more events and flags.
+
+  #### Events
+
+  Events are named functions that are invoked when sent to a record. The
+  record will first look for a method with the given name on the
+  current state. If no method is found, it will search the current
+  state's parent, and then its grandparent, and so on until reaching
+  the top of the hierarchy. If the root is reached without an event
+  handler being found, an exception will be raised. This can be very
+  helpful when debugging new features.
+
+  Here's an example implementation of a state with a `myEvent` event handler:
+
+  ```javascript
+  aState: DS.State.create({
+    myEvent: function(manager, param) {
+      console.log(&quot;Received myEvent with&quot;, param);
+    }
+  })
+  ```
+
+  To trigger this event:
+
+  ```javascript
+  record.send('myEvent', 'foo');
+  //=&gt; &quot;Received myEvent with foo&quot;
+  ```
+
+  Note that an optional parameter can be sent to a record's `send()` method,
+  which will be passed as the second parameter to the event handler.
+
+  Events should transition to a different state if appropriate. This can be
+  done by calling the record's `transitionTo()` method with a path to the
+  desired state. The state manager will attempt to resolve the state path
+  relative to the current state. If no state is found at that path, it will
+  attempt to resolve it relative to the current state's parent, and then its
+  parent, and so on until the root is reached. For example, imagine a hierarchy
+  like this:
+
+      * created
+        * uncommitted &lt;-- currentState
+        * inFlight
+      * updated
+        * inFlight
+
+  If we are currently in the `uncommitted` state, calling
+  `transitionTo('inFlight')` would transition to the `created.inFlight` state,
+  while calling `transitionTo('updated.inFlight')` would transition to
+  the `updated.inFlight` state.
+
+  Remember that *only events* should ever cause a state transition. You should
+  never call `transitionTo()` from outside a state's event handler. If you are
+  tempted to do so, create a new event and send that to the state manager.
+
+  #### Flags
+
+  Flags are Boolean values that can be used to introspect a record's current
+  state in a more user-friendly way than examining its state path. For example,
+  instead of doing this:
+
+  ```javascript
+  var statePath = record.get('stateManager.currentPath');
+  if (statePath === 'created.inFlight') {
+    doSomething();
+  }
+  ```
+
+  You can say:
+
+  ```javascript
+  if (record.get('isNew') &amp;&amp; record.get('isSaving')) {
+    doSomething();
+  }
+  ```
+
+  If your state does not set a value for a given flag, the value will
+  be inherited from its parent (or the first place in the state hierarchy
+  where it is defined).
+
+  The current set of flags are defined below. If you want to add a new flag,
+  in addition to the area below, you will also need to declare it in the
+  `DS.Model` class.
+
+
+   * [isEmpty](DS.Model.html#property_isEmpty)
+   * [isLoading](DS.Model.html#property_isLoading)
+   * [isLoaded](DS.Model.html#property_isLoaded)
+   * [isDirty](DS.Model.html#property_isDirty)
+   * [isSaving](DS.Model.html#property_isSaving)
+   * [isDeleted](DS.Model.html#property_isDeleted)
+   * [isNew](DS.Model.html#property_isNew)
+   * [isValid](DS.Model.html#property_isValid)
+
+  @namespace DS
+  @class RootState
+*/
+
+var hasDefinedProperties = function(object) {
+  // Ignore internal property defined by simulated `Ember.create`.
+  var names = Ember.keys(object);
+  var i, l, name;
+  for (i = 0, l = names.length; i &lt; l; i++ ) {
+    name = names[i];
+    if (object.hasOwnProperty(name) &amp;&amp; object[name]) { return true; }
+  }
+
+  return false;
+};
+
+var didSetProperty = function(record, context) {
+  if (context.value === context.originalValue) {
+    delete record._attributes[context.name];
+    record.send('propertyWasReset', context.name);
+  } else if (context.value !== context.oldValue) {
+    record.send('becomeDirty');
+  }
+
+  record.updateRecordArraysLater();
+};
+
+// Implementation notes:
+//
+// Each state has a boolean value for all of the following flags:
+//
+// * isLoaded: The record has a populated `data` property. When a
+//   record is loaded via `store.find`, `isLoaded` is false
+//   until the adapter sets it. When a record is created locally,
+//   its `isLoaded` property is always true.
+// * isDirty: The record has local changes that have not yet been
+//   saved by the adapter. This includes records that have been
+//   created (but not yet saved) or deleted.
+// * isSaving: The record has been committed, but
+//   the adapter has not yet acknowledged that the changes have
+//   been persisted to the backend.
+// * isDeleted: The record was marked for deletion. When `isDeleted`
+//   is true and `isDirty` is true, the record is deleted locally
+//   but the deletion was not yet persisted. When `isSaving` is
+//   true, the change is in-flight. When both `isDirty` and
+//   `isSaving` are false, the change has persisted.
+// * isError: The adapter reported that it was unable to save
+//   local changes to the backend. This may also result in the
+//   record having its `isValid` property become false if the
+//   adapter reported that server-side validations failed.
+// * isNew: The record was created on the client and the adapter
+//   did not yet report that it was successfully saved.
+// * isValid: No client-side validations have failed and the
+//   adapter did not report any server-side validation failures.
+
+// The dirty state is a abstract state whose functionality is
+// shared between the `created` and `updated` states.
+//
+// The deleted state shares the `isDirty` flag with the
+// subclasses of `DirtyState`, but with a very different
+// implementation.
+//
+// Dirty states have three child states:
+//
+// `uncommitted`: the store has not yet handed off the record
+//   to be saved.
+// `inFlight`: the store has handed off the record to be saved,
+//   but the adapter has not yet acknowledged success.
+// `invalid`: the record has invalid information and cannot be
+//   send to the adapter yet.
+var DirtyState = {
+  initialState: 'uncommitted',
+
+  // FLAGS
+  isDirty: true,
+
+  // SUBSTATES
+
+  // When a record first becomes dirty, it is `uncommitted`.
+  // This means that there are local pending changes, but they
+  // have not yet begun to be saved, and are not invalid.
+  uncommitted: {
+    // EVENTS
+    didSetProperty: didSetProperty,
+
+    propertyWasReset: function(record, name) {
+      var stillDirty = false;
+
+      for (var prop in record._attributes) {
+        stillDirty = true;
+        break;
+      }
+
+      if (!stillDirty) { record.send('rolledBack'); }
+    },
+
+    pushedData: Ember.K,
+
+    becomeDirty: Ember.K,
+
+    willCommit: function(record) {
+      record.transitionTo('inFlight');
+    },
+
+    reloadRecord: function(record, resolve) {
+      resolve(get(record, 'store').reloadRecord(record));
+    },
+
+    rolledBack: function(record) {
+      record.transitionTo('loaded.saved');
+    },
+
+    becameInvalid: function(record) {
+      record.transitionTo('invalid');
+    },
+
+    rollback: function(record) {
+      record.rollback();
+    }
+  },
+
+  // Once a record has been handed off to the adapter to be
+  // saved, it is in the 'in flight' state. Changes to the
+  // record cannot be made during this window.
+  inFlight: {
+    // FLAGS
+    isSaving: true,
+
+    // EVENTS
+    didSetProperty: didSetProperty,
+    becomeDirty: Ember.K,
+    pushedData: Ember.K,
+
+    // TODO: More robust semantics around save-while-in-flight
+    willCommit: Ember.K,
+
+    didCommit: function(record) {
+      var dirtyType = get(this, 'dirtyType');
+
+      record.transitionTo('saved');
+      record.send('invokeLifecycleCallbacks', dirtyType);
+    },
+
+    becameInvalid: function(record) {
+      record.transitionTo('invalid');
+      record.send('invokeLifecycleCallbacks');
+    },
+
+    becameError: function(record) {
+      record.transitionTo('uncommitted');
+      record.triggerLater('becameError', record);
+    }
+  },
+
+  // A record is in the `invalid` state when its client-side
+  // invalidations have failed, or if the adapter has indicated
+  // the the record failed server-side invalidations.
+  invalid: {
+    // FLAGS
+    isValid: false,
+
+    // EVENTS
+    deleteRecord: function(record) {
+      record.transitionTo('deleted.uncommitted');
+      record.clearRelationships();
+    },
+
+    didSetProperty: function(record, context) {
+      get(record, 'errors').remove(context.name);
+
+      didSetProperty(record, context);
+    },
+
+    becomeDirty: Ember.K,
+
+    rolledBack: function(record) {
+      get(record, 'errors').clear();
+    },
+
+    becameValid: function(record) {
+      record.transitionTo('uncommitted');
+    },
+
+    invokeLifecycleCallbacks: function(record) {
+      record.triggerLater('becameInvalid', record);
+    }
+  }
+};
+
+// The created and updated states are created outside the state
+// chart so we can reopen their substates and add mixins as
+// necessary.
+
+function deepClone(object) {
+  var clone = {}, value;
+
+  for (var prop in object) {
+    value = object[prop];
+    if (value &amp;&amp; typeof value === 'object') {
+      clone[prop] = deepClone(value);
+    } else {
+      clone[prop] = value;
+    }
+  }
+
+  return clone;
+}
+
+function mixin(original, hash) {
+  for (var prop in hash) {
+    original[prop] = hash[prop];
+  }
+
+  return original;
+}
+
+function dirtyState(options) {
+  var newState = deepClone(DirtyState);
+  return mixin(newState, options);
+}
+
+var createdState = dirtyState({
+  dirtyType: 'created',
+
+  // FLAGS
+  isNew: true
+});
+
+createdState.uncommitted.rolledBack = function(record) {
+  record.transitionTo('deleted.saved');
+};
+
+var updatedState = dirtyState({
+  dirtyType: 'updated'
+});
+
+createdState.uncommitted.deleteRecord = function(record) {
+  record.clearRelationships();
+  record.transitionTo('deleted.saved');
+};
+
+createdState.uncommitted.rollback = function(record) {
+  DirtyState.uncommitted.rollback.apply(this, arguments);
+  record.transitionTo('deleted.saved');
+};
+
+createdState.uncommitted.propertyWasReset = Ember.K;
+
+updatedState.uncommitted.deleteRecord = function(record) {
+  record.transitionTo('deleted.uncommitted');
+  record.clearRelationships();
+};
+
+var RootState = {
+  // FLAGS
+  isEmpty: false,
+  isLoading: false,
+  isLoaded: false,
+  isDirty: false,
+  isSaving: false,
+  isDeleted: false,
+  isNew: false,
+  isValid: true,
+
+  // DEFAULT EVENTS
+
+  // Trying to roll back if you're not in the dirty state
+  // doesn't change your state. For example, if you're in the
+  // in-flight state, rolling back the record doesn't move
+  // you out of the in-flight state.
+  rolledBack: Ember.K,
+
+  propertyWasReset: Ember.K,
+
+  // SUBSTATES
+
+  // A record begins its lifecycle in the `empty` state.
+  // If its data will come from the adapter, it will
+  // transition into the `loading` state. Otherwise, if
+  // the record is being created on the client, it will
+  // transition into the `created` state.
+  empty: {
+    isEmpty: true,
+
+    // EVENTS
+    loadingData: function(record, promise) {
+      record._loadingPromise = promise;
+      record.transitionTo('loading');
+    },
+
+    loadedData: function(record) {
+      record.transitionTo('loaded.created.uncommitted');
+
+      record.suspendRelationshipObservers(function() {
+        record.notifyPropertyChange('data');
+      });
+    },
+
+    pushedData: function(record) {
+      record.transitionTo('loaded.saved');
+      record.triggerLater('didLoad');
+    }
+  },
+
+  // A record enters this state when the store asks
+  // the adapter for its data. It remains in this state
+  // until the adapter provides the requested data.
+  //
+  // Usually, this process is asynchronous, using an
+  // XHR to retrieve the data.
+  loading: {
+    // FLAGS
+    isLoading: true,
+
+    exit: function(record) {
+      record._loadingPromise = null;
+    },
+
+    // EVENTS
+    pushedData: function(record) {
+      record.transitionTo('loaded.saved');
+      record.triggerLater('didLoad');
+      set(record, 'isError', false);
+    },
+
+    becameError: function(record) {
+      record.triggerLater('becameError', record);
+    },
+
+    notFound: function(record) {
+      record.transitionTo('empty');
+    }
+  },
+
+  // A record enters this state when its data is populated.
+  // Most of a record's lifecycle is spent inside substates
+  // of the `loaded` state.
+  loaded: {
+    initialState: 'saved',
+
+    // FLAGS
+    isLoaded: true,
+
+    // SUBSTATES
+
+    // If there are no local changes to a record, it remains
+    // in the `saved` state.
+    saved: {
+      setup: function(record) {
+        var attrs = record._attributes,
+            isDirty = false;
+
+        for (var prop in attrs) {
+          if (attrs.hasOwnProperty(prop)) {
+            isDirty = true;
+            break;
+          }
+        }
+
+        if (isDirty) {
+          record.adapterDidDirty();
+        }
+      },
+
+      // EVENTS
+      didSetProperty: didSetProperty,
+
+      pushedData: Ember.K,
+
+      becomeDirty: function(record) {
+        record.transitionTo('updated.uncommitted');
+      },
+
+      willCommit: function(record) {
+        record.transitionTo('updated.inFlight');
+      },
+
+      reloadRecord: function(record, resolve) {
+        resolve(get(record, 'store').reloadRecord(record));
+      },
+
+      deleteRecord: function(record) {
+        record.transitionTo('deleted.uncommitted');
+        record.clearRelationships();
+      },
+
+      unloadRecord: function(record) {
+        // clear relationships before moving to deleted state
+        // otherwise it fails
+        record.clearRelationships();
+        record.transitionTo('deleted.saved');
+      },
+
+      didCommit: function(record) {
+        record.send('invokeLifecycleCallbacks', get(record, 'lastDirtyType'));
+      },
+
+      // loaded.saved.notFound would be triggered by a failed
+      // `reload()` on an unchanged record
+      notFound: Ember.K
+
+    },
+
+    // A record is in this state after it has been locally
+    // created but before the adapter has indicated that
+    // it has been saved.
+    created: createdState,
+
+    // A record is in this state if it has already been
+    // saved to the server, but there are new local changes
+    // that have not yet been saved.
+    updated: updatedState
+  },
+
+  // A record is in this state if it was deleted from the store.
+  deleted: {
+    initialState: 'uncommitted',
+    dirtyType: 'deleted',
+
+    // FLAGS
+    isDeleted: true,
+    isLoaded: true,
+    isDirty: true,
+
+    // TRANSITIONS
+    setup: function(record) {
+      record.updateRecordArrays();
+    },
+
+    // SUBSTATES
+
+    // When a record is deleted, it enters the `start`
+    // state. It will exit this state when the record
+    // starts to commit.
+    uncommitted: {
+
+      // EVENTS
+
+      willCommit: function(record) {
+        record.transitionTo('inFlight');
+      },
+
+      rollback: function(record) {
+        record.rollback();
+      },
+
+      becomeDirty: Ember.K,
+      deleteRecord: Ember.K,
+
+      rolledBack: function(record) {
+        record.transitionTo('loaded.saved');
+      }
+    },
+
+    // After a record starts committing, but
+    // before the adapter indicates that the deletion
+    // has saved to the server, a record is in the
+    // `inFlight` substate of `deleted`.
+    inFlight: {
+      // FLAGS
+      isSaving: true,
+
+      // EVENTS
+
+      // TODO: More robust semantics around save-while-in-flight
+      willCommit: Ember.K,
+      didCommit: function(record) {
+        record.transitionTo('saved');
+
+        record.send('invokeLifecycleCallbacks');
+      },
+
+      becameError: function(record) {
+        record.transitionTo('uncommitted');
+        record.triggerLater('becameError', record);
+      }
+    },
+
+    // Once the adapter indicates that the deletion has
+    // been saved, the record enters the `saved` substate
+    // of `deleted`.
+    saved: {
+      // FLAGS
+      isDirty: false,
+
+      setup: function(record) {
+        var store = get(record, 'store');
+        store.dematerializeRecord(record);
+      },
+
+      invokeLifecycleCallbacks: function(record) {
+        record.triggerLater('didDelete', record);
+        record.triggerLater('didCommit', record);
+      }
+    }
+  },
+
+  invokeLifecycleCallbacks: function(record, dirtyType) {
+    if (dirtyType === 'created') {
+      record.triggerLater('didCreate', record);
+    } else {
+      record.triggerLater('didUpdate', record);
+    }
+
+    record.triggerLater('didCommit', record);
+  }
+};
+
+function wireState(object, parent, name) {
+  /*jshint proto:true*/
+  // TODO: Use Object.create and copy instead
+  object = mixin(parent ? Ember.create(parent) : {}, object);
+  object.parentState = parent;
+  object.stateName = name;
+
+  for (var prop in object) {
+    if (!object.hasOwnProperty(prop) || prop === 'parentState' || prop === 'stateName') { continue; }
+    if (typeof object[prop] === 'object') {
+      object[prop] = wireState(object[prop], object, name + &quot;.&quot; + prop);
+    }
+  }
+
+  return object;
+}
+
+RootState = wireState(RootState, null, &quot;root&quot;);
+
+DS.RootState = RootState;
+
+})();
+
+
+
+(function() {
+var get = Ember.get, isEmpty = Ember.isEmpty;
+
+/**
+@module ember-data
+*/
+
+/**
+  Holds validation errors for a given record organized by attribute names.
+
+  @class Errors
+  @namespace DS
+  @extends Ember.Object
+  @uses Ember.Enumerable
+  @uses Ember.Evented
+ */
+DS.Errors = Ember.Object.extend(Ember.Enumerable, Ember.Evented, {
+  /**
+    Register with target handler
+
+    @method registerHandlers
+    @param {Object} target
+    @param {Function} becameInvalid
+    @param {Function} becameValid
+  */
+  registerHandlers: function(target, becameInvalid, becameValid) {
+    this.on('becameInvalid', target, becameInvalid);
+    this.on('becameValid', target, becameValid);
+  },
+
+  /**
+    @property errorsByAttributeName
+    @type {Ember.MapWithDefault}
+    @private
+  */
+  errorsByAttributeName: Ember.reduceComputed(&quot;content&quot;, {
+    initialValue: function() {
+      return Ember.MapWithDefault.create({
+        defaultValue: function() {
+          return Ember.A();
+        }
+      });
+    },
+
+    addedItem: function(errors, error) {
+      errors.get(error.attribute).pushObject(error);
+
+      return errors;
+    },
+
+    removedItem: function(errors, error) {
+      errors.get(error.attribute).removeObject(error);
+
+      return errors;
+    }
+  }),
+
+  /**
+    Returns errors for a given attribute
+
+    @method errorsFor
+    @param {String} attribute
+    @returns {Array}
+  */
+  errorsFor: function(attribute) {
+    return get(this, 'errorsByAttributeName').get(attribute);
+  },
+
+  /**
+  */
+  messages: Ember.computed.mapBy('content', 'message'),
+
+  /**
+    @property content
+    @type {Array}
+    @private
+  */
+  content: Ember.computed(function() {
+    return Ember.A();
+  }),
+
+  /**
+    @method unknownProperty
+    @private
+  */
+  unknownProperty: function(attribute) {
+    var errors = this.errorsFor(attribute);
+    if (isEmpty(errors)) { return null; }
+    return errors;
+  },
+
+  /**
+    @method nextObject
+    @private
+  */
+  nextObject: function(index, previousObject, context) {
+    return get(this, 'content').objectAt(index);
+  },
+
+  /**
+    Total number of errors.
+
+    @property length
+    @type {Number}
+    @readOnly
+  */
+  length: Ember.computed.oneWay('content.length').readOnly(),
+
+  /**
+    @property isEmpty
+    @type {Boolean}
+    @readOnly
+  */
+  isEmpty: Ember.computed.not('length').readOnly(),
+
+  /**
+    Adds error messages to a given attribute and sends
+    `becameInvalid` event to the record.
+
+    @method add
+    @param {String} attribute
+    @param {Array|String} messages
+  */
+  add: function(attribute, messages) {
+    var wasEmpty = get(this, 'isEmpty');
+
+    messages = this._findOrCreateMessages(attribute, messages);
+    get(this, 'content').addObjects(messages);
+
+    this.notifyPropertyChange(attribute);
+    this.enumerableContentDidChange();
+
+    if (wasEmpty &amp;&amp; !get(this, 'isEmpty')) {
+      this.trigger('becameInvalid');
+    }
+  },
+
+  /**
+    @method _findOrCreateMessages
+    @private
+  */
+  _findOrCreateMessages: function(attribute, messages) {
+    var errors = this.errorsFor(attribute);
+
+    return Ember.makeArray(messages).map(function(message) {
+      return errors.findBy('message', message) || {
+        attribute: attribute,
+        message: message
+      };
+    });
+  },
+
+  /**
+    Removes all error messages from the given attribute and sends
+    `becameValid` event to the record if there no more errors left.
+
+    @method remove
+    @param {String} attribute
+  */
+  remove: function(attribute) {
+    if (get(this, 'isEmpty')) { return; }
+
+    var content = get(this, 'content').rejectBy('attribute', attribute);
+    get(this, 'content').setObjects(content);
+
+    this.notifyPropertyChange(attribute);
+    this.enumerableContentDidChange();
+
+    if (get(this, 'isEmpty')) {
+      this.trigger('becameValid');
+    }
+  },
+
+  /**
+    Removes all error messages and sends `becameValid` event
+    to the record.
+
+    @method clear
+  */
+  clear: function() {
+    if (get(this, 'isEmpty')) { return; }
+
+    get(this, 'content').clear();
+    this.enumerableContentDidChange();
+
+    this.trigger('becameValid');
+  },
+
+  /**
+    Checks if there is error messages for the given attribute.
+
+    @method has
+    @param {String} attribute
+    @returns {Boolean} true if there some errors on given attribute
+  */
+  has: function(attribute) {
+    return !isEmpty(this.errorsFor(attribute));
+  }
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var get = Ember.get, set = Ember.set,
+    merge = Ember.merge;
+
+var retrieveFromCurrentState = Ember.computed('currentState', function(key, value) {
+  return get(get(this, 'currentState'), key);
+}).readOnly();
+
+/**
+
+  The model class that all Ember Data records descend from.
+
+  @class Model
+  @namespace DS
+  @extends Ember.Object
+  @uses Ember.Evented
+*/
+DS.Model = Ember.Object.extend(Ember.Evented, {
+  /**
+    If this property is `true` the record is in the `empty`
+    state. Empty is the first state all records enter after they have
+    been created. Most records created by the store will quickly
+    transition to the `loading` state if data needs to be fetched from
+    the server or the `created` state if the record is created on the
+    client. A record can also enter the empty state if the adapter is
+    unable to locate the record.
+
+    @property isEmpty
+    @type {Boolean}
+    @readOnly
+  */
+  isEmpty: retrieveFromCurrentState,
+  /**
+    If this property is `true` the record is in the `loading` state. A
+    record enters this state when the store asks the adapter for its
+    data. It remains in this state until the adapter provides the
+    requested data.
+
+    @property isLoading
+    @type {Boolean}
+    @readOnly
+  */
+  isLoading: retrieveFromCurrentState,
+  /**
+    If this property is `true` the record is in the `loaded` state. A
+    record enters this state when its data is populated. Most of a
+    record's lifecycle is spent inside substates of the `loaded`
+    state.
+
+    Example
+
+    ```javascript
+    var record = store.createRecord(App.Model);
+    record.get('isLoaded'); // true
+
+    store.find('model', 1).then(function(model) {
+      model.get('isLoaded'); // true
+    });
+    ```
+
+    @property isLoaded
+    @type {Boolean}
+    @readOnly
+  */
+  isLoaded: retrieveFromCurrentState,
+  /**
+    If this property is `true` the record is in the `dirty` state. The
+    record has local changes that have not yet been saved by the
+    adapter. This includes records that have been created (but not yet
+    saved) or deleted.
+
+    Example
+
+    ```javascript
+    var record = store.createRecord(App.Model);
+    record.get('isDirty'); // true
+
+    store.find('model', 1).then(function(model) {
+      model.get('isDirty'); // false
+      model.set('foo', 'some value');
+      model.set('isDirty'); // true
+    });
+    ```
+
+    @property isDirty
+    @type {Boolean}
+    @readOnly
+  */
+  isDirty: retrieveFromCurrentState,
+  /**
+    If this property is `true` the record is in the `saving` state. A
+    record enters the saving state when `save` is called, but the
+    adapter has not yet acknowledged that the changes have been
+    persisted to the backend.
+
+    Example
+
+    ```javascript
+    var record = store.createRecord(App.Model);
+    record.get('isSaving'); // false
+    var promise = record.save();
+    record.get('isSaving'); // true
+    promise.then(function() {
+      record.get('isSaving'); // false
+    });
+    ```
+
+    @property isSaving
+    @type {Boolean}
+    @readOnly
+  */
+  isSaving: retrieveFromCurrentState,
+  /**
+    If this property is `true` the record is in the `deleted` state
+    and has been marked for deletion. When `isDeleted` is true and
+    `isDirty` is true, the record is deleted locally but the deletion
+    was not yet persisted. When `isSaving` is true, the change is
+    in-flight. When both `isDirty` and `isSaving` are false, the
+    change has persisted.
+
+    Example
+
+    ```javascript
+    var record = store.createRecord(App.Model);
+    record.get('isDeleted'); // false
+    record.deleteRecord();
+    record.get('isDeleted'); // true
+    ```
+
+    @property isDeleted
+    @type {Boolean}
+    @readOnly
+  */
+  isDeleted: retrieveFromCurrentState,
+  /**
+    If this property is `true` the record is in the `new` state. A
+    record will be in the `new` state when it has been created on the
+    client and the adapter has not yet report that it was successfully
+    saved.
+
+    Example
+
+    ```javascript
+    var record = store.createRecord(App.Model);
+    record.get('isNew'); // true
+
+    record.save().then(function(model) {
+      model.get('isNew'); // false
+    });
+    ```
+
+    @property isNew
+    @type {Boolean}
+    @readOnly
+  */
+  isNew: retrieveFromCurrentState,
+  /**
+    If this property is `true` the record is in the `valid` state. A
+    record will be in the `valid` state when no client-side
+    validations have failed and the adapter did not report any
+    server-side validation failures.
+
+    @property isValid
+    @type {Boolean}
+    @readOnly
+  */
+  isValid: retrieveFromCurrentState,
+  /**
+    If the record is in the dirty state this property will report what
+    kind of change has caused it to move into the dirty
+    state. Possible values are:
+
+    - `created` The record has been created by the client and not yet saved to the adapter.
+    - `updated` The record has been updated by the client and not yet saved to the adapter.
+    - `deleted` The record has been deleted by the client and not yet saved to the adapter.
+
+    Example
+
+    ```javascript
+    var record = store.createRecord(App.Model);
+    record.get('dirtyType'); // 'created'
+    ```
+
+    @property dirtyType
+    @type {String}
+    @readOnly
+  */
+  dirtyType: retrieveFromCurrentState,
+
+  /**
+    If `true` the adapter reported that it was unable to save local
+    changes to the backend. This may also result in the record having
+    its `isValid` property become false if the adapter reported that
+    server-side validations failed.
+
+    Example
+
+    ```javascript
+    record.get('isError'); // false
+    record.set('foo', 'invalid value');
+    record.save().then(null, function() {
+      record.get('isError'); // true
+    });
+    ```
+
+    @property isError
+    @type {Boolean}
+    @readOnly
+  */
+  isError: false,
+  /**
+    If `true` the store is attempting to reload the record form the adapter.
+
+    Example
+
+    ```javascript
+    record.get('isReloading'); // false
+    record.reload();
+    record.get('isReloading'); // true
+    ```
+
+    @property isReloading
+    @type {Boolean}
+    @readOnly
+  */
+  isReloading: false,
+
+  /**
+    The `clientId` property is a transient numerical identifier
+    generated at runtime by the data store. It is important
+    primarily because newly created objects may not yet have an
+    externally generated id.
+
+    @property clientId
+    @private
+    @type {Number|String}
+  */
+  clientId: null,
+  /**
+    All ember models have an id property. This is an identifier
+    managed by an external source. These are always coerced to be
+    strings before being used internally. Note when declaring the
+    attributes for a model it is an error to declare an id
+    attribute.
+
+    ```javascript
+    var record = store.createRecord(App.Model);
+    record.get('id'); // null
+
+    store.find('model', 1).then(function(model) {
+      model.get('id'); // '1'
+    });
+    ```
+
+    @property id
+    @type {String}
+  */
+  id: null,
+  transaction: null,
+  /**
+    @property currentState
+    @private
+    @type {Object}
+  */
+  currentState: null,
+  /**
+    When the record is in the `invalid` state this object will contain
+    any errors returned by the adapter. When present the errors hash
+    typically contains keys corresponding to the invalid property names
+    and values which are an array of error messages.
+
+    ```javascript
+    record.get('errors.length'); // 0
+    record.set('foo', 'invalid value');
+    record.save().then(null, function() {
+      record.get('errors').get('foo'); // ['foo should be a number.']
+    });
+    ```
+
+    @property errors
+    @type {Object}
+  */
+  errors: null,
+
+  /**
+    Create a JSON representation of the record, using the serialization
+    strategy of the store's adapter.
+
+   `serialize` takes an optional hash as a parameter, currently
+    supported options are:
+
+   - `includeId`: `true` if the record's ID should be included in the
+      JSON representation.
+
+    @method serialize
+    @param {Object} options
+    @returns {Object} an object whose values are primitive JSON values only
+  */
+  serialize: function(options) {
+    var store = get(this, 'store');
+    return store.serialize(this, options);
+  },
+
+  /**
+    Use [DS.JSONSerializer](DS.JSONSerializer.html) to
+    get the JSON representation of a record.
+
+    `toJSON` takes an optional hash as a parameter, currently
+    supported options are:
+
+    - `includeId`: `true` if the record's ID should be included in the
+      JSON representation.
+
+    @method toJSON
+    @param {Object} options
+    @returns {Object} A JSON representation of the object.
+  */
+  toJSON: function(options) {
+    // container is for lazy transform lookups
+    var serializer = DS.JSONSerializer.create({ container: this.container });
+    return serializer.serialize(this, options);
+  },
+
+  /**
+    Fired when the record is loaded from the server.
+
+    @event didLoad
+  */
+  didLoad: Ember.K,
+
+  /**
+    Fired when the record is updated.
+
+    @event didUpdate
+  */
+  didUpdate: Ember.K,
+
+  /**
+    Fired when the record is created.
+
+    @event didCreate
+  */
+  didCreate: Ember.K,
+
+  /**
+    Fired when the record is deleted.
+
+    @event didDelete
+  */
+  didDelete: Ember.K,
+
+  /**
+    Fired when the record becomes invalid.
+
+    @event becameInvalid
+  */
+  becameInvalid: Ember.K,
+
+  /**
+    Fired when the record enters the error state.
+
+    @event becameError
+  */
+  becameError: Ember.K,
+
+  /**
+    @property data
+    @private
+    @type {Object}
+  */
+  data: Ember.computed(function() {
+    this._data = this._data || {};
+    return this._data;
+  }).property(),
+
+  _data: null,
+
+  init: function() {
+    set(this, 'currentState', DS.RootState.empty);
+    var errors = DS.Errors.create();
+    errors.registerHandlers(this, function() {
+      this.send('becameInvalid');
+    }, function() {
+      this.send('becameValid');
+    });
+    set(this, 'errors', errors);
+    this._super();
+    this._setup();
+  },
+
+  _setup: function() {
+    this._changesToSync = {};
+    this._deferredTriggers = [];
+    this._data = {};
+    this._attributes = {};
+    this._inFlightAttributes = {};
+    this._relationships = {};
+  },
+
+  /**
+    @method send
+    @private
+    @param {String} name
+    @param {Object} context
+  */
+  send: function(name, context) {
+    var currentState = get(this, 'currentState');
+
+    if (!currentState[name]) {
+      this._unhandledEvent(currentState, name, context);
+    }
+
+    return currentState[name](this, context);
+  },
+
+  /**
+    @method transitionTo
+    @private
+    @param {String} name
+  */
+  transitionTo: function(name) {
+    // POSSIBLE TODO: Remove this code and replace with
+    // always having direct references to state objects
+
+    var pivotName = name.split(&quot;.&quot;, 1),
+        currentState = get(this, 'currentState'),
+        state = currentState;
+
+    do {
+      if (state.exit) { state.exit(this); }
+      state = state.parentState;
+    } while (!state.hasOwnProperty(pivotName));
+
+    var path = name.split(&quot;.&quot;);
+
+    var setups = [], enters = [], i, l;
+
+    for (i=0, l=path.length; i&lt;l; i++) {
+      state = state[path[i]];
+
+      if (state.enter) { enters.push(state); }
+      if (state.setup) { setups.push(state); }
+    }
+
+    for (i=0, l=enters.length; i&lt;l; i++) {
+      enters[i].enter(this);
+    }
+
+    set(this, 'currentState', state);
+
+    for (i=0, l=setups.length; i&lt;l; i++) {
+      setups[i].setup(this);
+    }
+
+    this.updateRecordArraysLater();
+  },
+
+  _unhandledEvent: function(state, name, context) {
+    var errorMessage = &quot;Attempted to handle event `&quot; + name + &quot;` &quot;;
+    errorMessage    += &quot;on &quot; + String(this) + &quot; while in state &quot;;
+    errorMessage    += state.stateName + &quot;. &quot;;
+
+    if (context !== undefined) {
+      errorMessage  += &quot;Called with &quot; + Ember.inspect(context) + &quot;.&quot;;
+    }
+
+    throw new Ember.Error(errorMessage);
+  },
+
+  withTransaction: function(fn) {
+    var transaction = get(this, 'transaction');
+    if (transaction) { fn(transaction); }
+  },
+
+  /**
+    @method loadingData
+    @private
+    @param {Promise} promise
+  */
+  loadingData: function(promise) {
+    this.send('loadingData', promise);
+  },
+
+  /**
+    @method loadedData
+    @private
+  */
+  loadedData: function() {
+    this.send('loadedData');
+  },
+
+  /**
+    @method notFound
+    @private
+  */
+  notFound: function() {
+    this.send('notFound');
+  },
+
+  /**
+    @method pushedData
+    @private
+  */
+  pushedData: function() {
+    this.send('pushedData');
+  },
+
+  /**
+    Marks the record as deleted but does not save it. You must call
+    `save` afterwards if you want to persist it. You might use this
+    method if you want to allow the user to still `rollback()` a
+    delete after it was made.
+
+    Example
+
+    ```javascript
+    App.ModelDeleteRoute = Ember.Route.extend({
+      actions: {
+        softDelete: function() {
+          this.get('model').deleteRecord();
+        },
+        confirm: function() {
+          this.get('model').save();
+        },
+        undo: function() {
+          this.get('model').rollback();
+        }
+      }
+    });
+    ```
+
+    @method deleteRecord
+  */
+  deleteRecord: function() {
+    this.send('deleteRecord');
+  },
+
+  /**
+    Same as `deleteRecord`, but saves the record immediately.
+
+    Example
+
+    ```javascript
+    App.ModelDeleteRoute = Ember.Route.extend({
+      actions: {
+        delete: function() {
+          var controller = this.controller;
+          this.get('model').destroyRecord().then(function() {
+            controller.transitionToRoute('model.index');
+          });
+        }
+      }
+    });
+    ```
+
+    @method destroyRecord
+    @return {Promise} a promise that will be resolved when the adapter returns
+    successfully or rejected if the adapter returns with an error.
+  */
+  destroyRecord: function() {
+    this.deleteRecord();
+    return this.save();
+  },
+
+  /**
+    @method unloadRecord
+    @private
+  */
+  unloadRecord: function() {
+    Ember.assert(&quot;You can only unload a loaded, non-dirty record.&quot;, !get(this, 'isDirty'));
+
+    this.send('unloadRecord');
+  },
+
+  /**
+    @method clearRelationships
+    @private
+  */
+  clearRelationships: function() {
+    this.eachRelationship(function(name, relationship) {
+      if (relationship.kind === 'belongsTo') {
+        set(this, name, null);
+      } else if (relationship.kind === 'hasMany') {
+        var hasMany = this._relationships[relationship.name];
+        if (hasMany) { hasMany.clear(); }
+      }
+    }, this);
+  },
+
+  /**
+    @method updateRecordArrays
+    @private
+  */
+  updateRecordArrays: function() {
+    this._updatingRecordArraysLater = false;
+    get(this, 'store').dataWasUpdated(this.constructor, this);
+  },
+
+  /**
+    Returns an object, whose keys are changed properties, and value is
+    an [oldProp, newProp] array.
+
+    Example
+
+    ```javascript
+    App.Mascot = DS.Model.extend({
+      name: attr('string')
+    });
+
+    var person = store.createRecord('person');
+    person.changedAttributes(); // {}
+    person.set('name', 'Tomster');
+    person.changedAttributes(); // {name: [undefined, 'Tomster']}
+    ```
+
+    @method changedAttributes
+    @return {Object} an object, whose keys are changed properties,
+      and value is an [oldProp, newProp] array.
+  */
+  changedAttributes: function() {
+    var oldData = get(this, '_data'),
+        newData = get(this, '_attributes'),
+        diffData = {},
+        prop;
+
+    for (prop in newData) {
+      diffData[prop] = [oldData[prop], newData[prop]];
+    }
+
+    return diffData;
+  },
+
+  /**
+    @method adapterWillCommit
+    @private
+  */
+  adapterWillCommit: function() {
+    this.send('willCommit');
+  },
+
+  /**
+    If the adapter did not return a hash in response to a commit,
+    merge the changed attributes and relationships into the existing
+    saved data.
+
+    @method adapterDidCommit
+  */
+  adapterDidCommit: function(data) {
+    set(this, 'isError', false);
+
+    if (data) {
+      this._data = data;
+    } else {
+      Ember.mixin(this._data, this._inFlightAttributes);
+    }
+
+    this._inFlightAttributes = {};
+
+    this.send('didCommit');
+    this.updateRecordArraysLater();
+
+    if (!data) { return; }
+
+    this.suspendRelationshipObservers(function() {
+      this.notifyPropertyChange('data');
+    });
+  },
+
+  /**
+    @method adapterDidDirty
+    @private
+  */
+  adapterDidDirty: function() {
+    this.send('becomeDirty');
+    this.updateRecordArraysLater();
+  },
+
+  dataDidChange: Ember.observer(function() {
+    this.reloadHasManys();
+  }, 'data'),
+
+  reloadHasManys: function() {
+    var relationships = get(this.constructor, 'relationshipsByName');
+    this.updateRecordArraysLater();
+    relationships.forEach(function(name, relationship) {
+      if (this._data.links &amp;&amp; this._data.links[name]) { return; }
+      if (relationship.kind === 'hasMany') {
+        this.hasManyDidChange(relationship.key);
+      }
+    }, this);
+  },
+
+  hasManyDidChange: function(key) {
+    var hasMany = this._relationships[key];
+
+    if (hasMany) {
+      var records = this._data[key] || [];
+
+      set(hasMany, 'content', Ember.A(records));
+      set(hasMany, 'isLoaded', true);
+      hasMany.trigger('didLoad');
+    }
+  },
+
+  /**
+    @method updateRecordArraysLater
+    @private
+  */
+  updateRecordArraysLater: function() {
+    // quick hack (something like this could be pushed into run.once
+    if (this._updatingRecordArraysLater) { return; }
+    this._updatingRecordArraysLater = true;
+
+    Ember.run.schedule('actions', this, this.updateRecordArrays);
+  },
+
+  /**
+    @method setupData
+    @private
+    @param {Object} data
+    @param {Boolean} partial the data should be merged into
+      the existing data, not replace it.
+  */
+  setupData: function(data, partial) {
+    if (partial) {
+      Ember.merge(this._data, data);
+    } else {
+      this._data = data;
+    }
+
+    var relationships = this._relationships;
+
+    this.eachRelationship(function(name, rel) {
+      if (data.links &amp;&amp; data.links[name]) { return; }
+      if (rel.options.async) { relationships[name] = null; }
+    });
+
+    if (data) { this.pushedData(); }
+
+    this.suspendRelationshipObservers(function() {
+      this.notifyPropertyChange('data');
+    });
+  },
+
+  materializeId: function(id) {
+    set(this, 'id', id);
+  },
+
+  materializeAttributes: function(attributes) {
+    Ember.assert(&quot;Must pass a hash of attributes to materializeAttributes&quot;, !!attributes);
+    merge(this._data, attributes);
+  },
+
+  materializeAttribute: function(name, value) {
+    this._data[name] = value;
+  },
+
+  /**
+    @method updateHasMany
+    @private
+    @param {String} name
+    @param {Array} records
+  */
+  updateHasMany: function(name, records) {
+    this._data[name] = records;
+    this.hasManyDidChange(name);
+  },
+
+  /**
+    @method updateBelongsTo
+    @private
+    @param {String} name
+    @param {DS.Model} record
+  */
+  updateBelongsTo: function(name, record) {
+    this._data[name] = record;
+  },
+
+  /**
+    If the model `isDirty` this function will discard any unsaved
+    changes
+
+    Example
+
+    ```javascript
+    record.get('name'); // 'Untitled Document'
+    record.set('name', 'Doc 1');
+    record.get('name'); // 'Doc 1'
+    record.rollback();
+    record.get('name'); // 'Untitled Document'
+    ```
+
+    @method rollback
+  */
+  rollback: function() {
+    this._attributes = {};
+
+    if (get(this, 'isError')) {
+      this._inFlightAttributes = {};
+      set(this, 'isError', false);
+    }
+
+    if (!get(this, 'isValid')) {
+      this._inFlightAttributes = {};
+    }
+
+    this.send('rolledBack');
+
+    this.suspendRelationshipObservers(function() {
+      this.notifyPropertyChange('data');
+    });
+  },
+
+  toStringExtension: function() {
+    return get(this, 'id');
+  },
+
+  /**
+    The goal of this method is to temporarily disable specific observers
+    that take action in response to application changes.
+
+    This allows the system to make changes (such as materialization and
+    rollback) that should not trigger secondary behavior (such as setting an
+    inverse relationship or marking records as dirty).
+
+    The specific implementation will likely change as Ember proper provides
+    better infrastructure for suspending groups of observers, and if Array
+    observation becomes more unified with regular observers.
+
+    @method suspendRelationshipObservers
+    @private
+    @param callback
+    @param binding
+  */
+  suspendRelationshipObservers: function(callback, binding) {
+    var observers = get(this.constructor, 'relationshipNames').belongsTo;
+    var self = this;
+
+    try {
+      this._suspendedRelationships = true;
+      Ember._suspendObservers(self, observers, null, 'belongsToDidChange', function() {
+        Ember._suspendBeforeObservers(self, observers, null, 'belongsToWillChange', function() {
+          callback.call(binding || self);
+        });
+      });
+    } finally {
+      this._suspendedRelationships = false;
+    }
+  },
+
+  /**
+    Save the record and persist any changes to the record to an
+    extenal source via the adapter.
+
+    Example
+
+    ```javascript
+    record.set('name', 'Tomster');
+    record.save().then(function(){
+      // Success callback
+    }, function() {
+      // Error callback
+    });
+    ```
+    @method save
+    @return {Promise} a promise that will be resolved when the adapter returns
+    successfully or rejected if the adapter returns with an error.
+  */
+  save: function() {
+    var promiseLabel = &quot;DS: Model#save &quot; + this;
+    var resolver = Ember.RSVP.defer(promiseLabel);
+
+    this.get('store').scheduleSave(this, resolver);
+    this._inFlightAttributes = this._attributes;
+    this._attributes = {};
+
+    return DS.PromiseObject.create({ promise: resolver.promise });
+  },
+
+  /**
+    Reload the record from the adapter.
+
+    This will only work if the record has already finished loading
+    and has not yet been modified (`isLoaded` but not `isDirty`,
+    or `isSaving`).
+
+    Example
+
+    ```javascript
+    App.ModelViewRoute = Ember.Route.extend({
+      actions: {
+        reload: function() {
+          this.get('model').reload();
+        }
+      }
+    });
+    ```
+
+    @method reload
+    @return {Promise} a promise that will be resolved with the record when the
+    adapter returns successfully or rejected if the adapter returns
+    with an error.
+  */
+  reload: function() {
+    set(this, 'isReloading', true);
+
+    var  record = this;
+
+    var promiseLabel = &quot;DS: Model#reload of &quot; + this;
+    var promise = new Ember.RSVP.Promise(function(resolve){
+       record.send('reloadRecord', resolve);
+    }, promiseLabel).then(function() {
+      record.set('isReloading', false);
+      record.set('isError', false);
+      return record;
+    }, function(reason) {
+      record.set('isError', true);
+      throw reason;
+    }, &quot;DS: Model#reload complete, update flags&quot;);
+
+    return DS.PromiseObject.create({ promise: promise });
+  },
+
+  // FOR USE DURING COMMIT PROCESS
+
+  adapterDidUpdateAttribute: function(attributeName, value) {
+
+    // If a value is passed in, update the internal attributes and clear
+    // the attribute cache so it picks up the new value. Otherwise,
+    // collapse the current value into the internal attributes because
+    // the adapter has acknowledged it.
+    if (value !== undefined) {
+      this._data[attributeName] = value;
+      this.notifyPropertyChange(attributeName);
+    } else {
+      this._data[attributeName] = this._inFlightAttributes[attributeName];
+    }
+
+    this.updateRecordArraysLater();
+  },
+
+  /**
+    @method adapterDidInvalidate
+    @private
+  */
+  adapterDidInvalidate: function(errors) {
+    var recordErrors = get(this, 'errors');
+    function addError(name) {
+      if (errors[name]) {
+        recordErrors.add(name, errors[name]);
+      }
+    }
+
+    this.eachAttribute(addError);
+    this.eachRelationship(addError);
+  },
+
+  /**
+    @method adapterDidError
+    @private
+  */
+  adapterDidError: function() {
+    this.send('becameError');
+    set(this, 'isError', true);
+  },
+
+  /**
+    Override the default event firing from Ember.Evented to
+    also call methods with the given name.
+
+    @method trigger
+    @private
+    @param name
+  */
+  trigger: function(name) {
+    Ember.tryInvoke(this, name, [].slice.call(arguments, 1));
+    this._super.apply(this, arguments);
+  },
+
+  triggerLater: function() {
+    if (this._deferredTriggers.push(arguments) !== 1) { return; }
+    Ember.run.schedule('actions', this, '_triggerDeferredTriggers');
+  },
+
+  _triggerDeferredTriggers: function() {
+    for (var i=0, l=this._deferredTriggers.length; i&lt;l; i++) {
+      this.trigger.apply(this, this._deferredTriggers[i]);
+    }
+
+    this._deferredTriggers.length = 0;
+  }
+});
+
+DS.Model.reopenClass({
+
+  /**
+    Alias DS.Model's `create` method to `_create`. This allows us to create DS.Model
+    instances from within the store, but if end users accidentally call `create()`
+    (instead of `createRecord()`), we can raise an error.
+
+    @method _create
+    @private
+    @static
+  */
+  _create: DS.Model.create,
+
+  /**
+    Override the class' `create()` method to raise an error. This
+    prevents end users from inadvertently calling `create()` instead
+    of `createRecord()`. The store is still able to create instances
+    by calling the `_create()` method. To create an instance of a
+    `DS.Model` use [store.createRecord](DS.Store.html#method_createRecord).
+
+    @method create
+    @private
+    @static
+  */
+  create: function() {
+    throw new Ember.Error(&quot;You should not call `create` on a model. Instead, call `store.createRecord` with the attributes you would like to set.&quot;);
+  }
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var get = Ember.get;
+
+/**
+  @class Model
+  @namespace DS
+*/
+DS.Model.reopenClass({
+  /**
+    A map whose keys are the attributes of the model (properties
+    described by DS.attr) and whose values are the meta object for the
+    property.
+
+    Example
+
+    ```javascript
+
+    App.Person = DS.Model.extend({
+      firstName: attr('string'),
+      lastName: attr('string'),
+      birthday: attr('date')
+    });
+
+    var attributes = Ember.get(App.Person, 'attributes')
+
+    attributes.forEach(function(name, meta) {
+      console.log(name, meta);
+    });
+
+    // prints:
+    // firstName {type: &quot;string&quot;, isAttribute: true, options: Object, parentType: function, name: &quot;firstName&quot;}
+    // lastName {type: &quot;string&quot;, isAttribute: true, options: Object, parentType: function, name: &quot;lastName&quot;}
+    // birthday {type: &quot;date&quot;, isAttribute: true, options: Object, parentType: function, name: &quot;birthday&quot;}
+    ```
+
+    @property attributes
+    @static
+    @type {Ember.Map}
+    @readOnly
+  */
+  attributes: Ember.computed(function() {
+    var map = Ember.Map.create();
+
+    this.eachComputedProperty(function(name, meta) {
+      if (meta.isAttribute) {
+        Ember.assert(&quot;You may not set `id` as an attribute on your model. Please remove any lines that look like: `id: DS.attr('&lt;type&gt;')` from &quot; + this.toString(), name !== 'id');
+
+        meta.name = name;
+        map.set(name, meta);
+      }
+    });
+
+    return map;
+  }),
+
+  /**
+    A map whose keys are the attributes of the model (properties
+    described by DS.attr) and whose values are type of transformation
+    applied to each attribute. This map does not include any
+    attributes that do not have an transformation type.
+
+    Example
+
+    ```javascript
+    App.Person = DS.Model.extend({
+      firstName: attr(),
+      lastName: attr('string'),
+      birthday: attr('date')
+    });
+
+    var transformedAttributes = Ember.get(App.Person, 'transformedAttributes')
+
+    transformedAttributes.forEach(function(field, type) {
+      console.log(field, type);
+    });
+
+    // prints:
+    // lastName string
+    // birthday date
+    ```
+
+    @property transformedAttributes
+    @static
+    @type {Ember.Map}
+    @readOnly
+  */
+  transformedAttributes: Ember.computed(function() {
+    var map = Ember.Map.create();
+
+    this.eachAttribute(function(key, meta) {
+      if (meta.type) {
+        map.set(key, meta.type);
+      }
+    });
+
+    return map;
+  }),
+
+  /**
+    Iterates through the attributes of the model, calling the passed function on each
+    attribute.
+
+    The callback method you provide should have the following signature (all
+    parameters are optional):
+
+    ```javascript
+    function(name, meta);
+    ```
+
+    - `name` the name of the current property in the iteration
+    - `meta` the meta object for the attribute property in the iteration
+
+    Note that in addition to a callback, you can also pass an optional target
+    object that will be set as `this` on the context.
+
+    Example
+
+    ```javascript
+    App.Person = DS.Model.extend({
+      firstName: attr('string'),
+      lastName: attr('string'),
+      birthday: attr('date')
+    });
+
+    App.Person.eachAttribute(function(name, meta) {
+      console.log(name, meta);
+    });
+
+    // prints:
+    // firstName {type: &quot;string&quot;, isAttribute: true, options: Object, parentType: function, name: &quot;firstName&quot;}
+    // lastName {type: &quot;string&quot;, isAttribute: true, options: Object, parentType: function, name: &quot;lastName&quot;}
+    // birthday {type: &quot;date&quot;, isAttribute: true, options: Object, parentType: function, name: &quot;birthday&quot;}
+   ```
+
+    @method eachAttribute
+    @param {Function} callback The callback to execute
+    @param {Object} [target] The target object to use
+    @static
+  */
+  eachAttribute: function(callback, binding) {
+    get(this, 'attributes').forEach(function(name, meta) {
+      callback.call(binding, name, meta);
+    }, binding);
+  },
+
+  /**
+    Iterates through the transformedAttributes of the model, calling
+    the passed function on each attribute. Note the callback will not be
+    called for any attributes that do not have an transformation type.
+
+    The callback method you provide should have the following signature (all
+    parameters are optional):
+
+    ```javascript
+    function(name, type);
+    ```
+
+    - `name` the name of the current property in the iteration
+    - `type` a string containing the name of the type of transformed
+      applied to the attribute
+
+    Note that in addition to a callback, you can also pass an optional target
+    object that will be set as `this` on the context.
+
+    Example
+
+    ```javascript
+    App.Person = DS.Model.extend({
+      firstName: attr(),
+      lastName: attr('string'),
+      birthday: attr('date')
+    });
+
+    App.Person.eachTransformedAttribute(function(name, type) {
+      console.log(name, type);
+    });
+
+    // prints:
+    // lastName string
+    // birthday date
+   ```
+
+    @method eachTransformedAttribute
+    @param {Function} callback The callback to execute
+    @param {Object} [target] The target object to use
+    @static
+  */
+  eachTransformedAttribute: function(callback, binding) {
+    get(this, 'transformedAttributes').forEach(function(name, type) {
+      callback.call(binding, name, type);
+    });
+  }
+});
+
+
+DS.Model.reopen({
+  eachAttribute: function(callback, binding) {
+    this.constructor.eachAttribute(callback, binding);
+  }
+});
+
+function getDefaultValue(record, options, key) {
+  if (typeof options.defaultValue === &quot;function&quot;) {
+    return options.defaultValue();
+  } else {
+    return options.defaultValue;
+  }
+}
+
+function hasValue(record, key) {
+  return record._attributes.hasOwnProperty(key) ||
+         record._inFlightAttributes.hasOwnProperty(key) ||
+         record._data.hasOwnProperty(key);
+}
+
+function getValue(record, key) {
+  if (record._attributes.hasOwnProperty(key)) {
+    return record._attributes[key];
+  } else if (record._inFlightAttributes.hasOwnProperty(key)) {
+    return record._inFlightAttributes[key];
+  } else {
+    return record._data[key];
+  }
+}
+
+/**
+  `DS.attr` defines an attribute on a [DS.Model](DS.Model.html).
+  By default, attributes are passed through as-is, however you can specify an
+  optional type to have the value automatically transformed.
+  Ember Data ships with four basic transform types: `string`, `number`,
+  `boolean` and `date`. You can define your own transforms by subclassing
+  [DS.Transform](DS.Transform.html).
+
+  `DS.attr` takes an optional hash as a second parameter, currently
+  supported options are:
+
+  - `defaultValue`: Pass a string or a function to be called to set the attribute
+                    to a default value if none is supplied.
+
+  Example
+
+  ```javascript
+  var attr = DS.attr;
+
+  App.User = DS.Model.extend({
+    username: attr('string'),
+    email: attr('string'),
+    verified: attr('boolean', {defaultValue: false})
+  });
+  ```
+
+  @namespace
+  @method attr
+  @for DS
+  @param {String} type the attribute type
+  @param {Object} options a hash of options
+  @return {Attribute}
+*/
+
+DS.attr = function(type, options) {
+  options = options || {};
+
+  var meta = {
+    type: type,
+    isAttribute: true,
+    options: options
+  };
+
+  return Ember.computed(function(key, value) {
+    if (arguments.length &gt; 1) {
+      Ember.assert(&quot;You may not set `id` as an attribute on your model. Please remove any lines that look like: `id: DS.attr('&lt;type&gt;')` from &quot; + this.constructor.toString(), key !== 'id');
+      var oldValue = this._attributes[key] || this._inFlightAttributes[key] || this._data[key];
+
+      this.send('didSetProperty', {
+        name: key,
+        oldValue: oldValue,
+        originalValue: this._data[key],
+        value: value
+      });
+
+      this._attributes[key] = value;
+      return value;
+    } else if (hasValue(this, key)) {
+      return getValue(this, key);
+    } else {
+      return getDefaultValue(this, options, key);
+    }
+
+  // `data` is never set directly. However, it may be
+  // invalidated from the state manager's setData
+  // event.
+  }).property('data').meta(meta);
+};
+
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+/**
+  An AttributeChange object is created whenever a record's
+  attribute changes value. It is used to track changes to a
+  record between transaction commits.
+
+  @class AttributeChange
+  @namespace DS
+  @private
+  @constructor
+*/
+var AttributeChange = DS.AttributeChange = function(options) {
+  this.record = options.record;
+  this.store = options.store;
+  this.name = options.name;
+  this.value = options.value;
+  this.oldValue = options.oldValue;
+};
+
+AttributeChange.createChange = function(options) {
+  return new AttributeChange(options);
+};
+
+AttributeChange.prototype = {
+  sync: function() {
+    if (this.value !== this.oldValue) {
+      this.record.send('becomeDirty');
+      this.record.updateRecordArraysLater();
+    }
+
+    // TODO: Use this object in the commit process
+    this.destroy();
+  },
+
+  /**
+    If the AttributeChange is destroyed (either by being rolled back
+    or being committed), remove it from the list of pending changes
+    on the record.
+
+    @method destroy
+  */
+  destroy: function() {
+    delete this.record._changesToSync[this.name];
+  }
+};
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var get = Ember.get, set = Ember.set;
+var forEach = Ember.EnumerableUtils.forEach;
+
+/**
+  @class RelationshipChange
+  @namespace DS
+  @private
+  @constructor
+*/
+DS.RelationshipChange = function(options) {
+  this.parentRecord = options.parentRecord;
+  this.childRecord = options.childRecord;
+  this.firstRecord = options.firstRecord;
+  this.firstRecordKind = options.firstRecordKind;
+  this.firstRecordName = options.firstRecordName;
+  this.secondRecord = options.secondRecord;
+  this.secondRecordKind = options.secondRecordKind;
+  this.secondRecordName = options.secondRecordName;
+  this.changeType = options.changeType;
+  this.store = options.store;
+
+  this.committed = {};
+};
+
+/**
+  @class RelationshipChangeAdd
+  @namespace DS
+  @private
+  @constructor
+*/
+DS.RelationshipChangeAdd = function(options){
+  DS.RelationshipChange.call(this, options);
+};
+
+/**
+  @class RelationshipChangeRemove
+  @namespace DS
+  @private
+  @constructor
+*/
+DS.RelationshipChangeRemove = function(options){
+  DS.RelationshipChange.call(this, options);
+};
+
+DS.RelationshipChange.create = function(options) {
+  return new DS.RelationshipChange(options);
+};
+
+DS.RelationshipChangeAdd.create = function(options) {
+  return new DS.RelationshipChangeAdd(options);
+};
+
+DS.RelationshipChangeRemove.create = function(options) {
+  return new DS.RelationshipChangeRemove(options);
+};
+
+DS.OneToManyChange = {};
+DS.OneToNoneChange = {};
+DS.ManyToNoneChange = {};
+DS.OneToOneChange = {};
+DS.ManyToManyChange = {};
+
+DS.RelationshipChange._createChange = function(options){
+  if(options.changeType === &quot;add&quot;){
+    return DS.RelationshipChangeAdd.create(options);
+  }
+  if(options.changeType === &quot;remove&quot;){
+    return DS.RelationshipChangeRemove.create(options);
+  }
+};
+
+
+DS.RelationshipChange.determineRelationshipType = function(recordType, knownSide){
+  var knownKey = knownSide.key, key, otherKind;
+  var knownKind = knownSide.kind;
+
+  var inverse = recordType.inverseFor(knownKey);
+
+  if (inverse){
+    key = inverse.name;
+    otherKind = inverse.kind;
+  }
+
+  if (!inverse){
+    return knownKind === &quot;belongsTo&quot; ? &quot;oneToNone&quot; : &quot;manyToNone&quot;;
+  }
+  else{
+    if(otherKind === &quot;belongsTo&quot;){
+      return knownKind === &quot;belongsTo&quot; ? &quot;oneToOne&quot; : &quot;manyToOne&quot;;
+    }
+    else{
+      return knownKind === &quot;belongsTo&quot; ? &quot;oneToMany&quot; : &quot;manyToMany&quot;;
+    }
+  }
+
+};
+
+DS.RelationshipChange.createChange = function(firstRecord, secondRecord, store, options){
+  // Get the type of the child based on the child's client ID
+  var firstRecordType = firstRecord.constructor, changeType;
+  changeType = DS.RelationshipChange.determineRelationshipType(firstRecordType, options);
+  if (changeType === &quot;oneToMany&quot;){
+    return DS.OneToManyChange.createChange(firstRecord, secondRecord, store, options);
+  }
+  else if (changeType === &quot;manyToOne&quot;){
+    return DS.OneToManyChange.createChange(secondRecord, firstRecord, store, options);
+  }
+  else if (changeType === &quot;oneToNone&quot;){
+    return DS.OneToNoneChange.createChange(firstRecord, secondRecord, store, options);
+  }
+  else if (changeType === &quot;manyToNone&quot;){
+    return DS.ManyToNoneChange.createChange(firstRecord, secondRecord, store, options);
+  }
+  else if (changeType === &quot;oneToOne&quot;){
+    return DS.OneToOneChange.createChange(firstRecord, secondRecord, store, options);
+  }
+  else if (changeType === &quot;manyToMany&quot;){
+    return DS.ManyToManyChange.createChange(firstRecord, secondRecord, store, options);
+  }
+};
+
+DS.OneToNoneChange.createChange = function(childRecord, parentRecord, store, options) {
+  var key = options.key;
+  var change = DS.RelationshipChange._createChange({
+      parentRecord: parentRecord,
+      childRecord: childRecord,
+      firstRecord: childRecord,
+      store: store,
+      changeType: options.changeType,
+      firstRecordName: key,
+      firstRecordKind: &quot;belongsTo&quot;
+  });
+
+  store.addRelationshipChangeFor(childRecord, key, parentRecord, null, change);
+
+  return change;
+};
+
+DS.ManyToNoneChange.createChange = function(childRecord, parentRecord, store, options) {
+  var key = options.key;
+  var change = DS.RelationshipChange._createChange({
+      parentRecord: childRecord,
+      childRecord: parentRecord,
+      secondRecord: childRecord,
+      store: store,
+      changeType: options.changeType,
+      secondRecordName: options.key,
+      secondRecordKind: &quot;hasMany&quot;
+  });
+
+  store.addRelationshipChangeFor(childRecord, key, parentRecord, null, change);
+  return change;
+};
+
+
+DS.ManyToManyChange.createChange = function(childRecord, parentRecord, store, options) {
+  // If the name of the belongsTo side of the relationship is specified,
+  // use that
+  // If the type of the parent is specified, look it up on the child's type
+  // definition.
+  var key = options.key;
+
+  var change = DS.RelationshipChange._createChange({
+      parentRecord: parentRecord,
+      childRecord: childRecord,
+      firstRecord: childRecord,
+      secondRecord: parentRecord,
+      firstRecordKind: &quot;hasMany&quot;,
+      secondRecordKind: &quot;hasMany&quot;,
+      store: store,
+      changeType: options.changeType,
+      firstRecordName:  key
+  });
+
+  store.addRelationshipChangeFor(childRecord, key, parentRecord, null, change);
+
+
+  return change;
+};
+
+DS.OneToOneChange.createChange = function(childRecord, parentRecord, store, options) {
+  var key;
+
+  // If the name of the belongsTo side of the relationship is specified,
+  // use that
+  // If the type of the parent is specified, look it up on the child's type
+  // definition.
+  if (options.parentType) {
+    key = options.parentType.inverseFor(options.key).name;
+  } else if (options.key) {
+    key = options.key;
+  } else {
+    Ember.assert(&quot;You must pass either a parentType or belongsToName option to OneToManyChange.forChildAndParent&quot;, false);
+  }
+
+  var change = DS.RelationshipChange._createChange({
+      parentRecord: parentRecord,
+      childRecord: childRecord,
+      firstRecord: childRecord,
+      secondRecord: parentRecord,
+      firstRecordKind: &quot;belongsTo&quot;,
+      secondRecordKind: &quot;belongsTo&quot;,
+      store: store,
+      changeType: options.changeType,
+      firstRecordName:  key
+  });
+
+  store.addRelationshipChangeFor(childRecord, key, parentRecord, null, change);
+
+
+  return change;
+};
+
+DS.OneToOneChange.maintainInvariant = function(options, store, childRecord, key){
+  if (options.changeType === &quot;add&quot; &amp;&amp; store.recordIsMaterialized(childRecord)) {
+    var oldParent = get(childRecord, key);
+    if (oldParent){
+      var correspondingChange = DS.OneToOneChange.createChange(childRecord, oldParent, store, {
+          parentType: options.parentType,
+          hasManyName: options.hasManyName,
+          changeType: &quot;remove&quot;,
+          key: options.key
+        });
+      store.addRelationshipChangeFor(childRecord, key, options.parentRecord , null, correspondingChange);
+     correspondingChange.sync();
+    }
+  }
+};
+
+DS.OneToManyChange.createChange = function(childRecord, parentRecord, store, options) {
+  var key;
+
+  // If the name of the belongsTo side of the relationship is specified,
+  // use that
+  // If the type of the parent is specified, look it up on the child's type
+  // definition.
+  if (options.parentType) {
+    key = options.parentType.inverseFor(options.key).name;
+    DS.OneToManyChange.maintainInvariant( options, store, childRecord, key );
+  } else if (options.key) {
+    key = options.key;
+  } else {
+    Ember.assert(&quot;You must pass either a parentType or belongsToName option to OneToManyChange.forChildAndParent&quot;, false);
+  }
+
+  var change = DS.RelationshipChange._createChange({
+      parentRecord: parentRecord,
+      childRecord: childRecord,
+      firstRecord: childRecord,
+      secondRecord: parentRecord,
+      firstRecordKind: &quot;belongsTo&quot;,
+      secondRecordKind: &quot;hasMany&quot;,
+      store: store,
+      changeType: options.changeType,
+      firstRecordName:  key
+  });
+
+  store.addRelationshipChangeFor(childRecord, key, parentRecord, change.getSecondRecordName(), change);
+
+
+  return change;
+};
+
+
+DS.OneToManyChange.maintainInvariant = function(options, store, childRecord, key){
+  if (options.changeType === &quot;add&quot; &amp;&amp; childRecord) {
+    var oldParent = get(childRecord, key);
+    if (oldParent){
+      var correspondingChange = DS.OneToManyChange.createChange(childRecord, oldParent, store, {
+          parentType: options.parentType,
+          hasManyName: options.hasManyName,
+          changeType: &quot;remove&quot;,
+          key: options.key
+        });
+      store.addRelationshipChangeFor(childRecord, key, options.parentRecord, correspondingChange.getSecondRecordName(), correspondingChange);
+      correspondingChange.sync();
+    }
+  }
+};
+
+/**
+  @class RelationshipChange
+  @namespace DS
+*/
+DS.RelationshipChange.prototype = {
+
+  getSecondRecordName: function() {
+    var name = this.secondRecordName, parent;
+
+    if (!name) {
+      parent = this.secondRecord;
+      if (!parent) { return; }
+
+      var childType = this.firstRecord.constructor;
+      var inverse = childType.inverseFor(this.firstRecordName);
+      this.secondRecordName = inverse.name;
+    }
+
+    return this.secondRecordName;
+  },
+
+  /**
+    Get the name of the relationship on the belongsTo side.
+
+    @method getFirstRecordName
+    @return {String}
+  */
+  getFirstRecordName: function() {
+    var name = this.firstRecordName;
+    return name;
+  },
+
+  /**
+    @method destroy
+    @private
+  */
+  destroy: function() {
+    var childRecord = this.childRecord,
+        belongsToName = this.getFirstRecordName(),
+        hasManyName = this.getSecondRecordName(),
+        store = this.store;
+
+    store.removeRelationshipChangeFor(childRecord, belongsToName, this.parentRecord, hasManyName, this.changeType);
+  },
+
+  getSecondRecord: function(){
+    return this.secondRecord;
+  },
+
+  /**
+    @method getFirstRecord
+    @private
+  */
+  getFirstRecord: function() {
+    return this.firstRecord;
+  },
+
+  coalesce: function(){
+    var relationshipPairs = this.store.relationshipChangePairsFor(this.firstRecord);
+    forEach(relationshipPairs, function(pair){
+      var addedChange = pair[&quot;add&quot;];
+      var removedChange = pair[&quot;remove&quot;];
+      if(addedChange &amp;&amp; removedChange) {
+        addedChange.destroy();
+        removedChange.destroy();
+      }
+    });
+  }
+};
+
+DS.RelationshipChangeAdd.prototype = Ember.create(DS.RelationshipChange.create({}));
+DS.RelationshipChangeRemove.prototype = Ember.create(DS.RelationshipChange.create({}));
+
+// the object is a value, and not a promise
+function isValue(object) {
+  return typeof object === 'object' &amp;&amp; (!object.then || typeof object.then !== 'function');
+}
+
+DS.RelationshipChangeAdd.prototype.changeType = &quot;add&quot;;
+DS.RelationshipChangeAdd.prototype.sync = function() {
+  var secondRecordName = this.getSecondRecordName(),
+      firstRecordName = this.getFirstRecordName(),
+      firstRecord = this.getFirstRecord(),
+      secondRecord = this.getSecondRecord();
+
+  //Ember.assert(&quot;You specified a hasMany (&quot; + hasManyName + &quot;) on &quot; + (!belongsToName &amp;&amp; (newParent || oldParent || this.lastParent).constructor) + &quot; but did not specify an inverse belongsTo on &quot; + child.constructor, belongsToName);
+  //Ember.assert(&quot;You specified a belongsTo (&quot; + belongsToName + &quot;) on &quot; + child.constructor + &quot; but did not specify an inverse hasMany on &quot; + (!hasManyName &amp;&amp; (newParent || oldParent || this.lastParentRecord).constructor), hasManyName);
+
+  if (secondRecord instanceof DS.Model &amp;&amp; firstRecord instanceof DS.Model) {
+    if(this.secondRecordKind === &quot;belongsTo&quot;){
+      secondRecord.suspendRelationshipObservers(function(){
+        set(secondRecord, secondRecordName, firstRecord);
+      });
+
+     }
+     else if(this.secondRecordKind === &quot;hasMany&quot;){
+      secondRecord.suspendRelationshipObservers(function(){
+        var relationship = get(secondRecord, secondRecordName);
+        if (isValue(relationship)) { relationship.addObject(firstRecord); }
+      });
+    }
+  }
+
+  if (firstRecord instanceof DS.Model &amp;&amp; secondRecord instanceof DS.Model &amp;&amp; get(firstRecord, firstRecordName) !== secondRecord) {
+    if(this.firstRecordKind === &quot;belongsTo&quot;){
+      firstRecord.suspendRelationshipObservers(function(){
+        set(firstRecord, firstRecordName, secondRecord);
+      });
+    }
+    else if(this.firstRecordKind === &quot;hasMany&quot;){
+      firstRecord.suspendRelationshipObservers(function(){
+        var relationship = get(firstRecord, firstRecordName);
+        if (isValue(relationship)) { relationship.addObject(secondRecord); }
+      });
+    }
+  }
+
+  this.coalesce();
+};
+
+DS.RelationshipChangeRemove.prototype.changeType = &quot;remove&quot;;
+DS.RelationshipChangeRemove.prototype.sync = function() {
+  var secondRecordName = this.getSecondRecordName(),
+      firstRecordName = this.getFirstRecordName(),
+      firstRecord = this.getFirstRecord(),
+      secondRecord = this.getSecondRecord();
+
+  //Ember.assert(&quot;You specified a hasMany (&quot; + hasManyName + &quot;) on &quot; + (!belongsToName &amp;&amp; (newParent || oldParent || this.lastParent).constructor) + &quot; but did not specify an inverse belongsTo on &quot; + child.constructor, belongsToName);
+  //Ember.assert(&quot;You specified a belongsTo (&quot; + belongsToName + &quot;) on &quot; + child.constructor + &quot; but did not specify an inverse hasMany on &quot; + (!hasManyName &amp;&amp; (newParent || oldParent || this.lastParentRecord).constructor), hasManyName);
+
+  if (secondRecord instanceof DS.Model &amp;&amp; firstRecord instanceof DS.Model) {
+    if(this.secondRecordKind === &quot;belongsTo&quot;){
+      secondRecord.suspendRelationshipObservers(function(){
+        set(secondRecord, secondRecordName, null);
+      });
+    }
+    else if(this.secondRecordKind === &quot;hasMany&quot;){
+      secondRecord.suspendRelationshipObservers(function(){
+        var relationship = get(secondRecord, secondRecordName);
+        if (isValue(relationship)) { relationship.removeObject(firstRecord); }
+      });
+    }
+  }
+
+  if (firstRecord instanceof DS.Model &amp;&amp; get(firstRecord, firstRecordName)) {
+    if(this.firstRecordKind === &quot;belongsTo&quot;){
+      firstRecord.suspendRelationshipObservers(function(){
+        set(firstRecord, firstRecordName, null);
+      });
+     }
+     else if(this.firstRecordKind === &quot;hasMany&quot;){
+       firstRecord.suspendRelationshipObservers(function(){
+         var relationship = get(firstRecord, firstRecordName);
+         if (isValue(relationship)) { relationship.removeObject(secondRecord); }
+      });
+    }
+  }
+
+  this.coalesce();
+};
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+})();
+
+
+
+(function() {
+var get = Ember.get, set = Ember.set,
+    isNone = Ember.isNone;
+
+/**
+  @module ember-data
+*/
+
+function asyncBelongsTo(type, options, meta) {
+  return Ember.computed(function(key, value) {
+    var data = get(this, 'data'),
+        store = get(this, 'store'),
+        promiseLabel = &quot;DS: Async belongsTo &quot; + this + &quot; : &quot; + key;
+
+    if (arguments.length === 2) {
+      Ember.assert(&quot;You can only add a '&quot; + type + &quot;' record to this relationship&quot;, !value || value instanceof store.modelFor(type));
+      return value === undefined ? null : DS.PromiseObject.create({ promise: Ember.RSVP.resolve(value, promiseLabel) });
+    }
+
+    var link = data.links &amp;&amp; data.links[key],
+        belongsTo = data[key];
+
+    if(!isNone(belongsTo)) {
+      var promise = store.fetchRecord(belongsTo) || Ember.RSVP.resolve(belongsTo, promiseLabel);
+      return DS.PromiseObject.create({ promise: promise});
+    } else if (link) {
+      var resolver = Ember.RSVP.defer(&quot;DS: Async belongsTo (link) &quot; + this + &quot; : &quot; + key);
+      store.findBelongsTo(this, link, meta, resolver);
+      return DS.PromiseObject.create({ promise: resolver.promise });
+    } else {
+      return null;
+    }
+  }).property('data').meta(meta);
+}
+
+/**
+  `DS.belongsTo` is used to define One-To-One and One-To-Many
+  relationships on a [DS.Model](DS.Model.html).
+
+
+  `DS.belongsTo` takes an optional hash as a second parameter, currently
+  supported options are:
+
+  - `async`: A boolean value used to explicitly declare this to be an async relationship.
+  - `inverse`: A string used to identify the inverse property on a
+    related model in a One-To-Many relationship. See [Explicit Inverses](#toc_explicit-inverses)
+
+  #### One-To-One
+  To declare a one-to-one relationship between two models, use
+  `DS.belongsTo`:
+
+  ```javascript
+  App.User = DS.Model.extend({
+    profile: DS.belongsTo('profile')
+  });
+
+  App.Profile = DS.Model.extend({
+    user: DS.belongsTo('user')
+  });
+  ```
+
+  #### One-To-Many
+  To declare a one-to-many relationship between two models, use
+  `DS.belongsTo` in combination with `DS.hasMany`, like this:
+
+  ```javascript
+  App.Post = DS.Model.extend({
+    comments: DS.hasMany('comment')
+  });
+
+  App.Comment = DS.Model.extend({
+    post: DS.belongsTo('post')
+  });
+  ```
+
+  @namespace
+  @method belongsTo
+  @for DS
+  @param {String or DS.Model} type the model type of the relationship
+  @param {Object} options a hash of options
+  @return {Ember.computed} relationship
+*/
+DS.belongsTo = function(type, options) {
+  if (typeof type === 'object') {
+    options = type;
+    type = undefined;
+  } else {
+    Ember.assert(&quot;The first argument DS.belongsTo must be a model type or string, like DS.belongsTo(App.Person)&quot;, !!type &amp;&amp; (typeof type === 'string' || DS.Model.detect(type)));
+  }
+
+  options = options || {};
+
+  var meta = { type: type, isRelationship: true, options: options, kind: 'belongsTo' };
+
+  if (options.async) {
+    return asyncBelongsTo(type, options, meta);
+  }
+
+  return Ember.computed(function(key, value) {
+    var data = get(this, 'data'),
+        store = get(this, 'store'), belongsTo, typeClass;
+
+    if (typeof type === 'string') {
+      typeClass = store.modelFor(type);
+    } else {
+      typeClass = type;
+    }
+
+    if (arguments.length === 2) {
+      Ember.assert(&quot;You can only add a '&quot; + type + &quot;' record to this relationship&quot;, !value || value instanceof typeClass);
+      return value === undefined ? null : value;
+    }
+
+    belongsTo = data[key];
+
+    if (isNone(belongsTo)) { return null; }
+
+    store.fetchRecord(belongsTo);
+
+    return belongsTo;
+  }).property('data').meta(meta);
+};
+
+/**
+  These observers observe all `belongsTo` relationships on the record. See
+  `relationships/ext` to see how these observers get their dependencies.
+
+  @class Model
+  @namespace DS
+*/
+DS.Model.reopen({
+
+  /**
+    @method belongsToWillChange
+    @private
+    @static
+    @param record
+    @param key
+  */
+  belongsToWillChange: Ember.beforeObserver(function(record, key) {
+    if (get(record, 'isLoaded')) {
+      var oldParent = get(record, key);
+
+      if (oldParent) {
+        var store = get(record, 'store'),
+            change = DS.RelationshipChange.createChange(record, oldParent, store, { key: key, kind: &quot;belongsTo&quot;, changeType: &quot;remove&quot; });
+
+        change.sync();
+        this._changesToSync[key] = change;
+      }
+    }
+  }),
+
+  /**
+    @method belongsToDidChange
+    @private
+    @static
+    @param record
+    @param key
+  */
+  belongsToDidChange: Ember.immediateObserver(function(record, key) {
+    if (get(record, 'isLoaded')) {
+      var newParent = get(record, key);
+
+      if (newParent) {
+        var store = get(record, 'store'),
+            change = DS.RelationshipChange.createChange(record, newParent, store, { key: key, kind: &quot;belongsTo&quot;, changeType: &quot;add&quot; });
+
+        change.sync();
+      }
+    }
+
+    delete this._changesToSync[key];
+  })
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var get = Ember.get, set = Ember.set, setProperties = Ember.setProperties;
+
+function asyncHasMany(type, options, meta) {
+  return Ember.computed(function(key, value) {
+    var relationship = this._relationships[key],
+        promiseLabel = &quot;DS: Async hasMany &quot; + this + &quot; : &quot; + key;
+
+    if (!relationship) {
+      var resolver = Ember.RSVP.defer(promiseLabel);
+      relationship = buildRelationship(this, key, options, function(store, data) {
+        var link = data.links &amp;&amp; data.links[key];
+        var rel;
+        if (link) {
+          rel = store.findHasMany(this, link, meta, resolver);
+        } else {
+          rel = store.findMany(this, data[key], meta.type, resolver);
+        }
+        // cache the promise so we can use it
+        // when we come back and don't need to rebuild
+        // the relationship.
+        set(rel, 'promise', resolver.promise);
+        return rel;
+      });
+    }
+
+    var promise = relationship.get('promise').then(function() {
+      return relationship;
+    }, null, &quot;DS: Async hasMany records received&quot;);
+
+    return DS.PromiseArray.create({ promise: promise });
+  }).property('data').meta(meta);
+}
+
+function buildRelationship(record, key, options, callback) {
+  var rels = record._relationships;
+
+  if (rels[key]) { return rels[key]; }
+
+  var data = get(record, 'data'),
+      store = get(record, 'store');
+
+  var relationship = rels[key] = callback.call(record, store, data);
+
+  return setProperties(relationship, {
+    owner: record, name: key, isPolymorphic: options.polymorphic
+  });
+}
+
+function hasRelationship(type, options) {
+  options = options || {};
+
+  var meta = { type: type, isRelationship: true, options: options, kind: 'hasMany' };
+
+  if (options.async) {
+    return asyncHasMany(type, options, meta);
+  }
+
+  return Ember.computed(function(key, value) {
+    return buildRelationship(this, key, options, function(store, data) {
+      var records = data[key];
+      Ember.assert(&quot;You looked up the '&quot; + key + &quot;' relationship on '&quot; + this + &quot;' but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (`DS.hasMany({ async: true })`)&quot;, Ember.A(records).everyProperty('isEmpty', false));
+      return store.findMany(this, data[key], meta.type);
+    });
+  }).property('data').meta(meta);
+}
+
+/**
+  `DS.hasMany` is used to define One-To-Many and Many-To-Many
+  relationships on a [DS.Model](DS.Model.html).
+
+  `DS.hasMany` takes an optional hash as a second parameter, currently
+  supported options are:
+
+  - `async`: A boolean value used to explicitly declare this to be an async relationship.
+  - `inverse`: A string used to identify the inverse property on a related model.
+
+  #### One-To-Many
+  To declare a one-to-many relationship between two models, use
+  `DS.belongsTo` in combination with `DS.hasMany`, like this:
+
+  ```javascript
+  App.Post = DS.Model.extend({
+    comments: DS.hasMany('comment')
+  });
+
+  App.Comment = DS.Model.extend({
+    post: DS.belongsTo('post')
+  });
+  ```
+
+  #### Many-To-Many
+  To declare a many-to-many relationship between two models, use
+  `DS.hasMany`:
+
+  ```javascript
+  App.Post = DS.Model.extend({
+    tags: DS.hasMany('tag')
+  });
+
+  App.Tag = DS.Model.extend({
+    posts: DS.hasMany('post')
+  });
+  ```
+
+  #### Explicit Inverses
+
+  Ember Data will do its best to discover which relationships map to
+  one another. In the one-to-many code above, for example, Ember Data
+  can figure out that changing the `comments` relationship should update
+  the `post` relationship on the inverse because post is the only
+  relationship to that model.
+
+  However, sometimes you may have multiple `belongsTo`/`hasManys` for the
+  same type. You can specify which property on the related model is
+  the inverse using `DS.hasMany`'s `inverse` option:
+
+  ```javascript
+  var belongsTo = DS.belongsTo,
+      hasMany = DS.hasMany;
+
+  App.Comment = DS.Model.extend({
+    onePost: belongsTo('post'),
+    twoPost: belongsTo('post'),
+    redPost: belongsTo('post'),
+    bluePost: belongsTo('post')
+  });
+
+  App.Post = DS.Model.extend({
+    comments: hasMany('comment', {
+      inverse: 'redPost'
+    })
+  });
+  ```
+
+  You can also specify an inverse on a `belongsTo`, which works how
+  you'd expect.
+
+  @namespace
+  @method hasMany
+  @for DS
+  @param {String or DS.Model} type the model type of the relationship
+  @param {Object} options a hash of options
+  @return {Ember.computed} relationship
+*/
+DS.hasMany = function(type, options) {
+  if (typeof type === 'object') {
+    options = type;
+    type = undefined;
+  }
+  return hasRelationship(type, options);
+};
+
+})();
+
+
+
+(function() {
+var get = Ember.get, set = Ember.set;
+
+/**
+  @module ember-data
+*/
+
+/*
+  This file defines several extensions to the base `DS.Model` class that
+  add support for one-to-many relationships.
+*/
+
+/**
+  @class Model
+  @namespace DS
+*/
+DS.Model.reopen({
+
+  /**
+    This Ember.js hook allows an object to be notified when a property
+    is defined.
+
+    In this case, we use it to be notified when an Ember Data user defines a
+    belongs-to relationship. In that case, we need to set up observers for
+    each one, allowing us to track relationship changes and automatically
+    reflect changes in the inverse has-many array.
+
+    This hook passes the class being set up, as well as the key and value
+    being defined. So, for example, when the user does this:
+
+    ```javascript
+    DS.Model.extend({
+      parent: DS.belongsTo('user')
+    });
+    ```
+
+    This hook would be called with &quot;parent&quot; as the key and the computed
+    property returned by `DS.belongsTo` as the value.
+
+    @method didDefineProperty
+    @param proto
+    @param key
+    @param value
+  */
+  didDefineProperty: function(proto, key, value) {
+    // Check if the value being set is a computed property.
+    if (value instanceof Ember.Descriptor) {
+
+      // If it is, get the metadata for the relationship. This is
+      // populated by the `DS.belongsTo` helper when it is creating
+      // the computed property.
+      var meta = value.meta();
+
+      if (meta.isRelationship &amp;&amp; meta.kind === 'belongsTo') {
+        Ember.addObserver(proto, key, null, 'belongsToDidChange');
+        Ember.addBeforeObserver(proto, key, null, 'belongsToWillChange');
+      }
+
+      meta.parentType = proto.constructor;
+    }
+  }
+});
+
+/*
+  These DS.Model extensions add class methods that provide relationship
+  introspection abilities about relationships.
+
+  A note about the computed properties contained here:
+
+  **These properties are effectively sealed once called for the first time.**
+  To avoid repeatedly doing expensive iteration over a model's fields, these
+  values are computed once and then cached for the remainder of the runtime of
+  your application.
+
+  If your application needs to modify a class after its initial definition
+  (for example, using `reopen()` to add additional attributes), make sure you
+  do it before using your model with the store, which uses these properties
+  extensively.
+*/
+
+DS.Model.reopenClass({
+  /**
+    For a given relationship name, returns the model type of the relationship.
+
+    For example, if you define a model like this:
+
+   ```javascript
+    App.Post = DS.Model.extend({
+      comments: DS.hasMany('comment')
+    });
+   ```
+
+    Calling `App.Post.typeForRelationship('comments')` will return `App.Comment`.
+
+    @method typeForRelationship
+    @static
+    @param {String} name the name of the relationship
+    @return {subclass of DS.Model} the type of the relationship, or undefined
+  */
+  typeForRelationship: function(name) {
+    var relationship = get(this, 'relationshipsByName').get(name);
+    return relationship &amp;&amp; relationship.type;
+  },
+
+  inverseFor: function(name) {
+    var inverseType = this.typeForRelationship(name);
+
+    if (!inverseType) { return null; }
+
+    var options = this.metaForProperty(name).options;
+
+    if (options.inverse === null) { return null; }
+
+    var inverseName, inverseKind;
+
+    if (options.inverse) {
+      inverseName = options.inverse;
+      inverseKind = Ember.get(inverseType, 'relationshipsByName').get(inverseName).kind;
+    } else {
+      var possibleRelationships = findPossibleInverses(this, inverseType);
+
+      if (possibleRelationships.length === 0) { return null; }
+
+      Ember.assert(&quot;You defined the '&quot; + name + &quot;' relationship on &quot; + this + &quot;, but multiple possible inverse relationships of type &quot; + this + &quot; were found on &quot; + inverseType + &quot;. Look at http://emberjs.com/guides/models/defining-models/#toc_explicit-inverses for how to explicitly specify inverses&quot;, possibleRelationships.length === 1);
+
+      inverseName = possibleRelationships[0].name;
+      inverseKind = possibleRelationships[0].kind;
+    }
+
+    function findPossibleInverses(type, inverseType, possibleRelationships) {
+      possibleRelationships = possibleRelationships || [];
+
+      var relationshipMap = get(inverseType, 'relationships');
+      if (!relationshipMap) { return; }
+
+      var relationships = relationshipMap.get(type);
+      if (relationships) {
+        possibleRelationships.push.apply(possibleRelationships, relationshipMap.get(type));
+      }
+
+      if (type.superclass) {
+        findPossibleInverses(type.superclass, inverseType, possibleRelationships);
+      }
+
+      return possibleRelationships;
+    }
+
+    return {
+      type: inverseType,
+      name: inverseName,
+      kind: inverseKind
+    };
+  },
+
+  /**
+    The model's relationships as a map, keyed on the type of the
+    relationship. The value of each entry is an array containing a descriptor
+    for each relationship with that type, describing the name of the relationship
+    as well as the type.
+
+    For example, given the following model definition:
+
+    ```javascript
+    App.Blog = DS.Model.extend({
+      users: DS.hasMany('user'),
+      owner: DS.belongsTo('user'),
+      posts: DS.hasMany('post')
+    });
+    ```
+
+    This computed property would return a map describing these
+    relationships, like this:
+
+    ```javascript
+    var relationships = Ember.get(App.Blog, 'relationships');
+    relationships.get(App.User);
+    //=&gt; [ { name: 'users', kind: 'hasMany' },
+    //     { name: 'owner', kind: 'belongsTo' } ]
+    relationships.get(App.Post);
+    //=&gt; [ { name: 'posts', kind: 'hasMany' } ]
+    ```
+
+    @property relationships
+    @static
+    @type Ember.Map
+    @readOnly
+  */
+  relationships: Ember.computed(function() {
+    var map = new Ember.MapWithDefault({
+      defaultValue: function() { return []; }
+    });
+
+    // Loop through each computed property on the class
+    this.eachComputedProperty(function(name, meta) {
+
+      // If the computed property is a relationship, add
+      // it to the map.
+      if (meta.isRelationship) {
+        if (typeof meta.type === 'string') {
+          meta.type = this.store.modelFor(meta.type);
+        }
+
+        var relationshipsForType = map.get(meta.type);
+
+        relationshipsForType.push({ name: name, kind: meta.kind });
+      }
+    });
+
+    return map;
+  }),
+
+  /**
+    A hash containing lists of the model's relationships, grouped
+    by the relationship kind. For example, given a model with this
+    definition:
+
+    ```javascript
+    App.Blog = DS.Model.extend({
+      users: DS.hasMany('user'),
+      owner: DS.belongsTo('user'),
+
+      posts: DS.hasMany('post')
+    });
+    ```
+
+    This property would contain the following:
+
+    ```javascript
+    var relationshipNames = Ember.get(App.Blog, 'relationshipNames');
+    relationshipNames.hasMany;
+    //=&gt; ['users', 'posts']
+    relationshipNames.belongsTo;
+    //=&gt; ['owner']
+    ```
+
+    @property relationshipNames
+    @static
+    @type Object
+    @readOnly
+  */
+  relationshipNames: Ember.computed(function() {
+    var names = { hasMany: [], belongsTo: [] };
+
+    this.eachComputedProperty(function(name, meta) {
+      if (meta.isRelationship) {
+        names[meta.kind].push(name);
+      }
+    });
+
+    return names;
+  }),
+
+  /**
+    An array of types directly related to a model. Each type will be
+    included once, regardless of the number of relationships it has with
+    the model.
+
+    For example, given a model with this definition:
+
+    ```javascript
+    App.Blog = DS.Model.extend({
+      users: DS.hasMany('user'),
+      owner: DS.belongsTo('user'),
+
+      posts: DS.hasMany('post')
+    });
+    ```
+
+    This property would contain the following:
+
+    ```javascript
+    var relatedTypes = Ember.get(App.Blog, 'relatedTypes');
+    //=&gt; [ App.User, App.Post ]
+    ```
+
+    @property relatedTypes
+    @static
+    @type Ember.Array
+    @readOnly
+  */
+  relatedTypes: Ember.computed(function() {
+    var type,
+        types = Ember.A();
+
+    // Loop through each computed property on the class,
+    // and create an array of the unique types involved
+    // in relationships
+    this.eachComputedProperty(function(name, meta) {
+      if (meta.isRelationship) {
+        type = meta.type;
+
+        if (typeof type === 'string') {
+          type = get(this, type, false) || this.store.modelFor(type);
+        }
+
+        Ember.assert(&quot;You specified a hasMany (&quot; + meta.type + &quot;) on &quot; + meta.parentType + &quot; but &quot; + meta.type + &quot; was not found.&quot;,  type);
+
+        if (!types.contains(type)) {
+          Ember.assert(&quot;Trying to sideload &quot; + name + &quot; on &quot; + this.toString() + &quot; but the type doesn't exist.&quot;, !!type);
+          types.push(type);
+        }
+      }
+    });
+
+    return types;
+  }),
+
+  /**
+    A map whose keys are the relationships of a model and whose values are
+    relationship descriptors.
+
+    For example, given a model with this
+    definition:
+
+    ```javascript
+    App.Blog = DS.Model.extend({
+      users: DS.hasMany('user'),
+      owner: DS.belongsTo('user'),
+
+      posts: DS.hasMany('post')
+    });
+    ```
+
+    This property would contain the following:
+
+    ```javascript
+    var relationshipsByName = Ember.get(App.Blog, 'relationshipsByName');
+    relationshipsByName.get('users');
+    //=&gt; { key: 'users', kind: 'hasMany', type: App.User }
+    relationshipsByName.get('owner');
+    //=&gt; { key: 'owner', kind: 'belongsTo', type: App.User }
+    ```
+
+    @property relationshipsByName
+    @static
+    @type Ember.Map
+    @readOnly
+  */
+  relationshipsByName: Ember.computed(function() {
+    var map = Ember.Map.create(), type;
+
+    this.eachComputedProperty(function(name, meta) {
+      if (meta.isRelationship) {
+        meta.key = name;
+        type = meta.type;
+
+        if (!type &amp;&amp; meta.kind === 'hasMany') {
+          type = Ember.String.singularize(name);
+        } else if (!type) {
+          type = name;
+        }
+
+        if (typeof type === 'string') {
+          meta.type = this.store.modelFor(type);
+        }
+
+        map.set(name, meta);
+      }
+    });
+
+    return map;
+  }),
+
+  /**
+    A map whose keys are the fields of the model and whose values are strings
+    describing the kind of the field. A model's fields are the union of all of its
+    attributes and relationships.
+
+    For example:
+
+    ```javascript
+
+    App.Blog = DS.Model.extend({
+      users: DS.hasMany('user'),
+      owner: DS.belongsTo('user'),
+
+      posts: DS.hasMany('post'),
+
+      title: DS.attr('string')
+    });
+
+    var fields = Ember.get(App.Blog, 'fields');
+    fields.forEach(function(field, kind) {
+      console.log(field, kind);
+    });
+
+    // prints:
+    // users, hasMany
+    // owner, belongsTo
+    // posts, hasMany
+    // title, attribute
+    ```
+
+    @property fields
+    @static
+    @type Ember.Map
+    @readOnly
+  */
+  fields: Ember.computed(function() {
+    var map = Ember.Map.create();
+
+    this.eachComputedProperty(function(name, meta) {
+      if (meta.isRelationship) {
+        map.set(name, meta.kind);
+      } else if (meta.isAttribute) {
+        map.set(name, 'attribute');
+      }
+    });
+
+    return map;
+  }),
+
+  /**
+    Given a callback, iterates over each of the relationships in the model,
+    invoking the callback with the name of each relationship and its relationship
+    descriptor.
+
+    @method eachRelationship
+    @static
+    @param {Function} callback the callback to invoke
+    @param {any} binding the value to which the callback's `this` should be bound
+  */
+  eachRelationship: function(callback, binding) {
+    get(this, 'relationshipsByName').forEach(function(name, relationship) {
+      callback.call(binding, name, relationship);
+    });
+  },
+
+  /**
+    Given a callback, iterates over each of the types related to a model,
+    invoking the callback with the related type's class. Each type will be
+    returned just once, regardless of how many different relationships it has
+    with a model.
+
+    @method eachRelatedType
+    @static
+    @param {Function} callback the callback to invoke
+    @param {any} binding the value to which the callback's `this` should be bound
+  */
+  eachRelatedType: function(callback, binding) {
+    get(this, 'relatedTypes').forEach(function(type) {
+      callback.call(binding, type);
+    });
+  }
+});
+
+DS.Model.reopen({
+  /**
+    Given a callback, iterates over each of the relationships in the model,
+    invoking the callback with the name of each relationship and its relationship
+    descriptor.
+
+    @method eachRelationship
+    @param {Function} callback the callback to invoke
+    @param {any} binding the value to which the callback's `this` should be bound
+  */
+  eachRelationship: function(callback, binding) {
+    this.constructor.eachRelationship(callback, binding);
+  }
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var get = Ember.get, set = Ember.set;
+var forEach = Ember.EnumerableUtils.forEach;
+
+/**
+  @class RecordArrayManager
+  @namespace DS
+  @private
+  @extends Ember.Object
+*/
+DS.RecordArrayManager = Ember.Object.extend({
+  init: function() {
+    this.filteredRecordArrays = Ember.MapWithDefault.create({
+      defaultValue: function() { return []; }
+    });
+
+    this.changedRecords = [];
+  },
+
+  recordDidChange: function(record) {
+    if (this.changedRecords.push(record) !== 1) { return; }
+
+    Ember.run.schedule('actions', this, this.updateRecordArrays);
+  },
+
+  recordArraysForRecord: function(record) {
+    record._recordArrays = record._recordArrays || Ember.OrderedSet.create();
+    return record._recordArrays;
+  },
+
+  /**
+    This method is invoked whenever data is loaded into the store by the
+    adapter or updated by the adapter, or when a record has changed.
+
+    It updates all record arrays that a record belongs to.
+
+    To avoid thrashing, it only runs at most once per run loop.
+
+    @method updateRecordArrays
+    @param {Class} type
+    @param {Number|String} clientId
+  */
+  updateRecordArrays: function() {
+    forEach(this.changedRecords, function(record) {
+      if (get(record, 'isDeleted')) {
+        this._recordWasDeleted(record);
+      } else {
+        this._recordWasChanged(record);
+      }
+    }, this);
+
+    this.changedRecords.length = 0;
+  },
+
+  _recordWasDeleted: function (record) {
+    var recordArrays = record._recordArrays;
+
+    if (!recordArrays) { return; }
+
+    forEach(recordArrays, function(array) {
+      array.removeRecord(record);
+    });
+  },
+
+  _recordWasChanged: function (record) {
+    var type = record.constructor,
+        recordArrays = this.filteredRecordArrays.get(type),
+        filter;
+
+    forEach(recordArrays, function(array) {
+      filter = get(array, 'filterFunction');
+      this.updateRecordArray(array, filter, type, record);
+    }, this);
+
+    // loop through all manyArrays containing an unloaded copy of this
+    // clientId and notify them that the record was loaded.
+    var manyArrays = record._loadingRecordArrays;
+
+    if (manyArrays) {
+      for (var i=0, l=manyArrays.length; i&lt;l; i++) {
+        manyArrays[i].loadedRecord();
+      }
+
+      record._loadingRecordArrays = [];
+    }
+  },
+
+  /**
+    Update an individual filter.
+
+    @method updateRecordArray
+    @param {DS.FilteredRecordArray} array
+    @param {Function} filter
+    @param {Class} type
+    @param {Number|String} clientId
+  */
+  updateRecordArray: function(array, filter, type, record) {
+    var shouldBeInArray;
+
+    if (!filter) {
+      shouldBeInArray = true;
+    } else {
+      shouldBeInArray = filter(record);
+    }
+
+    var recordArrays = this.recordArraysForRecord(record);
+
+    if (shouldBeInArray) {
+      recordArrays.add(array);
+      array.addRecord(record);
+    } else if (!shouldBeInArray) {
+      recordArrays.remove(array);
+      array.removeRecord(record);
+    }
+  },
+
+  /**
+    This method is invoked if the `filterFunction` property is
+    changed on a `DS.FilteredRecordArray`.
+
+    It essentially re-runs the filter from scratch. This same
+    method is invoked when the filter is created in th first place.
+
+    @method updateFilter
+    @param array
+    @param type
+    @param filter
+  */
+  updateFilter: function(array, type, filter) {
+    var typeMap = this.store.typeMapFor(type),
+        records = typeMap.records, record;
+
+    for (var i=0, l=records.length; i&lt;l; i++) {
+      record = records[i];
+
+      if (!get(record, 'isDeleted') &amp;&amp; !get(record, 'isEmpty')) {
+        this.updateRecordArray(array, filter, type, record);
+      }
+    }
+  },
+
+  /**
+    Create a `DS.ManyArray` for a type and list of record references, and index
+    the `ManyArray` under each reference. This allows us to efficiently remove
+    records from `ManyArray`s when they are deleted.
+
+    @method createManyArray
+    @param {Class} type
+    @param {Array} references
+    @return {DS.ManyArray}
+  */
+  createManyArray: function(type, records) {
+    var manyArray = DS.ManyArray.create({
+      type: type,
+      content: records,
+      store: this.store
+    });
+
+    forEach(records, function(record) {
+      var arrays = this.recordArraysForRecord(record);
+      arrays.add(manyArray);
+    }, this);
+
+    return manyArray;
+  },
+
+  /**
+    Create a `DS.RecordArray` for a type and register it for updates.
+
+    @method createRecordArray
+    @param {Class} type
+    @return {DS.RecordArray}
+  */
+  createRecordArray: function(type) {
+    var array = DS.RecordArray.create({
+      type: type,
+      content: Ember.A(),
+      store: this.store,
+      isLoaded: true
+    });
+
+    this.registerFilteredRecordArray(array, type);
+
+    return array;
+  },
+
+  /**
+    Create a `DS.FilteredRecordArray` for a type and register it for updates.
+
+    @method createFilteredRecordArray
+    @param {Class} type
+    @param {Function} filter
+    @return {DS.FilteredRecordArray}
+  */
+  createFilteredRecordArray: function(type, filter) {
+    var array = DS.FilteredRecordArray.create({
+      type: type,
+      content: Ember.A(),
+      store: this.store,
+      manager: this,
+      filterFunction: filter
+    });
+
+    this.registerFilteredRecordArray(array, type, filter);
+
+    return array;
+  },
+
+  /**
+    Create a `DS.AdapterPopulatedRecordArray` for a type with given query.
+
+    @method createAdapterPopulatedRecordArray
+    @param {Class} type
+    @param {Object} query
+    @return {DS.AdapterPopulatedRecordArray}
+  */
+  createAdapterPopulatedRecordArray: function(type, query) {
+    return DS.AdapterPopulatedRecordArray.create({
+      type: type,
+      query: query,
+      content: Ember.A(),
+      store: this.store
+    });
+  },
+
+  /**
+    Register a RecordArray for a given type to be backed by
+    a filter function. This will cause the array to update
+    automatically when records of that type change attribute
+    values or states.
+
+    @method registerFilteredRecordArray
+    @param {DS.RecordArray} array
+    @param {Class} type
+    @param {Function} filter
+  */
+  registerFilteredRecordArray: function(array, type, filter) {
+    var recordArrays = this.filteredRecordArrays.get(type);
+    recordArrays.push(array);
+
+    this.updateFilter(array, type, filter);
+  },
+
+  // Internally, we maintain a map of all unloaded IDs requested by
+  // a ManyArray. As the adapter loads data into the store, the
+  // store notifies any interested ManyArrays. When the ManyArray's
+  // total number of loading records drops to zero, it becomes
+  // `isLoaded` and fires a `didLoad` event.
+  registerWaitingRecordArray: function(record, array) {
+    var loadingRecordArrays = record._loadingRecordArrays || [];
+    loadingRecordArrays.push(array);
+    record._loadingRecordArrays = loadingRecordArrays;
+  }
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var get = Ember.get, set = Ember.set;
+var map = Ember.ArrayPolyfills.map;
+
+var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
+
+/**
+  A `DS.InvalidError` is used by an adapter to signal the external API
+  was unable to process a request because the content was not
+  semantically correct or meaningful per the API. Usually this means a
+  record failed some form of server side validation. When a promise
+  from an adapter is rejected with a `DS.InvalidError` the record will
+  transition to the `invalid` state and the errors will be set to the
+  `errors` property on the record.
+
+  Example
+
+  ```javascript
+  App.ApplicationAdapter = DS.RESTAdapter.extend({
+    ajaxError: function(jqXHR) {
+      var error = this._super(jqXHR);
+
+      if (jqXHR &amp;&amp; jqXHR.status === 422) {
+        var jsonErrors = Ember.$.parseJSON(jqXHR.responseText)[&quot;errors&quot;];
+        return new DS.InvalidError(jsonErrors);
+      } else {
+        return error;
+      }
+    }
+  });
+  ```
+
+  @class InvalidError
+  @namespace DS
+*/
+DS.InvalidError = function(errors) {
+  var tmp = Error.prototype.constructor.call(this, &quot;The backend rejected the commit because it was invalid: &quot; + Ember.inspect(errors));
+  this.errors = errors;
+
+  for (var i=0, l=errorProps.length; i&lt;l; i++) {
+    this[errorProps[i]] = tmp[errorProps[i]];
+  }
+};
+DS.InvalidError.prototype = Ember.create(Error.prototype);
+
+/**
+  An adapter is an object that receives requests from a store and
+  translates them into the appropriate action to take against your
+  persistence layer. The persistence layer is usually an HTTP API, but
+  may be anything, such as the browser's local storage. Typically the
+  adapter is not invoked directly instead its functionality is accessed
+  through the `store`.
+
+  ### Creating an Adapter
+
+  First, create a new subclass of `DS.Adapter`:
+
+  ```javascript
+  App.MyAdapter = DS.Adapter.extend({
+    // ...your code here
+  });
+  ```
+
+  To tell your store which adapter to use, set its `adapter` property:
+
+  ```javascript
+  App.store = DS.Store.create({
+    adapter: 'MyAdapter'
+  });
+  ```
+
+  `DS.Adapter` is an abstract base class that you should override in your
+  application to customize it for your backend. The minimum set of methods
+  that you should implement is:
+
+    * `find()`
+    * `createRecord()`
+    * `updateRecord()`
+    * `deleteRecord()`
+    * `findAll()`
+    * `findQuery()`
+
+  To improve the network performance of your application, you can optimize
+  your adapter by overriding these lower-level methods:
+
+    * `findMany()`
+
+
+  For an example implementation, see `DS.RESTAdapter`, the
+  included REST adapter.
+
+  @class Adapter
+  @namespace DS
+  @extends Ember.Object
+*/
+
+DS.Adapter = Ember.Object.extend({
+
+  /**
+    If you would like your adapter to use a custom serializer you can
+    set the `defaultSerializer` property to be the name of the custom
+    serializer.
+
+    Note the `defaultSerializer` serializer has a lower priority then
+    a model specific serializer (i.e. `PostSerializer`) or the
+    `application` serializer.
+
+    ```javascript
+    var DjangoAdapter = DS.Adapter.extend({
+      defaultSerializer: 'django'
+    });
+    ```
+
+    @property defaultSerializer
+    @type {String}
+  */
+
+  /**
+    The `find()` method is invoked when the store is asked for a record that
+    has not previously been loaded. In response to `find()` being called, you
+    should query your persistence layer for a record with the given ID. Once
+    found, you can asynchronously call the store's `push()` method to push
+    the record into the store.
+
+    Here is an example `find` implementation:
+
+    ```javascript
+    App.ApplicationAdapter = DS.Adapter.extend({
+      find: function(store, type, id) {
+        var url = [type, id].join('/');
+
+        return new Ember.RSVP.Promise(function(resolve, reject) {
+          jQuery.getJSON(url).then(function(data) {
+            Ember.run(null, resolve, data);
+          }, function(jqXHR) {
+            jqXHR.then = null; // tame jQuery's ill mannered promises
+            Ember.run(null, reject, jqXHR);
+          });
+        });
+      }
+    });
+    ```
+
+    @method find
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {String} id
+    @return {Promise} promise
+  */
+  find: Ember.required(Function),
+
+  /**
+    The `findAll()` method is called when you call `find` on the store
+    without an ID (i.e. `store.find('post')`).
+
+    Example
+
+    ```javascript
+    App.ApplicationAdapter = DS.Adapter.extend({
+      findAll: function(store, type, sinceToken) {
+        var url = type;
+        var query = { since: sinceToken };
+        return new Ember.RSVP.Promise(function(resolve, reject) {
+          jQuery.getJSON(url, query).then(function(data) {
+            Ember.run(null, resolve, data);
+          }, function(jqXHR) {
+            jqXHR.then = null; // tame jQuery's ill mannered promises
+            Ember.run(null, reject, jqXHR);
+          });
+        });
+      }
+    });
+    ```
+
+    @private
+    @method findAll
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {String} sinceToken
+    @return {Promise} promise
+  */
+  findAll: null,
+
+  /**
+    This method is called when you call `find` on the store with a
+    query object as the second parameter (i.e. `store.find('person', {
+    page: 1 })`).
+
+    Example
+
+    ```javascript
+    App.ApplicationAdapter = DS.Adapter.extend({
+      findQuery: function(store, type, query) {
+        var url = type;
+        return new Ember.RSVP.Promise(function(resolve, reject) {
+          jQuery.getJSON(url, query).then(function(data) {
+            Ember.run(null, resolve, data);
+          }, function(jqXHR) {
+            jqXHR.then = null; // tame jQuery's ill mannered promises
+            Ember.run(null, reject, jqXHR);
+          });
+        });
+      }
+    });
+    ```
+
+    @private
+    @method findQuery
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} query
+    @param {DS.AdapterPopulatedRecordArray} recordArray
+    @return {Promise} promise
+  */
+  findQuery: null,
+
+  /**
+    If the globally unique IDs for your records should be generated on the client,
+    implement the `generateIdForRecord()` method. This method will be invoked
+    each time you create a new record, and the value returned from it will be
+    assigned to the record's `primaryKey`.
+
+    Most traditional REST-like HTTP APIs will not use this method. Instead, the ID
+    of the record will be set by the server, and your adapter will update the store
+    with the new ID when it calls `didCreateRecord()`. Only implement this method if
+    you intend to generate record IDs on the client-side.
+
+    The `generateIdForRecord()` method will be invoked with the requesting store as
+    the first parameter and the newly created record as the second parameter:
+
+    ```javascript
+    generateIdForRecord: function(store, record) {
+      var uuid = App.generateUUIDWithStatisticallyLowOddsOfCollision();
+      return uuid;
+    }
+    ```
+
+    @method generateIdForRecord
+    @param {DS.Store} store
+    @param {DS.Model} record
+    @return {String|Number} id
+  */
+  generateIdForRecord: null,
+
+  /**
+    Proxies to the serializer's `serialize` method.
+
+    Example
+
+    ```javascript
+    App.ApplicationAdapter = DS.Adapter.extend({
+      createRecord: function(store, type, record) {
+        var data = this.serialize(record, { includeId: true });
+        var url = type;
+
+        // ...
+      }
+    });
+    ```
+
+    @method serialize
+    @param {DS.Model} record
+    @param {Object}   options
+    @return {Object} serialized record
+  */
+  serialize: function(record, options) {
+    return get(record, 'store').serializerFor(record.constructor.typeKey).serialize(record, options);
+  },
+
+  /**
+    Implement this method in a subclass to handle the creation of
+    new records.
+
+    Serializes the record and send it to the server.
+
+    Example
+
+    ```javascript
+    App.ApplicationAdapter = DS.Adapter.extend({
+      createRecord: function(store, type, record) {
+        var data = this.serialize(record, { includeId: true });
+        var url = type;
+
+        return new Ember.RSVP.Promise(function(resolve, reject) {
+          jQuery.ajax({
+            type: 'POST',
+            url: url,
+            dataType: 'json',
+            data: data
+          }).then(function(data) {
+            Ember.run(null, resolve, data);
+          }, function(jqXHR) {
+            jqXHR.then = null; // tame jQuery's ill mannered promises
+            Ember.run(null, reject, jqXHR);
+          });
+        });
+      }
+    });
+    ```
+
+    @method createRecord
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type   the DS.Model class of the record
+    @param {DS.Model} record
+    @return {Promise} promise
+  */
+  createRecord: Ember.required(Function),
+
+  /**
+    Implement this method in a subclass to handle the updating of
+    a record.
+
+    Serializes the record update and send it to the server.
+
+    Example
+
+    ```javascript
+    App.ApplicationAdapter = DS.Adapter.extend({
+      updateRecord: function(store, type, record) {
+        var data = this.serialize(record, { includeId: true });
+        var id = record.get('id');
+        var url = [type, id].join('/');
+
+        return new Ember.RSVP.Promise(function(resolve, reject) {
+          jQuery.ajax({
+            type: 'PUT',
+            url: url,
+            dataType: 'json',
+            data: data
+          }).then(function(data) {
+            Ember.run(null, resolve, data);
+          }, function(jqXHR) {
+            jqXHR.then = null; // tame jQuery's ill mannered promises
+            Ember.run(null, reject, jqXHR);
+          });
+        });
+      }
+    });
+    ```
+
+    @method updateRecord
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type   the DS.Model class of the record
+    @param {DS.Model} record
+    @return {Promise} promise
+  */
+  updateRecord: Ember.required(Function),
+
+  /**
+    Implement this method in a subclass to handle the deletion of
+    a record.
+
+    Sends a delete request for the record to the server.
+
+    Example
+
+    ```javascript
+    App.ApplicationAdapter = DS.Adapter.extend({
+      deleteRecord: function(store, type, record) {
+        var data = this.serialize(record, { includeId: true });
+        var id = record.get('id');
+        var url = [type, id].join('/');
+
+        return new Ember.RSVP.Promise(function(resolve, reject) {
+          jQuery.ajax({
+            type: 'DELETE',
+            url: url,
+            dataType: 'json',
+            data: data
+          }).then(function(data) {
+            Ember.run(null, resolve, data);
+          }, function(jqXHR) {
+            jqXHR.then = null; // tame jQuery's ill mannered promises
+            Ember.run(null, reject, jqXHR);
+          });
+        });
+      }
+    });
+    ```
+
+    @method deleteRecord
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type   the DS.Model class of the record
+    @param {DS.Model} record
+    @return {Promise} promise
+  */
+  deleteRecord: Ember.required(Function),
+
+  /**
+    Find multiple records at once.
+
+    By default, it loops over the provided ids and calls `find` on each.
+    May be overwritten to improve performance and reduce the number of
+    server requests.
+
+    Example
+
+    ```javascript
+    App.ApplicationAdapter = DS.Adapter.extend({
+      findMany: function(store, type, ids) {
+        var url = type;
+        return new Ember.RSVP.Promise(function(resolve, reject) {
+          jQuery.getJSON(url, {ids: ids}).then(function(data) {
+            Ember.run(null, resolve, data);
+          }, function(jqXHR) {
+            jqXHR.then = null; // tame jQuery's ill mannered promises
+            Ember.run(null, reject, jqXHR);
+          });
+        });
+      }
+    });
+    ```
+
+    @method findMany
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type   the DS.Model class of the records
+    @param {Array}    ids
+    @return {Promise} promise
+  */
+  findMany: function(store, type, ids) {
+    var promises = map.call(ids, function(id) {
+      return this.find(store, type, id);
+    }, this);
+
+    return Ember.RSVP.all(promises);
+  }
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var get = Ember.get, fmt = Ember.String.fmt,
+    indexOf = Ember.EnumerableUtils.indexOf;
+
+var counter = 0;
+
+/**
+  `DS.FixtureAdapter` is an adapter that loads records from memory.
+  Its primarily used for development and testing. You can also use
+  `DS.FixtureAdapter` while working on the API but are not ready to
+  integrate yet. It is a fully functioning adapter. All CRUD methods
+  are implemented. You can also implement query logic that a remote
+  system would do. Its possible to do develop your entire application
+  with `DS.FixtureAdapter`.
+
+  For information on how to use the `FixtureAdapter` in your
+  application please see the [FixtureAdapter
+  guide](/guides/models/the-fixture-adapter/).
+
+  @class FixtureAdapter
+  @namespace DS
+  @extends DS.Adapter
+*/
+DS.FixtureAdapter = DS.Adapter.extend({
+  // by default, fixtures are already in normalized form
+  serializer: null,
+
+  /**
+    If `simulateRemoteResponse` is `true` the `FixtureAdapter` will
+    wait a number of milliseconds before resolving promises with the
+    fixture values. The wait time can be configured via the `latency`
+    property.
+
+    @property simulateRemoteResponse
+    @type {Boolean}
+    @default true
+  */
+  simulateRemoteResponse: true,
+
+  /**
+    By default the `FixtureAdapter` will simulate a wait of the
+    `latency` milliseconds before resolving promises with the fixture
+    values. This behavior can be turned off via the
+    `simulateRemoteResponse` property.
+
+    @property latency
+    @type {Number}
+    @default 50
+  */
+  latency: 50,
+
+  /**
+    Implement this method in order to provide data associated with a type
+
+    @method fixturesForType
+    @param {Subclass of DS.Model} type
+    @return {Array}
+  */
+  fixturesForType: function(type) {
+    if (type.FIXTURES) {
+      var fixtures = Ember.A(type.FIXTURES);
+      return fixtures.map(function(fixture){
+        var fixtureIdType = typeof fixture.id;
+        if(fixtureIdType !== &quot;number&quot; &amp;&amp; fixtureIdType !== &quot;string&quot;){
+          throw new Error(fmt('the id property must be defined as a number or string for fixture %@', [fixture]));
+        }
+        fixture.id = fixture.id + '';
+        return fixture;
+      });
+    }
+    return null;
+  },
+
+  /**
+    Implement this method in order to query fixtures data
+
+    @method queryFixtures
+    @param {Array} fixture
+    @param {Object} query
+    @param {Subclass of DS.Model} type
+    @return {Promise|Array}
+  */
+  queryFixtures: function(fixtures, query, type) {
+    Ember.assert('Not implemented: You must override the DS.FixtureAdapter::queryFixtures method to support querying the fixture store.');
+  },
+
+  /**
+    @method updateFixtures
+    @param {Subclass of DS.Model} type
+    @param {Array} fixture
+  */
+  updateFixtures: function(type, fixture) {
+    if(!type.FIXTURES) {
+      type.FIXTURES = [];
+    }
+
+    var fixtures = type.FIXTURES;
+
+    this.deleteLoadedFixture(type, fixture);
+
+    fixtures.push(fixture);
+  },
+
+  /**
+    Implement this method in order to provide json for CRUD methods
+
+    @method mockJSON
+    @param {Subclass of DS.Model} type
+    @param {DS.Model} record
+  */
+  mockJSON: function(store, type, record) {
+    return store.serializerFor(type).serialize(record, { includeId: true });
+  },
+
+  /**
+    @method generateIdForRecord
+    @param {DS.Store} store
+    @param {DS.Model} record
+    @return {String} id
+  */
+  generateIdForRecord: function(store) {
+    return &quot;fixture-&quot; + counter++;
+  },
+
+  /**
+    @method find
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {String} id
+    @return {Promise} promise
+  */
+  find: function(store, type, id) {
+    var fixtures = this.fixturesForType(type),
+        fixture;
+
+    Ember.assert(&quot;Unable to find fixtures for model type &quot;+type.toString(), fixtures);
+
+    if (fixtures) {
+      fixture = Ember.A(fixtures).findProperty('id', id);
+    }
+
+    if (fixture) {
+      return this.simulateRemoteCall(function() {
+        return fixture;
+      }, this);
+    }
+  },
+
+  /**
+    @method findMany
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Array} ids
+    @return {Promise} promise
+  */
+  findMany: function(store, type, ids) {
+    var fixtures = this.fixturesForType(type);
+
+    Ember.assert(&quot;Unable to find fixtures for model type &quot;+type.toString(), fixtures);
+
+    if (fixtures) {
+      fixtures = fixtures.filter(function(item) {
+        return indexOf(ids, item.id) !== -1;
+      });
+    }
+
+    if (fixtures) {
+      return this.simulateRemoteCall(function() {
+        return fixtures;
+      }, this);
+    }
+  },
+
+  /**
+    @private
+    @method findAll
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {String} sinceToken
+    @return {Promise} promise
+  */
+  findAll: function(store, type) {
+    var fixtures = this.fixturesForType(type);
+
+    Ember.assert(&quot;Unable to find fixtures for model type &quot;+type.toString(), fixtures);
+
+    return this.simulateRemoteCall(function() {
+      return fixtures;
+    }, this);
+  },
+
+  /**
+    @private
+    @method findQuery
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} query
+    @param {DS.AdapterPopulatedRecordArray} recordArray
+    @return {Promise} promise
+  */
+  findQuery: function(store, type, query, array) {
+    var fixtures = this.fixturesForType(type);
+
+    Ember.assert(&quot;Unable to find fixtures for model type &quot;+type.toString(), fixtures);
+
+    fixtures = this.queryFixtures(fixtures, query, type);
+
+    if (fixtures) {
+      return this.simulateRemoteCall(function() {
+        return fixtures;
+      }, this);
+    }
+  },
+
+  /**
+    @method createRecord
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {DS.Model} record
+    @return {Promise} promise
+  */
+  createRecord: function(store, type, record) {
+    var fixture = this.mockJSON(store, type, record);
+
+    this.updateFixtures(type, fixture);
+
+    return this.simulateRemoteCall(function() {
+      return fixture;
+    }, this);
+  },
+
+  /**
+    @method updateRecord
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {DS.Model} record
+    @return {Promise} promise
+  */
+  updateRecord: function(store, type, record) {
+    var fixture = this.mockJSON(store, type, record);
+
+    this.updateFixtures(type, fixture);
+
+    return this.simulateRemoteCall(function() {
+      return fixture;
+    }, this);
+  },
+
+  /**
+    @method deleteRecord
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {DS.Model} record
+    @return {Promise} promise
+  */
+  deleteRecord: function(store, type, record) {
+    var fixture = this.mockJSON(store, type, record);
+
+    this.deleteLoadedFixture(type, fixture);
+
+    return this.simulateRemoteCall(function() {
+      // no payload in a deletion
+      return null;
+    });
+  },
+
+  /*
+    @method deleteLoadedFixture
+    @private
+    @param type
+    @param record
+  */
+  deleteLoadedFixture: function(type, record) {
+    var existingFixture = this.findExistingFixture(type, record);
+
+    if(existingFixture) {
+      var index = indexOf(type.FIXTURES, existingFixture);
+      type.FIXTURES.splice(index, 1);
+      return true;
+    }
+  },
+
+  /*
+    @method findExistingFixture
+    @private
+    @param type
+    @param record
+  */
+  findExistingFixture: function(type, record) {
+    var fixtures = this.fixturesForType(type);
+    var id = get(record, 'id');
+
+    return this.findFixtureById(fixtures, id);
+  },
+
+  /*
+    @method findFixtureById
+    @private
+    @param fixtures
+    @param id
+  */
+  findFixtureById: function(fixtures, id) {
+    return Ember.A(fixtures).find(function(r) {
+      if(''+get(r, 'id') === ''+id) {
+        return true;
+      } else {
+        return false;
+      }
+    });
+  },
+
+  /*
+    @method simulateRemoteCall
+    @private
+    @param callback
+    @param context
+  */
+  simulateRemoteCall: function(callback, context) {
+    var adapter = this;
+
+    return new Ember.RSVP.Promise(function(resolve) {
+      if (get(adapter, 'simulateRemoteResponse')) {
+        // Schedule with setTimeout
+        Ember.run.later(function() {
+          resolve(callback.call(context));
+        }, get(adapter, 'latency'));
+      } else {
+        // Asynchronous, but at the of the runloop with zero latency
+        Ember.run.schedule('actions', null, function() {
+          resolve(callback.call(context));
+        });
+      }
+    }, &quot;DS: FixtureAdapter#simulateRemoteCall&quot;);
+  }
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var get = Ember.get, set = Ember.set;
+var forEach = Ember.ArrayPolyfills.forEach;
+var map = Ember.ArrayPolyfills.map;
+
+function coerceId(id) {
+  return id == null ? null : id+'';
+}
+
+/**
+  Normally, applications will use the `RESTSerializer` by implementing
+  the `normalize` method and individual normalizations under
+  `normalizeHash`.
+
+  This allows you to do whatever kind of munging you need, and is
+  especially useful if your server is inconsistent and you need to
+  do munging differently for many different kinds of responses.
+
+  See the `normalize` documentation for more information.
+
+  ## Across the Board Normalization
+
+  There are also a number of hooks that you might find useful to defined
+  across-the-board rules for your payload. These rules will be useful
+  if your server is consistent, or if you're building an adapter for
+  an infrastructure service, like Parse, and want to encode service
+  conventions.
+
+  For example, if all of your keys are underscored and all-caps, but
+  otherwise consistent with the names you use in your models, you
+  can implement across-the-board rules for how to convert an attribute
+  name in your model to a key in your JSON.
+
+  ```js
+  App.ApplicationSerializer = DS.RESTSerializer.extend({
+    keyForAttribute: function(attr) {
+      return Ember.String.underscore(attr).toUpperCase();
+    }
+  });
+  ```
+
+  You can also implement `keyForRelationship`, which takes the name
+  of the relationship as the first parameter, and the kind of
+  relationship (`hasMany` or `belongsTo`) as the second parameter.
+
+  @class RESTSerializer
+  @namespace DS
+  @extends DS.JSONSerializer
+*/
+DS.RESTSerializer = DS.JSONSerializer.extend({
+  /**
+    If you want to do normalizations specific to some part of the payload, you
+    can specify those under `normalizeHash`.
+
+    For example, given the following json where the the `IDs` under
+    `&quot;comments&quot;` are provided as `_id` instead of `id`.
+
+    ```javascript
+    {
+      &quot;post&quot;: {
+        &quot;id&quot;: 1,
+        &quot;title&quot;: &quot;Rails is omakase&quot;,
+        &quot;comments&quot;: [ 1, 2 ]
+      },
+      &quot;comments&quot;: [{
+        &quot;_id&quot;: 1,
+        &quot;body&quot;: &quot;FIRST&quot;
+      }, {
+        &quot;_id&quot;: 2,
+        &quot;body&quot;: &quot;Rails is unagi&quot;
+      }]
+    }
+    ```
+
+    You use `normalizeHash` to normalize just the comments:
+
+    ```javascript
+    App.PostSerializer = DS.RESTSerializer.extend({
+      normalizeHash: {
+        comments: function(hash) {
+          hash.id = hash._id;
+          delete hash._id;
+          return hash;
+        }
+      }
+    });
+    ```
+
+    The key under `normalizeHash` is usually just the original key
+    that was in the original payload. However, key names will be
+    impacted by any modifications done in the `normalizePayload`
+    method. The `DS.RESTSerializer`'s default implementation makes no
+    changes to the payload keys.
+
+    @property normalizeHash
+    @type {Object}
+    @default undefined
+  */
+
+  /**
+    Normalizes a part of the JSON payload returned by
+    the server. You should override this method, munge the hash
+    and call super if you have generic normalization to do.
+
+    It takes the type of the record that is being normalized
+    (as a DS.Model class), the property where the hash was
+    originally found, and the hash to normalize.
+
+    For example, if you have a payload that looks like this:
+
+    ```js
+    {
+      &quot;post&quot;: {
+        &quot;id&quot;: 1,
+        &quot;title&quot;: &quot;Rails is omakase&quot;,
+        &quot;comments&quot;: [ 1, 2 ]
+      },
+      &quot;comments&quot;: [{
+        &quot;id&quot;: 1,
+        &quot;body&quot;: &quot;FIRST&quot;
+      }, {
+        &quot;id&quot;: 2,
+        &quot;body&quot;: &quot;Rails is unagi&quot;
+      }]
+    }
+    ```
+
+    The `normalize` method will be called three times:
+
+    * With `App.Post`, `&quot;posts&quot;` and `{ id: 1, title: &quot;Rails is omakase&quot;, ... }`
+    * With `App.Comment`, `&quot;comments&quot;` and `{ id: 1, body: &quot;FIRST&quot; }`
+    * With `App.Comment`, `&quot;comments&quot;` and `{ id: 2, body: &quot;Rails is unagi&quot; }`
+
+    You can use this method, for example, to normalize underscored keys to camelized
+    or other general-purpose normalizations.
+
+    If you want to do normalizations specific to some part of the payload, you
+    can specify those under `normalizeHash`.
+
+    For example, if the `IDs` under `&quot;comments&quot;` are provided as `_id` instead of
+    `id`, you can specify how to normalize just the comments:
+
+    ```js
+    App.PostSerializer = DS.RESTSerializer.extend({
+      normalizeHash: {
+        comments: function(hash) {
+          hash.id = hash._id;
+          delete hash._id;
+          return hash;
+        }
+      }
+    });
+    ```
+
+    The key under `normalizeHash` is just the original key that was in the original
+    payload.
+
+    @method normalize
+    @param {subclass of DS.Model} type
+    @param {Object} hash
+    @param {String} prop
+    @returns {Object}
+  */
+  normalize: function(type, hash, prop) {
+    this.normalizeId(hash);
+    this.normalizeAttributes(type, hash);
+    this.normalizeRelationships(type, hash);
+
+    this.normalizeUsingDeclaredMapping(type, hash);
+
+    if (this.normalizeHash &amp;&amp; this.normalizeHash[prop]) {
+      this.normalizeHash[prop](hash);
+    }
+
+    return this._super(type, hash, prop);
+  },
+
+  /**
+    You can use this method to normalize all payloads, regardless of whether they
+    represent single records or an array.
+
+    For example, you might want to remove some extraneous data from the payload:
+
+    ```js
+    App.ApplicationSerializer = DS.RESTSerializer.extend({
+      normalizePayload: function(type, payload) {
+        delete payload.version;
+        delete payload.status;
+        return payload;
+      }
+    });
+    ```
+
+    @method normalizePayload
+    @param {subclass of DS.Model} type
+    @param {Object} hash
+    @returns {Object} the normalized payload
+  */
+  normalizePayload: function(type, payload) {
+    return payload;
+  },
+
+  /**
+    @method normalizeId
+    @private
+  */
+  normalizeId: function(hash) {
+    var primaryKey = get(this, 'primaryKey');
+
+    if (primaryKey === 'id') { return; }
+
+    hash.id = hash[primaryKey];
+    delete hash[primaryKey];
+  },
+
+  /**
+    @method normalizeUsingDeclaredMapping
+    @private
+  */
+  normalizeUsingDeclaredMapping: function(type, hash) {
+    var attrs = get(this, 'attrs'), payloadKey, key;
+
+    if (attrs) {
+      for (key in attrs) {
+        payloadKey = attrs[key];
+        if (payloadKey &amp;&amp; payloadKey.key) {
+          payloadKey = payloadKey.key;
+        }
+        if (typeof payloadKey === 'string') {
+          hash[key] = hash[payloadKey];
+          delete hash[payloadKey];
+        }
+      }
+    }
+  },
+
+  /**
+    @method normalizeAttributes
+    @private
+  */
+  normalizeAttributes: function(type, hash) {
+    var payloadKey, key;
+
+    if (this.keyForAttribute) {
+      type.eachAttribute(function(key) {
+        payloadKey = this.keyForAttribute(key);
+        if (key === payloadKey) { return; }
+
+        hash[key] = hash[payloadKey];
+        delete hash[payloadKey];
+      }, this);
+    }
+  },
+
+  /**
+    @method normalizeRelationships
+    @private
+  */
+  normalizeRelationships: function(type, hash) {
+    var payloadKey, key;
+
+    if (this.keyForRelationship) {
+      type.eachRelationship(function(key, relationship) {
+        payloadKey = this.keyForRelationship(key, relationship.kind);
+        if (key === payloadKey) { return; }
+
+        hash[key] = hash[payloadKey];
+        delete hash[payloadKey];
+      }, this);
+    }
+  },
+
+  /**
+    Called when the server has returned a payload representing
+    a single record, such as in response to a `find` or `save`.
+
+    It is your opportunity to clean up the server's response into the normalized
+    form expected by Ember Data.
+
+    If you want, you can just restructure the top-level of your payload, and
+    do more fine-grained normalization in the `normalize` method.
+
+    For example, if you have a payload like this in response to a request for
+    post 1:
+
+    ```js
+    {
+      &quot;id&quot;: 1,
+      &quot;title&quot;: &quot;Rails is omakase&quot;,
+
+      &quot;_embedded&quot;: {
+        &quot;comment&quot;: [{
+          &quot;_id&quot;: 1,
+          &quot;comment_title&quot;: &quot;FIRST&quot;
+        }, {
+          &quot;_id&quot;: 2,
+          &quot;comment_title&quot;: &quot;Rails is unagi&quot;
+        }]
+      }
+    }
+    ```
+
+    You could implement a serializer that looks like this to get your payload
+    into shape:
+
+    ```js
+    App.PostSerializer = DS.RESTSerializer.extend({
+      // First, restructure the top-level so it's organized by type
+      extractSingle: function(store, type, payload, id, requestType) {
+        var comments = payload._embedded.comment;
+        delete payload._embedded;
+
+        payload = { comments: comments, post: payload };
+        return this._super(store, type, payload, id, requestType);
+      },
+
+      normalizeHash: {
+        // Next, normalize individual comments, which (after `extract`)
+        // are now located under `comments`
+        comments: function(hash) {
+          hash.id = hash._id;
+          hash.title = hash.comment_title;
+          delete hash._id;
+          delete hash.comment_title;
+          return hash;
+        }
+      }
+    })
+    ```
+
+    When you call super from your own implementation of `extractSingle`, the
+    built-in implementation will find the primary record in your normalized
+    payload and push the remaining records into the store.
+
+    The primary record is the single hash found under `post` or the first
+    element of the `posts` array.
+
+    The primary record has special meaning when the record is being created
+    for the first time or updated (`createRecord` or `updateRecord`). In
+    particular, it will update the properties of the record that was saved.
+
+    @method extractSingle
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} payload
+    @param {String} id
+    @param {'find'|'createRecord'|'updateRecord'|'deleteRecord'} requestType
+    @returns {Object} the primary response to the original request
+  */
+  extractSingle: function(store, primaryType, payload, recordId, requestType) {
+    payload = this.normalizePayload(primaryType, payload);
+
+    var primaryTypeName = primaryType.typeKey,
+        primaryRecord;
+
+    for (var prop in payload) {
+      var typeName  = this.typeForRoot(prop),
+          type = store.modelFor(typeName),
+          isPrimary = type.typeKey === primaryTypeName;
+
+      // legacy support for singular resources
+      if (isPrimary &amp;&amp; Ember.typeOf(payload[prop]) !== &quot;array&quot; ) {
+        primaryRecord = this.normalize(primaryType, payload[prop], prop);
+        continue;
+      }
+
+      /*jshint loopfunc:true*/
+      forEach.call(payload[prop], function(hash) {
+        var typeName = this.typeForRoot(prop),
+            type = store.modelFor(typeName),
+            typeSerializer = store.serializerFor(type);
+
+        hash = typeSerializer.normalize(type, hash, prop);
+
+        var isFirstCreatedRecord = isPrimary &amp;&amp; !recordId &amp;&amp; !primaryRecord,
+            isUpdatedRecord = isPrimary &amp;&amp; coerceId(hash.id) === recordId;
+
+        // find the primary record.
+        //
+        // It's either:
+        // * the record with the same ID as the original request
+        // * in the case of a newly created record that didn't have an ID, the first
+        //   record in the Array
+        if (isFirstCreatedRecord || isUpdatedRecord) {
+          primaryRecord = hash;
+        } else {
+          store.push(typeName, hash);
+        }
+      }, this);
+    }
+
+    return primaryRecord;
+  },
+
+  /**
+    Called when the server has returned a payload representing
+    multiple records, such as in response to a `findAll` or `findQuery`.
+
+    It is your opportunity to clean up the server's response into the normalized
+    form expected by Ember Data.
+
+    If you want, you can just restructure the top-level of your payload, and
+    do more fine-grained normalization in the `normalize` method.
+
+    For example, if you have a payload like this in response to a request for
+    all posts:
+
+    ```js
+    {
+      &quot;_embedded&quot;: {
+        &quot;post&quot;: [{
+          &quot;id&quot;: 1,
+          &quot;title&quot;: &quot;Rails is omakase&quot;
+        }, {
+          &quot;id&quot;: 2,
+          &quot;title&quot;: &quot;The Parley Letter&quot;
+        }],
+        &quot;comment&quot;: [{
+          &quot;_id&quot;: 1,
+          &quot;comment_title&quot;: &quot;Rails is unagi&quot;
+          &quot;post_id&quot;: 1
+        }, {
+          &quot;_id&quot;: 2,
+          &quot;comment_title&quot;: &quot;Don't tread on me&quot;,
+          &quot;post_id&quot;: 2
+        }]
+      }
+    }
+    ```
+
+    You could implement a serializer that looks like this to get your payload
+    into shape:
+
+    ```js
+    App.PostSerializer = DS.RESTSerializer.extend({
+      // First, restructure the top-level so it's organized by type
+      // and the comments are listed under a post's `comments` key.
+      extractArray: function(store, type, payload, id, requestType) {
+        var posts = payload._embedded.post;
+        var comments = [];
+        var postCache = {};
+
+        posts.forEach(function(post) {
+          post.comments = [];
+          postCache[post.id] = post;
+        });
+
+        payload._embedded.comment.forEach(function(comment) {
+          comments.push(comment);
+          postCache[comment.post_id].comments.push(comment);
+          delete comment.post_id;
+        }
+
+        payload = { comments: comments, posts: payload };
+
+        return this._super(store, type, payload, id, requestType);
+      },
+
+      normalizeHash: {
+        // Next, normalize individual comments, which (after `extract`)
+        // are now located under `comments`
+        comments: function(hash) {
+          hash.id = hash._id;
+          hash.title = hash.comment_title;
+          delete hash._id;
+          delete hash.comment_title;
+          return hash;
+        }
+      }
+    })
+    ```
+
+    When you call super from your own implementation of `extractArray`, the
+    built-in implementation will find the primary array in your normalized
+    payload and push the remaining records into the store.
+
+    The primary array is the array found under `posts`.
+
+    The primary record has special meaning when responding to `findQuery`
+    or `findHasMany`. In particular, the primary array will become the
+    list of records in the record array that kicked off the request.
+
+    If your primary array contains secondary (embedded) records of the same type,
+    you cannot place these into the primary array `posts`. Instead, place the
+    secondary items into an underscore prefixed property `_posts`, which will
+    push these items into the store and will not affect the resulting query.
+
+    @method extractArray
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} payload
+    @param {'findAll'|'findMany'|'findHasMany'|'findQuery'} requestType
+    @returns {Array} The primary array that was returned in response
+      to the original query.
+  */
+  extractArray: function(store, primaryType, payload) {
+    payload = this.normalizePayload(primaryType, payload);
+
+    var primaryTypeName = primaryType.typeKey,
+        primaryArray;
+
+    for (var prop in payload) {
+      var typeKey = prop,
+          forcedSecondary = false;
+
+      if (prop.charAt(0) === '_') {
+        forcedSecondary = true;
+        typeKey = prop.substr(1);
+      }
+
+      var typeName = this.typeForRoot(typeKey),
+          type = store.modelFor(typeName),
+          typeSerializer = store.serializerFor(type),
+          isPrimary = (!forcedSecondary &amp;&amp; (type.typeKey === primaryTypeName));
+
+      /*jshint loopfunc:true*/
+      var normalizedArray = map.call(payload[prop], function(hash) {
+        return typeSerializer.normalize(type, hash, prop);
+      }, this);
+
+      if (isPrimary) {
+        primaryArray = normalizedArray;
+      } else {
+        store.pushMany(typeName, normalizedArray);
+      }
+    }
+
+    return primaryArray;
+  },
+
+  /**
+    This method allows you to push a payload containing top-level
+    collections of records organized per type.
+
+    ```js
+    {
+      &quot;posts&quot;: [{
+        &quot;id&quot;: &quot;1&quot;,
+        &quot;title&quot;: &quot;Rails is omakase&quot;,
+        &quot;author&quot;, &quot;1&quot;,
+        &quot;comments&quot;: [ &quot;1&quot; ]
+      }],
+      &quot;comments&quot;: [{
+        &quot;id&quot;: &quot;1&quot;,
+        &quot;body&quot;: &quot;FIRST&quot;
+      }],
+      &quot;users&quot;: [{
+        &quot;id&quot;: &quot;1&quot;,
+        &quot;name&quot;: &quot;@d2h&quot;
+      }]
+    }
+    ```
+
+    It will first normalize the payload, so you can use this to push
+    in data streaming in from your server structured the same way
+    that fetches and saves are structured.
+
+    @method pushPayload
+    @param {DS.Store} store
+    @param {Object} payload
+  */
+  pushPayload: function(store, payload) {
+    payload = this.normalizePayload(null, payload);
+
+    for (var prop in payload) {
+      var typeName = this.typeForRoot(prop),
+          type = store.modelFor(typeName);
+
+      /*jshint loopfunc:true*/
+      var normalizedArray = map.call(Ember.makeArray(payload[prop]), function(hash) {
+        return this.normalize(type, hash, prop);
+      }, this);
+
+      store.pushMany(typeName, normalizedArray);
+    }
+  },
+
+  /**
+    You can use this method to normalize the JSON root keys returned
+    into the model type expected by your store.
+
+    For example, your server may return underscored root keys rather than
+    the expected camelcased versions.
+
+    ```js
+    App.ApplicationSerializer = DS.RESTSerializer.extend({
+      typeForRoot: function(root) {
+        var camelized = Ember.String.camelize(root);
+        return Ember.String.singularize(camelized);
+      }
+    });
+    ```
+
+    @method typeForRoot
+    @param {String} root
+    @returns {String} the model's typeKey
+  */
+  typeForRoot: function(root) {
+    return Ember.String.singularize(root);
+  },
+
+  // 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:
+
+    ```js
+    App.Comment = DS.Model.extend({
+      title: DS.attr(),
+      body: DS.attr(),
+
+      author: DS.belongsTo('user')
+    });
+    ```
+
+    The default serialization would create a JSON object like:
+
+    ```js
+    {
+      &quot;title&quot;: &quot;Rails is unagi&quot;,
+      &quot;body&quot;: &quot;Rails? Omakase? O_O&quot;,
+      &quot;author&quot;: 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.
+
+    ```js
+    App.PostSerializer = DS.RESTSerializer.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.
+
+    ```js
+    App.ApplicationSerializer = DS.RESTSerializer.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()) + &quot;_IDS&quot;;
+    }
+    ```
+
+    This serializer will generate JSON that looks like this:
+
+    ```js
+    {
+      &quot;TITLE&quot;: &quot;Rails is omakase&quot;,
+      &quot;BODY&quot;: &quot;Yep. Omakase.&quot;,
+      &quot;COMMENT_IDS&quot;: [ 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.
+
+    ```js
+    App.PostSerializer = DS.RESTSerializer.extend({
+      serialize: function(record, options) {
+        var json = this._super(record, options);
+
+        json.subject = json.title;
+        delete json.title;
+
+        return json;
+      }
+    });
+    ```
+
+    @method serialize
+    @param record
+    @param options
+  */
+  serialize: function(record, options) {
+    return this._super.apply(this, arguments);
+  },
+
+  /**
+    You can use this method to customize the root keys serialized into the JSON.
+    By default the REST Serializer sends camelized root keys.
+    For example, your server may expect underscored root objects.
+
+    ```js
+    App.ApplicationSerializer = DS.RESTSerializer.extend({
+      serializeIntoHash: function(data, type, record, options) {
+        var root = Ember.String.decamelize(type.typeKey);
+        data[root] = this.serialize(record, options);
+      }
+    });
+    ```
+
+    @method serializeIntoHash
+    @param {Object} hash
+    @param {subclass of DS.Model} type
+    @param {DS.Model} record
+    @param {Object} options
+  */
+  serializeIntoHash: function(hash, type, record, options) {
+    var root = Ember.String.camelize(type.typeKey);
+    hash[root] = this.serialize(record, options);
+  },
+
+  /**
+    You can use this method to customize how polymorphic objects are serialized.
+    By default the JSON Serializer creates the key by appending `Type` to
+    the attribute and value from the model's camelcased model name.
+
+    @method serializePolymorphicType
+    @param {DS.Model} record
+    @param {Object} json
+    @param {Object} relationship
+  */
+  serializePolymorphicType: function(record, json, relationship) {
+    var key = relationship.key,
+        belongsTo = get(record, key);
+    key = this.keyForAttribute ? this.keyForAttribute(key) : key;
+    json[key + &quot;Type&quot;] = Ember.String.camelize(belongsTo.constructor.typeKey);
+  }
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var get = Ember.get, set = Ember.set;
+var forEach = Ember.ArrayPolyfills.forEach;
+
+/**
+  The REST adapter allows your store to communicate with an HTTP server by
+  transmitting JSON via XHR. Most Ember.js apps that consume a JSON API
+  should use the REST adapter.
+
+  This adapter is designed around the idea that the JSON exchanged with
+  the server should be conventional.
+
+  ## JSON Structure
+
+  The REST adapter expects the JSON returned from your server to follow
+  these conventions.
+
+  ### Object Root
+
+  The JSON payload should be an object that contains the record inside a
+  root property. For example, in response to a `GET` request for
+  `/posts/1`, the JSON should look like this:
+
+  ```js
+  {
+    &quot;post&quot;: {
+      &quot;title&quot;: &quot;I'm Running to Reform the W3C's Tag&quot;,
+      &quot;author&quot;: &quot;Yehuda Katz&quot;
+    }
+  }
+  ```
+
+  ### Conventional Names
+
+  Attribute names in your JSON payload should be the camelCased versions of
+  the attributes in your Ember.js models.
+
+  For example, if you have a `Person` model:
+
+  ```js
+  App.Person = DS.Model.extend({
+    firstName: DS.attr('string'),
+    lastName: DS.attr('string'),
+    occupation: DS.attr('string')
+  });
+  ```
+
+  The JSON returned should look like this:
+
+  ```js
+  {
+    &quot;person&quot;: {
+      &quot;firstName&quot;: &quot;Barack&quot;,
+      &quot;lastName&quot;: &quot;Obama&quot;,
+      &quot;occupation&quot;: &quot;President&quot;
+    }
+  }
+  ```
+
+  ## Customization
+
+  ### Endpoint path customization
+
+  Endpoint paths can be prefixed with a `namespace` by setting the namespace
+  property on the adapter:
+
+  ```js
+  DS.RESTAdapter.reopen({
+    namespace: 'api/1'
+  });
+  ```
+  Requests for `App.Person` would now target `/api/1/people/1`.
+
+  ### Host customization
+
+  An adapter can target other hosts by setting the `host` property.
+
+  ```js
+  DS.RESTAdapter.reopen({
+    host: 'https://api.example.com'
+  });
+  ```
+
+  ### Headers customization
+
+  Some APIs require HTTP headers, e.g. to provide an API key. An array of
+  headers can be added to the adapter which are passed with every request:
+
+  ```js
+  DS.RESTAdapter.reopen({
+    headers: {
+      &quot;API_KEY&quot;: &quot;secret key&quot;,
+      &quot;ANOTHER_HEADER&quot;: &quot;Some header value&quot;
+    }
+  });
+  ```
+
+  @class RESTAdapter
+  @constructor
+  @namespace DS
+  @extends DS.Adapter
+*/
+DS.RESTAdapter = DS.Adapter.extend({
+  defaultSerializer: '-rest',
+
+
+  /**
+    Endpoint paths can be prefixed with a `namespace` by setting the namespace
+    property on the adapter:
+
+    ```javascript
+    DS.RESTAdapter.reopen({
+      namespace: 'api/1'
+    });
+    ```
+
+    Requests for `App.Post` would now target `/api/1/post/`.
+
+    @property namespace
+    @type {String}
+  */
+
+  /**
+    An adapter can target other hosts by setting the `host` property.
+
+    ```javascript
+    DS.RESTAdapter.reopen({
+      host: 'https://api.example.com'
+    });
+    ```
+
+    Requests for `App.Post` would now target `https://api.example.com/post/`.
+
+    @property host
+    @type {String}
+  */
+
+  /**
+    Some APIs require HTTP headers, e.g. to provide an API key. An array of
+    headers can be added to the adapter which are passed with every request:
+
+    ```javascript
+    DS.RESTAdapter.reopen({
+      headers: {
+        &quot;API_KEY&quot;: &quot;secret key&quot;,
+        &quot;ANOTHER_HEADER&quot;: &quot;Some header value&quot;
+      }
+    });
+    ```
+
+    @property headers
+    @type {Object}
+  */
+
+  /**
+    Called by the store in order to fetch the JSON for a given
+    type and ID.
+
+    The `find` method makes an Ajax request to a URL computed by `buildURL`, and returns a
+    promise for the resulting payload.
+
+    This method performs an HTTP `GET` request with the id provided as part of the query string.
+
+    @method find
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {String} id
+    @returns {Promise} promise
+  */
+  find: function(store, type, id) {
+    return this.ajax(this.buildURL(type.typeKey, id), 'GET');
+  },
+
+  /**
+    Called by the store in order to fetch a JSON array for all
+    of the records for a given type.
+
+    The `findAll` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
+    promise for the resulting payload.
+
+    @private
+    @method findAll
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {String} sinceToken
+    @returns {Promise} promise
+  */
+  findAll: function(store, type, sinceToken) {
+    var query;
+
+    if (sinceToken) {
+      query = { since: sinceToken };
+    }
+
+    return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query });
+  },
+
+  /**
+    Called by the store in order to fetch a JSON array for
+    the records that match a particular query.
+
+    The `findQuery` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
+    promise for the resulting payload.
+
+    The `query` argument is a simple JavaScript object that will be passed directly
+    to the server as parameters.
+
+    @private
+    @method findQuery
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Object} query
+    @returns {Promise} promise
+  */
+  findQuery: function(store, type, query) {
+    return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query });
+  },
+
+  /**
+    Called by the store in order to fetch a JSON array for
+    the unloaded records in a has-many relationship that were originally
+    specified as IDs.
+
+    For example, if the original payload looks like:
+
+    ```js
+    {
+      &quot;id&quot;: 1,
+      &quot;title&quot;: &quot;Rails is omakase&quot;,
+      &quot;comments&quot;: [ 1, 2, 3 ]
+    }
+    ```
+
+    The IDs will be passed as a URL-encoded Array of IDs, in this form:
+
+    ```
+    ids[]=1&amp;ids[]=2&amp;ids[]=3
+    ```
+
+    Many servers, such as Rails and PHP, will automatically convert this URL-encoded array
+    into an Array for you on the server-side. If you want to encode the
+    IDs, differently, just override this (one-line) method.
+
+    The `findMany` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
+    promise for the resulting payload.
+
+    @method findMany
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {Array} ids
+    @returns {Promise} promise
+  */
+  findMany: function(store, type, ids) {
+    return this.ajax(this.buildURL(type.typeKey), 'GET', { data: { ids: ids } });
+  },
+
+  /**
+    Called by the store in order to fetch a JSON array for
+    the unloaded records in a has-many relationship that were originally
+    specified as a URL (inside of `links`).
+
+    For example, if your original payload looks like this:
+
+    ```js
+    {
+      &quot;post&quot;: {
+        &quot;id&quot;: 1,
+        &quot;title&quot;: &quot;Rails is omakase&quot;,
+        &quot;links&quot;: { &quot;comments&quot;: &quot;/posts/1/comments&quot; }
+      }
+    }
+    ```
+
+    This method will be called with the parent record and `/posts/1/comments`.
+
+    The `findHasMany` method will make an Ajax (HTTP GET) request to the originally specified URL.
+    If the URL is host-relative (starting with a single slash), the
+    request will use the host specified on the adapter (if any).
+
+    @method findHasMany
+    @param {DS.Store} store
+    @param {DS.Model} record
+    @param {String} url
+    @returns {Promise} promise
+  */
+  findHasMany: function(store, record, url) {
+    var host = get(this, 'host'),
+        id   = get(record, 'id'),
+        type = record.constructor.typeKey;
+
+    if (host &amp;&amp; url.charAt(0) === '/' &amp;&amp; url.charAt(1) !== '/') {
+      url = host + url;
+    }
+
+    return this.ajax(this.urlPrefix(url, this.buildURL(type, id)), 'GET');
+  },
+
+  /**
+    Called by the store in order to fetch a JSON array for
+    the unloaded records in a belongs-to relationship that were originally
+    specified as a URL (inside of `links`).
+
+    For example, if your original payload looks like this:
+
+    ```js
+    {
+      &quot;person&quot;: {
+        &quot;id&quot;: 1,
+        &quot;name&quot;: &quot;Tom Dale&quot;,
+        &quot;links&quot;: { &quot;group&quot;: &quot;/people/1/group&quot; }
+      }
+    }
+    ```
+
+    This method will be called with the parent record and `/people/1/group`.
+
+    The `findBelongsTo` method will make an Ajax (HTTP GET) request to the originally specified URL.
+
+    @method findBelongsTo
+    @param {DS.Store} store
+    @param {DS.Model} record
+    @param {String} url
+    @returns {Promise} promise
+  */
+  findBelongsTo: function(store, record, url) {
+    var id   = get(record, 'id'),
+        type = record.constructor.typeKey;
+
+    return this.ajax(this.urlPrefix(url, this.buildURL(type, id)), 'GET');
+  },
+
+  /**
+    Called by the store when a newly created record is
+    saved via the `save` method on a model record instance.
+
+    The `createRecord` method serializes the record and makes an Ajax (HTTP POST) request
+    to a URL computed by `buildURL`.
+
+    See `serialize` for information on how to customize the serialized form
+    of a record.
+
+    @method createRecord
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {DS.Model} record
+    @returns {Promise} promise
+  */
+  createRecord: function(store, type, record) {
+    var data = {};
+    var serializer = store.serializerFor(type.typeKey);
+
+    serializer.serializeIntoHash(data, type, record, { includeId: true });
+
+    return this.ajax(this.buildURL(type.typeKey), &quot;POST&quot;, { data: data });
+  },
+
+  /**
+    Called by the store when an existing record is saved
+    via the `save` method on a model record instance.
+
+    The `updateRecord` method serializes the record and makes an Ajax (HTTP PUT) request
+    to a URL computed by `buildURL`.
+
+    See `serialize` for information on how to customize the serialized form
+    of a record.
+
+    @method updateRecord
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {DS.Model} record
+    @returns {Promise} promise
+  */
+  updateRecord: function(store, type, record) {
+    var data = {};
+    var serializer = store.serializerFor(type.typeKey);
+
+    serializer.serializeIntoHash(data, type, record);
+
+    var id = get(record, 'id');
+
+    return this.ajax(this.buildURL(type.typeKey, id), &quot;PUT&quot;, { data: data });
+  },
+
+  /**
+    Called by the store when a record is deleted.
+
+    The `deleteRecord` method  makes an Ajax (HTTP DELETE) request to a URL computed by `buildURL`.
+
+    @method deleteRecord
+    @param {DS.Store} store
+    @param {subclass of DS.Model} type
+    @param {DS.Model} record
+    @returns {Promise} promise
+  */
+  deleteRecord: function(store, type, record) {
+    var id = get(record, 'id');
+
+    return this.ajax(this.buildURL(type.typeKey, id), &quot;DELETE&quot;);
+  },
+
+  /**
+    Builds a URL for a given type and optional ID.
+
+    By default, it pluralizes the type's name (for example, 'post'
+    becomes 'posts' and 'person' becomes 'people'). To override the
+    pluralization see [pathForType](#method_pathForType).
+
+    If an ID is specified, it adds the ID to the path generated
+    for the type, separated by a `/`.
+
+    @method buildURL
+    @param {String} type
+    @param {String} id
+    @returns {String} url
+  */
+  buildURL: function(type, id) {
+    var url = [],
+        host = get(this, 'host'),
+        prefix = this.urlPrefix();
+
+    if (type) { url.push(this.pathForType(type)); }
+    if (id) { url.push(id); }
+
+    if (prefix) { url.unshift(prefix); }
+
+    url = url.join('/');
+    if (!host &amp;&amp; url) { url = '/' + url; }
+
+    return url;
+  },
+
+  /**
+    @method urlPrefix
+    @private
+    @param {String} path
+    @param {String} parentUrl
+    @return {String} urlPrefix
+  */
+  urlPrefix: function(path, parentURL) {
+    var host = get(this, 'host'),
+        namespace = get(this, 'namespace'),
+        url = [];
+
+    if (path) {
+      // Absolute path
+      if (path.charAt(0) === '/') {
+        if (host) {
+          path = path.slice(1);
+          url.push(host);
+        }
+      // Relative path
+      } else if (!/^http(s)?:\/\//.test(path)) {
+        url.push(parentURL);
+      }
+    } else {
+      if (host) { url.push(host); }
+      if (namespace) { url.push(namespace); }
+    }
+
+    if (path) {
+      url.push(path);
+    }
+
+    return url.join('/');
+  },
+
+  /**
+    Determines the pathname for a given type.
+
+    By default, it pluralizes the type's name (for example,
+    'post' becomes 'posts' and 'person' becomes 'people').
+
+    ### Pathname customization
+
+    For example if you have an object LineItem with an
+    endpoint of &quot;/line_items/&quot;.
+
+    ```js
+    DS.RESTAdapter.reopen({
+      pathForType: function(type) {
+        var decamelized = Ember.String.decamelize(type);
+        return Ember.String.pluralize(decamelized);
+      };
+    });
+    ```
+
+    @method pathForType
+    @param {String} type
+    @returns {String} path
+  **/
+  pathForType: function(type) {
+    var camelized = Ember.String.camelize(type);
+    return Ember.String.pluralize(camelized);
+  },
+
+  /**
+    Takes an ajax response, and returns a relevant error.
+
+    Returning a `DS.InvalidError` from this method will cause the
+    record to transition into the `invalid` state and make the
+    `errors` object available on the record.
+
+    ```javascript
+    App.ApplicationAdapter = DS.RESTAdapter.extend({
+      ajaxError: function(jqXHR) {
+        var error = this._super(jqXHR);
+
+        if (jqXHR &amp;&amp; jqXHR.status === 422) {
+          var jsonErrors = Ember.$.parseJSON(jqXHR.responseText)[&quot;errors&quot;];
+
+          return new DS.InvalidError(jsonErrors);
+        } else {
+          return error;
+        }
+      }
+    });
+    ```
+
+    Note: As a correctness optimization, the default implementation of
+    the `ajaxError` method strips out the `then` method from jquery's
+    ajax response (jqXHR). This is important because the jqXHR's
+    `then` method fulfills the promise with itself resulting in a
+    circular &quot;thenable&quot; chain which may cause problems for some
+    promise libraries.
+
+    @method ajaxError
+    @param  {Object} jqXHR
+    @return {Object} jqXHR
+  */
+  ajaxError: function(jqXHR) {
+    if (jqXHR) {
+      jqXHR.then = null;
+    }
+
+    return jqXHR;
+  },
+
+  /**
+    Takes a URL, an HTTP method and a hash of data, and makes an
+    HTTP request.
+
+    When the server responds with a payload, Ember Data will call into `extractSingle`
+    or `extractArray` (depending on whether the original query was for one record or
+    many records).
+
+    By default, `ajax` method has the following behavior:
+
+    * It sets the response `dataType` to `&quot;json&quot;`
+    * If the HTTP method is not `&quot;GET&quot;`, it sets the `Content-Type` to be
+      `application/json; charset=utf-8`
+    * If the HTTP method is not `&quot;GET&quot;`, it stringifies the data passed in. The
+      data is the serialized record in the case of a save.
+    * Registers success and failure handlers.
+
+    @method ajax
+    @private
+    @param {String} url
+    @param {String} type The request type GET, POST, PUT, DELETE etc.
+    @param {Object} hash
+    @return {Promise} promise
+  */
+  ajax: function(url, type, hash) {
+    var adapter = this;
+
+    return new Ember.RSVP.Promise(function(resolve, reject) {
+      hash = adapter.ajaxOptions(url, type, hash);
+
+      hash.success = function(json) {
+        Ember.run(null, resolve, json);
+      };
+
+      hash.error = function(jqXHR, textStatus, errorThrown) {
+        Ember.run(null, reject, adapter.ajaxError(jqXHR));
+      };
+
+      Ember.$.ajax(hash);
+    }, &quot;DS: RestAdapter#ajax &quot; + type + &quot; to &quot; + url);
+  },
+
+  /**
+    @method ajaxOptions
+    @private
+    @param {String} url
+    @param {String} type The request type GET, POST, PUT, DELETE etc.
+    @param {Object} hash
+    @return {Object} hash
+  */
+  ajaxOptions: function(url, type, hash) {
+    hash = hash || {};
+    hash.url = url;
+    hash.type = type;
+    hash.dataType = 'json';
+    hash.context = this;
+
+    if (hash.data &amp;&amp; type !== 'GET') {
+      hash.contentType = 'application/json; charset=utf-8';
+      hash.data = JSON.stringify(hash.data);
+    }
+
+    if (this.headers !== undefined) {
+      var headers = this.headers;
+      hash.beforeSend = function (xhr) {
+        forEach.call(Ember.keys(headers), function(key) {
+          xhr.setRequestHeader(key, headers[key]);
+        });
+      };
+    }
+
+
+    return hash;
+  }
+
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+})();
+
+
+
+(function() {
+DS.Model.reopen({
+
+  /**
+    Provides info about the model for debugging purposes
+    by grouping the properties into more semantic groups.
+
+    Meant to be used by debugging tools such as the Chrome Ember Extension.
+
+    - Groups all attributes in &quot;Attributes&quot; group.
+    - Groups all belongsTo relationships in &quot;Belongs To&quot; group.
+    - Groups all hasMany relationships in &quot;Has Many&quot; group.
+    - Groups all flags in &quot;Flags&quot; group.
+    - Flags relationship CPs as expensive properties.
+
+    @method _debugInfo
+    @for DS.Model
+    @private
+  */
+  _debugInfo: function() {
+    var attributes = ['id'],
+        relationships = { belongsTo: [], hasMany: [] },
+        expensiveProperties = [];
+
+    this.eachAttribute(function(name, meta) {
+      attributes.push(name);
+    }, this);
+
+    this.eachRelationship(function(name, relationship) {
+      relationships[relationship.kind].push(name);
+      expensiveProperties.push(name);
+    });
+
+    var groups = [
+      {
+        name: 'Attributes',
+        properties: attributes,
+        expand: true
+      },
+      {
+        name: 'Belongs To',
+        properties: relationships.belongsTo,
+        expand: true
+      },
+      {
+        name: 'Has Many',
+        properties: relationships.hasMany,
+        expand: true
+      },
+      {
+        name: 'Flags',
+        properties: ['isLoaded', 'isDirty', 'isSaving', 'isDeleted', 'isError', 'isNew', 'isValid']
+      }
+    ];
+
+    return {
+      propertyInfo: {
+        // include all other mixins / properties (not just the grouped ones)
+        includeOtherProperties: true,
+        groups: groups,
+        // don't pre-calculate unless cached
+        expensiveProperties: expensiveProperties
+      }
+    };
+  }
+
+});
+
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+})();
+
+
+
+(function() {
+/**
+  Ember Data
+
+  @module ember-data
+  @main ember-data
+*/
+
+})();
+
+(function() {
+Ember.String.pluralize = function(word) {
+  return Ember.Inflector.inflector.pluralize(word);
+};
+
+Ember.String.singularize = function(word) {
+  return Ember.Inflector.inflector.singularize(word);
+};
+
+})();
+
+
+
+(function() {
+var BLANK_REGEX = /^\s*$/;
+
+function loadUncountable(rules, uncountable) {
+  for (var i = 0, length = uncountable.length; i &lt; length; i++) {
+    rules.uncountable[uncountable[i].toLowerCase()] = true;
+  }
+}
+
+function loadIrregular(rules, irregularPairs) {
+  var pair;
+
+  for (var i = 0, length = irregularPairs.length; i &lt; length; i++) {
+    pair = irregularPairs[i];
+
+    rules.irregular[pair[0].toLowerCase()] = pair[1];
+    rules.irregularInverse[pair[1].toLowerCase()] = pair[0];
+  }
+}
+
+/**
+  Inflector.Ember provides a mechanism for supplying inflection rules for your
+  application. Ember includes a default set of inflection rules, and provides an
+  API for providing additional rules.
+
+  Examples:
+
+  Creating an inflector with no rules.
+
+  ```js
+  var inflector = new Ember.Inflector();
+  ```
+
+  Creating an inflector with the default ember ruleset.
+
+  ```js
+  var inflector = new Ember.Inflector(Ember.Inflector.defaultRules);
+
+  inflector.pluralize('cow') //=&gt; 'kine'
+  inflector.singularize('kine') //=&gt; 'cow'
+  ```
+
+  Creating an inflector and adding rules later.
+
+  ```javascript
+  var inflector = Ember.Inflector.inflector;
+
+  inflector.pluralize('advice') // =&gt; 'advices'
+  inflector.uncountable('advice');
+  inflector.pluralize('advice') // =&gt; 'advice'
+
+  inflector.pluralize('formula') // =&gt; 'formulas'
+  inflector.irregular('formula', 'formulae');
+  inflector.pluralize('formula') // =&gt; 'formulae'
+
+  // you would not need to add these as they are the default rules
+  inflector.plural(/$/, 's');
+  inflector.singular(/s$/i, '');
+  ```
+
+  Creating an inflector with a nondefault ruleset.
+
+  ```javascript
+  var rules = {
+    plurals:  [ /$/, 's' ],
+    singular: [ /\s$/, '' ],
+    irregularPairs: [
+      [ 'cow', 'kine' ]
+    ],
+    uncountable: [ 'fish' ]
+  };
+
+  var inflector = new Ember.Inflector(rules);
+  ```
+
+  @class Inflector
+  @namespace Ember
+*/
+function Inflector(ruleSet) {
+  ruleSet = ruleSet || {};
+  ruleSet.uncountable = ruleSet.uncountable || {};
+  ruleSet.irregularPairs = ruleSet.irregularPairs || {};
+
+  var rules = this.rules = {
+    plurals:  ruleSet.plurals || [],
+    singular: ruleSet.singular || [],
+    irregular: {},
+    irregularInverse: {},
+    uncountable: {}
+  };
+
+  loadUncountable(rules, ruleSet.uncountable);
+  loadIrregular(rules, ruleSet.irregularPairs);
+}
+
+Inflector.prototype = {
+  /**
+    @method plural
+    @param {RegExp} regex
+    @param {String} string
+  */
+  plural: function(regex, string) {
+    this.rules.plurals.push([regex, string.toLowerCase()]);
+  },
+
+  /**
+    @method singular
+    @param {RegExp} regex
+    @param {String} string
+  */
+  singular: function(regex, string) {
+    this.rules.singular.push([regex, string.toLowerCase()]);
+  },
+
+  /**
+    @method uncountable
+    @param {String} regex
+  */
+  uncountable: function(string) {
+    loadUncountable(this.rules, [string.toLowerCase()]);
+  },
+
+  /**
+    @method irregular
+    @param {String} singular
+    @param {String} plural
+  */
+  irregular: function (singular, plural) {
+    loadIrregular(this.rules, [[singular, plural]]);
+  },
+
+  /**
+    @method pluralize
+    @param {String} word
+  */
+  pluralize: function(word) {
+    return this.inflect(word, this.rules.plurals, this.rules.irregular);
+  },
+
+  /**
+    @method singularize
+    @param {String} word
+  */
+  singularize: function(word) {
+    return this.inflect(word, this.rules.singular,  this.rules.irregularInverse);
+  },
+
+  /**
+    @protected
+
+    @method inflect
+    @param {String} word
+    @param {Object} typeRules
+    @param {Object} irregular
+  */
+  inflect: function(word, typeRules, irregular) {
+    var inflection, substitution, result, lowercase, isBlank,
+    isUncountable, isIrregular, isIrregularInverse, rule;
+
+    isBlank = BLANK_REGEX.test(word);
+
+    if (isBlank) {
+      return word;
+    }
+
+    lowercase = word.toLowerCase();
+
+    isUncountable = this.rules.uncountable[lowercase];
+
+    if (isUncountable) {
+      return word;
+    }
+
+    isIrregular = irregular &amp;&amp; irregular[lowercase];
+
+    if (isIrregular) {
+      return isIrregular;
+    }
+
+    for (var i = typeRules.length, min = 0; i &gt; min; i--) {
+       inflection = typeRules[i-1];
+       rule = inflection[0];
+
+      if (rule.test(word)) {
+        break;
+      }
+    }
+
+    inflection = inflection || [];
+
+    rule = inflection[0];
+    substitution = inflection[1];
+
+    result = word.replace(rule, substitution);
+
+    return result;
+  }
+};
+
+Ember.Inflector = Inflector;
+
+})();
+
+
+
+(function() {
+Ember.Inflector.defaultRules = {
+  plurals: [
+    [/$/, 's'],
+    [/s$/i, 's'],
+    [/^(ax|test)is$/i, '$1es'],
+    [/(octop|vir)us$/i, '$1i'],
+    [/(octop|vir)i$/i, '$1i'],
+    [/(alias|status)$/i, '$1es'],
+    [/(bu)s$/i, '$1ses'],
+    [/(buffal|tomat)o$/i, '$1oes'],
+    [/([ti])um$/i, '$1a'],
+    [/([ti])a$/i, '$1a'],
+    [/sis$/i, 'ses'],
+    [/(?:([^f])fe|([lr])f)$/i, '$1$2ves'],
+    [/(hive)$/i, '$1s'],
+    [/([^aeiouy]|qu)y$/i, '$1ies'],
+    [/(x|ch|ss|sh)$/i, '$1es'],
+    [/(matr|vert|ind)(?:ix|ex)$/i, '$1ices'],
+    [/^(m|l)ouse$/i, '$1ice'],
+    [/^(m|l)ice$/i, '$1ice'],
+    [/^(ox)$/i, '$1en'],
+    [/^(oxen)$/i, '$1'],
+    [/(quiz)$/i, '$1zes']
+  ],
+
+  singular: [
+    [/s$/i, ''],
+    [/(ss)$/i, '$1'],
+    [/(n)ews$/i, '$1ews'],
+    [/([ti])a$/i, '$1um'],
+    [/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '$1sis'],
+    [/(^analy)(sis|ses)$/i, '$1sis'],
+    [/([^f])ves$/i, '$1fe'],
+    [/(hive)s$/i, '$1'],
+    [/(tive)s$/i, '$1'],
+    [/([lr])ves$/i, '$1f'],
+    [/([^aeiouy]|qu)ies$/i, '$1y'],
+    [/(s)eries$/i, '$1eries'],
+    [/(m)ovies$/i, '$1ovie'],
+    [/(x|ch|ss|sh)es$/i, '$1'],
+    [/^(m|l)ice$/i, '$1ouse'],
+    [/(bus)(es)?$/i, '$1'],
+    [/(o)es$/i, '$1'],
+    [/(shoe)s$/i, '$1'],
+    [/(cris|test)(is|es)$/i, '$1is'],
+    [/^(a)x[ie]s$/i, '$1xis'],
+    [/(octop|vir)(us|i)$/i, '$1us'],
+    [/(alias|status)(es)?$/i, '$1'],
+    [/^(ox)en/i, '$1'],
+    [/(vert|ind)ices$/i, '$1ex'],
+    [/(matr)ices$/i, '$1ix'],
+    [/(quiz)zes$/i, '$1'],
+    [/(database)s$/i, '$1']
+  ],
+
+  irregularPairs: [
+    ['person', 'people'],
+    ['man', 'men'],
+    ['child', 'children'],
+    ['sex', 'sexes'],
+    ['move', 'moves'],
+    ['cow', 'kine'],
+    ['zombie', 'zombies']
+  ],
+
+  uncountable: [
+    'equipment',
+    'information',
+    'rice',
+    'money',
+    'species',
+    'series',
+    'fish',
+    'sheep',
+    'jeans',
+    'police'
+  ]
+};
+
+})();
+
+
+
+(function() {
+if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {
+  /**
+    See {{#crossLink &quot;Ember.String/pluralize&quot;}}{{/crossLink}}
+
+    @method pluralize
+    @for String
+  */
+  String.prototype.pluralize = function() {
+    return Ember.String.pluralize(this);
+  };
+
+  /**
+    See {{#crossLink &quot;Ember.String/singularize&quot;}}{{/crossLink}}
+
+    @method singularize
+    @for String
+  */
+  String.prototype.singularize = function() {
+    return Ember.String.singularize(this);
+  };
+}
+
+})();
+
+
+
+(function() {
+Ember.Inflector.inflector = new Ember.Inflector(Ember.Inflector.defaultRules);
+
+})();
+
+
+
+(function() {
+
+})();
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var get = Ember.get,
+    forEach = Ember.EnumerableUtils.forEach,
+    camelize =   Ember.String.camelize,
+    capitalize = Ember.String.capitalize,
+    decamelize = Ember.String.decamelize,
+    singularize = Ember.String.singularize,
+    underscore = Ember.String.underscore;
+
+DS.ActiveModelSerializer = DS.RESTSerializer.extend({
+  // SERIALIZE
+
+  /**
+    Converts camelcased attributes to underscored when serializing.
+
+    @method keyForAttribute
+    @param {String} attribute
+    @returns String
+  */
+  keyForAttribute: function(attr) {
+    return decamelize(attr);
+  },
+
+  /**
+    Underscores relationship names and appends &quot;_id&quot; or &quot;_ids&quot; when serializing
+    relationship keys.
+
+    @method keyForRelationship
+    @param {String} key
+    @param {String} kind
+    @returns String
+  */
+  keyForRelationship: function(key, kind) {
+    key = decamelize(key);
+    if (kind === &quot;belongsTo&quot;) {
+      return key + &quot;_id&quot;;
+    } else if (kind === &quot;hasMany&quot;) {
+      return singularize(key) + &quot;_ids&quot;;
+    } else {
+      return key;
+    }
+  },
+
+  /**
+    Does not serialize hasMany relationships by default.
+  */
+  serializeHasMany: Ember.K,
+
+  /**
+    Underscores the JSON root keys when serializing.
+
+    @method serializeIntoHash
+    @param {Object} hash
+    @param {subclass of DS.Model} type
+    @param {DS.Model} record
+    @param {Object} options
+  */
+  serializeIntoHash: function(data, type, record, options) {
+    var root = underscore(decamelize(type.typeKey));
+    data[root] = this.serialize(record, options);
+  },
+
+  /**
+    Serializes a polymorphic type as a fully capitalized model name.
+
+    @method serializePolymorphicType
+    @param {DS.Model} record
+    @param {Object} json
+    @param relationship
+  */
+  serializePolymorphicType: function(record, json, relationship) {
+    var key = relationship.key,
+        belongsTo = get(record, key);
+    key = this.keyForAttribute(key);
+    json[key + &quot;_type&quot;] = capitalize(camelize(belongsTo.constructor.typeKey));
+  },
+
+  // EXTRACT
+
+  /**
+    Extracts the model typeKey from underscored root objects.
+
+    @method typeForRoot
+    @param {String} root
+    @returns String the model's typeKey
+  */
+  typeForRoot: function(root) {
+    var camelized = camelize(root);
+    return singularize(camelized);
+  },
+
+  /**
+    Add extra step to `DS.RESTSerializer.normalize` so links are
+    normalized.
+
+    If your payload looks like this
+
+    ```js
+    {
+      &quot;post&quot;: {
+        &quot;id&quot;: 1,
+        &quot;title&quot;: &quot;Rails is omakase&quot;,
+        &quot;links&quot;: { &quot;flagged_comments&quot;: &quot;api/comments/flagged&quot; }
+      }
+    }
+    ```
+    The normalized version would look like this
+
+    ```js
+    {
+      &quot;post&quot;: {
+        &quot;id&quot;: 1,
+        &quot;title&quot;: &quot;Rails is omakase&quot;,
+        &quot;links&quot;: { &quot;flaggedComments&quot;: &quot;api/comments/flagged&quot; }
+      }
+    }
+    ```
+
+    @method normalize
+    @param {subclass of DS.Model} type
+    @param {Object} hash
+    @param {String} prop
+    @returns Object
+  */
+
+  normalize: function(type, hash, prop) {
+    this.normalizeLinks(hash);
+
+    return this._super(type, hash, prop);
+  },
+
+  /**
+    Convert `snake_cased` links  to `camelCase`
+
+    @method normalizeLinks
+    @param {Object} hash
+  */
+
+  normalizeLinks: function(data){
+    if (data.links) {
+      var links = data.links;
+
+      for (var link in links) {
+        var camelizedLink = camelize(link);
+
+        if (camelizedLink !== link) {
+          links[camelizedLink] = links[link];
+          delete links[link];
+        }
+      }
+    }
+  },
+
+  /**
+    Normalize the polymorphic type from the JSON.
+
+    Normalize:
+    ```js
+      {
+        id: &quot;1&quot;
+        minion: { type: &quot;evil_minion&quot;, id: &quot;12&quot;}
+      }
+    ```
+
+    To:
+    ```js
+      {
+        id: &quot;1&quot;
+        minion: { type: &quot;evilMinion&quot;, id: &quot;12&quot;}
+      }
+    ```
+
+    @method normalizeRelationships
+    @private
+  */
+  normalizeRelationships: function(type, hash) {
+    var payloadKey, payload;
+
+    if (this.keyForRelationship) {
+      type.eachRelationship(function(key, relationship) {
+        if (relationship.options.polymorphic) {
+          payloadKey = this.keyForAttribute(key);
+          payload = hash[payloadKey];
+          if (payload &amp;&amp; payload.type) {
+            payload.type = this.typeForRoot(payload.type);
+          } else if (payload &amp;&amp; relationship.kind === &quot;hasMany&quot;) {
+            var self = this;
+            forEach(payload, function(single) {
+              single.type = self.typeForRoot(single.type);
+            });
+          }
+        } else {
+          payloadKey = this.keyForRelationship(key, relationship.kind);
+          payload = hash[payloadKey];
+        }
+
+        hash[key] = payload;
+
+        if (key !== payloadKey) {
+          delete hash[payloadKey];
+        }
+      }, this);
+    }
+  }
+});
+
+})();
+
+
+
+(function() {
+var get = Ember.get;
+var forEach = Ember.EnumerableUtils.forEach;
+
+/**
+  The EmbeddedRecordsMixin allows you to add embedded record support to your
+  serializers.
+  To set up embedded records, you include the mixin into the serializer and then
+  define your embedded relations.
+
+  ```js
+  App.PostSerializer = DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {
+    attrs: {
+      comments: {embedded: 'always'}
+    }
+  })
+  ```
+
+  Currently only `{embedded: 'always'}` records are supported.
+
+  @class EmbeddedRecordsMixin
+  @namespace DS
+*/
+DS.EmbeddedRecordsMixin = Ember.Mixin.create({
+
+  /**
+    Serialize has-may relationship when it is configured as embedded objects.
+
+    @method serializeHasMany
+  */
+  serializeHasMany: function(record, json, relationship) {
+    var key   = relationship.key,
+        attrs = get(this, 'attrs'),
+        embed = attrs &amp;&amp; attrs[key] &amp;&amp; attrs[key].embedded === 'always';
+
+    if (embed) {
+      json[this.keyForAttribute(key)] = get(record, key).map(function(relation) {
+        var data = relation.serialize(),
+            primaryKey = get(this, 'primaryKey');
+
+        data[primaryKey] = get(relation, primaryKey);
+
+        return data;
+      }, this);
+    }
+  },
+
+  /**
+    Extract embedded objects out of the payload for a single object
+    and add them as sideloaded objects instead.
+
+    @method extractSingle
+  */
+  extractSingle: function(store, primaryType, payload, recordId, requestType) {
+    var root = this.keyForAttribute(primaryType.typeKey),
+        partial = payload[root];
+
+    updatePayloadWithEmbedded(store, this, primaryType, partial, payload);
+
+    return this._super(store, primaryType, payload, recordId, requestType);
+  },
+
+  /**
+    Extract embedded objects out of a standard payload
+    and add them as sideloaded objects instead.
+
+    @method extractArray
+  */
+  extractArray: function(store, type, payload) {
+    var root = this.keyForAttribute(type.typeKey),
+        partials = payload[Ember.String.pluralize(root)];
+
+    forEach(partials, function(partial) {
+      updatePayloadWithEmbedded(store, this, type, partial, payload);
+    }, this);
+
+    return this._super(store, type, payload);
+  }
+});
+
+function updatePayloadWithEmbedded(store, serializer, type, partial, payload) {
+  var attrs = get(serializer, 'attrs');
+
+  if (!attrs) {
+    return;
+  }
+
+  type.eachRelationship(function(key, relationship) {
+    var expandedKey, embeddedTypeKey, attribute, ids,
+        config = attrs[key],
+        serializer = store.serializerFor(relationship.type.typeKey),
+        primaryKey = get(serializer, &quot;primaryKey&quot;);
+
+    if (relationship.kind !== &quot;hasMany&quot;) {
+      return;
+    }
+
+    if (config &amp;&amp; (config.embedded === 'always' || config.embedded === 'load')) {
+      // underscore forces the embedded records to be side loaded.
+      // it is needed when main type === relationship.type
+      embeddedTypeKey = '_' + Ember.String.pluralize(relationship.type.typeKey);
+      expandedKey = this.keyForRelationship(key, relationship.kind);
+      attribute  = this.keyForAttribute(key);
+      ids = [];
+
+      if (!partial[attribute]) {
+        return;
+      }
+
+      payload[embeddedTypeKey] = payload[embeddedTypeKey] || [];
+
+      forEach(partial[attribute], function(data) {
+        var embeddedType = store.modelFor(relationship.type.typeKey);
+        updatePayloadWithEmbedded(store, serializer, embeddedType, data, payload);
+        ids.push(data[primaryKey]);
+        payload[embeddedTypeKey].push(data);
+      });
+
+      partial[expandedKey] = ids;
+      delete partial[attribute];
+    }
+  }, serializer);
+}
+})();
+
+
+
+(function() {
+/**
+  @module ember-data
+*/
+
+var forEach = Ember.EnumerableUtils.forEach;
+var decamelize = Ember.String.decamelize,
+    underscore = Ember.String.underscore,
+    pluralize  = Ember.String.pluralize;
+
+/**
+  The ActiveModelAdapter is a subclass of the RESTAdapter designed to integrate
+  with a JSON API that uses an underscored naming convention instead of camelcasing.
+  It has been designed to work out of the box with the
+  [active_model_serializers](http://github.com/rails-api/active_model_serializers)
+  Ruby gem.
+
+  This adapter extends the DS.RESTAdapter by making consistent use of the camelization,
+  decamelization and pluralization methods to normalize the serialized JSON into a
+  format that is compatible with a conventional Rails backend and Ember Data.
+
+  ## JSON Structure
+
+  The ActiveModelAdapter expects the JSON returned from your server to follow
+  the REST adapter conventions substituting underscored keys for camelcased ones.
+
+  ### Conventional Names
+
+  Attribute names in your JSON payload should be the underscored versions of
+  the attributes in your Ember.js models.
+
+  For example, if you have a `Person` model:
+
+  ```js
+  App.FamousPerson = DS.Model.extend({
+    firstName: DS.attr('string'),
+    lastName: DS.attr('string'),
+    occupation: DS.attr('string')
+  });
+  ```
+
+  The JSON returned should look like this:
+
+  ```js
+  {
+    &quot;famous_person&quot;: {
+      &quot;first_name&quot;: &quot;Barack&quot;,
+      &quot;last_name&quot;: &quot;Obama&quot;,
+      &quot;occupation&quot;: &quot;President&quot;
+    }
+  }
+  ```
+
+  @class ActiveModelAdapter
+  @constructor
+  @namespace DS
+  @extends DS.Adapter
+**/
+
+DS.ActiveModelAdapter = DS.RESTAdapter.extend({
+  defaultSerializer: '-active-model',
+  /**
+    The ActiveModelAdapter overrides the `pathForType` method to build
+    underscored URLs by decamelizing and pluralizing the object type name.
+
+    ```js
+      this.pathForType(&quot;famousPerson&quot;);
+      //=&gt; &quot;famous_people&quot;
+    ```
+
+    @method pathForType
+    @param {String} type
+    @returns String
+  */
+  pathForType: function(type) {
+    var decamelized = decamelize(type);
+    var underscored = underscore(decamelized);
+    return pluralize(underscored);
+  },
+
+  /**
+    The ActiveModelAdapter overrides the `ajaxError` method
+    to return a DS.InvalidError for all 422 Unprocessable Entity
+    responses.
+
+    A 422 HTTP response from the server generally implies that the request
+    was well formed but the API was unable to process it because the
+    content was not semantically correct or meaningful per the API.
+
+    For more information on 422 HTTP Error code see 11.2 WebDAV RFC 4918
+    https://tools.ietf.org/html/rfc4918#section-11.2
+
+    @method ajaxError
+    @param jqXHR
+    @returns error
+  */
+  ajaxError: function(jqXHR) {
+    var error = this._super(jqXHR);
+
+    if (jqXHR &amp;&amp; jqXHR.status === 422) {
+      var response = Ember.$.parseJSON(jqXHR.responseText),
+          errors = {};
+
+      if (response.errors !== undefined) {
+        var jsonErrors = response.errors;
+
+        forEach(Ember.keys(jsonErrors), function(key) {
+          errors[Ember.String.camelize(key)] = jsonErrors[key];
+        });
+      }
+
+      return new DS.InvalidError(errors);
+    } else {
+      return error;
+    }
+  }
+});
+
+})();
+
+
+
+(function() {
+
+})();
+
+
+
+(function() {
+Ember.onLoad('Ember.Application', function(Application) {
+  Application.initializer({
+    name: &quot;activeModelAdapter&quot;,
+
+    initialize: function(container, application) {
+      var proxy = new DS.ContainerProxy(container);
+      proxy.registerDeprecations([
+        {deprecated: 'serializer:_ams',  valid: 'serializer:-active-model'},
+        {deprecated: 'adapter:_ams',     valid: 'adapter:-active-model'}
+      ]);
+
+      application.register('serializer:-active-model', DS.ActiveModelSerializer);
+      application.register('adapter:-active-model', DS.ActiveModelAdapter);
+    }
+  });
+});
+
+})();
+
+
+
+(function() {
+
+})();
+
+
+})();
</ins></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbower_componentsemberlocalstorageadapterlocalstorage_adapterjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember-localstorage-adapter/localstorage_adapter.js (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember-localstorage-adapter/localstorage_adapter.js        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/ember-localstorage-adapter/localstorage_adapter.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -1,66 +1,31 @@
</span><del>-DS.LSSerializer = DS.JSONSerializer.extend({
</del><ins>+/*global Ember*/
+/*global DS*/
+'use strict';
</ins><span class="cx"> 
</span><del>-  addBelongsTo: function(data, record, key, association) {
-    data[key] = record.get(key + '.id');
-  },
-
-  addHasMany: function(data, record, key, association) {
-    data[key] = record.get(key).map(function(record) {
-      return record.get('id');
-    });
-  },
-
-  // extract expects a root key, we don't want to save all these keys to
-  // localStorage so we generate the root keys here
-  extract: function(loader, json, type, record) {
-    this._super(loader, this.rootJSON(json, type), type, record);
-  },
-
-  extractMany: function(loader, json, type, records) {
-    this._super(loader, this.rootJSON(json, type, 'pluralize'), type, records);
-  },
-
-  rootJSON: function(json, type, pluralize) {
-    var root = this.rootForType(type);
-    if (pluralize == 'pluralize') { root = this.pluralize(root); }
-    var rootedJSON = {};
-    rootedJSON[root] = json;
-    return rootedJSON;
-  }
-
-});
-
</del><span class="cx"> DS.LSAdapter = DS.Adapter.extend(Ember.Evented, {
</span><span class="cx"> 
</span><del>-  init: function() {
-    this._loadData();
-  },
</del><ins>+    init: function () {
+        this._loadData();
+    },
</ins><span class="cx"> 
</span><del>-  generateIdForRecord: function() {
-    return Math.random().toString(32).slice(2).substr(0,5);
-  },
</del><ins>+    generateIdForRecord: function () {
+        return Math.random().toString(32).slice(2).substr(0, 5);
+    },
</ins><span class="cx"> 
</span><del>-  serializer: DS.LSSerializer.create(),
</del><ins>+    find: function (store, type, id) {
+        var namespace = this._namespaceForType(type);
+        return Ember.RSVP.resolve(Ember.copy(namespace.records[id]));
+    },
</ins><span class="cx"> 
</span><del>-  find: function(store, type, id) {
-    var namespace = this._namespaceForType(type);
-    this._async(function(){
-      var copy = Ember.copy(namespace.records[id]);
-      this.didFindRecord(store, type, copy, id);
-    });
-  },
</del><ins>+    findMany: function (store, type, ids) {
+        var namespace = this._namespaceForType(type);
+        var results = [];
+        for (var i = 0; i &lt; ids.length; i++) {
+            results.push(Ember.copy(namespace.records[ids[i]]));
+        }
+        return Ember.RSVP.resolve(results);
+    },
</ins><span class="cx"> 
</span><del>-  findMany: function(store, type, ids) {
-    var namespace = this._namespaceForType(type);
-    this._async(function(){
-      var results = [];
-      for (var i = 0; i &lt; ids.length; i++) {
-        results.push(Ember.copy(namespace.records[ids[i]]));
-      }
-      this.didFindMany(store, type, results);
-    });
-  },
-
</del><span class="cx">   // Supports queries that look like this:
</span><span class="cx">   //
</span><span class="cx">   //   {
</span><span class="lines">@@ -75,141 +40,87 @@
</span><span class="cx">   //  match records with &quot;complete: true&quot; and the name &quot;foo&quot; or &quot;bar&quot;
</span><span class="cx">   //
</span><span class="cx">   //    { complete: true, name: /foo|bar/ }
</span><del>-  findQuery: function(store, type, query, recordArray) {
-    var namespace = this._namespaceForType(type);
-    this._async(function() {
-      var results = this.query(namespace.records, query);
-      this.didFindQuery(store, type, results, recordArray);
-    });
-  },
</del><ins>+    findQuery: function (store, type, query, recordArray) {
+        var namespace = this._namespaceForType(type);
+        var results = this.query(namespace.records, query);
+        return Ember.RSVP.resolve(results);
+    },
</ins><span class="cx"> 
</span><del>-  query: function(records, query) {
-    var results = [];
-    var id, record, property, test, push;
-    for (id in records) {
-      record = records[id];
-      for (property in query) {
-        test = query[property];
-        push = false;
-        if (Object.prototype.toString.call(test) == '[object RegExp]') {
-          push = test.test(record[property]);
-        } else {
-          push = record[property] === test;
</del><ins>+    query: function (records, query) {
+        var results = [];
+        var id, record, property, test, push;
+        for (id in records) {
+            record = records[id];
+            for (property in query) {
+                test = query[property];
+                push = false;
+                if (Object.prototype.toString.call(test) === '[object RegExp]') {
+                    push = test.test(record[property]);
+                } else {
+                    push = record[property] === test;
+                }
+            }
+            if (push) {
+                results.push(record);
+            }
</ins><span class="cx">         }
</span><del>-      }
-      if (push) {
-        results.push(record);
-      }
-    }
-    return results;
-  },
</del><ins>+        return results;
+    },
</ins><span class="cx"> 
</span><del>-  findAll: function(store, type) {
-    var namespace = this._namespaceForType(type);
-    this._async(function() {
-      var results = [];
-      for (var id in namespace.records) {
-        results.push(Ember.copy(namespace.records[id]));
-      }
-      this.didFindAll(store, type, results);
-    });
-  },
</del><ins>+    findAll: function (store, type) {
+        var namespace = this._namespaceForType(type);
+        var results = [];
+        for (var id in namespace.records) {
+            results.push(Ember.copy(namespace.records[id]));
+        }
+        return Ember.RSVP.resolve(results);
+    },
</ins><span class="cx"> 
</span><del>-  createRecords: function(store, type, records) {
-    var namespace = this._namespaceForType(type);
-    records.forEach(function(record) {
-      this._addRecordToNamespace(namespace, record);
-    }, this);
-    this._async(function() {
-      this._didSaveRecords(store, type, records);
-    });
-  },
</del><ins>+    createRecord: function (store, type, record) {
+        var namespace = this._namespaceForType(type);
+        this._addRecordToNamespace(namespace, record);
+        this._saveData();
+        return Ember.RSVP.resolve();
+    },
</ins><span class="cx"> 
</span><del>-  updateRecords: function(store, type, records) {
-    var namespace = this._namespaceForType(type);
-    this._async(function() {
-      records.forEach(function(record) {
</del><ins>+    updateRecord: function (store, type, record) {
+        var namespace = this._namespaceForType(type);
</ins><span class="cx">         var id = record.get('id');
</span><del>-        namespace.records[id] = record.serialize({includeId:true});
-      }, this);
-      this._didSaveRecords(store, type, records);
-    });
-  },
</del><ins>+        namespace.records[id] = record.toJSON({ includeId: true });
+        this._saveData();
+        return Ember.RSVP.resolve();
+    },
</ins><span class="cx"> 
</span><del>-  deleteRecords: function(store, type, records) {
-    var namespace = this._namespaceForType(type);
-    this._async(function() {
-      records.forEach(function(record) {
</del><ins>+    deleteRecord: function (store, type, record) {
+        var namespace = this._namespaceForType(type);
</ins><span class="cx">         var id = record.get('id');
</span><span class="cx">         delete namespace.records[id];
</span><del>-      });
-      this._didSaveRecords(store, type, records);
-    });
</del><ins>+        this._saveData();
+        return Ember.RSVP.resolve();
+    },
</ins><span class="cx"> 
</span><del>-  },
-
-  dirtyRecordsForHasManyChange: function(dirtySet, parent, relationship) {
-    dirtySet.add(parent);
-  },
-
-  dirtyRecordsForBelongsToChange: function(dirtySet, child, relationship) {
-    dirtySet.add(child);
-  },
-
</del><span class="cx">   // private
</span><span class="cx"> 
</span><del>-  _getNamespace: function() {
-    return this.namespace || 'DS.LSAdapter';
-  },
</del><ins>+    _getNamespace: function () {
+        return this.namespace || 'DS.LSAdapter';
+    },
</ins><span class="cx"> 
</span><del>-  _loadData: function() {
-    var storage = localStorage.getItem(this._getNamespace());
-    this._data = storage ? JSON.parse(storage) : {};
-  },
</del><ins>+    _loadData: function () {
+        this._data = {};
+    },
</ins><span class="cx"> 
</span><del>-  _didSaveRecords: function(store, type, records) {
-    var success = this._saveData();
-    if (success) {
-      store.didSaveRecords(records);
-    } else {
-      records.forEach(function(record) {
-        store.recordWasError(record);
-      });
-      this.trigger('QUOTA_EXCEEDED_ERR', records);
-    }
-  },
</del><ins>+    _saveData: function () {
+    },
</ins><span class="cx"> 
</span><del>-  _saveData: function() {
-    try {
-      localStorage.setItem(this._getNamespace(), JSON.stringify(this._data));
-      return true;
-    } catch(error) {
-      if (error.name == 'QUOTA_EXCEEDED_ERR') {
-        return false;
-      } else {
-        throw new Error(error);
-      }
-    }
-  },
</del><ins>+    _namespaceForType: function (type) {
+        var namespace = type.url || type.toString();
+        return this._data[namespace] || (
+            this._data[namespace] = {records: {}}
+        );
+    },
</ins><span class="cx"> 
</span><del>-  _namespaceForType: function(type) {
-    var namespace = type.url || type.toString();
-    return this._data[namespace] || (
-      this._data[namespace] = {records: {}}
-    );
-  },
-
-  _addRecordToNamespace: function(namespace, record) {
-    var data = record.serialize({includeId: true});
-    namespace.records[data.id] = data;
-  },
-
-  _async: function(callback) {
-    var _this = this;
-    setTimeout(function(){
-      Ember.run(_this, callback);
-    }, 1);
-  }
-
</del><ins>+    _addRecordToNamespace: function (namespace, record) {
+        var data = record.serialize({includeId: true});
+        namespace.records[data.id] = data;
+    }
</ins><span class="cx"> });
</span><del>-
</del></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbower_componentshandlebarshandlebarsjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/handlebars/handlebars.js (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/handlebars/handlebars.js        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/handlebars/handlebars.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -1,5 +1,7 @@
</span><del>-/*
</del><ins>+/*!
</ins><span class="cx"> 
</span><ins>+ handlebars v1.3.0
+
</ins><span class="cx"> Copyright (C) 2011 by Yehuda Katz
</span><span class="cx"> 
</span><span class="cx"> Permission is hereby granted, free of charge, to any person obtaining a copy
</span><span class="lines">@@ -20,846 +22,1269 @@
</span><span class="cx"> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
</span><span class="cx"> THE SOFTWARE.
</span><span class="cx"> 
</span><ins>+@license
</ins><span class="cx"> */
</span><ins>+/* exported Handlebars */
+var Handlebars = (function() {
+// handlebars/safe-string.js
+var __module4__ = (function() {
+  &quot;use strict&quot;;
+  var __exports__;
+  // Build out our basic SafeString type
+  function SafeString(string) {
+    this.string = string;
+  }
</ins><span class="cx"> 
</span><del>-// lib/handlebars/base.js
</del><ins>+  SafeString.prototype.toString = function() {
+    return &quot;&quot; + this.string;
+  };
</ins><span class="cx"> 
</span><del>-/*jshint eqnull:true*/
-this.Handlebars = {};
</del><ins>+  __exports__ = SafeString;
+  return __exports__;
+})();
</ins><span class="cx"> 
</span><del>-(function(Handlebars) {
</del><ins>+// handlebars/utils.js
+var __module3__ = (function(__dependency1__) {
+  &quot;use strict&quot;;
+  var __exports__ = {};
+  /*jshint -W004 */
+  var SafeString = __dependency1__;
</ins><span class="cx"> 
</span><del>-Handlebars.VERSION = &quot;1.0.0-rc.3&quot;;
-Handlebars.COMPILER_REVISION = 2;
</del><ins>+  var escape = {
+    &quot;&amp;&quot;: &quot;&amp;amp;&quot;,
+    &quot;&lt;&quot;: &quot;&amp;lt;&quot;,
+    &quot;&gt;&quot;: &quot;&amp;gt;&quot;,
+    '&quot;': &quot;&amp;quot;&quot;,
+    &quot;'&quot;: &quot;&amp;#x27;&quot;,
+    &quot;`&quot;: &quot;&amp;#x60;&quot;
+  };
</ins><span class="cx"> 
</span><del>-Handlebars.REVISION_CHANGES = {
-  1: '&lt;= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
-  2: '&gt;= 1.0.0-rc.3'
-};
</del><ins>+  var badChars = /[&amp;&lt;&gt;&quot;'`]/g;
+  var possible = /[&amp;&lt;&gt;&quot;'`]/;
</ins><span class="cx"> 
</span><del>-Handlebars.helpers  = {};
-Handlebars.partials = {};
</del><ins>+  function escapeChar(chr) {
+    return escape[chr] || &quot;&amp;amp;&quot;;
+  }
</ins><span class="cx"> 
</span><del>-Handlebars.registerHelper = function(name, fn, inverse) {
-  if(inverse) { fn.not = inverse; }
-  this.helpers[name] = fn;
-};
</del><ins>+  function extend(obj, value) {
+    for(var key in value) {
+      if(Object.prototype.hasOwnProperty.call(value, key)) {
+        obj[key] = value[key];
+      }
+    }
+  }
</ins><span class="cx"> 
</span><del>-Handlebars.registerPartial = function(name, str) {
-  this.partials[name] = str;
-};
</del><ins>+  __exports__.extend = extend;var toString = Object.prototype.toString;
+  __exports__.toString = toString;
+  // Sourced from lodash
+  // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
+  var isFunction = function(value) {
+    return typeof value === 'function';
+  };
+  // fallback for older versions of Chrome and Safari
+  if (isFunction(/x/)) {
+    isFunction = function(value) {
+      return typeof value === 'function' &amp;&amp; toString.call(value) === '[object Function]';
+    };
+  }
+  var isFunction;
+  __exports__.isFunction = isFunction;
+  var isArray = Array.isArray || function(value) {
+    return (value &amp;&amp; typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
+  };
+  __exports__.isArray = isArray;
</ins><span class="cx"> 
</span><del>-Handlebars.registerHelper('helperMissing', function(arg) {
-  if(arguments.length === 2) {
-    return undefined;
-  } else {
-    throw new Error(&quot;Could not find property '&quot; + arg + &quot;'&quot;);
</del><ins>+  function escapeExpression(string) {
+    // don't escape SafeStrings, since they're already safe
+    if (string instanceof SafeString) {
+      return string.toString();
+    } else if (!string &amp;&amp; string !== 0) {
+      return &quot;&quot;;
+    }
+
+    // Force a string conversion as this will be done by the append regardless and
+    // the regex test will do this transparently behind the scenes, causing issues if
+    // an object's to string has escaped characters in it.
+    string = &quot;&quot; + string;
+
+    if(!possible.test(string)) { return string; }
+    return string.replace(badChars, escapeChar);
</ins><span class="cx">   }
</span><del>-});
</del><span class="cx"> 
</span><del>-var toString = Object.prototype.toString, functionType = &quot;[object Function]&quot;;
</del><ins>+  __exports__.escapeExpression = escapeExpression;function isEmpty(value) {
+    if (!value &amp;&amp; value !== 0) {
+      return true;
+    } else if (isArray(value) &amp;&amp; value.length === 0) {
+      return true;
+    } else {
+      return false;
+    }
+  }
</ins><span class="cx"> 
</span><del>-Handlebars.registerHelper('blockHelperMissing', function(context, options) {
-  var inverse = options.inverse || function() {}, fn = options.fn;
</del><ins>+  __exports__.isEmpty = isEmpty;
+  return __exports__;
+})(__module4__);
</ins><span class="cx"> 
</span><ins>+// handlebars/exception.js
+var __module5__ = (function() {
+  &quot;use strict&quot;;
+  var __exports__;
</ins><span class="cx"> 
</span><del>-  var ret = &quot;&quot;;
-  var type = toString.call(context);
</del><ins>+  var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
</ins><span class="cx"> 
</span><del>-  if(type === functionType) { context = context.call(this); }
</del><ins>+  function Exception(message, node) {
+    var line;
+    if (node &amp;&amp; node.firstLine) {
+      line = node.firstLine;
</ins><span class="cx"> 
</span><del>-  if(context === true) {
-    return fn(this);
-  } else if(context === false || context == null) {
-    return inverse(this);
-  } else if(type === &quot;[object Array]&quot;) {
-    if(context.length &gt; 0) {
-      return Handlebars.helpers.each(context, options);
-    } else {
-      return inverse(this);
</del><ins>+      message += ' - ' + line + ':' + node.firstColumn;
</ins><span class="cx">     }
</span><del>-  } else {
-    return fn(context);
</del><ins>+
+    var tmp = Error.prototype.constructor.call(this, message);
+
+    // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
+    for (var idx = 0; idx &lt; errorProps.length; idx++) {
+      this[errorProps[idx]] = tmp[errorProps[idx]];
+    }
+
+    if (line) {
+      this.lineNumber = line;
+      this.column = node.firstColumn;
+    }
</ins><span class="cx">   }
</span><del>-});
</del><span class="cx"> 
</span><del>-Handlebars.K = function() {};
</del><ins>+  Exception.prototype = new Error();
</ins><span class="cx"> 
</span><del>-Handlebars.createFrame = Object.create || function(object) {
-  Handlebars.K.prototype = object;
-  var obj = new Handlebars.K();
-  Handlebars.K.prototype = null;
-  return obj;
-};
</del><ins>+  __exports__ = Exception;
+  return __exports__;
+})();
</ins><span class="cx"> 
</span><del>-Handlebars.logger = {
-  DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
</del><ins>+// handlebars/base.js
+var __module2__ = (function(__dependency1__, __dependency2__) {
+  &quot;use strict&quot;;
+  var __exports__ = {};
+  var Utils = __dependency1__;
+  var Exception = __dependency2__;
</ins><span class="cx"> 
</span><del>-  methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'},
</del><ins>+  var VERSION = &quot;1.3.0&quot;;
+  __exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
+  __exports__.COMPILER_REVISION = COMPILER_REVISION;
+  var REVISION_CHANGES = {
+    1: '&lt;= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
+    2: '== 1.0.0-rc.3',
+    3: '== 1.0.0-rc.4',
+    4: '&gt;= 1.0.0'
+  };
+  __exports__.REVISION_CHANGES = REVISION_CHANGES;
+  var isArray = Utils.isArray,
+      isFunction = Utils.isFunction,
+      toString = Utils.toString,
+      objectType = '[object Object]';
</ins><span class="cx"> 
</span><del>-  // can be overridden in the host environment
-  log: function(level, obj) {
-    if (Handlebars.logger.level &lt;= level) {
-      var method = Handlebars.logger.methodMap[level];
-      if (typeof console !== 'undefined' &amp;&amp; console[method]) {
-        console[method].call(console, obj);
</del><ins>+  function HandlebarsEnvironment(helpers, partials) {
+    this.helpers = helpers || {};
+    this.partials = partials || {};
+
+    registerDefaultHelpers(this);
+  }
+
+  __exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
+    constructor: HandlebarsEnvironment,
+
+    logger: logger,
+    log: log,
+
+    registerHelper: function(name, fn, inverse) {
+      if (toString.call(name) === objectType) {
+        if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
+        Utils.extend(this.helpers, name);
+      } else {
+        if (inverse) { fn.not = inverse; }
+        this.helpers[name] = fn;
</ins><span class="cx">       }
</span><ins>+    },
+
+    registerPartial: function(name, str) {
+      if (toString.call(name) === objectType) {
+        Utils.extend(this.partials,  name);
+      } else {
+        this.partials[name] = str;
+      }
</ins><span class="cx">     }
</span><del>-  }
-};
</del><ins>+  };
</ins><span class="cx"> 
</span><del>-Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); };
</del><ins>+  function registerDefaultHelpers(instance) {
+    instance.registerHelper('helperMissing', function(arg) {
+      if(arguments.length === 2) {
+        return undefined;
+      } else {
+        throw new Exception(&quot;Missing helper: '&quot; + arg + &quot;'&quot;);
+      }
+    });
</ins><span class="cx"> 
</span><del>-Handlebars.registerHelper('each', function(context, options) {
-  var fn = options.fn, inverse = options.inverse;
-  var i = 0, ret = &quot;&quot;, data;
</del><ins>+    instance.registerHelper('blockHelperMissing', function(context, options) {
+      var inverse = options.inverse || function() {}, fn = options.fn;
</ins><span class="cx"> 
</span><del>-  if (options.data) {
-    data = Handlebars.createFrame(options.data);
-  }
</del><ins>+      if (isFunction(context)) { context = context.call(this); }
</ins><span class="cx"> 
</span><del>-  if(context &amp;&amp; typeof context === 'object') {
-    if(context instanceof Array){
-      for(var j = context.length; i&lt;j; i++) {
-        if (data) { data.index = i; }
-        ret = ret + fn(context[i], { data: data });
</del><ins>+      if(context === true) {
+        return fn(this);
+      } else if(context === false || context == null) {
+        return inverse(this);
+      } else if (isArray(context)) {
+        if(context.length &gt; 0) {
+          return instance.helpers.each(context, options);
+        } else {
+          return inverse(this);
+        }
+      } else {
+        return fn(context);
</ins><span class="cx">       }
</span><del>-    } else {
-      for(var key in context) {
-        if(context.hasOwnProperty(key)) {
-          if(data) { data.key = key; }
-          ret = ret + fn(context[key], {data: data});
-          i++;
</del><ins>+    });
+
+    instance.registerHelper('each', function(context, options) {
+      var fn = options.fn, inverse = options.inverse;
+      var i = 0, ret = &quot;&quot;, data;
+
+      if (isFunction(context)) { context = context.call(this); }
+
+      if (options.data) {
+        data = createFrame(options.data);
+      }
+
+      if(context &amp;&amp; typeof context === 'object') {
+        if (isArray(context)) {
+          for(var j = context.length; i&lt;j; i++) {
+            if (data) {
+              data.index = i;
+              data.first = (i === 0);
+              data.last  = (i === (context.length-1));
+            }
+            ret = ret + fn(context[i], { data: data });
+          }
+        } else {
+          for(var key in context) {
+            if(context.hasOwnProperty(key)) {
+              if(data) { 
+                data.key = key; 
+                data.index = i;
+                data.first = (i === 0);
+              }
+              ret = ret + fn(context[key], {data: data});
+              i++;
+            }
+          }
</ins><span class="cx">         }
</span><span class="cx">       }
</span><del>-    }
-  }
</del><span class="cx"> 
</span><del>-  if(i === 0){
-    ret = inverse(this);
-  }
</del><ins>+      if(i === 0){
+        ret = inverse(this);
+      }
</ins><span class="cx"> 
</span><del>-  return ret;
-});
</del><ins>+      return ret;
+    });
</ins><span class="cx"> 
</span><del>-Handlebars.registerHelper('if', function(context, options) {
-  var type = toString.call(context);
-  if(type === functionType) { context = context.call(this); }
</del><ins>+    instance.registerHelper('if', function(conditional, options) {
+      if (isFunction(conditional)) { conditional = conditional.call(this); }
</ins><span class="cx"> 
</span><del>-  if(!context || Handlebars.Utils.isEmpty(context)) {
-    return options.inverse(this);
-  } else {
-    return options.fn(this);
</del><ins>+      // Default behavior is to render the positive path if the value is truthy and not empty.
+      // The `includeZero` option may be set to treat the condtional as purely not empty based on the
+      // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
+      if ((!options.hash.includeZero &amp;&amp; !conditional) || Utils.isEmpty(conditional)) {
+        return options.inverse(this);
+      } else {
+        return options.fn(this);
+      }
+    });
+
+    instance.registerHelper('unless', function(conditional, options) {
+      return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
+    });
+
+    instance.registerHelper('with', function(context, options) {
+      if (isFunction(context)) { context = context.call(this); }
+
+      if (!Utils.isEmpty(context)) return options.fn(context);
+    });
+
+    instance.registerHelper('log', function(context, options) {
+      var level = options.data &amp;&amp; options.data.level != null ? parseInt(options.data.level, 10) : 1;
+      instance.log(level, context);
+    });
</ins><span class="cx">   }
</span><del>-});
</del><span class="cx"> 
</span><del>-Handlebars.registerHelper('unless', function(context, options) {
-  var fn = options.fn, inverse = options.inverse;
-  options.fn = inverse;
-  options.inverse = fn;
</del><ins>+  var logger = {
+    methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
</ins><span class="cx"> 
</span><del>-  return Handlebars.helpers['if'].call(this, context, options);
-});
</del><ins>+    // State enum
+    DEBUG: 0,
+    INFO: 1,
+    WARN: 2,
+    ERROR: 3,
+    level: 3,
</ins><span class="cx"> 
</span><del>-Handlebars.registerHelper('with', function(context, options) {
-  return options.fn(context);
-});
</del><ins>+    // can be overridden in the host environment
+    log: function(level, obj) {
+      if (logger.level &lt;= level) {
+        var method = logger.methodMap[level];
+        if (typeof console !== 'undefined' &amp;&amp; console[method]) {
+          console[method].call(console, obj);
+        }
+      }
+    }
+  };
+  __exports__.logger = logger;
+  function log(level, obj) { logger.log(level, obj); }
</ins><span class="cx"> 
</span><del>-Handlebars.registerHelper('log', function(context, options) {
-  var level = options.data &amp;&amp; options.data.level != null ? parseInt(options.data.level, 10) : 1;
-  Handlebars.log(level, context);
-});
</del><ins>+  __exports__.log = log;var createFrame = function(object) {
+    var obj = {};
+    Utils.extend(obj, object);
+    return obj;
+  };
+  __exports__.createFrame = createFrame;
+  return __exports__;
+})(__module3__, __module5__);
</ins><span class="cx"> 
</span><del>-}(this.Handlebars));
-;
-// lib/handlebars/compiler/parser.js
-/* Jison generated parser */
-var handlebars = (function(){
-var parser = {trace: function trace() { },
-yy: {},
-symbols_: {&quot;error&quot;:2,&quot;root&quot;:3,&quot;program&quot;:4,&quot;EOF&quot;:5,&quot;simpleInverse&quot;:6,&quot;statements&quot;:7,&quot;statement&quot;:8,&quot;openInverse&quot;:9,&quot;closeBlock&quot;:10,&quot;openBlock&quot;:11,&quot;mustache&quot;:12,&quot;partial&quot;:13,&quot;CONTENT&quot;:14,&quot;COMMENT&quot;:15,&quot;OPEN_BLOCK&quot;:16,&quot;inMustache&quot;:17,&quot;CLOSE&quot;:18,&quot;OPEN_INVERSE&quot;:19,&quot;OPEN_ENDBLOCK&quot;:20,&quot;path&quot;:21,&quot;OPEN&quot;:22,&quot;OPEN_UNESCAPED&quot;:23,&quot;OPEN_PARTIAL&quot;:24,&quot;partialName&quot;:25,&quot;params&quot;:26,&quot;hash&quot;:27,&quot;DATA&quot;:28,&quot;param&quot;:29,&quot;STRING&quot;:30,&quot;INTEGER&quot;:31,&quot;BOOLEAN&quot;:32,&quot;hashSegments&quot;:33,&quot;hashSegment&quot;:34,&quot;ID&quot;:35,&quot;EQUALS&quot;:36,&quot;PARTIAL_NAME&quot;:37,&quot;pathSegments&quot;:38,&quot;SEP&quot;:39,&quot;$accept&quot;:0,&quot;$end&quot;:1},
-terminals_: {2:&quot;error&quot;,5:&quot;EOF&quot;,14:&quot;CONTENT&quot;,15:&quot;COMMENT&quot;,16:&quot;OPEN_BLOCK&quot;,18:&quot;CLOSE&quot;,19:&quot;OPEN_INVERSE&quot;,20:&quot;OPEN_ENDBLOCK&quot;,22:&quot;OPEN&quot;,23:&quot;OPEN_UNESCAPED&quot;,24:&quot;OPEN_PARTIAL&quot;,28:&quot;DATA&quot;,30:&quot;STRING&quot;,31:&quot;INTEGER&quot;,32:&quot;BOOLEAN&quot;,35:&quot;ID&quot;,36:&quot;EQUALS&quot;,37:&quot;PARTIAL_NAME&quot;,39:&quot;SEP&quot;},
-productions_: [0,[3,2],[4,2],[4,3],[4,2],[4,1],[4,1],[4,0],[7,1],[7,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[6,2],[17,3],[17,2],[17,2],[17,1],[17,1],[26,2],[26,1],[29,1],[29,1],[29,1],[29,1],[29,1],[27,1],[33,2],[33,1],[34,3],[34,3],[34,3],[34,3],[34,3],[25,1],[21,1],[38,3],[38,1]],
-performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
</del><ins>+// handlebars/runtime.js
+var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
+  &quot;use strict&quot;;
+  var __exports__ = {};
+  var Utils = __dependency1__;
+  var Exception = __dependency2__;
+  var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
+  var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
</ins><span class="cx"> 
</span><del>-var $0 = $$.length - 1;
-switch (yystate) {
-case 1: return $$[$0-1]; 
-break;
-case 2: this.$ = new yy.ProgramNode([], $$[$0]); 
-break;
-case 3: this.$ = new yy.ProgramNode($$[$0-2], $$[$0]); 
-break;
-case 4: this.$ = new yy.ProgramNode($$[$0-1], []); 
-break;
-case 5: this.$ = new yy.ProgramNode($$[$0]); 
-break;
-case 6: this.$ = new yy.ProgramNode([], []); 
-break;
-case 7: this.$ = new yy.ProgramNode([]); 
-break;
-case 8: this.$ = [$$[$0]]; 
-break;
-case 9: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; 
-break;
-case 10: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0]); 
-break;
-case 11: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0]); 
-break;
-case 12: this.$ = $$[$0]; 
-break;
-case 13: this.$ = $$[$0]; 
-break;
-case 14: this.$ = new yy.ContentNode($$[$0]); 
-break;
-case 15: this.$ = new yy.CommentNode($$[$0]); 
-break;
-case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]); 
-break;
-case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]); 
-break;
-case 18: this.$ = $$[$0-1]; 
-break;
-case 19: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]); 
-break;
-case 20: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true); 
-break;
-case 21: this.$ = new yy.PartialNode($$[$0-1]); 
-break;
-case 22: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1]); 
-break;
-case 23: 
-break;
-case 24: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]]; 
-break;
-case 25: this.$ = [[$$[$0-1]].concat($$[$0]), null]; 
-break;
-case 26: this.$ = [[$$[$0-1]], $$[$0]]; 
-break;
-case 27: this.$ = [[$$[$0]], null]; 
-break;
-case 28: this.$ = [[new yy.DataNode($$[$0])], null]; 
-break;
-case 29: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; 
-break;
-case 30: this.$ = [$$[$0]]; 
-break;
-case 31: this.$ = $$[$0]; 
-break;
-case 32: this.$ = new yy.StringNode($$[$0]); 
-break;
-case 33: this.$ = new yy.IntegerNode($$[$0]); 
-break;
-case 34: this.$ = new yy.BooleanNode($$[$0]); 
-break;
-case 35: this.$ = new yy.DataNode($$[$0]); 
-break;
-case 36: this.$ = new yy.HashNode($$[$0]); 
-break;
-case 37: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; 
-break;
-case 38: this.$ = [$$[$0]]; 
-break;
-case 39: this.$ = [$$[$0-2], $$[$0]]; 
-break;
-case 40: this.$ = [$$[$0-2], new yy.StringNode($$[$0])]; 
-break;
-case 41: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])]; 
-break;
-case 42: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])]; 
-break;
-case 43: this.$ = [$$[$0-2], new yy.DataNode($$[$0])]; 
-break;
-case 44: this.$ = new yy.PartialNameNode($$[$0]); 
-break;
-case 45: this.$ = new yy.IdNode($$[$0]); 
-break;
-case 46: $$[$0-2].push($$[$0]); this.$ = $$[$0-2]; 
-break;
-case 47: this.$ = [$$[$0]]; 
-break;
-}
-},
-table: [{3:1,4:2,5:[2,7],6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],22:[1,14],23:[1,15],24:[1,16]},{1:[3]},{5:[1,17]},{5:[2,6],7:18,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,6],22:[1,14],23:[1,15],24:[1,16]},{5:[2,5],6:20,8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,5],22:[1,14],23:[1,15],24:[1,16]},{17:23,18:[1,22],21:24,28:[1,25],35:[1,27],38:26},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{4:28,6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,7],22:[1,14],23:[1,15],24:[1,16]},{4:29,6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,7],22:[1,14],23:[1,15],24:[1,16]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]},{17:30,21:24,28:[1,25],35:[1,27],38:26},{17:31,21:24,28:[1,25],35:[1,27],38:26},{17:32,21:24,28:[1,25],35:[1,27],38:26},{25:33,37:[1,34]},{1:[2,1]},{5:[2,2],8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,2],22:[1,14],23:[1,15],24:[1,16]},{17:23,21:24,28:[1,25],35:[1,27],38:26},{5:[2,4],7:35,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,4],22:[1,14],23:[1,15],24:[1,16]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,23],14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],24:[2,23]},{18:[1,36]},{18:[2,27],21:41,26:37,27:38,28:[1,45],29:39,30:[1,42],31:[1,43],32:[1,44],33:40,34:46,35:[1,47],38:26},{18:[2,28]},{18:[2,45],28:[2,45],30:[2,45],31:[2,45],32:[2,45],35:[2,45],39:[1,48]},{18:[2,47],28:[2,47],30:[2,47],31:[2,47],32:[2,47],35:[2,47],39:[2,47]},{10:49,20:[1,50]},{10:51,20:[1,50]},{18:[1,52]},{18:[1,53]},{18:[1,54]},{18:[1,55],21:56,35:[1,27],38:26},{18:[2,44],35:[2,44]},{5:[2,3],8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,3],22:[1,14],23:[1,15],24:[1,16]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{18:[2,25],21:41,27:57,28:[1,45],29:58,30:[1,42],31:[1,43],32:[1,44],33:40,34:46,35:[1,47],38:26},{18:[2,26]},{18:[2,30],28:[2,30],30:[2,30],31:[2,30],32:[2,30],35:[2,30]},{18:[2,36],34:59,35:[1,60]},{18:[2,31],28:[2,31],30:[2,31],31:[2,31],32:[2,31],35:[2,31]},{18:[2,32],28:[2,32],30:[2,32],31:[2,32],32:[2,32],35:[2,32]},{18:[2,33],28:[2,33],30:[2,33],31:[2,33],32:[2,33],35:[2,33]},{18:[2,34],28:[2,34],30:[2,34],31:[2,34],32:[2,34],35:[2,34]},{18:[2,35],28:[2,35],30:[2,35],31:[2,35],32:[2,35],35:[2,35]},{18:[2,38],35:[2,38]},{18:[2,47],28:[2,47],30:[2,47],31:[2,47],32:[2,47],35:[2,47],36:[1,61],39:[2,47]},{35:[1,62]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{21:63,35:[1,27],38:26},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],24:[2,21]},{18:[1,64]},{18:[2,24]},{18:[2,29],28:[2,29],30:[2,29],31:[2,29],32:[2,29],35:[2,29]},{18:[2,37],35:[2,37]},{36:[1,61]},{21:65,28:[1,69],30:[1,66],31:[1,67],32:[1,68],35:[1,27],38:26},{18:[2,46],28:[2,46],30:[2,46],31:[2,46],32:[2,46],35:[2,46],39:[2,46]},{18:[1,70]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],24:[2,22]},{18:[2,39],35:[2,39]},{18:[2,40],35:[2,40]},{18:[2,41],35:[2,41]},{18:[2,42],35:[2,42]},{18:[2,43],35:[2,43]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]}],
-defaultActions: {17:[2,1],25:[2,28],38:[2,26],57:[2,24]},
-parseError: function parseError(str, hash) {
-    throw new Error(str);
-},
-parse: function parse(input) {
-    var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = &quot;&quot;, yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
-    this.lexer.setInput(input);
-    this.lexer.yy = this.yy;
-    this.yy.lexer = this.lexer;
-    this.yy.parser = this;
-    if (typeof this.lexer.yylloc == &quot;undefined&quot;)
-        this.lexer.yylloc = {};
-    var yyloc = this.lexer.yylloc;
-    lstack.push(yyloc);
-    var ranges = this.lexer.options &amp;&amp; this.lexer.options.ranges;
-    if (typeof this.yy.parseError === &quot;function&quot;)
-        this.parseError = this.yy.parseError;
-    function popStack(n) {
-        stack.length = stack.length - 2 * n;
-        vstack.length = vstack.length - n;
-        lstack.length = lstack.length - n;
</del><ins>+  function checkRevision(compilerInfo) {
+    var compilerRevision = compilerInfo &amp;&amp; compilerInfo[0] || 1,
+        currentRevision = COMPILER_REVISION;
+
+    if (compilerRevision !== currentRevision) {
+      if (compilerRevision &lt; currentRevision) {
+        var runtimeVersions = REVISION_CHANGES[currentRevision],
+            compilerVersions = REVISION_CHANGES[compilerRevision];
+        throw new Exception(&quot;Template was precompiled with an older version of Handlebars than the current runtime. &quot;+
+              &quot;Please update your precompiler to a newer version (&quot;+runtimeVersions+&quot;) or downgrade your runtime to an older version (&quot;+compilerVersions+&quot;).&quot;);
+      } else {
+        // Use the embedded version info since the runtime doesn't know about this revision yet
+        throw new Exception(&quot;Template was precompiled with a newer version of Handlebars than the current runtime. &quot;+
+              &quot;Please update your runtime to a newer version (&quot;+compilerInfo[1]+&quot;).&quot;);
+      }
</ins><span class="cx">     }
</span><del>-    function lex() {
-        var token;
-        token = self.lexer.lex() || 1;
-        if (typeof token !== &quot;number&quot;) {
-            token = self.symbols_[token] || token;
-        }
-        return token;
</del><ins>+  }
+
+  __exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial
+
+  function template(templateSpec, env) {
+    if (!env) {
+      throw new Exception(&quot;No environment passed to template&quot;);
</ins><span class="cx">     }
</span><del>-    var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
-    while (true) {
-        state = stack[stack.length - 1];
-        if (this.defaultActions[state]) {
-            action = this.defaultActions[state];
-        } else {
-            if (symbol === null || typeof symbol == &quot;undefined&quot;) {
-                symbol = lex();
-            }
-            action = table[state] &amp;&amp; table[state][symbol];
</del><ins>+
+    // Note: Using env.VM references rather than local var references throughout this section to allow
+    // for external users to override these as psuedo-supported APIs.
+    var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
+      var result = env.VM.invokePartial.apply(this, arguments);
+      if (result != null) { return result; }
+
+      if (env.compile) {
+        var options = { helpers: helpers, partials: partials, data: data };
+        partials[name] = env.compile(partial, { data: data !== undefined }, env);
+        return partials[name](context, options);
+      } else {
+        throw new Exception(&quot;The partial &quot; + name + &quot; could not be compiled when running in runtime-only mode&quot;);
+      }
+    };
+
+    // Just add water
+    var container = {
+      escapeExpression: Utils.escapeExpression,
+      invokePartial: invokePartialWrapper,
+      programs: [],
+      program: function(i, fn, data) {
+        var programWrapper = this.programs[i];
+        if(data) {
+          programWrapper = program(i, fn, data);
+        } else if (!programWrapper) {
+          programWrapper = this.programs[i] = program(i, fn);
</ins><span class="cx">         }
</span><del>-        if (typeof action === &quot;undefined&quot; || !action.length || !action[0]) {
-            var errStr = &quot;&quot;;
-            if (!recovering) {
-                expected = [];
-                for (p in table[state])
-                    if (this.terminals_[p] &amp;&amp; p &gt; 2) {
-                        expected.push(&quot;'&quot; + this.terminals_[p] + &quot;'&quot;);
-                    }
-                if (this.lexer.showPosition) {
-                    errStr = &quot;Parse error on line &quot; + (yylineno + 1) + &quot;:\n&quot; + this.lexer.showPosition() + &quot;\nExpecting &quot; + expected.join(&quot;, &quot;) + &quot;, got '&quot; + (this.terminals_[symbol] || symbol) + &quot;'&quot;;
-                } else {
-                    errStr = &quot;Parse error on line &quot; + (yylineno + 1) + &quot;: Unexpected &quot; + (symbol == 1?&quot;end of input&quot;:&quot;'&quot; + (this.terminals_[symbol] || symbol) + &quot;'&quot;);
-                }
-                this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
-            }
</del><ins>+        return programWrapper;
+      },
+      merge: function(param, common) {
+        var ret = param || common;
+
+        if (param &amp;&amp; common &amp;&amp; (param !== common)) {
+          ret = {};
+          Utils.extend(ret, common);
+          Utils.extend(ret, param);
</ins><span class="cx">         }
</span><del>-        if (action[0] instanceof Array &amp;&amp; action.length &gt; 1) {
-            throw new Error(&quot;Parse Error: multiple actions possible at state: &quot; + state + &quot;, token: &quot; + symbol);
-        }
-        switch (action[0]) {
-        case 1:
-            stack.push(symbol);
-            vstack.push(this.lexer.yytext);
-            lstack.push(this.lexer.yylloc);
-            stack.push(action[1]);
-            symbol = null;
-            if (!preErrorSymbol) {
-                yyleng = this.lexer.yyleng;
-                yytext = this.lexer.yytext;
-                yylineno = this.lexer.yylineno;
-                yyloc = this.lexer.yylloc;
-                if (recovering &gt; 0)
-                    recovering--;
-            } else {
-                symbol = preErrorSymbol;
-                preErrorSymbol = null;
-            }
-            break;
-        case 2:
-            len = this.productions_[action[1]][1];
-            yyval.$ = vstack[vstack.length - len];
-            yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
-            if (ranges) {
-                yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
-            }
-            r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
-            if (typeof r !== &quot;undefined&quot;) {
-                return r;
-            }
-            if (len) {
-                stack = stack.slice(0, -1 * len * 2);
-                vstack = vstack.slice(0, -1 * len);
-                lstack = lstack.slice(0, -1 * len);
-            }
-            stack.push(this.productions_[action[1]][0]);
-            vstack.push(yyval.$);
-            lstack.push(yyval._$);
-            newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
-            stack.push(newState);
-            break;
-        case 3:
-            return true;
-        }
</del><ins>+        return ret;
+      },
+      programWithDepth: env.VM.programWithDepth,
+      noop: env.VM.noop,
+      compilerInfo: null
+    };
+
+    return function(context, options) {
+      options = options || {};
+      var namespace = options.partial ? options : env,
+          helpers,
+          partials;
+
+      if (!options.partial) {
+        helpers = options.helpers;
+        partials = options.partials;
+      }
+      var result = templateSpec.call(
+            container,
+            namespace, context,
+            helpers,
+            partials,
+            options.data);
+
+      if (!options.partial) {
+        env.VM.checkRevision(container.compilerInfo);
+      }
+
+      return result;
+    };
+  }
+
+  __exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) {
+    var args = Array.prototype.slice.call(arguments, 3);
+
+    var prog = function(context, options) {
+      options = options || {};
+
+      return fn.apply(this, [context, options.data || data].concat(args));
+    };
+    prog.program = i;
+    prog.depth = args.length;
+    return prog;
+  }
+
+  __exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
+    var prog = function(context, options) {
+      options = options || {};
+
+      return fn(context, options.data || data);
+    };
+    prog.program = i;
+    prog.depth = 0;
+    return prog;
+  }
+
+  __exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
+    var options = { partial: true, helpers: helpers, partials: partials, data: data };
+
+    if(partial === undefined) {
+      throw new Exception(&quot;The partial &quot; + name + &quot; could not be found&quot;);
+    } else if(partial instanceof Function) {
+      return partial(context, options);
</ins><span class="cx">     }
</span><del>-    return true;
-}
-};
-/* Jison generated lexer */
-var lexer = (function(){
-var lexer = ({EOF:1,
-parseError:function parseError(str, hash) {
-        if (this.yy.parser) {
-            this.yy.parser.parseError(str, hash);
</del><ins>+  }
+
+  __exports__.invokePartial = invokePartial;function noop() { return &quot;&quot;; }
+
+  __exports__.noop = noop;
+  return __exports__;
+})(__module3__, __module5__, __module2__);
+
+// handlebars.runtime.js
+var __module1__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
+  &quot;use strict&quot;;
+  var __exports__;
+  /*globals Handlebars: true */
+  var base = __dependency1__;
+
+  // Each of these augment the Handlebars object. No need to setup here.
+  // (This is done to easily share code between commonjs and browse envs)
+  var SafeString = __dependency2__;
+  var Exception = __dependency3__;
+  var Utils = __dependency4__;
+  var runtime = __dependency5__;
+
+  // For compatibility and usage outside of module systems, make the Handlebars object a namespace
+  var create = function() {
+    var hb = new base.HandlebarsEnvironment();
+
+    Utils.extend(hb, base);
+    hb.SafeString = SafeString;
+    hb.Exception = Exception;
+    hb.Utils = Utils;
+
+    hb.VM = runtime;
+    hb.template = function(spec) {
+      return runtime.template(spec, hb);
+    };
+
+    return hb;
+  };
+
+  var Handlebars = create();
+  Handlebars.create = create;
+
+  __exports__ = Handlebars;
+  return __exports__;
+})(__module2__, __module4__, __module5__, __module3__, __module6__);
+
+// handlebars/compiler/ast.js
+var __module7__ = (function(__dependency1__) {
+  &quot;use strict&quot;;
+  var __exports__;
+  var Exception = __dependency1__;
+
+  function LocationInfo(locInfo){
+    locInfo = locInfo || {};
+    this.firstLine   = locInfo.first_line;
+    this.firstColumn = locInfo.first_column;
+    this.lastColumn  = locInfo.last_column;
+    this.lastLine    = locInfo.last_line;
+  }
+
+  var AST = {
+    ProgramNode: function(statements, inverseStrip, inverse, locInfo) {
+      var inverseLocationInfo, firstInverseNode;
+      if (arguments.length === 3) {
+        locInfo = inverse;
+        inverse = null;
+      } else if (arguments.length === 2) {
+        locInfo = inverseStrip;
+        inverseStrip = null;
+      }
+
+      LocationInfo.call(this, locInfo);
+      this.type = &quot;program&quot;;
+      this.statements = statements;
+      this.strip = {};
+
+      if(inverse) {
+        firstInverseNode = inverse[0];
+        if (firstInverseNode) {
+          inverseLocationInfo = {
+            first_line: firstInverseNode.firstLine,
+            last_line: firstInverseNode.lastLine,
+            last_column: firstInverseNode.lastColumn,
+            first_column: firstInverseNode.firstColumn
+          };
+          this.inverse = new AST.ProgramNode(inverse, inverseStrip, inverseLocationInfo);
</ins><span class="cx">         } else {
</span><del>-            throw new Error(str);
</del><ins>+          this.inverse = new AST.ProgramNode(inverse, inverseStrip);
</ins><span class="cx">         }
</span><ins>+        this.strip.right = inverseStrip.left;
+      } else if (inverseStrip) {
+        this.strip.left = inverseStrip.right;
+      }
</ins><span class="cx">     },
</span><del>-setInput:function (input) {
-        this._input = input;
-        this._more = this._less = this.done = false;
-        this.yylineno = this.yyleng = 0;
-        this.yytext = this.matched = this.match = '';
-        this.conditionStack = ['INITIAL'];
-        this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
-        if (this.options.ranges) this.yylloc.range = [0,0];
-        this.offset = 0;
-        return this;
-    },
-input:function () {
-        var ch = this._input[0];
-        this.yytext += ch;
-        this.yyleng++;
-        this.offset++;
-        this.match += ch;
-        this.matched += ch;
-        var lines = ch.match(/(?:\r\n?|\n).*/g);
-        if (lines) {
-            this.yylineno++;
-            this.yylloc.last_line++;
-        } else {
-            this.yylloc.last_column++;
-        }
-        if (this.options.ranges) this.yylloc.range[1]++;
</del><span class="cx"> 
</span><del>-        this._input = this._input.slice(1);
-        return ch;
</del><ins>+    MustacheNode: function(rawParams, hash, open, strip, locInfo) {
+      LocationInfo.call(this, locInfo);
+      this.type = &quot;mustache&quot;;
+      this.strip = strip;
+
+      // Open may be a string parsed from the parser or a passed boolean flag
+      if (open != null &amp;&amp; open.charAt) {
+        // Must use charAt to support IE pre-10
+        var escapeFlag = open.charAt(3) || open.charAt(2);
+        this.escaped = escapeFlag !== '{' &amp;&amp; escapeFlag !== '&amp;';
+      } else {
+        this.escaped = !!open;
+      }
+
+      if (rawParams instanceof AST.SexprNode) {
+        this.sexpr = rawParams;
+      } else {
+        // Support old AST API
+        this.sexpr = new AST.SexprNode(rawParams, hash);
+      }
+
+      this.sexpr.isRoot = true;
+
+      // Support old AST API that stored this info in MustacheNode
+      this.id = this.sexpr.id;
+      this.params = this.sexpr.params;
+      this.hash = this.sexpr.hash;
+      this.eligibleHelper = this.sexpr.eligibleHelper;
+      this.isHelper = this.sexpr.isHelper;
</ins><span class="cx">     },
</span><del>-unput:function (ch) {
-        var len = ch.length;
-        var lines = ch.split(/(?:\r\n?|\n)/g);
</del><span class="cx"> 
</span><del>-        this._input = ch + this._input;
-        this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
-        //this.yyleng -= len;
-        this.offset -= len;
-        var oldLines = this.match.split(/(?:\r\n?|\n)/g);
-        this.match = this.match.substr(0, this.match.length-1);
-        this.matched = this.matched.substr(0, this.matched.length-1);
</del><ins>+    SexprNode: function(rawParams, hash, locInfo) {
+      LocationInfo.call(this, locInfo);
</ins><span class="cx"> 
</span><del>-        if (lines.length-1) this.yylineno -= lines.length-1;
-        var r = this.yylloc.range;
</del><ins>+      this.type = &quot;sexpr&quot;;
+      this.hash = hash;
</ins><span class="cx"> 
</span><del>-        this.yylloc = {first_line: this.yylloc.first_line,
-          last_line: this.yylineno+1,
-          first_column: this.yylloc.first_column,
-          last_column: lines ?
-              (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
-              this.yylloc.first_column - len
-          };
</del><ins>+      var id = this.id = rawParams[0];
+      var params = this.params = rawParams.slice(1);
</ins><span class="cx"> 
</span><del>-        if (this.options.ranges) {
-            this.yylloc.range = [r[0], r[0] + this.yyleng - len];
-        }
-        return this;
</del><ins>+      // a mustache is an eligible helper if:
+      // * its id is simple (a single part, not `this` or `..`)
+      var eligibleHelper = this.eligibleHelper = id.isSimple;
+
+      // a mustache is definitely a helper if:
+      // * it is an eligible helper, and
+      // * it has at least one parameter or hash segment
+      this.isHelper = eligibleHelper &amp;&amp; (params.length || hash);
+
+      // if a mustache is an eligible helper but not a definite
+      // helper, it is ambiguous, and will be resolved in a later
+      // pass or at runtime.
</ins><span class="cx">     },
</span><del>-more:function () {
-        this._more = true;
-        return this;
-    },
-less:function (n) {
-        this.unput(this.match.slice(n));
-    },
-pastInput:function () {
-        var past = this.matched.substr(0, this.matched.length - this.match.length);
-        return (past.length &gt; 20 ? '...':'') + past.substr(-20).replace(/\n/g, &quot;&quot;);
-    },
-upcomingInput:function () {
-        var next = this.match;
-        if (next.length &lt; 20) {
-            next += this._input.substr(0, 20-next.length);
-        }
-        return (next.substr(0,20)+(next.length &gt; 20 ? '...':'')).replace(/\n/g, &quot;&quot;);
-    },
-showPosition:function () {
-        var pre = this.pastInput();
-        var c = new Array(pre.length + 1).join(&quot;-&quot;);
-        return pre + this.upcomingInput() + &quot;\n&quot; + c+&quot;^&quot;;
-    },
-next:function () {
-        if (this.done) {
-            return this.EOF;
-        }
-        if (!this._input) this.done = true;
</del><span class="cx"> 
</span><del>-        var token,
-            match,
-            tempMatch,
-            index,
-            col,
-            lines;
-        if (!this._more) {
-            this.yytext = '';
-            this.match = '';
-        }
-        var rules = this._currentRules();
-        for (var i=0;i &lt; rules.length; i++) {
-            tempMatch = this._input.match(this.rules[rules[i]]);
-            if (tempMatch &amp;&amp; (!match || tempMatch[0].length &gt; match[0].length)) {
-                match = tempMatch;
-                index = i;
-                if (!this.options.flex) break;
-            }
-        }
-        if (match) {
-            lines = match[0].match(/(?:\r\n?|\n).*/g);
-            if (lines) this.yylineno += lines.length;
-            this.yylloc = {first_line: this.yylloc.last_line,
-                           last_line: this.yylineno+1,
-                           first_column: this.yylloc.last_column,
-                           last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
-            this.yytext += match[0];
-            this.match += match[0];
-            this.matches = match;
-            this.yyleng = this.yytext.length;
-            if (this.options.ranges) {
-                this.yylloc.range = [this.offset, this.offset += this.yyleng];
-            }
-            this._more = false;
-            this._input = this._input.slice(match[0].length);
-            this.matched += match[0];
-            token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
-            if (this.done &amp;&amp; this._input) this.done = false;
-            if (token) return token;
-            else return;
-        }
-        if (this._input === &quot;&quot;) {
-            return this.EOF;
-        } else {
-            return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
-                    {text: &quot;&quot;, token: null, line: this.yylineno});
-        }
</del><ins>+    PartialNode: function(partialName, context, strip, locInfo) {
+      LocationInfo.call(this, locInfo);
+      this.type         = &quot;partial&quot;;
+      this.partialName  = partialName;
+      this.context      = context;
+      this.strip = strip;
</ins><span class="cx">     },
</span><del>-lex:function lex() {
-        var r = this.next();
-        if (typeof r !== 'undefined') {
-            return r;
-        } else {
-            return this.lex();
-        }
-    },
-begin:function begin(condition) {
-        this.conditionStack.push(condition);
-    },
-popState:function popState() {
-        return this.conditionStack.pop();
-    },
-_currentRules:function _currentRules() {
-        return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
-    },
-topState:function () {
-        return this.conditionStack[this.conditionStack.length-2];
-    },
-pushState:function begin(condition) {
-        this.begin(condition);
-    }});
-lexer.options = {};
-lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
</del><span class="cx"> 
</span><del>-var YYSTATE=YY_START
-switch($avoiding_name_collisions) {
-case 0:
-                                   if(yy_.yytext.slice(-1) !== &quot;\\&quot;) this.begin(&quot;mu&quot;);
-                                   if(yy_.yytext.slice(-1) === &quot;\\&quot;) yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1), this.begin(&quot;emu&quot;);
-                                   if(yy_.yytext) return 14;
-                                 
-break;
-case 1: return 14; 
-break;
-case 2:
-                                   if(yy_.yytext.slice(-1) !== &quot;\\&quot;) this.popState();
-                                   if(yy_.yytext.slice(-1) === &quot;\\&quot;) yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1);
-                                   return 14;
-                                 
-break;
-case 3: yy_.yytext = yy_.yytext.substr(0, yy_.yyleng-4); this.popState(); return 15; 
-break;
-case 4: this.begin(&quot;par&quot;); return 24; 
-break;
-case 5: return 16; 
-break;
-case 6: return 20; 
-break;
-case 7: return 19; 
-break;
-case 8: return 19; 
-break;
-case 9: return 23; 
-break;
-case 10: return 23; 
-break;
-case 11: this.popState(); this.begin('com'); 
-break;
-case 12: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15; 
-break;
-case 13: return 22; 
-break;
-case 14: return 36; 
-break;
-case 15: return 35; 
-break;
-case 16: return 35; 
-break;
-case 17: return 39; 
-break;
-case 18: /*ignore whitespace*/ 
-break;
-case 19: this.popState(); return 18; 
-break;
-case 20: this.popState(); return 18; 
-break;
-case 21: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\&quot;/g,'&quot;'); return 30; 
-break;
-case 22: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\'/g,&quot;'&quot;); return 30; 
-break;
-case 23: yy_.yytext = yy_.yytext.substr(1); return 28; 
-break;
-case 24: return 32; 
-break;
-case 25: return 32; 
-break;
-case 26: return 31; 
-break;
-case 27: return 35; 
-break;
-case 28: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 35; 
-break;
-case 29: return 'INVALID'; 
-break;
-case 30: /*ignore whitespace*/ 
-break;
-case 31: this.popState(); return 37; 
-break;
-case 32: return 5; 
-break;
-}
-};
-lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{&gt;)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&amp;)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[} ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:&quot;(\\[&quot;]|[^&quot;])*&quot;)/,/^(?:'(\\[']|[^'])*')/,/^(?:@[a-zA-Z]+)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:[0-9]+(?=[}\s]))/,/^(?:[a-zA-Z0-9_$-]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:\s+)/,/^(?:[a-zA-Z0-9_$-/]+)/,/^(?:$)/];
-lexer.conditions = {&quot;mu&quot;:{&quot;rules&quot;:[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,32],&quot;inclusive&quot;:false},&quot;emu&quot;:{&quot;rules&quot;:[2],&quot;inclusive&quot;:false},&quot;com&quot;:{&quot;rules&quot;:[3],&quot;inclusive&quot;:false},&quot;par&quot;:{&quot;rules&quot;:[30,31],&quot;inclusive&quot;:false},&quot;INITIAL&quot;:{&quot;rules&quot;:[0,1,32],&quot;inclusive&quot;:true}};
-return lexer;})()
-parser.lexer = lexer;
-function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
-return new Parser;
-})();;
-// lib/handlebars/compiler/base.js
-Handlebars.Parser = handlebars;
</del><ins>+    BlockNode: function(mustache, program, inverse, close, locInfo) {
+      LocationInfo.call(this, locInfo);
</ins><span class="cx"> 
</span><del>-Handlebars.parse = function(input) {
</del><ins>+      if(mustache.sexpr.id.original !== close.path.original) {
+        throw new Exception(mustache.sexpr.id.original + &quot; doesn't match &quot; + close.path.original, this);
+      }
</ins><span class="cx"> 
</span><del>-  // Just return if an already-compile AST was passed in.
-  if(input.constructor === Handlebars.AST.ProgramNode) { return input; }
</del><ins>+      this.type = 'block';
+      this.mustache = mustache;
+      this.program  = program;
+      this.inverse  = inverse;
</ins><span class="cx"> 
</span><del>-  Handlebars.Parser.yy = Handlebars.AST;
-  return Handlebars.Parser.parse(input);
-};
</del><ins>+      this.strip = {
+        left: mustache.strip.left,
+        right: close.strip.right
+      };
</ins><span class="cx"> 
</span><del>-Handlebars.print = function(ast) {
-  return new Handlebars.PrintVisitor().accept(ast);
-};;
-// lib/handlebars/compiler/ast.js
-(function() {
</del><ins>+      (program || inverse).strip.left = mustache.strip.right;
+      (inverse || program).strip.right = close.strip.left;
</ins><span class="cx"> 
</span><del>-  Handlebars.AST = {};
</del><ins>+      if (inverse &amp;&amp; !program) {
+        this.isInverse = true;
+      }
+    },
</ins><span class="cx"> 
</span><del>-  Handlebars.AST.ProgramNode = function(statements, inverse) {
-    this.type = &quot;program&quot;;
-    this.statements = statements;
-    if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
-  };
</del><ins>+    ContentNode: function(string, locInfo) {
+      LocationInfo.call(this, locInfo);
+      this.type = &quot;content&quot;;
+      this.string = string;
+    },
</ins><span class="cx"> 
</span><del>-  Handlebars.AST.MustacheNode = function(rawParams, hash, unescaped) {
-    this.type = &quot;mustache&quot;;
-    this.escaped = !unescaped;
-    this.hash = hash;
</del><ins>+    HashNode: function(pairs, locInfo) {
+      LocationInfo.call(this, locInfo);
+      this.type = &quot;hash&quot;;
+      this.pairs = pairs;
+    },
</ins><span class="cx"> 
</span><del>-    var id = this.id = rawParams[0];
-    var params = this.params = rawParams.slice(1);
</del><ins>+    IdNode: function(parts, locInfo) {
+      LocationInfo.call(this, locInfo);
+      this.type = &quot;ID&quot;;
</ins><span class="cx"> 
</span><del>-    // a mustache is an eligible helper if:
-    // * its id is simple (a single part, not `this` or `..`)
-    var eligibleHelper = this.eligibleHelper = id.isSimple;
</del><ins>+      var original = &quot;&quot;,
+          dig = [],
+          depth = 0;
</ins><span class="cx"> 
</span><del>-    // a mustache is definitely a helper if:
-    // * it is an eligible helper, and
-    // * it has at least one parameter or hash segment
-    this.isHelper = eligibleHelper &amp;&amp; (params.length || hash);
</del><ins>+      for(var i=0,l=parts.length; i&lt;l; i++) {
+        var part = parts[i].part;
+        original += (parts[i].separator || '') + part;
</ins><span class="cx"> 
</span><del>-    // if a mustache is an eligible helper but not a definite
-    // helper, it is ambiguous, and will be resolved in a later
-    // pass or at runtime.
-  };
</del><ins>+        if (part === &quot;..&quot; || part === &quot;.&quot; || part === &quot;this&quot;) {
+          if (dig.length &gt; 0) {
+            throw new Exception(&quot;Invalid path: &quot; + original, this);
+          } else if (part === &quot;..&quot;) {
+            depth++;
+          } else {
+            this.isScoped = true;
+          }
+        } else {
+          dig.push(part);
+        }
+      }
</ins><span class="cx"> 
</span><del>-  Handlebars.AST.PartialNode = function(partialName, context) {
-    this.type         = &quot;partial&quot;;
-    this.partialName  = partialName;
-    this.context      = context;
-  };
</del><ins>+      this.original = original;
+      this.parts    = dig;
+      this.string   = dig.join('.');
+      this.depth    = depth;
</ins><span class="cx"> 
</span><del>-  var verifyMatch = function(open, close) {
-    if(open.original !== close.original) {
-      throw new Handlebars.Exception(open.original + &quot; doesn't match &quot; + close.original);
-    }
-  };
</del><ins>+      // an ID is simple if it only has one part, and that part is not
+      // `..` or `this`.
+      this.isSimple = parts.length === 1 &amp;&amp; !this.isScoped &amp;&amp; depth === 0;
</ins><span class="cx"> 
</span><del>-  Handlebars.AST.BlockNode = function(mustache, program, inverse, close) {
-    verifyMatch(mustache.id, close);
-    this.type = &quot;block&quot;;
-    this.mustache = mustache;
-    this.program  = program;
-    this.inverse  = inverse;
</del><ins>+      this.stringModeValue = this.string;
+    },
</ins><span class="cx"> 
</span><del>-    if (this.inverse &amp;&amp; !this.program) {
-      this.isInverse = true;
-    }
-  };
</del><ins>+    PartialNameNode: function(name, locInfo) {
+      LocationInfo.call(this, locInfo);
+      this.type = &quot;PARTIAL_NAME&quot;;
+      this.name = name.original;
+    },
</ins><span class="cx"> 
</span><del>-  Handlebars.AST.ContentNode = function(string) {
-    this.type = &quot;content&quot;;
-    this.string = string;
-  };
</del><ins>+    DataNode: function(id, locInfo) {
+      LocationInfo.call(this, locInfo);
+      this.type = &quot;DATA&quot;;
+      this.id = id;
+    },
</ins><span class="cx"> 
</span><del>-  Handlebars.AST.HashNode = function(pairs) {
-    this.type = &quot;hash&quot;;
-    this.pairs = pairs;
-  };
</del><ins>+    StringNode: function(string, locInfo) {
+      LocationInfo.call(this, locInfo);
+      this.type = &quot;STRING&quot;;
+      this.original =
+        this.string =
+        this.stringModeValue = string;
+    },
</ins><span class="cx"> 
</span><del>-  Handlebars.AST.IdNode = function(parts) {
-    this.type = &quot;ID&quot;;
-    this.original = parts.join(&quot;.&quot;);
</del><ins>+    IntegerNode: function(integer, locInfo) {
+      LocationInfo.call(this, locInfo);
+      this.type = &quot;INTEGER&quot;;
+      this.original =
+        this.integer = integer;
+      this.stringModeValue = Number(integer);
+    },
</ins><span class="cx"> 
</span><del>-    var dig = [], depth = 0;
</del><ins>+    BooleanNode: function(bool, locInfo) {
+      LocationInfo.call(this, locInfo);
+      this.type = &quot;BOOLEAN&quot;;
+      this.bool = bool;
+      this.stringModeValue = bool === &quot;true&quot;;
+    },
</ins><span class="cx"> 
</span><del>-    for(var i=0,l=parts.length; i&lt;l; i++) {
-      var part = parts[i];
-
-      if (part === &quot;..&quot; || part === &quot;.&quot; || part === &quot;this&quot;) {
-        if (dig.length &gt; 0) { throw new Handlebars.Exception(&quot;Invalid path: &quot; + this.original); }
-        else if (part === &quot;..&quot;) { depth++; }
-        else { this.isScoped = true; }
-      }
-      else { dig.push(part); }
</del><ins>+    CommentNode: function(comment, locInfo) {
+      LocationInfo.call(this, locInfo);
+      this.type = &quot;comment&quot;;
+      this.comment = comment;
</ins><span class="cx">     }
</span><ins>+  };
</ins><span class="cx"> 
</span><del>-    this.parts    = dig;
-    this.string   = dig.join('.');
-    this.depth    = depth;
</del><ins>+  // Must be exported as an object rather than the root of the module as the jison lexer
+  // most modify the object to operate properly.
+  __exports__ = AST;
+  return __exports__;
+})(__module5__);
</ins><span class="cx"> 
</span><del>-    // an ID is simple if it only has one part, and that part is not
-    // `..` or `this`.
-    this.isSimple = parts.length === 1 &amp;&amp; !this.isScoped &amp;&amp; depth === 0;
</del><ins>+// handlebars/compiler/parser.js
+var __module9__ = (function() {
+  &quot;use strict&quot;;
+  var __exports__;
+  /* jshint ignore:start */
+  /* Jison generated parser */
+  var handlebars = (function(){
+  var parser = {trace: function trace() { },
+  yy: {},
+  symbols_: {&quot;error&quot;:2,&quot;root&quot;:3,&quot;statements&quot;:4,&quot;EOF&quot;:5,&quot;program&quot;:6,&quot;simpleInverse&quot;:7,&quot;statement&quot;:8,&quot;openInverse&quot;:9,&quot;closeBlock&quot;:10,&quot;openBlock&quot;:11,&quot;mustache&quot;:12,&quot;partial&quot;:13,&quot;CONTENT&quot;:14,&quot;COMMENT&quot;:15,&quot;OPEN_BLOCK&quot;:16,&quot;sexpr&quot;:17,&quot;CLOSE&quot;:18,&quot;OPEN_INVERSE&quot;:19,&quot;OPEN_ENDBLOCK&quot;:20,&quot;path&quot;:21,&quot;OPEN&quot;:22,&quot;OPEN_UNESCAPED&quot;:23,&quot;CLOSE_UNESCAPED&quot;:24,&quot;OPEN_PARTIAL&quot;:25,&quot;partialName&quot;:26,&quot;partial_option0&quot;:27,&quot;sexpr_repetition0&quot;:28,&quot;sexpr_option0&quot;:29,&quot;dataName&quot;:30,&quot;param&quot;:31,&quot;STRING&quot;:32,&quot;INTEGER&quot;:33,&quot;BOOLEAN&quot;:34,&quot;OPEN_SEXPR&quot;:35,&quot;CLOSE_SEXPR&quot;:36,&quot;hash&quot;:37,&quot;hash_repetition_plus0&quot;:38,&quot;hashSegment&quot;:39,&quot;ID&quot;:40,&quot;EQUALS&quot;:41,&quot;DATA&quot;:42,&quot;pathSegments&quot;:43,&quot;SEP&quot;:44,&quot;$accept&quot;:0,&quot;$end&quot;:1},
+  terminals_: {2:&quot;error&quot;,5:&quot;EOF&quot;,14:&quot;CONTENT&quot;,15:&quot;COMMENT&quot;,16:&quot;OPEN_BLOCK&quot;,18:&quot;CLOSE&quot;,19:&quot;OPEN_INVERSE&quot;,20:&quot;OPEN_ENDBLOCK&quot;,22:&quot;OPEN&quot;,23:&quot;OPEN_UNESCAPED&quot;,24:&quot;CLOSE_UNESCAPED&quot;,25:&quot;OPEN_PARTIAL&quot;,32:&quot;STRING&quot;,33:&quot;INTEGER&quot;,34:&quot;BOOLEAN&quot;,35:&quot;OPEN_SEXPR&quot;,36:&quot;CLOSE_SEXPR&quot;,40:&quot;ID&quot;,41:&quot;EQUALS&quot;,42:&quot;DATA&quot;,44:&quot;SEP&quot;},
+  productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[31,3],[37,1],[39,3],[26,1],[26,1],[26,1],[30,2],[21,1],[43,3],[43,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[38,1],[38,2]],
+  performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
</ins><span class="cx"> 
</span><del>-    this.stringModeValue = this.string;
</del><ins>+  var $0 = $$.length - 1;
+  switch (yystate) {
+  case 1: return new yy.ProgramNode($$[$0-1], this._$); 
+  break;
+  case 2: return new yy.ProgramNode([], this._$); 
+  break;
+  case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0], this._$);
+  break;
+  case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0], this._$);
+  break;
+  case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], [], this._$);
+  break;
+  case 6:this.$ = new yy.ProgramNode($$[$0], this._$);
+  break;
+  case 7:this.$ = new yy.ProgramNode([], this._$);
+  break;
+  case 8:this.$ = new yy.ProgramNode([], this._$);
+  break;
+  case 9:this.$ = [$$[$0]];
+  break;
+  case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; 
+  break;
+  case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0], this._$);
+  break;
+  case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0], this._$);
+  break;
+  case 13:this.$ = $$[$0];
+  break;
+  case 14:this.$ = $$[$0];
+  break;
+  case 15:this.$ = new yy.ContentNode($$[$0], this._$);
+  break;
+  case 16:this.$ = new yy.CommentNode($$[$0], this._$);
+  break;
+  case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
+  break;
+  case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
+  break;
+  case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])};
+  break;
+  case 20:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
+  break;
+  case 21:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
+  break;
+  case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]), this._$);
+  break;
+  case 23:this.$ = stripFlags($$[$0-1], $$[$0]);
+  break;
+  case 24:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$);
+  break;
+  case 25:this.$ = new yy.SexprNode([$$[$0]], null, this._$);
+  break;
+  case 26:this.$ = $$[$0];
+  break;
+  case 27:this.$ = new yy.StringNode($$[$0], this._$);
+  break;
+  case 28:this.$ = new yy.IntegerNode($$[$0], this._$);
+  break;
+  case 29:this.$ = new yy.BooleanNode($$[$0], this._$);
+  break;
+  case 30:this.$ = $$[$0];
+  break;
+  case 31:$$[$0-1].isHelper = true; this.$ = $$[$0-1];
+  break;
+  case 32:this.$ = new yy.HashNode($$[$0], this._$);
+  break;
+  case 33:this.$ = [$$[$0-2], $$[$0]];
+  break;
+  case 34:this.$ = new yy.PartialNameNode($$[$0], this._$);
+  break;
+  case 35:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$);
+  break;
+  case 36:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0], this._$));
+  break;
+  case 37:this.$ = new yy.DataNode($$[$0], this._$);
+  break;
+  case 38:this.$ = new yy.IdNode($$[$0], this._$);
+  break;
+  case 39: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2]; 
+  break;
+  case 40:this.$ = [{part: $$[$0]}];
+  break;
+  case 43:this.$ = [];
+  break;
+  case 44:$$[$0-1].push($$[$0]);
+  break;
+  case 47:this.$ = [$$[$0]];
+  break;
+  case 48:$$[$0-1].push($$[$0]);
+  break;
+  }
+  },
+  table: [{3:1,4:2,5:[1,3],8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[3]},{5:[1,16],8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[2,2]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],25:[2,9]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],25:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],25:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],25:[2,15]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:29,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:30,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:31,21:24,30:25,40:[1,28],42:[1,27],43:26},{21:33,26:32,32:[1,34],33:[1,35],40:[1,28],43:26},{1:[2,1]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,40:[1,28],42:[1,27],43:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,43],24:[2,43],28:43,32:[2,43],33:[2,43],34:[2,43],35:[2,43],36:[2,43],40:[2,43],42:[2,43]},{18:[2,25],24:[2,25],36:[2,25]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],35:[2,38],36:[2,38],40:[2,38],42:[2,38],44:[1,44]},{21:45,40:[1,28],43:26},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],42:[2,40],44:[2,40]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,41],21:50,27:49,40:[1,28],43:26},{18:[2,34],40:[2,34]},{18:[2,35],40:[2,35]},{18:[2,36],40:[2,36]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],25:[2,11]},{21:51,40:[1,28],43:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],25:[2,12]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,45],21:56,24:[2,45],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:[1,61],36:[2,45],37:55,38:62,39:63,40:[1,64],42:[1,27],43:26},{40:[1,65]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],35:[2,37],36:[2,37],40:[2,37],42:[2,37]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],25:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],25:[2,21]},{18:[1,66]},{18:[2,42]},{18:[1,67]},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],25:[1,15]},{18:[2,24],24:[2,24],36:[2,24]},{18:[2,44],24:[2,44],32:[2,44],33:[2,44],34:[2,44],35:[2,44],36:[2,44],40:[2,44],42:[2,44]},{18:[2,46],24:[2,46],36:[2,46]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],35:[2,26],36:[2,26],40:[2,26],42:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],35:[2,27],36:[2,27],40:[2,27],42:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],35:[2,28],36:[2,28],40:[2,28],42:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],35:[2,29],36:[2,29],40:[2,29],42:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],35:[2,30],36:[2,30],40:[2,30],42:[2,30]},{17:68,21:24,30:25,40:[1,28],42:[1,27],43:26},{18:[2,32],24:[2,32],36:[2,32],39:69,40:[1,70]},{18:[2,47],24:[2,47],36:[2,47],40:[2,47]},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],41:[1,71],42:[2,40],44:[2,40]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],35:[2,39],36:[2,39],40:[2,39],42:[2,39],44:[2,39]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],25:[2,19]},{36:[1,72]},{18:[2,48],24:[2,48],36:[2,48],40:[2,48]},{41:[1,71]},{21:56,30:60,31:73,32:[1,57],33:[1,58],34:[1,59],35:[1,61],40:[1,28],42:[1,27],43:26},{18:[2,31],24:[2,31],32:[2,31],33:[2,31],34:[2,31],35:[2,31],36:[2,31],40:[2,31],42:[2,31]},{18:[2,33],24:[2,33],36:[2,33],40:[2,33]}],
+  defaultActions: {3:[2,2],16:[2,1],50:[2,42]},
+  parseError: function parseError(str, hash) {
+      throw new Error(str);
+  },
+  parse: function parse(input) {
+      var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = &quot;&quot;, yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
+      this.lexer.setInput(input);
+      this.lexer.yy = this.yy;
+      this.yy.lexer = this.lexer;
+      this.yy.parser = this;
+      if (typeof this.lexer.yylloc == &quot;undefined&quot;)
+          this.lexer.yylloc = {};
+      var yyloc = this.lexer.yylloc;
+      lstack.push(yyloc);
+      var ranges = this.lexer.options &amp;&amp; this.lexer.options.ranges;
+      if (typeof this.yy.parseError === &quot;function&quot;)
+          this.parseError = this.yy.parseError;
+      function popStack(n) {
+          stack.length = stack.length - 2 * n;
+          vstack.length = vstack.length - n;
+          lstack.length = lstack.length - n;
+      }
+      function lex() {
+          var token;
+          token = self.lexer.lex() || 1;
+          if (typeof token !== &quot;number&quot;) {
+              token = self.symbols_[token] || token;
+          }
+          return token;
+      }
+      var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
+      while (true) {
+          state = stack[stack.length - 1];
+          if (this.defaultActions[state]) {
+              action = this.defaultActions[state];
+          } else {
+              if (symbol === null || typeof symbol == &quot;undefined&quot;) {
+                  symbol = lex();
+              }
+              action = table[state] &amp;&amp; table[state][symbol];
+          }
+          if (typeof action === &quot;undefined&quot; || !action.length || !action[0]) {
+              var errStr = &quot;&quot;;
+              if (!recovering) {
+                  expected = [];
+                  for (p in table[state])
+                      if (this.terminals_[p] &amp;&amp; p &gt; 2) {
+                          expected.push(&quot;'&quot; + this.terminals_[p] + &quot;'&quot;);
+                      }
+                  if (this.lexer.showPosition) {
+                      errStr = &quot;Parse error on line &quot; + (yylineno + 1) + &quot;:\n&quot; + this.lexer.showPosition() + &quot;\nExpecting &quot; + expected.join(&quot;, &quot;) + &quot;, got '&quot; + (this.terminals_[symbol] || symbol) + &quot;'&quot;;
+                  } else {
+                      errStr = &quot;Parse error on line &quot; + (yylineno + 1) + &quot;: Unexpected &quot; + (symbol == 1?&quot;end of input&quot;:&quot;'&quot; + (this.terminals_[symbol] || symbol) + &quot;'&quot;);
+                  }
+                  this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
+              }
+          }
+          if (action[0] instanceof Array &amp;&amp; action.length &gt; 1) {
+              throw new Error(&quot;Parse Error: multiple actions possible at state: &quot; + state + &quot;, token: &quot; + symbol);
+          }
+          switch (action[0]) {
+          case 1:
+              stack.push(symbol);
+              vstack.push(this.lexer.yytext);
+              lstack.push(this.lexer.yylloc);
+              stack.push(action[1]);
+              symbol = null;
+              if (!preErrorSymbol) {
+                  yyleng = this.lexer.yyleng;
+                  yytext = this.lexer.yytext;
+                  yylineno = this.lexer.yylineno;
+                  yyloc = this.lexer.yylloc;
+                  if (recovering &gt; 0)
+                      recovering--;
+              } else {
+                  symbol = preErrorSymbol;
+                  preErrorSymbol = null;
+              }
+              break;
+          case 2:
+              len = this.productions_[action[1]][1];
+              yyval.$ = vstack[vstack.length - len];
+              yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
+              if (ranges) {
+                  yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
+              }
+              r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
+              if (typeof r !== &quot;undefined&quot;) {
+                  return r;
+              }
+              if (len) {
+                  stack = stack.slice(0, -1 * len * 2);
+                  vstack = vstack.slice(0, -1 * len);
+                  lstack = lstack.slice(0, -1 * len);
+              }
+              stack.push(this.productions_[action[1]][0]);
+              vstack.push(yyval.$);
+              lstack.push(yyval._$);
+              newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
+              stack.push(newState);
+              break;
+          case 3:
+              return true;
+          }
+      }
+      return true;
+  }
</ins><span class="cx">   };
</span><span class="cx"> 
</span><del>-  Handlebars.AST.PartialNameNode = function(name) {
-    this.type = &quot;PARTIAL_NAME&quot;;
-    this.name = name;
-  };
</del><span class="cx"> 
</span><del>-  Handlebars.AST.DataNode = function(id) {
-    this.type = &quot;DATA&quot;;
-    this.id = id;
-  };
</del><ins>+  function stripFlags(open, close) {
+    return {
+      left: open.charAt(2) === '~',
+      right: close.charAt(0) === '~' || close.charAt(1) === '~'
+    };
+  }
</ins><span class="cx"> 
</span><del>-  Handlebars.AST.StringNode = function(string) {
-    this.type = &quot;STRING&quot;;
-    this.string = string;
-    this.stringModeValue = string;
-  };
</del><ins>+  /* Jison generated lexer */
+  var lexer = (function(){
+  var lexer = ({EOF:1,
+  parseError:function parseError(str, hash) {
+          if (this.yy.parser) {
+              this.yy.parser.parseError(str, hash);
+          } else {
+              throw new Error(str);
+          }
+      },
+  setInput:function (input) {
+          this._input = input;
+          this._more = this._less = this.done = false;
+          this.yylineno = this.yyleng = 0;
+          this.yytext = this.matched = this.match = '';
+          this.conditionStack = ['INITIAL'];
+          this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
+          if (this.options.ranges) this.yylloc.range = [0,0];
+          this.offset = 0;
+          return this;
+      },
+  input:function () {
+          var ch = this._input[0];
+          this.yytext += ch;
+          this.yyleng++;
+          this.offset++;
+          this.match += ch;
+          this.matched += ch;
+          var lines = ch.match(/(?:\r\n?|\n).*/g);
+          if (lines) {
+              this.yylineno++;
+              this.yylloc.last_line++;
+          } else {
+              this.yylloc.last_column++;
+          }
+          if (this.options.ranges) this.yylloc.range[1]++;
</ins><span class="cx"> 
</span><del>-  Handlebars.AST.IntegerNode = function(integer) {
-    this.type = &quot;INTEGER&quot;;
-    this.integer = integer;
-    this.stringModeValue = Number(integer);
-  };
</del><ins>+          this._input = this._input.slice(1);
+          return ch;
+      },
+  unput:function (ch) {
+          var len = ch.length;
+          var lines = ch.split(/(?:\r\n?|\n)/g);
</ins><span class="cx"> 
</span><del>-  Handlebars.AST.BooleanNode = function(bool) {
-    this.type = &quot;BOOLEAN&quot;;
-    this.bool = bool;
-    this.stringModeValue = bool === &quot;true&quot;;
-  };
</del><ins>+          this._input = ch + this._input;
+          this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
+          //this.yyleng -= len;
+          this.offset -= len;
+          var oldLines = this.match.split(/(?:\r\n?|\n)/g);
+          this.match = this.match.substr(0, this.match.length-1);
+          this.matched = this.matched.substr(0, this.matched.length-1);
</ins><span class="cx"> 
</span><del>-  Handlebars.AST.CommentNode = function(comment) {
-    this.type = &quot;comment&quot;;
-    this.comment = comment;
-  };
</del><ins>+          if (lines.length-1) this.yylineno -= lines.length-1;
+          var r = this.yylloc.range;
</ins><span class="cx"> 
</span><del>-})();;
-// lib/handlebars/utils.js
</del><ins>+          this.yylloc = {first_line: this.yylloc.first_line,
+            last_line: this.yylineno+1,
+            first_column: this.yylloc.first_column,
+            last_column: lines ?
+                (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
+                this.yylloc.first_column - len
+            };
</ins><span class="cx"> 
</span><del>-var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
</del><ins>+          if (this.options.ranges) {
+              this.yylloc.range = [r[0], r[0] + this.yyleng - len];
+          }
+          return this;
+      },
+  more:function () {
+          this._more = true;
+          return this;
+      },
+  less:function (n) {
+          this.unput(this.match.slice(n));
+      },
+  pastInput:function () {
+          var past = this.matched.substr(0, this.matched.length - this.match.length);
+          return (past.length &gt; 20 ? '...':'') + past.substr(-20).replace(/\n/g, &quot;&quot;);
+      },
+  upcomingInput:function () {
+          var next = this.match;
+          if (next.length &lt; 20) {
+              next += this._input.substr(0, 20-next.length);
+          }
+          return (next.substr(0,20)+(next.length &gt; 20 ? '...':'')).replace(/\n/g, &quot;&quot;);
+      },
+  showPosition:function () {
+          var pre = this.pastInput();
+          var c = new Array(pre.length + 1).join(&quot;-&quot;);
+          return pre + this.upcomingInput() + &quot;\n&quot; + c+&quot;^&quot;;
+      },
+  next:function () {
+          if (this.done) {
+              return this.EOF;
+          }
+          if (!this._input) this.done = true;
</ins><span class="cx"> 
</span><del>-Handlebars.Exception = function(message) {
-  var tmp = Error.prototype.constructor.apply(this, arguments);
</del><ins>+          var token,
+              match,
+              tempMatch,
+              index,
+              col,
+              lines;
+          if (!this._more) {
+              this.yytext = '';
+              this.match = '';
+          }
+          var rules = this._currentRules();
+          for (var i=0;i &lt; rules.length; i++) {
+              tempMatch = this._input.match(this.rules[rules[i]]);
+              if (tempMatch &amp;&amp; (!match || tempMatch[0].length &gt; match[0].length)) {
+                  match = tempMatch;
+                  index = i;
+                  if (!this.options.flex) break;
+              }
+          }
+          if (match) {
+              lines = match[0].match(/(?:\r\n?|\n).*/g);
+              if (lines) this.yylineno += lines.length;
+              this.yylloc = {first_line: this.yylloc.last_line,
+                             last_line: this.yylineno+1,
+                             first_column: this.yylloc.last_column,
+                             last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
+              this.yytext += match[0];
+              this.match += match[0];
+              this.matches = match;
+              this.yyleng = this.yytext.length;
+              if (this.options.ranges) {
+                  this.yylloc.range = [this.offset, this.offset += this.yyleng];
+              }
+              this._more = false;
+              this._input = this._input.slice(match[0].length);
+              this.matched += match[0];
+              token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
+              if (this.done &amp;&amp; this._input) this.done = false;
+              if (token) return token;
+              else return;
+          }
+          if (this._input === &quot;&quot;) {
+              return this.EOF;
+          } else {
+              return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
+                      {text: &quot;&quot;, token: null, line: this.yylineno});
+          }
+      },
+  lex:function lex() {
+          var r = this.next();
+          if (typeof r !== 'undefined') {
+              return r;
+          } else {
+              return this.lex();
+          }
+      },
+  begin:function begin(condition) {
+          this.conditionStack.push(condition);
+      },
+  popState:function popState() {
+          return this.conditionStack.pop();
+      },
+  _currentRules:function _currentRules() {
+          return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
+      },
+  topState:function () {
+          return this.conditionStack[this.conditionStack.length-2];
+      },
+  pushState:function begin(condition) {
+          this.begin(condition);
+      }});
+  lexer.options = {};
+  lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
</ins><span class="cx"> 
</span><del>-  // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
-  for (var idx = 0; idx &lt; errorProps.length; idx++) {
-    this[errorProps[idx]] = tmp[errorProps[idx]];
</del><ins>+
+  function strip(start, end) {
+    return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end);
</ins><span class="cx">   }
</span><del>-};
-Handlebars.Exception.prototype = new Error();
</del><span class="cx"> 
</span><del>-// Build out our basic SafeString type
-Handlebars.SafeString = function(string) {
-  this.string = string;
-};
-Handlebars.SafeString.prototype.toString = function() {
-  return this.string.toString();
-};
</del><span class="cx"> 
</span><del>-(function() {
-  var escape = {
-    &quot;&amp;&quot;: &quot;&amp;amp;&quot;,
-    &quot;&lt;&quot;: &quot;&amp;lt;&quot;,
-    &quot;&gt;&quot;: &quot;&amp;gt;&quot;,
-    '&quot;': &quot;&amp;quot;&quot;,
-    &quot;'&quot;: &quot;&amp;#x27;&quot;,
-    &quot;`&quot;: &quot;&amp;#x60;&quot;
</del><ins>+  var YYSTATE=YY_START
+  switch($avoiding_name_collisions) {
+  case 0:
+                                     if(yy_.yytext.slice(-2) === &quot;\\\\&quot;) {
+                                       strip(0,1);
+                                       this.begin(&quot;mu&quot;);
+                                     } else if(yy_.yytext.slice(-1) === &quot;\\&quot;) {
+                                       strip(0,1);
+                                       this.begin(&quot;emu&quot;);
+                                     } else {
+                                       this.begin(&quot;mu&quot;);
+                                     }
+                                     if(yy_.yytext) return 14;
+                                   
+  break;
+  case 1:return 14;
+  break;
+  case 2:
+                                     this.popState();
+                                     return 14;
+                                   
+  break;
+  case 3:strip(0,4); this.popState(); return 15;
+  break;
+  case 4:return 35;
+  break;
+  case 5:return 36;
+  break;
+  case 6:return 25;
+  break;
+  case 7:return 16;
+  break;
+  case 8:return 20;
+  break;
+  case 9:return 19;
+  break;
+  case 10:return 19;
+  break;
+  case 11:return 23;
+  break;
+  case 12:return 22;
+  break;
+  case 13:this.popState(); this.begin('com');
+  break;
+  case 14:strip(3,5); this.popState(); return 15;
+  break;
+  case 15:return 22;
+  break;
+  case 16:return 41;
+  break;
+  case 17:return 40;
+  break;
+  case 18:return 40;
+  break;
+  case 19:return 44;
+  break;
+  case 20:// ignore whitespace
+  break;
+  case 21:this.popState(); return 24;
+  break;
+  case 22:this.popState(); return 18;
+  break;
+  case 23:yy_.yytext = strip(1,2).replace(/\\&quot;/g,'&quot;'); return 32;
+  break;
+  case 24:yy_.yytext = strip(1,2).replace(/\\'/g,&quot;'&quot;); return 32;
+  break;
+  case 25:return 42;
+  break;
+  case 26:return 34;
+  break;
+  case 27:return 34;
+  break;
+  case 28:return 33;
+  break;
+  case 29:return 40;
+  break;
+  case 30:yy_.yytext = strip(1,2); return 40;
+  break;
+  case 31:return 'INVALID';
+  break;
+  case 32:return 5;
+  break;
+  }
</ins><span class="cx">   };
</span><ins>+  lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{(~)?&gt;)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&amp;)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:&quot;(\\[&quot;]|[^&quot;])*&quot;)/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?=([~}\s)])))/,/^(?:([^\s!&quot;#%-,\.\/;-&gt;@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
+  lexer.conditions = {&quot;mu&quot;:{&quot;rules&quot;:[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],&quot;inclusive&quot;:false},&quot;emu&quot;:{&quot;rules&quot;:[2],&quot;inclusive&quot;:false},&quot;com&quot;:{&quot;rules&quot;:[3],&quot;inclusive&quot;:false},&quot;INITIAL&quot;:{&quot;rules&quot;:[0,1,32],&quot;inclusive&quot;:true}};
+  return lexer;})()
+  parser.lexer = lexer;
+  function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
+  return new Parser;
+  })();__exports__ = handlebars;
+  /* jshint ignore:end */
+  return __exports__;
+})();
</ins><span class="cx"> 
</span><del>-  var badChars = /[&amp;&lt;&gt;&quot;'`]/g;
-  var possible = /[&amp;&lt;&gt;&quot;'`]/;
</del><ins>+// handlebars/compiler/base.js
+var __module8__ = (function(__dependency1__, __dependency2__) {
+  &quot;use strict&quot;;
+  var __exports__ = {};
+  var parser = __dependency1__;
+  var AST = __dependency2__;
</ins><span class="cx"> 
</span><del>-  var escapeChar = function(chr) {
-    return escape[chr] || &quot;&amp;amp;&quot;;
-  };
</del><ins>+  __exports__.parser = parser;
</ins><span class="cx"> 
</span><del>-  Handlebars.Utils = {
-    escapeExpression: function(string) {
-      // don't escape SafeStrings, since they're already safe
-      if (string instanceof Handlebars.SafeString) {
-        return string.toString();
-      } else if (string == null || string === false) {
-        return &quot;&quot;;
-      }
</del><ins>+  function parse(input) {
+    // Just return if an already-compile AST was passed in.
+    if(input.constructor === AST.ProgramNode) { return input; }
</ins><span class="cx"> 
</span><del>-      if(!possible.test(string)) { return string; }
-      return string.replace(badChars, escapeChar);
-    },
</del><ins>+    parser.yy = AST;
+    return parser.parse(input);
+  }
</ins><span class="cx"> 
</span><del>-    isEmpty: function(value) {
-      if (!value &amp;&amp; value !== 0) {
-        return true;
-      } else if(Object.prototype.toString.call(value) === &quot;[object Array]&quot; &amp;&amp; value.length === 0) {
-        return true;
-      } else {
-        return false;
-      }
-    }
-  };
-})();;
-// lib/handlebars/compiler/compiler.js
</del><ins>+  __exports__.parse = parse;
+  return __exports__;
+})(__module9__, __module7__);
</ins><span class="cx"> 
</span><del>-/*jshint eqnull:true*/
-Handlebars.Compiler = function() {};
-Handlebars.JavaScriptCompiler = function() {};
</del><ins>+// handlebars/compiler/compiler.js
+var __module10__ = (function(__dependency1__) {
+  &quot;use strict&quot;;
+  var __exports__ = {};
+  var Exception = __dependency1__;
</ins><span class="cx"> 
</span><del>-(function(Compiler, JavaScriptCompiler) {
-  // the foundHelper register will disambiguate helper lookup from finding a
</del><ins>+  function Compiler() {}
+
+  __exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a
</ins><span class="cx">   // function in a context. This is necessary for mustache compatibility, which
</span><span class="cx">   // requires that context functions in blocks are evaluated by blockHelperMissing,
</span><span class="cx">   // and then proceed as if the resulting value was provided to blockHelperMissing.
</span><span class="lines">@@ -890,6 +1315,7 @@
</span><span class="cx"> 
</span><span class="cx">       return out.join(&quot;\n&quot;);
</span><span class="cx">     },
</span><ins>+
</ins><span class="cx">     equals: function(other) {
</span><span class="cx">       var len = this.opcodes.length;
</span><span class="cx">       if (other.opcodes.length !== len) {
</span><span class="lines">@@ -908,12 +1334,24 @@
</span><span class="cx">           }
</span><span class="cx">         }
</span><span class="cx">       }
</span><ins>+
+      len = this.children.length;
+      if (other.children.length !== len) {
+        return false;
+      }
+      for (i = 0; i &lt; len; i++) {
+        if (!this.children[i].equals(other.children[i])) {
+          return false;
+        }
+      }
+
</ins><span class="cx">       return true;
</span><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     guid: 0,
</span><span class="cx"> 
</span><span class="cx">     compile: function(program, options) {
</span><ins>+      this.opcodes = [];
</ins><span class="cx">       this.children = [];
</span><span class="cx">       this.depths = {list: []};
</span><span class="cx">       this.options = options;
</span><span class="lines">@@ -935,20 +1373,30 @@
</span><span class="cx">         }
</span><span class="cx">       }
</span><span class="cx"> 
</span><del>-      return this.program(program);
</del><ins>+      return this.accept(program);
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     accept: function(node) {
</span><del>-      return this[node.type](node);
</del><ins>+      var strip = node.strip || {},
+          ret;
+      if (strip.left) {
+        this.opcode('strip');
+      }
+
+      ret = this[node.type](node);
+
+      if (strip.right) {
+        this.opcode('strip');
+      }
+
+      return ret;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     program: function(program) {
</span><del>-      var statements = program.statements, statement;
-      this.opcodes = [];
</del><ins>+      var statements = program.statements;
</ins><span class="cx"> 
</span><span class="cx">       for(var i=0, l=statements.length; i&lt;l; i++) {
</span><del>-        statement = statements[i];
-        this[statement.type](statement);
</del><ins>+        this.accept(statements[i]);
</ins><span class="cx">       }
</span><span class="cx">       this.isSimple = l === 1;
</span><span class="cx"> 
</span><span class="lines">@@ -990,12 +1438,13 @@
</span><span class="cx">         inverse = this.compileProgram(inverse);
</span><span class="cx">       }
</span><span class="cx"> 
</span><del>-      var type = this.classifyMustache(mustache);
</del><ins>+      var sexpr = mustache.sexpr;
+      var type = this.classifySexpr(sexpr);
</ins><span class="cx"> 
</span><span class="cx">       if (type === &quot;helper&quot;) {
</span><del>-        this.helperMustache(mustache, program, inverse);
</del><ins>+        this.helperSexpr(sexpr, program, inverse);
</ins><span class="cx">       } else if (type === &quot;simple&quot;) {
</span><del>-        this.simpleMustache(mustache);
</del><ins>+        this.simpleSexpr(sexpr);
</ins><span class="cx"> 
</span><span class="cx">         // now that the simple mustache is resolved, we need to
</span><span class="cx">         // evaluate it by executing `blockHelperMissing`
</span><span class="lines">@@ -1004,7 +1453,7 @@
</span><span class="cx">         this.opcode('emptyHash');
</span><span class="cx">         this.opcode('blockValue');
</span><span class="cx">       } else {
</span><del>-        this.ambiguousMustache(mustache, program, inverse);
</del><ins>+        this.ambiguousSexpr(sexpr, program, inverse);
</ins><span class="cx"> 
</span><span class="cx">         // now that the simple mustache is resolved, we need to
</span><span class="cx">         // evaluate it by executing `blockHelperMissing`
</span><span class="lines">@@ -1027,7 +1476,17 @@
</span><span class="cx">         val  = pair[1];
</span><span class="cx"> 
</span><span class="cx">         if (this.options.stringParams) {
</span><ins>+          if(val.depth) {
+            this.addDepth(val.depth);
+          }
+          this.opcode('getContext', val.depth || 0);
</ins><span class="cx">           this.opcode('pushStringParam', val.stringModeValue, val.type);
</span><ins>+
+          if (val.type === 'sexpr') {
+            // Subexpressions get evaluated and passed in
+            // in string params mode.
+            this.sexpr(val);
+          }
</ins><span class="cx">         } else {
</span><span class="cx">           this.accept(val);
</span><span class="cx">         }
</span><span class="lines">@@ -1056,26 +1515,17 @@
</span><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     mustache: function(mustache) {
</span><del>-      var options = this.options;
-      var type = this.classifyMustache(mustache);
</del><ins>+      this.sexpr(mustache.sexpr);
</ins><span class="cx"> 
</span><del>-      if (type === &quot;simple&quot;) {
-        this.simpleMustache(mustache);
-      } else if (type === &quot;helper&quot;) {
-        this.helperMustache(mustache);
-      } else {
-        this.ambiguousMustache(mustache);
-      }
-
-      if(mustache.escaped &amp;&amp; !options.noEscape) {
</del><ins>+      if(mustache.escaped &amp;&amp; !this.options.noEscape) {
</ins><span class="cx">         this.opcode('appendEscaped');
</span><span class="cx">       } else {
</span><span class="cx">         this.opcode('append');
</span><span class="cx">       }
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    ambiguousMustache: function(mustache, program, inverse) {
-      var id = mustache.id,
</del><ins>+    ambiguousSexpr: function(sexpr, program, inverse) {
+      var id = sexpr.id,
</ins><span class="cx">           name = id.parts[0],
</span><span class="cx">           isBlock = program != null || inverse != null;
</span><span class="cx"> 
</span><span class="lines">@@ -1087,8 +1537,8 @@
</span><span class="cx">       this.opcode('invokeAmbiguous', name, isBlock);
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    simpleMustache: function(mustache) {
-      var id = mustache.id;
</del><ins>+    simpleSexpr: function(sexpr) {
+      var id = sexpr.id;
</ins><span class="cx"> 
</span><span class="cx">       if (id.type === 'DATA') {
</span><span class="cx">         this.DATA(id);
</span><span class="lines">@@ -1104,19 +1554,31 @@
</span><span class="cx">       this.opcode('resolvePossibleLambda');
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    helperMustache: function(mustache, program, inverse) {
-      var params = this.setupFullMustacheParams(mustache, program, inverse),
-          name = mustache.id.parts[0];
</del><ins>+    helperSexpr: function(sexpr, program, inverse) {
+      var params = this.setupFullMustacheParams(sexpr, program, inverse),
+          name = sexpr.id.parts[0];
</ins><span class="cx"> 
</span><span class="cx">       if (this.options.knownHelpers[name]) {
</span><span class="cx">         this.opcode('invokeKnownHelper', params.length, name);
</span><del>-      } else if (this.knownHelpersOnly) {
-        throw new Error(&quot;You specified knownHelpersOnly, but used the unknown helper &quot; + name);
</del><ins>+      } else if (this.options.knownHelpersOnly) {
+        throw new Exception(&quot;You specified knownHelpersOnly, but used the unknown helper &quot; + name, sexpr);
</ins><span class="cx">       } else {
</span><del>-        this.opcode('invokeHelper', params.length, name);
</del><ins>+        this.opcode('invokeHelper', params.length, name, sexpr.isRoot);
</ins><span class="cx">       }
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    sexpr: function(sexpr) {
+      var type = this.classifySexpr(sexpr);
+
+      if (type === &quot;simple&quot;) {
+        this.simpleSexpr(sexpr);
+      } else if (type === &quot;helper&quot;) {
+        this.helperSexpr(sexpr);
+      } else {
+        this.ambiguousSexpr(sexpr);
+      }
+    },
+
</ins><span class="cx">     ID: function(id) {
</span><span class="cx">       this.addDepth(id.depth);
</span><span class="cx">       this.opcode('getContext', id.depth);
</span><span class="lines">@@ -1135,7 +1597,15 @@
</span><span class="cx"> 
</span><span class="cx">     DATA: function(data) {
</span><span class="cx">       this.options.data = true;
</span><del>-      this.opcode('lookupData', data.id);
</del><ins>+      if (data.id.isScoped || data.id.depth) {
+        throw new Exception('Scoped data references are not supported: ' + data.original, data);
+      }
+
+      this.opcode('lookupData');
+      var parts = data.id.parts;
+      for(var i=0, l=parts.length; i&lt;l; i++) {
+        this.opcode('lookup', parts[i]);
+      }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     STRING: function(string) {
</span><span class="lines">@@ -1162,7 +1632,6 @@
</span><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     addDepth: function(depth) {
</span><del>-      if(isNaN(depth)) { throw new Error(&quot;EWOT&quot;); }
</del><span class="cx">       if(depth === 0) { return; }
</span><span class="cx"> 
</span><span class="cx">       if(!this.depths[depth]) {
</span><span class="lines">@@ -1171,14 +1640,14 @@
</span><span class="cx">       }
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    classifyMustache: function(mustache) {
-      var isHelper   = mustache.isHelper;
-      var isEligible = mustache.eligibleHelper;
</del><ins>+    classifySexpr: function(sexpr) {
+      var isHelper   = sexpr.isHelper;
+      var isEligible = sexpr.eligibleHelper;
</ins><span class="cx">       var options    = this.options;
</span><span class="cx"> 
</span><span class="cx">       // if ambiguous, we can possibly resolve the ambiguity now
</span><span class="cx">       if (isEligible &amp;&amp; !isHelper) {
</span><del>-        var name = mustache.id.parts[0];
</del><ins>+        var name = sexpr.id.parts[0];
</ins><span class="cx"> 
</span><span class="cx">         if (options.knownHelpers[name]) {
</span><span class="cx">           isHelper = true;
</span><span class="lines">@@ -1205,35 +1674,27 @@
</span><span class="cx"> 
</span><span class="cx">           this.opcode('getContext', param.depth || 0);
</span><span class="cx">           this.opcode('pushStringParam', param.stringModeValue, param.type);
</span><ins>+
+          if (param.type === 'sexpr') {
+            // Subexpressions get evaluated and passed in
+            // in string params mode.
+            this.sexpr(param);
+          }
</ins><span class="cx">         } else {
</span><span class="cx">           this[param.type](param);
</span><span class="cx">         }
</span><span class="cx">       }
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    setupMustacheParams: function(mustache) {
-      var params = mustache.params;
</del><ins>+    setupFullMustacheParams: function(sexpr, program, inverse) {
+      var params = sexpr.params;
</ins><span class="cx">       this.pushParams(params);
</span><span class="cx"> 
</span><del>-      if(mustache.hash) {
-        this.hash(mustache.hash);
-      } else {
-        this.opcode('emptyHash');
-      }
-
-      return params;
-    },
-
-    // this will replace setupMustacheParams when we're done
-    setupFullMustacheParams: function(mustache, program, inverse) {
-      var params = mustache.params;
-      this.pushParams(params);
-
</del><span class="cx">       this.opcode('pushProgram', program);
</span><span class="cx">       this.opcode('pushProgram', inverse);
</span><span class="cx"> 
</span><del>-      if(mustache.hash) {
-        this.hash(mustache.hash);
</del><ins>+      if (sexpr.hash) {
+        this.hash(sexpr.hash);
</ins><span class="cx">       } else {
</span><span class="cx">         this.opcode('emptyHash');
</span><span class="cx">       }
</span><span class="lines">@@ -1242,24 +1703,101 @@
</span><span class="cx">     }
</span><span class="cx">   };
</span><span class="cx"> 
</span><del>-  var Literal = function(value) {
</del><ins>+  function precompile(input, options, env) {
+    if (input == null || (typeof input !== 'string' &amp;&amp; input.constructor !== env.AST.ProgramNode)) {
+      throw new Exception(&quot;You must pass a string or Handlebars AST to Handlebars.precompile. You passed &quot; + input);
+    }
+
+    options = options || {};
+    if (!('data' in options)) {
+      options.data = true;
+    }
+
+    var ast = env.parse(input);
+    var environment = new env.Compiler().compile(ast, options);
+    return new env.JavaScriptCompiler().compile(environment, options);
+  }
+
+  __exports__.precompile = precompile;function compile(input, options, env) {
+    if (input == null || (typeof input !== 'string' &amp;&amp; input.constructor !== env.AST.ProgramNode)) {
+      throw new Exception(&quot;You must pass a string or Handlebars AST to Handlebars.compile. You passed &quot; + input);
+    }
+
+    options = options || {};
+
+    if (!('data' in options)) {
+      options.data = true;
+    }
+
+    var compiled;
+
+    function compileInput() {
+      var ast = env.parse(input);
+      var environment = new env.Compiler().compile(ast, options);
+      var templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
+      return env.template(templateSpec);
+    }
+
+    // Template is only compiled on first use and cached after that point.
+    return function(context, options) {
+      if (!compiled) {
+        compiled = compileInput();
+      }
+      return compiled.call(this, context, options);
+    };
+  }
+
+  __exports__.compile = compile;
+  return __exports__;
+})(__module5__);
+
+// handlebars/compiler/javascript-compiler.js
+var __module11__ = (function(__dependency1__, __dependency2__) {
+  &quot;use strict&quot;;
+  var __exports__;
+  var COMPILER_REVISION = __dependency1__.COMPILER_REVISION;
+  var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;
+  var log = __dependency1__.log;
+  var Exception = __dependency2__;
+
+  function Literal(value) {
</ins><span class="cx">     this.value = value;
</span><del>-  };
</del><ins>+  }
</ins><span class="cx"> 
</span><ins>+  function JavaScriptCompiler() {}
+
</ins><span class="cx">   JavaScriptCompiler.prototype = {
</span><span class="cx">     // PUBLIC API: You can override these methods in a subclass to provide
</span><span class="cx">     // alternative compiled forms for name lookup and buffering semantics
</span><span class="cx">     nameLookup: function(parent, name /* , type*/) {
</span><ins>+      var wrap,
+          ret;
+      if (parent.indexOf('depth') === 0) {
+        wrap = true;
+      }
+
</ins><span class="cx">       if (/^[0-9]+$/.test(name)) {
</span><del>-        return parent + &quot;[&quot; + name + &quot;]&quot;;
</del><ins>+        ret = parent + &quot;[&quot; + name + &quot;]&quot;;
</ins><span class="cx">       } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
</span><del>-        return parent + &quot;.&quot; + name;
</del><ins>+        ret = parent + &quot;.&quot; + name;
</ins><span class="cx">       }
</span><span class="cx">       else {
</span><del>-        return parent + &quot;['&quot; + name + &quot;']&quot;;
</del><ins>+        ret = parent + &quot;['&quot; + name + &quot;']&quot;;
</ins><span class="cx">       }
</span><ins>+
+      if (wrap) {
+        return '(' + parent + ' &amp;&amp; ' + ret + ')';
+      } else {
+        return ret;
+      }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    compilerInfo: function() {
+      var revision = COMPILER_REVISION,
+          versions = REVISION_CHANGES[revision];
+      return &quot;this.compilerInfo = [&quot;+revision+&quot;,'&quot;+versions+&quot;'];\n&quot;;
+    },
+
</ins><span class="cx">     appendToBuffer: function(string) {
</span><span class="cx">       if (this.environment.isSimple) {
</span><span class="cx">         return &quot;return &quot; + string + &quot;;&quot;;
</span><span class="lines">@@ -1283,7 +1821,7 @@
</span><span class="cx">       this.environment = environment;
</span><span class="cx">       this.options = options || {};
</span><span class="cx"> 
</span><del>-      Handlebars.log(Handlebars.logger.DEBUG, this.environment.disassemble() + &quot;\n\n&quot;);
</del><ins>+      log('debug', this.environment.disassemble() + &quot;\n\n&quot;);
</ins><span class="cx"> 
</span><span class="cx">       this.name = this.environment.name;
</span><span class="cx">       this.isChild = !!context;
</span><span class="lines">@@ -1298,6 +1836,7 @@
</span><span class="cx">       this.stackSlot = 0;
</span><span class="cx">       this.stackVars = [];
</span><span class="cx">       this.registers = { list: [] };
</span><ins>+      this.hashes = [];
</ins><span class="cx">       this.compileStack = [];
</span><span class="cx">       this.inlineStack = [];
</span><span class="cx"> 
</span><span class="lines">@@ -1307,7 +1846,7 @@
</span><span class="cx"> 
</span><span class="cx">       this.i = 0;
</span><span class="cx"> 
</span><del>-      for(l=opcodes.length; this.i&lt;l; this.i++) {
</del><ins>+      for(var l=opcodes.length; this.i&lt;l; this.i++) {
</ins><span class="cx">         opcode = opcodes[this.i];
</span><span class="cx"> 
</span><span class="cx">         if(opcode.opcode === 'DECLARE') {
</span><span class="lines">@@ -1315,18 +1854,21 @@
</span><span class="cx">         } else {
</span><span class="cx">           this[opcode.opcode].apply(this, opcode.args);
</span><span class="cx">         }
</span><ins>+
+        // Reset the stripNext flag if it was not set by this operation.
+        if (opcode.opcode !== this.stripNext) {
+          this.stripNext = false;
+        }
</ins><span class="cx">       }
</span><span class="cx"> 
</span><del>-      return this.createFunctionContext(asObject);
-    },
</del><ins>+      // Flush any trailing content that might be pending.
+      this.pushSource('');
</ins><span class="cx"> 
</span><del>-    nextOpcode: function() {
-      var opcodes = this.environment.opcodes;
-      return opcodes[this.i + 1];
-    },
</del><ins>+      if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
+        throw new Exception('Compile completed with content left on stack');
+      }
</ins><span class="cx"> 
</span><del>-    eat: function() {
-      this.i = this.i + 1;
</del><ins>+      return this.createFunctionContext(asObject);
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     preamble: function() {
</span><span class="lines">@@ -1334,8 +1876,9 @@
</span><span class="cx"> 
</span><span class="cx">       if (!this.isChild) {
</span><span class="cx">         var namespace = this.namespace;
</span><del>-        var copies = &quot;helpers = helpers || &quot; + namespace + &quot;.helpers;&quot;;
-        if (this.environment.usePartial) { copies = copies + &quot; partials = partials || &quot; + namespace + &quot;.partials;&quot;; }
</del><ins>+
+        var copies = &quot;helpers = this.merge(helpers, &quot; + namespace + &quot;.helpers);&quot;;
+        if (this.environment.usePartial) { copies = copies + &quot; partials = this.merge(partials, &quot; + namespace + &quot;.partials);&quot;; }
</ins><span class="cx">         if (this.options.data) { copies = copies + &quot; data = data || {};&quot;; }
</span><span class="cx">         out.push(copies);
</span><span class="cx">       } else {
</span><span class="lines">@@ -1364,7 +1907,9 @@
</span><span class="cx">       // Generate minimizer alias mappings
</span><span class="cx">       if (!this.isChild) {
</span><span class="cx">         for (var alias in this.context.aliases) {
</span><del>-          this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
</del><ins>+          if (this.context.aliases.hasOwnProperty(alias)) {
+            this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
+          }
</ins><span class="cx">         }
</span><span class="cx">       }
</span><span class="cx"> 
</span><span class="lines">@@ -1378,7 +1923,7 @@
</span><span class="cx">       }
</span><span class="cx"> 
</span><span class="cx">       if (!this.environment.isSimple) {
</span><del>-        this.source.push(&quot;return buffer;&quot;);
</del><ins>+        this.pushSource(&quot;return buffer;&quot;);
</ins><span class="cx">       }
</span><span class="cx"> 
</span><span class="cx">       var params = this.isChild ? [&quot;depth0&quot;, &quot;data&quot;] : [&quot;Handlebars&quot;, &quot;depth0&quot;, &quot;helpers&quot;, &quot;partials&quot;, &quot;data&quot;];
</span><span class="lines">@@ -1391,9 +1936,7 @@
</span><span class="cx">       var source = this.mergeSource();
</span><span class="cx"> 
</span><span class="cx">       if (!this.isChild) {
</span><del>-        var revision = Handlebars.COMPILER_REVISION,
-            versions = Handlebars.REVISION_CHANGES[revision];
-        source = &quot;this.compilerInfo = [&quot;+revision+&quot;,'&quot;+versions+&quot;'];\n&quot;+source;
</del><ins>+        source = this.compilerInfo()+source;
</ins><span class="cx">       }
</span><span class="cx"> 
</span><span class="cx">       if (asObject) {
</span><span class="lines">@@ -1402,7 +1945,7 @@
</span><span class="cx">         return Function.apply(this, params);
</span><span class="cx">       } else {
</span><span class="cx">         var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n  ' + source + '}';
</span><del>-        Handlebars.log(Handlebars.logger.DEBUG, functionSource + &quot;\n\n&quot;);
</del><ins>+        log('debug', functionSource + &quot;\n\n&quot;);
</ins><span class="cx">         return functionSource;
</span><span class="cx">       }
</span><span class="cx">     },
</span><span class="lines">@@ -1466,10 +2009,7 @@
</span><span class="cx">       var current = this.topStack();
</span><span class="cx">       params.splice(1, 0, current);
</span><span class="cx"> 
</span><del>-      // Use the options value generated from the invocation
-      params[params.length-1] = 'options';
-
-      this.source.push(&quot;if (!&quot; + this.lastHelper + &quot;) { &quot; + current + &quot; = blockHelperMissing.call(&quot; + params.join(&quot;, &quot;) + &quot;); }&quot;);
</del><ins>+      this.pushSource(&quot;if (!&quot; + this.lastHelper + &quot;) { &quot; + current + &quot; = blockHelperMissing.call(&quot; + params.join(&quot;, &quot;) + &quot;); }&quot;);
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // [appendContent]
</span><span class="lines">@@ -1479,9 +2019,30 @@
</span><span class="cx">     //
</span><span class="cx">     // Appends the string value of `content` to the current buffer
</span><span class="cx">     appendContent: function(content) {
</span><del>-      this.source.push(this.appendToBuffer(this.quotedString(content)));
</del><ins>+      if (this.pendingContent) {
+        content = this.pendingContent + content;
+      }
+      if (this.stripNext) {
+        content = content.replace(/^\s+/, '');
+      }
+
+      this.pendingContent = content;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    // [strip]
+    //
+    // On stack, before: ...
+    // On stack, after: ...
+    //
+    // Removes any trailing whitespace from the prior content node and flags
+    // the next operation for stripping if it is a content node.
+    strip: function() {
+      if (this.pendingContent) {
+        this.pendingContent = this.pendingContent.replace(/\s+$/, '');
+      }
+      this.stripNext = 'strip';
+    },
+
</ins><span class="cx">     // [append]
</span><span class="cx">     //
</span><span class="cx">     // On stack, before: value, ...
</span><span class="lines">@@ -1496,9 +2057,9 @@
</span><span class="cx">       // when we examine local
</span><span class="cx">       this.flushInline();
</span><span class="cx">       var local = this.popStack();
</span><del>-      this.source.push(&quot;if(&quot; + local + &quot; || &quot; + local + &quot; === 0) { &quot; + this.appendToBuffer(local) + &quot; }&quot;);
</del><ins>+      this.pushSource(&quot;if(&quot; + local + &quot; || &quot; + local + &quot; === 0) { &quot; + this.appendToBuffer(local) + &quot; }&quot;);
</ins><span class="cx">       if (this.environment.isSimple) {
</span><del>-        this.source.push(&quot;else { &quot; + this.appendToBuffer(&quot;''&quot;) + &quot; }&quot;);
</del><ins>+        this.pushSource(&quot;else { &quot; + this.appendToBuffer(&quot;''&quot;) + &quot; }&quot;);
</ins><span class="cx">       }
</span><span class="cx">     },
</span><span class="cx"> 
</span><span class="lines">@@ -1511,7 +2072,7 @@
</span><span class="cx">     appendEscaped: function() {
</span><span class="cx">       this.context.aliases.escapeExpression = 'this.escapeExpression';
</span><span class="cx"> 
</span><del>-      this.source.push(this.appendToBuffer(&quot;escapeExpression(&quot; + this.popStack() + &quot;)&quot;));
</del><ins>+      this.pushSource(this.appendToBuffer(&quot;escapeExpression(&quot; + this.popStack() + &quot;)&quot;));
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // [getContext]
</span><span class="lines">@@ -1579,11 +2140,11 @@
</span><span class="cx">     // [lookupData]
</span><span class="cx">     //
</span><span class="cx">     // On stack, before: ...
</span><del>-    // On stack, after: data[id], ...
</del><ins>+    // On stack, after: data, ...
</ins><span class="cx">     //
</span><del>-    // Push the result of looking up `id` on the current data
-    lookupData: function(id) {
-      this.push(this.nameLookup('data', id, 'data'));
</del><ins>+    // Push the data lookup operator
+    lookupData: function() {
+      this.pushStackLiteral('data');
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // [pushStringParam]
</span><span class="lines">@@ -1599,10 +2160,14 @@
</span><span class="cx"> 
</span><span class="cx">       this.pushString(type);
</span><span class="cx"> 
</span><del>-      if (typeof string === 'string') {
-        this.pushString(string);
-      } else {
-        this.pushStackLiteral(string);
</del><ins>+      // If it's a subexpression, the string result
+      // will be pushed after this opcode.
+      if (type !== 'sexpr') {
+        if (typeof string === 'string') {
+          this.pushString(string);
+        } else {
+          this.pushStackLiteral(string);
+        }
</ins><span class="cx">       }
</span><span class="cx">     },
</span><span class="cx"> 
</span><span class="lines">@@ -1610,19 +2175,25 @@
</span><span class="cx">       this.pushStackLiteral('{}');
</span><span class="cx"> 
</span><span class="cx">       if (this.options.stringParams) {
</span><del>-        this.register('hashTypes', '{}');
</del><ins>+        this.push('{}'); // hashContexts
+        this.push('{}'); // hashTypes
</ins><span class="cx">       }
</span><span class="cx">     },
</span><span class="cx">     pushHash: function() {
</span><del>-      this.hash = {values: [], types: []};
</del><ins>+      if (this.hash) {
+        this.hashes.push(this.hash);
+      }
+      this.hash = {values: [], types: [], contexts: []};
</ins><span class="cx">     },
</span><span class="cx">     popHash: function() {
</span><span class="cx">       var hash = this.hash;
</span><del>-      this.hash = undefined;
</del><ins>+      this.hash = this.hashes.pop();
</ins><span class="cx"> 
</span><span class="cx">       if (this.options.stringParams) {
</span><del>-        this.register('hashTypes', '{' + hash.types.join(',') + '}');
</del><ins>+        this.push('{' + hash.contexts.join(',') + '}');
+        this.push('{' + hash.types.join(',') + '}');
</ins><span class="cx">       }
</span><ins>+
</ins><span class="cx">       this.push('{\n    ' + hash.values.join(',\n    ') + '\n  }');
</span><span class="cx">     },
</span><span class="cx"> 
</span><span class="lines">@@ -1684,17 +2255,31 @@
</span><span class="cx">     // and pushes the helper's return value onto the stack.
</span><span class="cx">     //
</span><span class="cx">     // If the helper is not found, `helperMissing` is called.
</span><del>-    invokeHelper: function(paramSize, name) {
</del><ins>+    invokeHelper: function(paramSize, name, isRoot) {
</ins><span class="cx">       this.context.aliases.helperMissing = 'helpers.helperMissing';
</span><ins>+      this.useRegister('helper');
</ins><span class="cx"> 
</span><span class="cx">       var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
</span><ins>+      var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
</ins><span class="cx"> 
</span><del>-      this.push(helper.name);
-      this.replaceStack(function(name) {
-        return name + ' ? ' + name + '.call(' +
-            helper.callParams + &quot;) &quot; + &quot;: helperMissing.call(&quot; +
-            helper.helperMissingParams + &quot;)&quot;;
-      });
</del><ins>+      var lookup = 'helper = ' + helper.name + ' || ' + nonHelper;
+      if (helper.paramsInit) {
+        lookup += ',' + helper.paramsInit;
+      }
+
+      this.push(
+        '('
+          + lookup
+          + ',helper '
+            + '? helper.call(' + helper.callParams + ') '
+            + ': helperMissing.call(' + helper.helperMissingParams + '))');
+
+      // Always flush subexpressions. This is both to prevent the compounding size issue that
+      // occurs when the code has to be duplicated for inlining and also to prevent errors
+      // due to the incorrect options object being passed due to the shared register.
+      if (!isRoot) {
+        this.flushInline();
+      }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // [invokeKnownHelper]
</span><span class="lines">@@ -1723,8 +2308,9 @@
</span><span class="cx">     // `knownHelpersOnly` flags at compile-time.
</span><span class="cx">     invokeAmbiguous: function(name, helperCall) {
</span><span class="cx">       this.context.aliases.functionType = '&quot;function&quot;';
</span><ins>+      this.useRegister('helper');
</ins><span class="cx"> 
</span><del>-      this.pushStackLiteral('{}');    // Hash value
</del><ins>+      this.emptyHash();
</ins><span class="cx">       var helper = this.setupHelper(0, name, helperCall);
</span><span class="cx"> 
</span><span class="cx">       var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
</span><span class="lines">@@ -1732,8 +2318,11 @@
</span><span class="cx">       var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
</span><span class="cx">       var nextStack = this.nextStack();
</span><span class="cx"> 
</span><del>-      this.source.push('if (' + nextStack + ' = ' + helperName + ') { ' + nextStack + ' = ' + nextStack + '.call(' + helper.callParams + '); }');
-      this.source.push('else { ' + nextStack + ' = ' + nonHelper + '; ' + nextStack + ' = typeof ' + nextStack + ' === functionType ? ' + nextStack + '.apply(depth0) : ' + nextStack + '; }');
</del><ins>+      if (helper.paramsInit) {
+        this.pushSource(helper.paramsInit);
+      }
+      this.pushSource('if (helper = ' + helperName + ') { ' + nextStack + ' = helper.call(' + helper.callParams + '); }');
+      this.pushSource('else { helper = ' + nonHelper + '; ' + nextStack + ' = typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper; }');
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // [invokePartial]
</span><span class="lines">@@ -1763,14 +2352,18 @@
</span><span class="cx">     // and pushes the hash back onto the stack.
</span><span class="cx">     assignToHash: function(key) {
</span><span class="cx">       var value = this.popStack(),
</span><ins>+          context,
</ins><span class="cx">           type;
</span><span class="cx"> 
</span><span class="cx">       if (this.options.stringParams) {
</span><span class="cx">         type = this.popStack();
</span><del>-        this.popStack();
</del><ins>+        context = this.popStack();
</ins><span class="cx">       }
</span><span class="cx"> 
</span><span class="cx">       var hash = this.hash;
</span><ins>+      if (context) {
+        hash.contexts.push(&quot;'&quot; + key + &quot;': &quot; + context);
+      }
</ins><span class="cx">       if (type) {
</span><span class="cx">         hash.types.push(&quot;'&quot; + key + &quot;': &quot; + type);
</span><span class="cx">       }
</span><span class="lines">@@ -1831,17 +2424,12 @@
</span><span class="cx">         else { programParams.push(&quot;depth&quot; + (depth - 1)); }
</span><span class="cx">       }
</span><span class="cx"> 
</span><del>-      if(depths.length === 0) {
-        return &quot;self.program(&quot; + programParams.join(&quot;, &quot;) + &quot;)&quot;;
-      } else {
-        programParams.shift();
-        return &quot;self.programWithDepth(&quot; + programParams.join(&quot;, &quot;) + &quot;)&quot;;
-      }
</del><ins>+      return (depths.length === 0 ? &quot;self.program(&quot; : &quot;self.programWithDepth(&quot;) + programParams.join(&quot;, &quot;) + &quot;)&quot;;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     register: function(name, val) {
</span><span class="cx">       this.useRegister(name);
</span><del>-      this.source.push(name + &quot; = &quot; + val + &quot;;&quot;);
</del><ins>+      this.pushSource(name + &quot; = &quot; + val + &quot;;&quot;);
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     useRegister: function(name) {
</span><span class="lines">@@ -1855,12 +2443,23 @@
</span><span class="cx">       return this.push(new Literal(item));
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    pushSource: function(source) {
+      if (this.pendingContent) {
+        this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
+        this.pendingContent = undefined;
+      }
+
+      if (source) {
+        this.source.push(source);
+      }
+    },
+
</ins><span class="cx">     pushStack: function(item) {
</span><span class="cx">       this.flushInline();
</span><span class="cx"> 
</span><span class="cx">       var stack = this.incrStack();
</span><span class="cx">       if (item) {
</span><del>-        this.source.push(stack + &quot; = &quot; + item + &quot;;&quot;);
</del><ins>+        this.pushSource(stack + &quot; = &quot; + item + &quot;;&quot;);
</ins><span class="cx">       }
</span><span class="cx">       this.compileStack.push(stack);
</span><span class="cx">       return stack;
</span><span class="lines">@@ -1869,7 +2468,9 @@
</span><span class="cx">     replaceStack: function(callback) {
</span><span class="cx">       var prefix = '',
</span><span class="cx">           inline = this.isInline(),
</span><del>-          stack;
</del><ins>+          stack,
+          createdStack,
+          usedLiteral;
</ins><span class="cx"> 
</span><span class="cx">       // If we are currently inline then we want to merge the inline statement into the
</span><span class="cx">       // replacement statement via ','
</span><span class="lines">@@ -1879,9 +2480,11 @@
</span><span class="cx">         if (top instanceof Literal) {
</span><span class="cx">           // Literals do not need to be inlined
</span><span class="cx">           stack = top.value;
</span><ins>+          usedLiteral = true;
</ins><span class="cx">         } else {
</span><span class="cx">           // Get or create the current stack name for use by the inline
</span><del>-          var name = this.stackSlot ? this.topStackName() : this.incrStack();
</del><ins>+          createdStack = !this.stackSlot;
+          var name = !createdStack ? this.topStackName() : this.incrStack();
</ins><span class="cx"> 
</span><span class="cx">           prefix = '(' + this.push(name) + ' = ' + top + '),';
</span><span class="cx">           stack = this.topStack();
</span><span class="lines">@@ -1893,9 +2496,12 @@
</span><span class="cx">       var item = callback.call(this, stack);
</span><span class="cx"> 
</span><span class="cx">       if (inline) {
</span><del>-        if (this.inlineStack.length || this.compileStack.length) {
</del><ins>+        if (!usedLiteral) {
</ins><span class="cx">           this.popStack();
</span><span class="cx">         }
</span><ins>+        if (createdStack) {
+          this.stackSlot--;
+        }
</ins><span class="cx">         this.push('(' + prefix + item + ')');
</span><span class="cx">       } else {
</span><span class="cx">         // Prevent modification of the context depth variable. Through replaceStack
</span><span class="lines">@@ -1903,7 +2509,7 @@
</span><span class="cx">           stack = this.nextStack();
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        this.source.push(stack + &quot; = (&quot; + prefix + item + &quot;);&quot;);
</del><ins>+        this.pushSource(stack + &quot; = (&quot; + prefix + item + &quot;);&quot;);
</ins><span class="cx">       }
</span><span class="cx">       return stack;
</span><span class="cx">     },
</span><span class="lines">@@ -1946,6 +2552,9 @@
</span><span class="cx">         return item.value;
</span><span class="cx">       } else {
</span><span class="cx">         if (!inline) {
</span><ins>+          if (!this.stackSlot) {
+            throw new Exception('Invalid stack pop');
+          }
</ins><span class="cx">           this.stackSlot--;
</span><span class="cx">         }
</span><span class="cx">         return item;
</span><span class="lines">@@ -1968,29 +2577,35 @@
</span><span class="cx">         .replace(/\\/g, '\\\\')
</span><span class="cx">         .replace(/&quot;/g, '\\&quot;')
</span><span class="cx">         .replace(/\n/g, '\\n')
</span><del>-        .replace(/\r/g, '\\r') + '&quot;';
</del><ins>+        .replace(/\r/g, '\\r')
+        .replace(/\u2028/g, '\\u2028')   // Per Ecma-262 7.3 + 7.8.4
+        .replace(/\u2029/g, '\\u2029') + '&quot;';
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     setupHelper: function(paramSize, name, missingParams) {
</span><del>-      var params = [];
-      this.setupParams(paramSize, params, missingParams);
</del><ins>+      var params = [],
+          paramsInit = this.setupParams(paramSize, params, missingParams);
</ins><span class="cx">       var foundHelper = this.nameLookup('helpers', name, 'helper');
</span><span class="cx"> 
</span><span class="cx">       return {
</span><span class="cx">         params: params,
</span><ins>+        paramsInit: paramsInit,
</ins><span class="cx">         name: foundHelper,
</span><span class="cx">         callParams: [&quot;depth0&quot;].concat(params).join(&quot;, &quot;),
</span><span class="cx">         helperMissingParams: missingParams &amp;&amp; [&quot;depth0&quot;, this.quotedString(name)].concat(params).join(&quot;, &quot;)
</span><span class="cx">       };
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    // the params and contexts arguments are passed in arrays
-    // to fill in
-    setupParams: function(paramSize, params, useRegister) {
</del><ins>+    setupOptions: function(paramSize, params) {
</ins><span class="cx">       var options = [], contexts = [], types = [], param, inverse, program;
</span><span class="cx"> 
</span><span class="cx">       options.push(&quot;hash:&quot; + this.popStack());
</span><span class="cx"> 
</span><ins>+      if (this.options.stringParams) {
+        options.push(&quot;hashTypes:&quot; + this.popStack());
+        options.push(&quot;hashContexts:&quot; + this.popStack());
+      }
+
</ins><span class="cx">       inverse = this.popStack();
</span><span class="cx">       program = this.popStack();
</span><span class="cx"> 
</span><span class="lines">@@ -2003,7 +2618,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (!inverse) {
</span><del>-         this.context.aliases.self = &quot;this&quot;;
</del><ins>+          this.context.aliases.self = &quot;this&quot;;
</ins><span class="cx">           inverse = &quot;self.noop&quot;;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2024,21 +2639,28 @@
</span><span class="cx">       if (this.options.stringParams) {
</span><span class="cx">         options.push(&quot;contexts:[&quot; + contexts.join(&quot;,&quot;) + &quot;]&quot;);
</span><span class="cx">         options.push(&quot;types:[&quot; + types.join(&quot;,&quot;) + &quot;]&quot;);
</span><del>-        options.push(&quot;hashTypes:hashTypes&quot;);
</del><span class="cx">       }
</span><span class="cx"> 
</span><span class="cx">       if(this.options.data) {
</span><span class="cx">         options.push(&quot;data:data&quot;);
</span><span class="cx">       }
</span><span class="cx"> 
</span><del>-      options = &quot;{&quot; + options.join(&quot;,&quot;) + &quot;}&quot;;
</del><ins>+      return options;
+    },
+
+    // the params and contexts arguments are passed in arrays
+    // to fill in
+    setupParams: function(paramSize, params, useRegister) {
+      var options = '{' + this.setupOptions(paramSize, params).join(',') + '}';
+
</ins><span class="cx">       if (useRegister) {
</span><del>-        this.register('options', options);
</del><ins>+        this.useRegister('options');
</ins><span class="cx">         params.push('options');
</span><ins>+        return 'options=' + options;
</ins><span class="cx">       } else {
</span><span class="cx">         params.push(options);
</span><ins>+        return '';
</ins><span class="cx">       }
</span><del>-      return params.join(&quot;, &quot;);
</del><span class="cx">     }
</span><span class="cx">   };
</span><span class="cx"> 
</span><span class="lines">@@ -2067,135 +2689,58 @@
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
</span><del>-    if(!JavaScriptCompiler.RESERVED_WORDS[name] &amp;&amp; /^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(name)) {
</del><ins>+    if(!JavaScriptCompiler.RESERVED_WORDS[name] &amp;&amp; /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) {
</ins><span class="cx">       return true;
</span><span class="cx">     }
</span><span class="cx">     return false;
</span><span class="cx">   };
</span><span class="cx"> 
</span><del>-})(Handlebars.Compiler, Handlebars.JavaScriptCompiler);
</del><ins>+  __exports__ = JavaScriptCompiler;
+  return __exports__;
+})(__module2__, __module5__);
</ins><span class="cx"> 
</span><del>-Handlebars.precompile = function(input, options) {
-  if (!input || (typeof input !== 'string' &amp;&amp; input.constructor !== Handlebars.AST.ProgramNode)) {
-    throw new Handlebars.Exception(&quot;You must pass a string or Handlebars AST to Handlebars.compile. You passed &quot; + input);
-  }
</del><ins>+// handlebars.js
+var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
+  &quot;use strict&quot;;
+  var __exports__;
+  /*globals Handlebars: true */
+  var Handlebars = __dependency1__;
</ins><span class="cx"> 
</span><del>-  options = options || {};
-  if (!('data' in options)) {
-    options.data = true;
-  }
-  var ast = Handlebars.parse(input);
-  var environment = new Handlebars.Compiler().compile(ast, options);
-  return new Handlebars.JavaScriptCompiler().compile(environment, options);
-};
</del><ins>+  // Compiler imports
+  var AST = __dependency2__;
+  var Parser = __dependency3__.parser;
+  var parse = __dependency3__.parse;
+  var Compiler = __dependency4__.Compiler;
+  var compile = __dependency4__.compile;
+  var precompile = __dependency4__.precompile;
+  var JavaScriptCompiler = __dependency5__;
</ins><span class="cx"> 
</span><del>-Handlebars.compile = function(input, options) {
-  if (!input || (typeof input !== 'string' &amp;&amp; input.constructor !== Handlebars.AST.ProgramNode)) {
-    throw new Handlebars.Exception(&quot;You must pass a string or Handlebars AST to Handlebars.compile. You passed &quot; + input);
-  }
</del><ins>+  var _create = Handlebars.create;
+  var create = function() {
+    var hb = _create();
</ins><span class="cx"> 
</span><del>-  options = options || {};
-  if (!('data' in options)) {
-    options.data = true;
-  }
-  var compiled;
-  function compile() {
-    var ast = Handlebars.parse(input);
-    var environment = new Handlebars.Compiler().compile(ast, options);
-    var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
-    return Handlebars.template(templateSpec);
-  }
-
-  // Template is only compiled on first use and cached after that point.
-  return function(context, options) {
-    if (!compiled) {
-      compiled = compile();
-    }
-    return compiled.call(this, context, options);
-  };
-};
-;
-// lib/handlebars/runtime.js
-Handlebars.VM = {
-  template: function(templateSpec) {
-    // Just add water
-    var container = {
-      escapeExpression: Handlebars.Utils.escapeExpression,
-      invokePartial: Handlebars.VM.invokePartial,
-      programs: [],
-      program: function(i, fn, data) {
-        var programWrapper = this.programs[i];
-        if(data) {
-          return Handlebars.VM.program(fn, data);
-        } else if(programWrapper) {
-          return programWrapper;
-        } else {
-          programWrapper = this.programs[i] = Handlebars.VM.program(fn);
-          return programWrapper;
-        }
-      },
-      programWithDepth: Handlebars.VM.programWithDepth,
-      noop: Handlebars.VM.noop,
-      compilerInfo: null
</del><ins>+    hb.compile = function(input, options) {
+      return compile(input, options, hb);
</ins><span class="cx">     };
</span><del>-
-    return function(context, options) {
-      options = options || {};
-      var result = templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
-
-      var compilerInfo = container.compilerInfo || [],
-          compilerRevision = compilerInfo[0] || 1,
-          currentRevision = Handlebars.COMPILER_REVISION;
-
-      if (compilerRevision !== currentRevision) {
-        if (compilerRevision &lt; currentRevision) {
-          var runtimeVersions = Handlebars.REVISION_CHANGES[currentRevision],
-              compilerVersions = Handlebars.REVISION_CHANGES[compilerRevision];
-          throw &quot;Template was precompiled with an older version of Handlebars than the current runtime. &quot;+
-                &quot;Please update your precompiler to a newer version (&quot;+runtimeVersions+&quot;) or downgrade your runtime to an older version (&quot;+compilerVersions+&quot;).&quot;;
-        } else {
-          // Use the embedded version info since the runtime doesn't know about this revision yet
-          throw &quot;Template was precompiled with a newer version of Handlebars than the current runtime. &quot;+
-                &quot;Please update your runtime to a newer version (&quot;+compilerInfo[1]+&quot;).&quot;;
-        }
-      }
-
-      return result;
</del><ins>+    hb.precompile = function (input, options) {
+      return precompile(input, options, hb);
</ins><span class="cx">     };
</span><del>-  },
</del><span class="cx"> 
</span><del>-  programWithDepth: function(fn, data, $depth) {
-    var args = Array.prototype.slice.call(arguments, 2);
</del><ins>+    hb.AST = AST;
+    hb.Compiler = Compiler;
+    hb.JavaScriptCompiler = JavaScriptCompiler;
+    hb.Parser = Parser;
+    hb.parse = parse;
</ins><span class="cx"> 
</span><del>-    return function(context, options) {
-      options = options || {};
</del><ins>+    return hb;
+  };
</ins><span class="cx"> 
</span><del>-      return fn.apply(this, [context, options.data || data].concat(args));
-    };
-  },
-  program: function(fn, data) {
-    return function(context, options) {
-      options = options || {};
</del><ins>+  Handlebars = create();
+  Handlebars.create = create;
</ins><span class="cx"> 
</span><del>-      return fn(context, options.data || data);
-    };
-  },
-  noop: function() { return &quot;&quot;; },
-  invokePartial: function(partial, name, context, helpers, partials, data) {
-    var options = { helpers: helpers, partials: partials, data: data };
</del><ins>+  __exports__ = Handlebars;
+  return __exports__;
+})(__module1__, __module7__, __module8__, __module10__, __module11__);
</ins><span class="cx"> 
</span><del>-    if(partial === undefined) {
-      throw new Handlebars.Exception(&quot;The partial &quot; + name + &quot; could not be found&quot;);
-    } else if(partial instanceof Function) {
-      return partial(context, options);
-    } else if (!Handlebars.compile) {
-      throw new Handlebars.Exception(&quot;The partial &quot; + name + &quot; could not be compiled when running in runtime-only mode&quot;);
-    } else {
-      partials[name] = Handlebars.compile(partial, {data: data !== undefined});
-      return partials[name](context, options);
-    }
-  }
-};
-
-Handlebars.template = Handlebars.VM.template;
-;
</del><ins>+  return __module0__;
+})();
</ins></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbower_componentsjqueryjqueryjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/jquery/jquery.js (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/jquery/jquery.js        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/jquery/jquery.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -1,795 +1,493 @@
</span><span class="cx"> /*!
</span><del>- * jQuery JavaScript Library v1.9.1
</del><ins>+ * jQuery JavaScript Library v2.1.0
</ins><span class="cx">  * http://jquery.com/
</span><span class="cx">  *
</span><span class="cx">  * Includes Sizzle.js
</span><span class="cx">  * http://sizzlejs.com/
</span><span class="cx">  *
</span><del>- * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors
</del><ins>+ * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
</ins><span class="cx">  * Released under the MIT license
</span><span class="cx">  * http://jquery.org/license
</span><span class="cx">  *
</span><del>- * Date: 2013-2-4
</del><ins>+ * Date: 2014-01-23T21:10Z
</ins><span class="cx">  */
</span><del>-(function( window, undefined ) {
</del><span class="cx"> 
</span><ins>+(function( global, factory ) {
+
+    if ( typeof module === &quot;object&quot; &amp;&amp; typeof module.exports === &quot;object&quot; ) {
+        // For CommonJS and CommonJS-like environments where a proper window is present,
+        // execute the factory and get jQuery
+        // For environments that do not inherently posses a window with a document
+        // (such as Node.js), expose a jQuery-making factory as module.exports
+        // This accentuates the need for the creation of a real window
+        // e.g. var jQuery = require(&quot;jquery&quot;)(window);
+        // See ticket #14549 for more info
+        module.exports = global.document ?
+            factory( global, true ) :
+            function( w ) {
+                if ( !w.document ) {
+                    throw new Error( &quot;jQuery requires a window with a document&quot; );
+                }
+                return factory( w );
+            };
+    } else {
+        factory( global );
+    }
+
+// Pass this if window is not defined yet
+}(typeof window !== &quot;undefined&quot; ? window : this, function( window, noGlobal ) {
+
</ins><span class="cx"> // Can't do this because several apps including ASP.NET trace
</span><span class="cx"> // the stack via arguments.caller.callee and Firefox dies if
</span><span class="cx"> // you try to trace through &quot;use strict&quot; call chains. (#13335)
</span><span class="cx"> // Support: Firefox 18+
</span><del>-//&quot;use strict&quot;;
-var
-    // The deferred used on DOM ready
-    readyList,
</del><ins>+//
</ins><span class="cx"> 
</span><del>-    // A central reference to the root jQuery(document)
-    rootjQuery,
</del><ins>+var arr = [];
</ins><span class="cx"> 
</span><del>-    // Support: IE&lt;9
-    // For `typeof node.method` instead of `node.method !== undefined`
-    core_strundefined = typeof undefined,
</del><ins>+var slice = arr.slice;
</ins><span class="cx"> 
</span><del>-    // Use the correct document accordingly with window argument (sandbox)
-    document = window.document,
-    location = window.location,
</del><ins>+var concat = arr.concat;
</ins><span class="cx"> 
</span><del>-    // Map over jQuery in case of overwrite
-    _jQuery = window.jQuery,
</del><ins>+var push = arr.push;
</ins><span class="cx"> 
</span><del>-    // Map over the $ in case of overwrite
-    _$ = window.$,
</del><ins>+var indexOf = arr.indexOf;
</ins><span class="cx"> 
</span><del>-    // [[Class]] -&gt; type pairs
-    class2type = {},
</del><ins>+var class2type = {};
</ins><span class="cx"> 
</span><del>-    // List of deleted data cache ids, so we can reuse them
-    core_deletedIds = [],
</del><ins>+var toString = class2type.toString;
</ins><span class="cx"> 
</span><del>-    core_version = &quot;1.9.1&quot;,
</del><ins>+var hasOwn = class2type.hasOwnProperty;
</ins><span class="cx"> 
</span><del>-    // Save a reference to some core methods
-    core_concat = core_deletedIds.concat,
-    core_push = core_deletedIds.push,
-    core_slice = core_deletedIds.slice,
-    core_indexOf = core_deletedIds.indexOf,
-    core_toString = class2type.toString,
-    core_hasOwn = class2type.hasOwnProperty,
-    core_trim = core_version.trim,
</del><ins>+var trim = &quot;&quot;.trim;
</ins><span class="cx"> 
</span><del>-    // Define a local copy of jQuery
-    jQuery = function( selector, context ) {
-    // The jQuery object is actually just the init constructor 'enhanced'
-    return new jQuery.fn.init( selector, context, rootjQuery );
-    },
</del><ins>+var support = {};
</ins><span class="cx"> 
</span><del>-    // Used for matching numbers
-    core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
</del><span class="cx"> 
</span><del>-    // Used for splitting on whitespace
-    core_rnotwhite = /\S+/g,
</del><span class="cx"> 
</span><del>-    // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
-    rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
</del><ins>+var
+    // Use the correct document accordingly with window argument (sandbox)
+    document = window.document,
</ins><span class="cx"> 
</span><del>-    // A simple way to check for HTML strings
-    // Prioritize #id over &lt;tag&gt; to avoid XSS via location.hash (#9521)
-    // Strict HTML recognition (#11290: must start with &lt;)
-    rquickExpr = /^(?:(&lt;[\w\W]+&gt;)[^&gt;]*|#([\w-]*))$/,
</del><ins>+    version = &quot;2.1.0&quot;,
</ins><span class="cx"> 
</span><del>-    // Match a standalone tag
-    rsingleTag = /^&lt;(\w+)\s*\/?&gt;(?:&lt;\/\1&gt;|)$/,
</del><ins>+    // Define a local copy of jQuery
+    jQuery = function( selector, context ) {
+        // The jQuery object is actually just the init constructor 'enhanced'
+        // Need init if jQuery is called (just allow error to be thrown if not included)
+        return new jQuery.fn.init( selector, context );
+    },
</ins><span class="cx"> 
</span><del>-    // JSON RegExp
-    rvalidchars = /^[\],:{}\s]*$/,
-    rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
-    rvalidescape = /\\(?:[&quot;\\\/bfnrt]|u[\da-fA-F]{4})/g,
-    rvalidtokens = /&quot;[^&quot;\\\r\n]*&quot;|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,
-
</del><span class="cx">     // Matches dashed string for camelizing
</span><span class="cx">     rmsPrefix = /^-ms-/,
</span><span class="cx">     rdashAlpha = /-([\da-z])/gi,
</span><span class="cx"> 
</span><span class="cx">     // Used by jQuery.camelCase as callback to replace()
</span><span class="cx">     fcamelCase = function( all, letter ) {
</span><del>-    return letter.toUpperCase();
-    },
-
-    // The ready event handler
-    completed = function( event ) {
-
-    // readyState === &quot;complete&quot; is good enough for us to call the dom ready in oldIE
-    if ( document.addEventListener || event.type === &quot;load&quot; || document.readyState === &quot;complete&quot; ) {
-    detach();
-    jQuery.ready();
-    }
-    },
-    // Clean-up method for dom ready events
-    detach = function() {
-    if ( document.addEventListener ) {
-    document.removeEventListener( &quot;DOMContentLoaded&quot;, completed, false );
-    window.removeEventListener( &quot;load&quot;, completed, false );
-
-    } else {
-    document.detachEvent( &quot;onreadystatechange&quot;, completed );
-    window.detachEvent( &quot;onload&quot;, completed );
-    }
</del><ins>+        return letter.toUpperCase();
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx"> jQuery.fn = jQuery.prototype = {
</span><span class="cx">     // The current version of jQuery being used
</span><del>-    jquery: core_version,
</del><ins>+    jquery: version,
</ins><span class="cx"> 
</span><span class="cx">     constructor: jQuery,
</span><del>-    init: function( selector, context, rootjQuery ) {
-    var match, elem;
</del><span class="cx"> 
</span><del>-    // HANDLE: $(&quot;&quot;), $(null), $(undefined), $(false)
-    if ( !selector ) {
-    return this;
-    }
-
-    // Handle HTML strings
-    if ( typeof selector === &quot;string&quot; ) {
-    if ( selector.charAt(0) === &quot;&lt;&quot; &amp;&amp; selector.charAt( selector.length - 1 ) === &quot;&gt;&quot; &amp;&amp; selector.length &gt;= 3 ) {
-    // Assume that strings that start and end with &lt;&gt; are HTML and skip the regex check
-    match = [ null, selector, null ];
-
-    } else {
-    match = rquickExpr.exec( selector );
-    }
-
-    // Match html or make sure no context is specified for #id
-    if ( match &amp;&amp; (match[1] || !context) ) {
-
-    // HANDLE: $(html) -&gt; $(array)
-    if ( match[1] ) {
-    context = context instanceof jQuery ? context[0] : context;
-
-    // scripts is true for back-compat
-    jQuery.merge( this, jQuery.parseHTML(
-    match[1],
-    context &amp;&amp; context.nodeType ? context.ownerDocument || context : document,
-    true
-    ) );
-
-    // HANDLE: $(html, props)
-    if ( rsingleTag.test( match[1] ) &amp;&amp; jQuery.isPlainObject( context ) ) {
-    for ( match in context ) {
-    // Properties of context are called as methods if possible
-    if ( jQuery.isFunction( this[ match ] ) ) {
-    this[ match ]( context[ match ] );
-
-    // ...and otherwise set as attributes
-    } else {
-    this.attr( match, context[ match ] );
-    }
-    }
-    }
-
-    return this;
-
-    // HANDLE: $(#id)
-    } else {
-    elem = document.getElementById( match[2] );
-
-    // Check parentNode to catch when Blackberry 4.6 returns
-    // nodes that are no longer in the document #6963
-    if ( elem &amp;&amp; elem.parentNode ) {
-    // Handle the case where IE and Opera return items
-    // by name instead of ID
-    if ( elem.id !== match[2] ) {
-    return rootjQuery.find( selector );
-    }
-
-    // Otherwise, we inject the element directly into the jQuery object
-    this.length = 1;
-    this[0] = elem;
-    }
-
-    this.context = document;
-    this.selector = selector;
-    return this;
-    }
-
-    // HANDLE: $(expr, $(...))
-    } else if ( !context || context.jquery ) {
-    return ( context || rootjQuery ).find( selector );
-
-    // HANDLE: $(expr, context)
-    // (which is just equivalent to: $(context).find(expr)
-    } else {
-    return this.constructor( context ).find( selector );
-    }
-
-    // HANDLE: $(DOMElement)
-    } else if ( selector.nodeType ) {
-    this.context = this[0] = selector;
-    this.length = 1;
-    return this;
-
-    // HANDLE: $(function)
-    // Shortcut for document ready
-    } else if ( jQuery.isFunction( selector ) ) {
-    return rootjQuery.ready( selector );
-    }
-
-    if ( selector.selector !== undefined ) {
-    this.selector = selector.selector;
-    this.context = selector.context;
-    }
-
-    return jQuery.makeArray( selector, this );
-    },
-
</del><span class="cx">     // Start with an empty selector
</span><span class="cx">     selector: &quot;&quot;,
</span><span class="cx"> 
</span><span class="cx">     // The default length of a jQuery object is 0
</span><span class="cx">     length: 0,
</span><span class="cx"> 
</span><del>-    // The number of elements contained in the matched element set
-    size: function() {
-    return this.length;
-    },
-
</del><span class="cx">     toArray: function() {
</span><del>-    return core_slice.call( this );
</del><ins>+        return slice.call( this );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // Get the Nth element in the matched element set OR
</span><span class="cx">     // Get the whole matched element set as a clean array
</span><span class="cx">     get: function( num ) {
</span><del>-    return num == null ?
</del><ins>+        return num != null ?
</ins><span class="cx"> 
</span><del>-    // Return a 'clean' array
-    this.toArray() :
</del><ins>+            // Return a 'clean' array
+            ( num &lt; 0 ? this[ num + this.length ] : this[ num ] ) :
</ins><span class="cx"> 
</span><del>-    // Return just the object
-    ( num &lt; 0 ? this[ this.length + num ] : this[ num ] );
</del><ins>+            // Return just the object
+            slice.call( this );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // Take an array of elements and push it onto the stack
</span><span class="cx">     // (returning the new matched element set)
</span><span class="cx">     pushStack: function( elems ) {
</span><span class="cx"> 
</span><del>-    // Build a new jQuery matched element set
-    var ret = jQuery.merge( this.constructor(), elems );
</del><ins>+        // Build a new jQuery matched element set
+        var ret = jQuery.merge( this.constructor(), elems );
</ins><span class="cx"> 
</span><del>-    // Add the old object onto the stack (as a reference)
-    ret.prevObject = this;
-    ret.context = this.context;
</del><ins>+        // Add the old object onto the stack (as a reference)
+        ret.prevObject = this;
+        ret.context = this.context;
</ins><span class="cx"> 
</span><del>-    // Return the newly-formed element set
-    return ret;
</del><ins>+        // Return the newly-formed element set
+        return ret;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // Execute a callback for every element in the matched set.
</span><span class="cx">     // (You can seed the arguments with an array of args, but this is
</span><span class="cx">     // only used internally.)
</span><span class="cx">     each: function( callback, args ) {
</span><del>-    return jQuery.each( this, callback, args );
</del><ins>+        return jQuery.each( this, callback, args );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    ready: function( fn ) {
-    // Add the callback
-    jQuery.ready.promise().done( fn );
-
-    return this;
</del><ins>+    map: function( callback ) {
+        return this.pushStack( jQuery.map(this, function( elem, i ) {
+            return callback.call( elem, i, elem );
+        }));
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     slice: function() {
</span><del>-    return this.pushStack( core_slice.apply( this, arguments ) );
</del><ins>+        return this.pushStack( slice.apply( this, arguments ) );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     first: function() {
</span><del>-    return this.eq( 0 );
</del><ins>+        return this.eq( 0 );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     last: function() {
</span><del>-    return this.eq( -1 );
</del><ins>+        return this.eq( -1 );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     eq: function( i ) {
</span><del>-    var len = this.length,
-    j = +i + ( i &lt; 0 ? len : 0 );
-    return this.pushStack( j &gt;= 0 &amp;&amp; j &lt; len ? [ this[j] ] : [] );
</del><ins>+        var len = this.length,
+            j = +i + ( i &lt; 0 ? len : 0 );
+        return this.pushStack( j &gt;= 0 &amp;&amp; j &lt; len ? [ this[j] ] : [] );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    map: function( callback ) {
-    return this.pushStack( jQuery.map(this, function( elem, i ) {
-    return callback.call( elem, i, elem );
-    }));
-    },
-
</del><span class="cx">     end: function() {
</span><del>-    return this.prevObject || this.constructor(null);
</del><ins>+        return this.prevObject || this.constructor(null);
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // For internal use only.
</span><span class="cx">     // Behaves like an Array's method, not like a jQuery method.
</span><del>-    push: core_push,
-    sort: [].sort,
-    splice: [].splice
</del><ins>+    push: push,
+    sort: arr.sort,
+    splice: arr.splice
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-// Give the init function the jQuery prototype for later instantiation
-jQuery.fn.init.prototype = jQuery.fn;
-
</del><span class="cx"> jQuery.extend = jQuery.fn.extend = function() {
</span><del>-    var src, copyIsArray, copy, name, options, clone,
-    target = arguments[0] || {},
-    i = 1,
-    length = arguments.length,
-    deep = false;
</del><ins>+    var options, name, src, copy, copyIsArray, clone,
+        target = arguments[0] || {},
+        i = 1,
+        length = arguments.length,
+        deep = false;
</ins><span class="cx"> 
</span><span class="cx">     // Handle a deep copy situation
</span><span class="cx">     if ( typeof target === &quot;boolean&quot; ) {
</span><del>-    deep = target;
-    target = arguments[1] || {};
-    // skip the boolean and the target
-    i = 2;
</del><ins>+        deep = target;
+
+        // skip the boolean and the target
+        target = arguments[ i ] || {};
+        i++;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Handle case when target is a string or something (possible in deep copy)
</span><span class="cx">     if ( typeof target !== &quot;object&quot; &amp;&amp; !jQuery.isFunction(target) ) {
</span><del>-    target = {};
</del><ins>+        target = {};
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // extend jQuery itself if only one argument is passed
</span><del>-    if ( length === i ) {
-    target = this;
-    --i;
</del><ins>+    if ( i === length ) {
+        target = this;
+        i--;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     for ( ; i &lt; length; i++ ) {
</span><del>-    // Only deal with non-null/undefined values
-    if ( (options = arguments[ i ]) != null ) {
-    // Extend the base object
-    for ( name in options ) {
-    src = target[ name ];
-    copy = options[ name ];
</del><ins>+        // Only deal with non-null/undefined values
+        if ( (options = arguments[ i ]) != null ) {
+            // Extend the base object
+            for ( name in options ) {
+                src = target[ name ];
+                copy = options[ name ];
</ins><span class="cx"> 
</span><del>-    // Prevent never-ending loop
-    if ( target === copy ) {
-    continue;
-    }
</del><ins>+                // Prevent never-ending loop
+                if ( target === copy ) {
+                    continue;
+                }
</ins><span class="cx"> 
</span><del>-    // Recurse if we're merging plain objects or arrays
-    if ( deep &amp;&amp; copy &amp;&amp; ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
-    if ( copyIsArray ) {
-    copyIsArray = false;
-    clone = src &amp;&amp; jQuery.isArray(src) ? src : [];
</del><ins>+                // Recurse if we're merging plain objects or arrays
+                if ( deep &amp;&amp; copy &amp;&amp; ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+                    if ( copyIsArray ) {
+                        copyIsArray = false;
+                        clone = src &amp;&amp; jQuery.isArray(src) ? src : [];
</ins><span class="cx"> 
</span><del>-    } else {
-    clone = src &amp;&amp; jQuery.isPlainObject(src) ? src : {};
-    }
</del><ins>+                    } else {
+                        clone = src &amp;&amp; jQuery.isPlainObject(src) ? src : {};
+                    }
</ins><span class="cx"> 
</span><del>-    // Never move original objects, clone them
-    target[ name ] = jQuery.extend( deep, clone, copy );
</del><ins>+                    // Never move original objects, clone them
+                    target[ name ] = jQuery.extend( deep, clone, copy );
</ins><span class="cx"> 
</span><del>-    // Don't bring in undefined values
-    } else if ( copy !== undefined ) {
-    target[ name ] = copy;
</del><ins>+                // Don't bring in undefined values
+                } else if ( copy !== undefined ) {
+                    target[ name ] = copy;
+                }
+            }
+        }
</ins><span class="cx">     }
</span><del>-    }
-    }
-    }
</del><span class="cx"> 
</span><span class="cx">     // Return the modified object
</span><span class="cx">     return target;
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> jQuery.extend({
</span><del>-    noConflict: function( deep ) {
-    if ( window.$ === jQuery ) {
-    window.$ = _$;
-    }
</del><ins>+    // Unique for each copy of jQuery on the page
+    expando: &quot;jQuery&quot; + ( version + Math.random() ).replace( /\D/g, &quot;&quot; ),
</ins><span class="cx"> 
</span><del>-    if ( deep &amp;&amp; window.jQuery === jQuery ) {
-    window.jQuery = _jQuery;
-    }
</del><ins>+    // Assume jQuery is ready without the ready module
+    isReady: true,
</ins><span class="cx"> 
</span><del>-    return jQuery;
</del><ins>+    error: function( msg ) {
+        throw new Error( msg );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    // Is the DOM ready to be used? Set to true once it occurs.
-    isReady: false,
</del><ins>+    noop: function() {},
</ins><span class="cx"> 
</span><del>-    // A counter to track how many items to wait for before
-    // the ready event fires. See #6781
-    readyWait: 1,
-
-    // Hold (or release) the ready event
-    holdReady: function( hold ) {
-    if ( hold ) {
-    jQuery.readyWait++;
-    } else {
-    jQuery.ready( true );
-    }
-    },
-
-    // Handle when the DOM is ready
-    ready: function( wait ) {
-
-    // Abort if there are pending holds or we're already ready
-    if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
-    return;
-    }
-
-    // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
-    if ( !document.body ) {
-    return setTimeout( jQuery.ready );
-    }
-
-    // Remember that the DOM is ready
-    jQuery.isReady = true;
-
-    // If a normal DOM Ready event fired, decrement, and wait if need be
-    if ( wait !== true &amp;&amp; --jQuery.readyWait &gt; 0 ) {
-    return;
-    }
-
-    // If there are functions bound, to execute
-    readyList.resolveWith( document, [ jQuery ] );
-
-    // Trigger any bound ready events
-    if ( jQuery.fn.trigger ) {
-    jQuery( document ).trigger(&quot;ready&quot;).off(&quot;ready&quot;);
-    }
-    },
-
</del><span class="cx">     // See test/unit/core.js for details concerning isFunction.
</span><span class="cx">     // Since version 1.3, DOM methods and functions like alert
</span><span class="cx">     // aren't supported. They return false on IE (#2968).
</span><span class="cx">     isFunction: function( obj ) {
</span><del>-    return jQuery.type(obj) === &quot;function&quot;;
</del><ins>+        return jQuery.type(obj) === &quot;function&quot;;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    isArray: Array.isArray || function( obj ) {
-    return jQuery.type(obj) === &quot;array&quot;;
-    },
</del><ins>+    isArray: Array.isArray,
</ins><span class="cx"> 
</span><span class="cx">     isWindow: function( obj ) {
</span><del>-    return obj != null &amp;&amp; obj == obj.window;
</del><ins>+        return obj != null &amp;&amp; obj === obj.window;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     isNumeric: function( obj ) {
</span><del>-    return !isNaN( parseFloat(obj) ) &amp;&amp; isFinite( obj );
</del><ins>+        // parseFloat NaNs numeric-cast false positives (null|true|false|&quot;&quot;)
+        // ...but misinterprets leading-number strings, particularly hex literals (&quot;0x...&quot;)
+        // subtraction forces infinities to NaN
+        return obj - parseFloat( obj ) &gt;= 0;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    type: function( obj ) {
-    if ( obj == null ) {
-    return String( obj );
-    }
-    return typeof obj === &quot;object&quot; || typeof obj === &quot;function&quot; ?
-    class2type[ core_toString.call(obj) ] || &quot;object&quot; :
-    typeof obj;
-    },
-
</del><span class="cx">     isPlainObject: function( obj ) {
</span><del>-    // Must be an Object.
-    // Because of IE, we also have to check the presence of the constructor property.
-    // Make sure that DOM nodes and window objects don't pass through, as well
-    if ( !obj || jQuery.type(obj) !== &quot;object&quot; || obj.nodeType || jQuery.isWindow( obj ) ) {
-    return false;
-    }
</del><ins>+        // Not plain objects:
+        // - Any object or value whose internal [[Class]] property is not &quot;[object Object]&quot;
+        // - DOM nodes
+        // - window
+        if ( jQuery.type( obj ) !== &quot;object&quot; || obj.nodeType || jQuery.isWindow( obj ) ) {
+            return false;
+        }
</ins><span class="cx"> 
</span><del>-    try {
-    // Not own constructor property must be Object
-    if ( obj.constructor &amp;&amp;
-    !core_hasOwn.call(obj, &quot;constructor&quot;) &amp;&amp;
-    !core_hasOwn.call(obj.constructor.prototype, &quot;isPrototypeOf&quot;) ) {
-    return false;
-    }
-    } catch ( e ) {
-    // IE8,9 Will throw exceptions on certain host objects #9897
-    return false;
-    }
</del><ins>+        // Support: Firefox &lt;20
+        // The try/catch suppresses exceptions thrown when attempting to access
+        // the &quot;constructor&quot; property of certain host objects, ie. |window.location|
+        // https://bugzilla.mozilla.org/show_bug.cgi?id=814622
+        try {
+            if ( obj.constructor &amp;&amp;
+                    !hasOwn.call( obj.constructor.prototype, &quot;isPrototypeOf&quot; ) ) {
+                return false;
+            }
+        } catch ( e ) {
+            return false;
+        }
</ins><span class="cx"> 
</span><del>-    // Own properties are enumerated firstly, so to speed up,
-    // if last one is own, then all properties are own.
-
-    var key;
-    for ( key in obj ) {}
-
-    return key === undefined || core_hasOwn.call( obj, key );
</del><ins>+        // If the function hasn't returned already, we're confident that
+        // |obj| is a plain object, created by {} or constructed with new Object
+        return true;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     isEmptyObject: function( obj ) {
</span><del>-    var name;
-    for ( name in obj ) {
-    return false;
-    }
-    return true;
</del><ins>+        var name;
+        for ( name in obj ) {
+            return false;
+        }
+        return true;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    error: function( msg ) {
-    throw new Error( msg );
</del><ins>+    type: function( obj ) {
+        if ( obj == null ) {
+            return obj + &quot;&quot;;
+        }
+        // Support: Android &lt; 4.0, iOS &lt; 6 (functionish RegExp)
+        return typeof obj === &quot;object&quot; || typeof obj === &quot;function&quot; ?
+            class2type[ toString.call(obj) ] || &quot;object&quot; :
+            typeof obj;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    // data: string of html
-    // context (optional): If specified, the fragment will be created in this context, defaults to document
-    // keepScripts (optional): If true, will include scripts passed in the html string
-    parseHTML: function( data, context, keepScripts ) {
-    if ( !data || typeof data !== &quot;string&quot; ) {
-    return null;
-    }
-    if ( typeof context === &quot;boolean&quot; ) {
-    keepScripts = context;
-    context = false;
-    }
-    context = context || document;
</del><ins>+    // Evaluates a script in a global context
+    globalEval: function( code ) {
+        var script,
+            indirect = eval;
</ins><span class="cx"> 
</span><del>-    var parsed = rsingleTag.exec( data ),
-    scripts = !keepScripts &amp;&amp; [];
</del><ins>+        code = jQuery.trim( code );
</ins><span class="cx"> 
</span><del>-    // Single tag
-    if ( parsed ) {
-    return [ context.createElement( parsed[1] ) ];
-    }
-
-    parsed = jQuery.buildFragment( [ data ], context, scripts );
-    if ( scripts ) {
-    jQuery( scripts ).remove();
-    }
-    return jQuery.merge( [], parsed.childNodes );
</del><ins>+        if ( code ) {
+            // If the code includes a valid, prologue position
+            // strict mode pragma, execute code by injecting a
+            // script tag into the document.
+            if ( code.indexOf(&quot;use strict&quot;) === 1 ) {
+                script = document.createElement(&quot;script&quot;);
+                script.text = code;
+                document.head.appendChild( script ).parentNode.removeChild( script );
+            } else {
+            // Otherwise, avoid the DOM node creation, insertion
+            // and removal by using an indirect global eval
+                indirect( code );
+            }
+        }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    parseJSON: function( data ) {
-    // Attempt to parse using the native JSON parser first
-    if ( window.JSON &amp;&amp; window.JSON.parse ) {
-    return window.JSON.parse( data );
-    }
-
-    if ( data === null ) {
-    return data;
-    }
-
-    if ( typeof data === &quot;string&quot; ) {
-
-    // Make sure leading/trailing whitespace is removed (IE can't handle it)
-    data = jQuery.trim( data );
-
-    if ( data ) {
-    // Make sure the incoming data is actual JSON
-    // Logic borrowed from http://json.org/json2.js
-    if ( rvalidchars.test( data.replace( rvalidescape, &quot;@&quot; )
-    .replace( rvalidtokens, &quot;]&quot; )
-    .replace( rvalidbraces, &quot;&quot;)) ) {
-
-    return ( new Function( &quot;return &quot; + data ) )();
-    }
-    }
-    }
-
-    jQuery.error( &quot;Invalid JSON: &quot; + data );
-    },
-
-    // Cross-browser xml parsing
-    parseXML: function( data ) {
-    var xml, tmp;
-    if ( !data || typeof data !== &quot;string&quot; ) {
-    return null;
-    }
-    try {
-    if ( window.DOMParser ) { // Standard
-    tmp = new DOMParser();
-    xml = tmp.parseFromString( data , &quot;text/xml&quot; );
-    } else { // IE
-    xml = new ActiveXObject( &quot;Microsoft.XMLDOM&quot; );
-    xml.async = &quot;false&quot;;
-    xml.loadXML( data );
-    }
-    } catch( e ) {
-    xml = undefined;
-    }
-    if ( !xml || !xml.documentElement || xml.getElementsByTagName( &quot;parsererror&quot; ).length ) {
-    jQuery.error( &quot;Invalid XML: &quot; + data );
-    }
-    return xml;
-    },
-
-    noop: function() {},
-
-    // Evaluates a script in a global context
-    // Workarounds based on findings by Jim Driscoll
-    // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
-    globalEval: function( data ) {
-    if ( data &amp;&amp; jQuery.trim( data ) ) {
-    // We use execScript on Internet Explorer
-    // We use an anonymous function so that context is window
-    // rather than jQuery in Firefox
-    ( window.execScript || function( data ) {
-    window[ &quot;eval&quot; ].call( window, data );
-    } )( data );
-    }
-    },
-
</del><span class="cx">     // Convert dashed to camelCase; used by the css and data modules
</span><span class="cx">     // Microsoft forgot to hump their vendor prefix (#9572)
</span><span class="cx">     camelCase: function( string ) {
</span><del>-    return string.replace( rmsPrefix, &quot;ms-&quot; ).replace( rdashAlpha, fcamelCase );
</del><ins>+        return string.replace( rmsPrefix, &quot;ms-&quot; ).replace( rdashAlpha, fcamelCase );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     nodeName: function( elem, name ) {
</span><del>-    return elem.nodeName &amp;&amp; elem.nodeName.toLowerCase() === name.toLowerCase();
</del><ins>+        return elem.nodeName &amp;&amp; elem.nodeName.toLowerCase() === name.toLowerCase();
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // args is for internal usage only
</span><span class="cx">     each: function( obj, callback, args ) {
</span><del>-    var value,
-    i = 0,
-    length = obj.length,
-    isArray = isArraylike( obj );
</del><ins>+        var value,
+            i = 0,
+            length = obj.length,
+            isArray = isArraylike( obj );
</ins><span class="cx"> 
</span><del>-    if ( args ) {
-    if ( isArray ) {
-    for ( ; i &lt; length; i++ ) {
-    value = callback.apply( obj[ i ], args );
</del><ins>+        if ( args ) {
+            if ( isArray ) {
+                for ( ; i &lt; length; i++ ) {
+                    value = callback.apply( obj[ i ], args );
</ins><span class="cx"> 
</span><del>-    if ( value === false ) {
-    break;
-    }
-    }
-    } else {
-    for ( i in obj ) {
-    value = callback.apply( obj[ i ], args );
</del><ins>+                    if ( value === false ) {
+                        break;
+                    }
+                }
+            } else {
+                for ( i in obj ) {
+                    value = callback.apply( obj[ i ], args );
</ins><span class="cx"> 
</span><del>-    if ( value === false ) {
-    break;
-    }
-    }
-    }
</del><ins>+                    if ( value === false ) {
+                        break;
+                    }
+                }
+            }
</ins><span class="cx"> 
</span><del>-    // A special, fast, case for the most common use of each
-    } else {
-    if ( isArray ) {
-    for ( ; i &lt; length; i++ ) {
-    value = callback.call( obj[ i ], i, obj[ i ] );
</del><ins>+        // A special, fast, case for the most common use of each
+        } else {
+            if ( isArray ) {
+                for ( ; i &lt; length; i++ ) {
+                    value = callback.call( obj[ i ], i, obj[ i ] );
</ins><span class="cx"> 
</span><del>-    if ( value === false ) {
-    break;
-    }
-    }
-    } else {
-    for ( i in obj ) {
-    value = callback.call( obj[ i ], i, obj[ i ] );
</del><ins>+                    if ( value === false ) {
+                        break;
+                    }
+                }
+            } else {
+                for ( i in obj ) {
+                    value = callback.call( obj[ i ], i, obj[ i ] );
</ins><span class="cx"> 
</span><del>-    if ( value === false ) {
-    break;
-    }
-    }
-    }
-    }
</del><ins>+                    if ( value === false ) {
+                        break;
+                    }
+                }
+            }
+        }
</ins><span class="cx"> 
</span><del>-    return obj;
</del><ins>+        return obj;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    // Use native String.trim function wherever possible
-    trim: core_trim &amp;&amp; !core_trim.call(&quot;\uFEFF\xA0&quot;) ?
-    function( text ) {
-    return text == null ?
-    &quot;&quot; :
-    core_trim.call( text );
-    } :
-
-    // Otherwise use our own trimming functionality
-    function( text ) {
-    return text == null ?
-    &quot;&quot; :
-    ( text + &quot;&quot; ).replace( rtrim, &quot;&quot; );
</del><ins>+    trim: function( text ) {
+        return text == null ? &quot;&quot; : trim.call( text );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // results is for internal usage only
</span><span class="cx">     makeArray: function( arr, results ) {
</span><del>-    var ret = results || [];
</del><ins>+        var ret = results || [];
</ins><span class="cx"> 
</span><del>-    if ( arr != null ) {
-    if ( isArraylike( Object(arr) ) ) {
-    jQuery.merge( ret,
-    typeof arr === &quot;string&quot; ?
-    [ arr ] : arr
-    );
-    } else {
-    core_push.call( ret, arr );
-    }
-    }
</del><ins>+        if ( arr != null ) {
+            if ( isArraylike( Object(arr) ) ) {
+                jQuery.merge( ret,
+                    typeof arr === &quot;string&quot; ?
+                    [ arr ] : arr
+                );
+            } else {
+                push.call( ret, arr );
+            }
+        }
</ins><span class="cx"> 
</span><del>-    return ret;
</del><ins>+        return ret;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     inArray: function( elem, arr, i ) {
</span><del>-    var len;
-
-    if ( arr ) {
-    if ( core_indexOf ) {
-    return core_indexOf.call( arr, elem, i );
-    }
-
-    len = arr.length;
-    i = i ? i &lt; 0 ? Math.max( 0, len + i ) : i : 0;
-
-    for ( ; i &lt; len; i++ ) {
-    // Skip accessing in sparse arrays
-    if ( i in arr &amp;&amp; arr[ i ] === elem ) {
-    return i;
-    }
-    }
-    }
-
-    return -1;
</del><ins>+        return arr == null ? -1 : indexOf.call( arr, elem, i );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     merge: function( first, second ) {
</span><del>-    var l = second.length,
-    i = first.length,
-    j = 0;
</del><ins>+        var len = +second.length,
+            j = 0,
+            i = first.length;
</ins><span class="cx"> 
</span><del>-    if ( typeof l === &quot;number&quot; ) {
-    for ( ; j &lt; l; j++ ) {
-    first[ i++ ] = second[ j ];
-    }
-    } else {
-    while ( second[j] !== undefined ) {
-    first[ i++ ] = second[ j++ ];
-    }
-    }
</del><ins>+        for ( ; j &lt; len; j++ ) {
+            first[ i++ ] = second[ j ];
+        }
</ins><span class="cx"> 
</span><del>-    first.length = i;
</del><ins>+        first.length = i;
</ins><span class="cx"> 
</span><del>-    return first;
</del><ins>+        return first;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    grep: function( elems, callback, inv ) {
-    var retVal,
-    ret = [],
-    i = 0,
-    length = elems.length;
-    inv = !!inv;
</del><ins>+    grep: function( elems, callback, invert ) {
+        var callbackInverse,
+            matches = [],
+            i = 0,
+            length = elems.length,
+            callbackExpect = !invert;
</ins><span class="cx"> 
</span><del>-    // Go through the array, only saving the items
-    // that pass the validator function
-    for ( ; i &lt; length; i++ ) {
-    retVal = !!callback( elems[ i ], i );
-    if ( inv !== retVal ) {
-    ret.push( elems[ i ] );
-    }
-    }
</del><ins>+        // Go through the array, only saving the items
+        // that pass the validator function
+        for ( ; i &lt; length; i++ ) {
+            callbackInverse = !callback( elems[ i ], i );
+            if ( callbackInverse !== callbackExpect ) {
+                matches.push( elems[ i ] );
+            }
+        }
</ins><span class="cx"> 
</span><del>-    return ret;
</del><ins>+        return matches;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // arg is for internal usage only
</span><span class="cx">     map: function( elems, callback, arg ) {
</span><del>-    var value,
-    i = 0,
-    length = elems.length,
-    isArray = isArraylike( elems ),
-    ret = [];
</del><ins>+        var value,
+            i = 0,
+            length = elems.length,
+            isArray = isArraylike( elems ),
+            ret = [];
</ins><span class="cx"> 
</span><del>-    // Go through the array, translating each of the items to their
-    if ( isArray ) {
-    for ( ; i &lt; length; i++ ) {
-    value = callback( elems[ i ], i, arg );
</del><ins>+        // Go through the array, translating each of the items to their new values
+        if ( isArray ) {
+            for ( ; i &lt; length; i++ ) {
+                value = callback( elems[ i ], i, arg );
</ins><span class="cx"> 
</span><del>-    if ( value != null ) {
-    ret[ ret.length ] = value;
-    }
-    }
</del><ins>+                if ( value != null ) {
+                    ret.push( value );
+                }
+            }
</ins><span class="cx"> 
</span><del>-    // Go through every key on the object,
-    } else {
-    for ( i in elems ) {
-    value = callback( elems[ i ], i, arg );
</del><ins>+        // Go through every key on the object,
+        } else {
+            for ( i in elems ) {
+                value = callback( elems[ i ], i, arg );
</ins><span class="cx"> 
</span><del>-    if ( value != null ) {
-    ret[ ret.length ] = value;
-    }
-    }
-    }
</del><ins>+                if ( value != null ) {
+                    ret.push( value );
+                }
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // Flatten any nested arrays
-    return core_concat.apply( [], ret );
</del><ins>+        // Flatten any nested arrays
+        return concat.apply( [], ret );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // A global GUID counter for objects
</span><span class="lines">@@ -798,6634 +496,6975 @@
</span><span class="cx">     // Bind a function to a context, optionally partially applying any
</span><span class="cx">     // arguments.
</span><span class="cx">     proxy: function( fn, context ) {
</span><del>-    var args, proxy, tmp;
</del><ins>+        var tmp, args, proxy;
</ins><span class="cx"> 
</span><del>-    if ( typeof context === &quot;string&quot; ) {
-    tmp = fn[ context ];
-    context = fn;
-    fn = tmp;
-    }
</del><ins>+        if ( typeof context === &quot;string&quot; ) {
+            tmp = fn[ context ];
+            context = fn;
+            fn = tmp;
+        }
</ins><span class="cx"> 
</span><del>-    // Quick check to determine if target is callable, in the spec
-    // this throws a TypeError, but we will just return undefined.
-    if ( !jQuery.isFunction( fn ) ) {
-    return undefined;
-    }
</del><ins>+        // Quick check to determine if target is callable, in the spec
+        // this throws a TypeError, but we will just return undefined.
+        if ( !jQuery.isFunction( fn ) ) {
+            return undefined;
+        }
</ins><span class="cx"> 
</span><del>-    // Simulated bind
-    args = core_slice.call( arguments, 2 );
-    proxy = function() {
-    return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
-    };
</del><ins>+        // Simulated bind
+        args = slice.call( arguments, 2 );
+        proxy = function() {
+            return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
+        };
</ins><span class="cx"> 
</span><del>-    // Set the guid of unique handler to the same of original handler, so it can be removed
-    proxy.guid = fn.guid = fn.guid || jQuery.guid++;
</del><ins>+        // Set the guid of unique handler to the same of original handler, so it can be removed
+        proxy.guid = fn.guid = fn.guid || jQuery.guid++;
</ins><span class="cx"> 
</span><del>-    return proxy;
</del><ins>+        return proxy;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    // Multifunctional method to get and set values of a collection
-    // The value/s can optionally be executed if it's a function
-    access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
-    var i = 0,
-    length = elems.length,
-    bulk = key == null;
</del><ins>+    now: Date.now,
</ins><span class="cx"> 
</span><del>-    // Sets many values
-    if ( jQuery.type( key ) === &quot;object&quot; ) {
-    chainable = true;
-    for ( i in key ) {
-    jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
-    }
</del><ins>+    // jQuery.support is not used in Core but other projects attach their
+    // properties to it so it needs to exist.
+    support: support
+});
</ins><span class="cx"> 
</span><del>-    // Sets one value
-    } else if ( value !== undefined ) {
-    chainable = true;
</del><ins>+// Populate the class2type map
+jQuery.each(&quot;Boolean Number String Function Array Date RegExp Object Error&quot;.split(&quot; &quot;), function(i, name) {
+    class2type[ &quot;[object &quot; + name + &quot;]&quot; ] = name.toLowerCase();
+});
</ins><span class="cx"> 
</span><del>-    if ( !jQuery.isFunction( value ) ) {
-    raw = true;
-    }
</del><ins>+function isArraylike( obj ) {
+    var length = obj.length,
+        type = jQuery.type( obj );
</ins><span class="cx"> 
</span><del>-    if ( bulk ) {
-    // Bulk operations run against the entire set
-    if ( raw ) {
-    fn.call( elems, value );
-    fn = null;
-
-    // ...except when executing function values
-    } else {
-    bulk = fn;
-    fn = function( elem, key, value ) {
-    return bulk.call( jQuery( elem ), value );
-    };
</del><ins>+    if ( type === &quot;function&quot; || jQuery.isWindow( obj ) ) {
+        return false;
</ins><span class="cx">     }
</span><del>-    }
</del><span class="cx"> 
</span><del>-    if ( fn ) {
-    for ( ; i &lt; length; i++ ) {
-    fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
</del><ins>+    if ( obj.nodeType === 1 &amp;&amp; length ) {
+        return true;
</ins><span class="cx">     }
</span><del>-    }
-    }
</del><span class="cx"> 
</span><del>-    return chainable ?
-    elems :
</del><ins>+    return type === &quot;array&quot; || length === 0 ||
+        typeof length === &quot;number&quot; &amp;&amp; length &gt; 0 &amp;&amp; ( length - 1 ) in obj;
+}
+var Sizzle =
+/*!
+ * Sizzle CSS Selector Engine v1.10.16
+ * http://sizzlejs.com/
+ *
+ * Copyright 2013 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2014-01-13
+ */
+(function( window ) {
</ins><span class="cx"> 
</span><del>-    // Gets
-    bulk ?
-    fn.call( elems ) :
-    length ? fn( elems[0], key ) : emptyGet;
</del><ins>+var i,
+    support,
+    Expr,
+    getText,
+    isXML,
+    compile,
+    outermostContext,
+    sortInput,
+    hasDuplicate,
+
+    // Local document vars
+    setDocument,
+    document,
+    docElem,
+    documentIsHTML,
+    rbuggyQSA,
+    rbuggyMatches,
+    matches,
+    contains,
+
+    // Instance-specific data
+    expando = &quot;sizzle&quot; + -(new Date()),
+    preferredDoc = window.document,
+    dirruns = 0,
+    done = 0,
+    classCache = createCache(),
+    tokenCache = createCache(),
+    compilerCache = createCache(),
+    sortOrder = function( a, b ) {
+        if ( a === b ) {
+            hasDuplicate = true;
+        }
+        return 0;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    now: function() {
-    return ( new Date() ).getTime();
-    }
-});
</del><ins>+    // General-purpose constants
+    strundefined = typeof undefined,
+    MAX_NEGATIVE = 1 &lt;&lt; 31,
</ins><span class="cx"> 
</span><del>-jQuery.ready.promise = function( obj ) {
-    if ( !readyList ) {
</del><ins>+    // Instance methods
+    hasOwn = ({}).hasOwnProperty,
+    arr = [],
+    pop = arr.pop,
+    push_native = arr.push,
+    push = arr.push,
+    slice = arr.slice,
+    // Use a stripped-down indexOf if we can't use a native one
+    indexOf = arr.indexOf || function( elem ) {
+        var i = 0,
+            len = this.length;
+        for ( ; i &lt; len; i++ ) {
+            if ( this[i] === elem ) {
+                return i;
+            }
+        }
+        return -1;
+    },
</ins><span class="cx"> 
</span><del>-    readyList = jQuery.Deferred();
</del><ins>+    booleans = &quot;checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped&quot;,
</ins><span class="cx"> 
</span><del>-    // Catch cases where $(document).ready() is called after the browser event has already occurred.
-    // we once tried to use readyState &quot;interactive&quot; here, but it caused issues like the one
-    // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
-    if ( document.readyState === &quot;complete&quot; ) {
-    // Handle it asynchronously to allow scripts the opportunity to delay ready
-    setTimeout( jQuery.ready );
</del><ins>+    // Regular expressions
</ins><span class="cx"> 
</span><del>-    // Standards-based browsers support DOMContentLoaded
-    } else if ( document.addEventListener ) {
-    // Use the handy event callback
-    document.addEventListener( &quot;DOMContentLoaded&quot;, completed, false );
</del><ins>+    // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+    whitespace = &quot;[\\x20\\t\\r\\n\\f]&quot;,
+    // http://www.w3.org/TR/css3-syntax/#characters
+    characterEncoding = &quot;(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+&quot;,
</ins><span class="cx"> 
</span><del>-    // A fallback to window.onload, that will always work
-    window.addEventListener( &quot;load&quot;, completed, false );
</del><ins>+    // Loosely modeled on CSS identifier characters
+    // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
+    // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+    identifier = characterEncoding.replace( &quot;w&quot;, &quot;w#&quot; ),
</ins><span class="cx"> 
</span><del>-    // If IE event model is used
-    } else {
-    // Ensure firing before onload, maybe late but safe also for iframes
-    document.attachEvent( &quot;onreadystatechange&quot;, completed );
</del><ins>+    // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
+    attributes = &quot;\\[&quot; + whitespace + &quot;*(&quot; + characterEncoding + &quot;)&quot; + whitespace +
+        &quot;*(?:([*^$|!~]?=)&quot; + whitespace + &quot;*(?:(['\&quot;])((?:\\\\.|[^\\\\])*?)\\3|(&quot; + identifier + &quot;)|)|)&quot; + whitespace + &quot;*\\]&quot;,
</ins><span class="cx"> 
</span><del>-    // A fallback to window.onload, that will always work
-    window.attachEvent( &quot;onload&quot;, completed );
</del><ins>+    // Prefer arguments quoted,
+    //   then not containing pseudos/brackets,
+    //   then attribute selectors/non-parenthetical expressions,
+    //   then anything else
+    // These preferences are here to reduce the number of selectors
+    //   needing tokenize in the PSEUDO preFilter
+    pseudos = &quot;:(&quot; + characterEncoding + &quot;)(?:\\(((['\&quot;])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|&quot; + attributes.replace( 3, 8 ) + &quot;)*)|.*)\\)|)&quot;,
</ins><span class="cx"> 
</span><del>-    // If IE and not a frame
-    // continually check to see if the document is ready
-    var top = false;
</del><ins>+    // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+    rtrim = new RegExp( &quot;^&quot; + whitespace + &quot;+|((?:^|[^\\\\])(?:\\\\.)*)&quot; + whitespace + &quot;+$&quot;, &quot;g&quot; ),
</ins><span class="cx"> 
</span><del>-    try {
-    top = window.frameElement == null &amp;&amp; document.documentElement;
-    } catch(e) {}
</del><ins>+    rcomma = new RegExp( &quot;^&quot; + whitespace + &quot;*,&quot; + whitespace + &quot;*&quot; ),
+    rcombinators = new RegExp( &quot;^&quot; + whitespace + &quot;*([&gt;+~]|&quot; + whitespace + &quot;)&quot; + whitespace + &quot;*&quot; ),
</ins><span class="cx"> 
</span><del>-    if ( top &amp;&amp; top.doScroll ) {
-    (function doScrollCheck() {
-    if ( !jQuery.isReady ) {
</del><ins>+    rattributeQuotes = new RegExp( &quot;=&quot; + whitespace + &quot;*([^\\]'\&quot;]*?)&quot; + whitespace + &quot;*\\]&quot;, &quot;g&quot; ),
</ins><span class="cx"> 
</span><del>-    try {
-    // Use the trick by Diego Perini
-    // http://javascript.nwbox.com/IEContentLoaded/
-    top.doScroll(&quot;left&quot;);
-    } catch(e) {
-    return setTimeout( doScrollCheck, 50 );
-    }
</del><ins>+    rpseudo = new RegExp( pseudos ),
+    ridentifier = new RegExp( &quot;^&quot; + identifier + &quot;$&quot; ),
</ins><span class="cx"> 
</span><del>-    // detach all dom ready events
-    detach();
</del><ins>+    matchExpr = {
+        &quot;ID&quot;: new RegExp( &quot;^#(&quot; + characterEncoding + &quot;)&quot; ),
+        &quot;CLASS&quot;: new RegExp( &quot;^\\.(&quot; + characterEncoding + &quot;)&quot; ),
+        &quot;TAG&quot;: new RegExp( &quot;^(&quot; + characterEncoding.replace( &quot;w&quot;, &quot;w*&quot; ) + &quot;)&quot; ),
+        &quot;ATTR&quot;: new RegExp( &quot;^&quot; + attributes ),
+        &quot;PSEUDO&quot;: new RegExp( &quot;^&quot; + pseudos ),
+        &quot;CHILD&quot;: new RegExp( &quot;^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(&quot; + whitespace +
+            &quot;*(even|odd|(([+-]|)(\\d*)n|)&quot; + whitespace + &quot;*(?:([+-]|)&quot; + whitespace +
+            &quot;*(\\d+)|))&quot; + whitespace + &quot;*\\)|)&quot;, &quot;i&quot; ),
+        &quot;bool&quot;: new RegExp( &quot;^(?:&quot; + booleans + &quot;)$&quot;, &quot;i&quot; ),
+        // For use in libraries implementing .is()
+        // We use this for POS matching in `select`
+        &quot;needsContext&quot;: new RegExp( &quot;^&quot; + whitespace + &quot;*[&gt;+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(&quot; +
+            whitespace + &quot;*((?:-\\d)?\\d*)&quot; + whitespace + &quot;*\\)|)(?=[^-]|$)&quot;, &quot;i&quot; )
+    },
</ins><span class="cx"> 
</span><del>-    // and execute any waiting functions
-    jQuery.ready();
-    }
-    })();
-    }
-    }
-    }
-    return readyList.promise( obj );
-};
</del><ins>+    rinputs = /^(?:input|select|textarea|button)$/i,
+    rheader = /^h\d$/i,
</ins><span class="cx"> 
</span><del>-// Populate the class2type map
-jQuery.each(&quot;Boolean Number String Function Array Date RegExp Object Error&quot;.split(&quot; &quot;), function(i, name) {
-    class2type[ &quot;[object &quot; + name + &quot;]&quot; ] = name.toLowerCase();
-});
</del><ins>+    rnative = /^[^{]+\{\s*\[native \w/,
</ins><span class="cx"> 
</span><del>-function isArraylike( obj ) {
-    var length = obj.length,
-    type = jQuery.type( obj );
</del><ins>+    // Easily-parseable/retrievable ID or TAG or CLASS selectors
+    rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
</ins><span class="cx"> 
</span><del>-    if ( jQuery.isWindow( obj ) ) {
-    return false;
-    }
</del><ins>+    rsibling = /[+~]/,
+    rescape = /'|\\/g,
</ins><span class="cx"> 
</span><del>-    if ( obj.nodeType === 1 &amp;&amp; length ) {
-    return true;
-    }
</del><ins>+    // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+    runescape = new RegExp( &quot;\\\\([\\da-f]{1,6}&quot; + whitespace + &quot;?|(&quot; + whitespace + &quot;)|.)&quot;, &quot;ig&quot; ),
+    funescape = function( _, escaped, escapedWhitespace ) {
+        var high = &quot;0x&quot; + escaped - 0x10000;
+        // NaN means non-codepoint
+        // Support: Firefox
+        // Workaround erroneous numeric interpretation of +&quot;0x&quot;
+        return high !== high || escapedWhitespace ?
+            escaped :
+            high &lt; 0 ?
+                // BMP codepoint
+                String.fromCharCode( high + 0x10000 ) :
+                // Supplemental Plane codepoint (surrogate pair)
+                String.fromCharCode( high &gt;&gt; 10 | 0xD800, high &amp; 0x3FF | 0xDC00 );
+    };
</ins><span class="cx"> 
</span><del>-    return type === &quot;array&quot; || type !== &quot;function&quot; &amp;&amp;
-    ( length === 0 ||
-    typeof length === &quot;number&quot; &amp;&amp; length &gt; 0 &amp;&amp; ( length - 1 ) in obj );
-}
</del><ins>+// Optimize for push.apply( _, NodeList )
+try {
+    push.apply(
+        (arr = slice.call( preferredDoc.childNodes )),
+        preferredDoc.childNodes
+    );
+    // Support: Android&lt;4.0
+    // Detect silently failing push.apply
+    arr[ preferredDoc.childNodes.length ].nodeType;
+} catch ( e ) {
+    push = { apply: arr.length ?
</ins><span class="cx"> 
</span><del>-// All jQuery objects should point back to these
-rootjQuery = jQuery(document);
-// String to Object options format cache
-var optionsCache = {};
</del><ins>+        // Leverage slice if possible
+        function( target, els ) {
+            push_native.apply( target, slice.call(els) );
+        } :
</ins><span class="cx"> 
</span><del>-// Convert String-formatted options into Object-formatted ones and store in cache
-function createOptions( options ) {
-    var object = optionsCache[ options ] = {};
-    jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
-    object[ flag ] = true;
-    });
-    return object;
</del><ins>+        // Support: IE&lt;9
+        // Otherwise append directly
+        function( target, els ) {
+            var j = target.length,
+                i = 0;
+            // Can't trust NodeList.length
+            while ( (target[j++] = els[i++]) ) {}
+            target.length = j - 1;
+        }
+    };
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-/*
- * Create a callback list using the following parameters:
- *
- *    options: an optional list of space-separated options that will change how
- *            the callback list behaves or a more traditional option object
- *
- * By default a callback list will act like an event callback list and can be
- * &quot;fired&quot; multiple times.
- *
- * Possible options:
- *
- *    once:            will ensure the callback list can only be fired once (like a Deferred)
- *
- *    memory:            will keep track of previous values and will call any callback added
- *                    after the list has been fired right away with the latest &quot;memorized&quot;
- *                    values (like a Deferred)
- *
- *    unique:            will ensure a callback can only be added once (no duplicate in the list)
- *
- *    stopOnFalse:    interrupt callings when a callback returns false
- *
- */
-jQuery.Callbacks = function( options ) {
</del><ins>+function Sizzle( selector, context, results, seed ) {
+    var match, elem, m, nodeType,
+        // QSA vars
+        i, groups, old, nid, newContext, newSelector;
</ins><span class="cx"> 
</span><del>-    // Convert options from String-formatted to Object-formatted if needed
-    // (we check in cache first)
-    options = typeof options === &quot;string&quot; ?
-    ( optionsCache[ options ] || createOptions( options ) ) :
-    jQuery.extend( {}, options );
-
-    var // Flag to know if list is currently firing
-    firing,
-    // Last fire value (for non-forgettable lists)
-    memory,
-    // Flag to know if list was already fired
-    fired,
-    // End of the loop when firing
-    firingLength,
-    // Index of currently firing callback (modified by remove if needed)
-    firingIndex,
-    // First callback to fire (used internally by add and fireWith)
-    firingStart,
-    // Actual callback list
-    list = [],
-    // Stack of fire calls for repeatable lists
-    stack = !options.once &amp;&amp; [],
-    // Fire callbacks
-    fire = function( data ) {
-    memory = options.memory &amp;&amp; data;
-    fired = true;
-    firingIndex = firingStart || 0;
-    firingStart = 0;
-    firingLength = list.length;
-    firing = true;
-    for ( ; list &amp;&amp; firingIndex &lt; firingLength; firingIndex++ ) {
-    if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false &amp;&amp; options.stopOnFalse ) {
-    memory = false; // To prevent further calls using add
-    break;
</del><ins>+    if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+        setDocument( context );
</ins><span class="cx">     }
</span><del>-    }
-    firing = false;
-    if ( list ) {
-    if ( stack ) {
-    if ( stack.length ) {
-    fire( stack.shift() );
-    }
-    } else if ( memory ) {
-    list = [];
-    } else {
-    self.disable();
-    }
-    }
-    },
-    // Actual Callbacks object
-    self = {
-    // Add a callback or a collection of callbacks to the list
-    add: function() {
-    if ( list ) {
-    // First, we save the current length
-    var start = list.length;
-    (function add( args ) {
-    jQuery.each( args, function( _, arg ) {
-    var type = jQuery.type( arg );
-    if ( type === &quot;function&quot; ) {
-    if ( !options.unique || !self.has( arg ) ) {
-    list.push( arg );
-    }
-    } else if ( arg &amp;&amp; arg.length &amp;&amp; type !== &quot;string&quot; ) {
-    // Inspect recursively
-    add( arg );
-    }
-    });
-    })( arguments );
-    // Do we need to add the callbacks to the
-    // current firing batch?
-    if ( firing ) {
-    firingLength = list.length;
-    // With memory, if we're not firing then
-    // we should call right away
-    } else if ( memory ) {
-    firingStart = start;
-    fire( memory );
-    }
-    }
-    return this;
-    },
-    // Remove a callback from the list
-    remove: function() {
-    if ( list ) {
-    jQuery.each( arguments, function( _, arg ) {
-    var index;
-    while( ( index = jQuery.inArray( arg, list, index ) ) &gt; -1 ) {
-    list.splice( index, 1 );
-    // Handle firing indexes
-    if ( firing ) {
-    if ( index &lt;= firingLength ) {
-    firingLength--;
-    }
-    if ( index &lt;= firingIndex ) {
-    firingIndex--;
-    }
-    }
-    }
-    });
-    }
-    return this;
-    },
-    // Check if a given callback is in the list.
-    // If no argument is given, return whether or not list has callbacks attached.
-    has: function( fn ) {
-    return fn ? jQuery.inArray( fn, list ) &gt; -1 : !!( list &amp;&amp; list.length );
-    },
-    // Remove all callbacks from the list
-    empty: function() {
-    list = [];
-    return this;
-    },
-    // Have the list do nothing anymore
-    disable: function() {
-    list = stack = memory = undefined;
-    return this;
-    },
-    // Is it disabled?
-    disabled: function() {
-    return !list;
-    },
-    // Lock the list in its current state
-    lock: function() {
-    stack = undefined;
-    if ( !memory ) {
-    self.disable();
-    }
-    return this;
-    },
-    // Is it locked?
-    locked: function() {
-    return !stack;
-    },
-    // Call all callbacks with the given context and arguments
-    fireWith: function( context, args ) {
-    args = args || [];
-    args = [ context, args.slice ? args.slice() : args ];
-    if ( list &amp;&amp; ( !fired || stack ) ) {
-    if ( firing ) {
-    stack.push( args );
-    } else {
-    fire( args );
-    }
-    }
-    return this;
-    },
-    // Call all the callbacks with the given arguments
-    fire: function() {
-    self.fireWith( this, arguments );
-    return this;
-    },
-    // To know if the callbacks have already been called at least once
-    fired: function() {
-    return !!fired;
-    }
-    };
</del><span class="cx"> 
</span><del>-    return self;
-};
-jQuery.extend({
</del><ins>+    context = context || document;
+    results = results || [];
</ins><span class="cx"> 
</span><del>-    Deferred: function( func ) {
-    var tuples = [
-    // action, add listener, listener list, final state
-    [ &quot;resolve&quot;, &quot;done&quot;, jQuery.Callbacks(&quot;once memory&quot;), &quot;resolved&quot; ],
-    [ &quot;reject&quot;, &quot;fail&quot;, jQuery.Callbacks(&quot;once memory&quot;), &quot;rejected&quot; ],
-    [ &quot;notify&quot;, &quot;progress&quot;, jQuery.Callbacks(&quot;memory&quot;) ]
-    ],
-    state = &quot;pending&quot;,
-    promise = {
-    state: function() {
-    return state;
-    },
-    always: function() {
-    deferred.done( arguments ).fail( arguments );
-    return this;
-    },
-    then: function( /* fnDone, fnFail, fnProgress */ ) {
-    var fns = arguments;
-    return jQuery.Deferred(function( newDefer ) {
-    jQuery.each( tuples, function( i, tuple ) {
-    var action = tuple[ 0 ],
-    fn = jQuery.isFunction( fns[ i ] ) &amp;&amp; fns[ i ];
-    // deferred[ done | fail | progress ] for forwarding actions to newDefer
-    deferred[ tuple[1] ](function() {
-    var returned = fn &amp;&amp; fn.apply( this, arguments );
-    if ( returned &amp;&amp; jQuery.isFunction( returned.promise ) ) {
-    returned.promise()
-    .done( newDefer.resolve )
-    .fail( newDefer.reject )
-    .progress( newDefer.notify );
-    } else {
-    newDefer[ action + &quot;With&quot; ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
</del><ins>+    if ( !selector || typeof selector !== &quot;string&quot; ) {
+        return results;
</ins><span class="cx">     }
</span><del>-    });
-    });
-    fns = null;
-    }).promise();
-    },
-    // Get a promise for this deferred
-    // If obj is provided, the promise aspect is added to the object
-    promise: function( obj ) {
-    return obj != null ? jQuery.extend( obj, promise ) : promise;
</del><ins>+
+    if ( (nodeType = context.nodeType) !== 1 &amp;&amp; nodeType !== 9 ) {
+        return [];
</ins><span class="cx">     }
</span><del>-    },
-    deferred = {};
</del><span class="cx"> 
</span><del>-    // Keep pipe for back-compat
-    promise.pipe = promise.then;
</del><ins>+    if ( documentIsHTML &amp;&amp; !seed ) {
</ins><span class="cx"> 
</span><del>-    // Add list-specific methods
-    jQuery.each( tuples, function( i, tuple ) {
-    var list = tuple[ 2 ],
-    stateString = tuple[ 3 ];
</del><ins>+        // Shortcuts
+        if ( (match = rquickExpr.exec( selector )) ) {
+            // Speed-up: Sizzle(&quot;#ID&quot;)
+            if ( (m = match[1]) ) {
+                if ( nodeType === 9 ) {
+                    elem = context.getElementById( m );
+                    // Check parentNode to catch when Blackberry 4.6 returns
+                    // nodes that are no longer in the document (jQuery #6963)
+                    if ( elem &amp;&amp; elem.parentNode ) {
+                        // Handle the case where IE, Opera, and Webkit return items
+                        // by name instead of ID
+                        if ( elem.id === m ) {
+                            results.push( elem );
+                            return results;
+                        }
+                    } else {
+                        return results;
+                    }
+                } else {
+                    // Context is not a document
+                    if ( context.ownerDocument &amp;&amp; (elem = context.ownerDocument.getElementById( m )) &amp;&amp;
+                        contains( context, elem ) &amp;&amp; elem.id === m ) {
+                        results.push( elem );
+                        return results;
+                    }
+                }
</ins><span class="cx"> 
</span><del>-    // promise[ done | fail | progress ] = list.add
-    promise[ tuple[1] ] = list.add;
</del><ins>+            // Speed-up: Sizzle(&quot;TAG&quot;)
+            } else if ( match[2] ) {
+                push.apply( results, context.getElementsByTagName( selector ) );
+                return results;
</ins><span class="cx"> 
</span><del>-    // Handle state
-    if ( stateString ) {
-    list.add(function() {
-    // state = [ resolved | rejected ]
-    state = stateString;
</del><ins>+            // Speed-up: Sizzle(&quot;.CLASS&quot;)
+            } else if ( (m = match[3]) &amp;&amp; support.getElementsByClassName &amp;&amp; context.getElementsByClassName ) {
+                push.apply( results, context.getElementsByClassName( m ) );
+                return results;
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // [ reject_list | resolve_list ].disable; progress_list.lock
-    }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
-    }
</del><ins>+        // QSA path
+        if ( support.qsa &amp;&amp; (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+            nid = old = expando;
+            newContext = context;
+            newSelector = nodeType === 9 &amp;&amp; selector;
</ins><span class="cx"> 
</span><del>-    // deferred[ resolve | reject | notify ]
-    deferred[ tuple[0] ] = function() {
-    deferred[ tuple[0] + &quot;With&quot; ]( this === deferred ? promise : this, arguments );
-    return this;
-    };
-    deferred[ tuple[0] + &quot;With&quot; ] = list.fireWith;
-    });
</del><ins>+            // qSA works strangely on Element-rooted queries
+            // We can work around this by specifying an extra ID on the root
+            // and working up from there (Thanks to Andrew Dupont for the technique)
+            // IE 8 doesn't work on object elements
+            if ( nodeType === 1 &amp;&amp; context.nodeName.toLowerCase() !== &quot;object&quot; ) {
+                groups = tokenize( selector );
</ins><span class="cx"> 
</span><del>-    // Make the deferred a promise
-    promise.promise( deferred );
</del><ins>+                if ( (old = context.getAttribute(&quot;id&quot;)) ) {
+                    nid = old.replace( rescape, &quot;\\$&amp;&quot; );
+                } else {
+                    context.setAttribute( &quot;id&quot;, nid );
+                }
+                nid = &quot;[id='&quot; + nid + &quot;'] &quot;;
</ins><span class="cx"> 
</span><del>-    // Call given func if any
-    if ( func ) {
-    func.call( deferred, deferred );
</del><ins>+                i = groups.length;
+                while ( i-- ) {
+                    groups[i] = nid + toSelector( groups[i] );
+                }
+                newContext = rsibling.test( selector ) &amp;&amp; testContext( context.parentNode ) || context;
+                newSelector = groups.join(&quot;,&quot;);
+            }
+
+            if ( newSelector ) {
+                try {
+                    push.apply( results,
+                        newContext.querySelectorAll( newSelector )
+                    );
+                    return results;
+                } catch(qsaError) {
+                } finally {
+                    if ( !old ) {
+                        context.removeAttribute(&quot;id&quot;);
+                    }
+                }
+            }
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // All done!
-    return deferred;
-    },
</del><ins>+    // All others
+    return select( selector.replace( rtrim, &quot;$1&quot; ), context, results, seed );
+}
</ins><span class="cx"> 
</span><del>-    // Deferred helper
-    when: function( subordinate /* , ..., subordinateN */ ) {
-    var i = 0,
-    resolveValues = core_slice.call( arguments ),
-    length = resolveValues.length,
</del><ins>+/**
+ * Create key-value caches of limited size
+ * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
+ *  property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ *  deleting the oldest entry
+ */
+function createCache() {
+    var keys = [];
</ins><span class="cx"> 
</span><del>-    // the count of uncompleted subordinates
-    remaining = length !== 1 || ( subordinate &amp;&amp; jQuery.isFunction( subordinate.promise ) ) ? length : 0,
</del><ins>+    function cache( key, value ) {
+        // Use (key + &quot; &quot;) to avoid collision with native prototype properties (see Issue #157)
+        if ( keys.push( key + &quot; &quot; ) &gt; Expr.cacheLength ) {
+            // Only keep the most recent entries
+            delete cache[ keys.shift() ];
+        }
+        return (cache[ key + &quot; &quot; ] = value);
+    }
+    return cache;
+}
</ins><span class="cx"> 
</span><del>-    // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
-    deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
</del><ins>+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+    fn[ expando ] = true;
+    return fn;
+}
</ins><span class="cx"> 
</span><del>-    // Update function for both resolve and progress values
-    updateFunc = function( i, contexts, values ) {
-    return function( value ) {
-    contexts[ i ] = this;
-    values[ i ] = arguments.length &gt; 1 ? core_slice.call( arguments ) : value;
-    if( values === progressValues ) {
-    deferred.notifyWith( contexts, values );
-    } else if ( !( --remaining ) ) {
-    deferred.resolveWith( contexts, values );
</del><ins>+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created div and expects a boolean result
+ */
+function assert( fn ) {
+    var div = document.createElement(&quot;div&quot;);
+
+    try {
+        return !!fn( div );
+    } catch (e) {
+        return false;
+    } finally {
+        // Remove from its parent by default
+        if ( div.parentNode ) {
+            div.parentNode.removeChild( div );
+        }
+        // release memory in IE
+        div = null;
</ins><span class="cx">     }
</span><del>-    };
-    },
</del><ins>+}
</ins><span class="cx"> 
</span><del>-    progressValues, progressContexts, resolveContexts;
</del><ins>+/**
+ * Adds the same handler for all of the specified attrs
+ * @param {String} attrs Pipe-separated list of attributes
+ * @param {Function} handler The method that will be applied
+ */
+function addHandle( attrs, handler ) {
+    var arr = attrs.split(&quot;|&quot;),
+        i = attrs.length;
</ins><span class="cx"> 
</span><del>-    // add listeners to Deferred subordinates; treat others as resolved
-    if ( length &gt; 1 ) {
-    progressValues = new Array( length );
-    progressContexts = new Array( length );
-    resolveContexts = new Array( length );
-    for ( ; i &lt; length; i++ ) {
-    if ( resolveValues[ i ] &amp;&amp; jQuery.isFunction( resolveValues[ i ].promise ) ) {
-    resolveValues[ i ].promise()
-    .done( updateFunc( i, resolveContexts, resolveValues ) )
-    .fail( deferred.reject )
-    .progress( updateFunc( i, progressContexts, progressValues ) );
-    } else {
-    --remaining;
</del><ins>+    while ( i-- ) {
+        Expr.attrHandle[ arr[i] ] = handler;
</ins><span class="cx">     }
</span><del>-    }
-    }
</del><ins>+}
</ins><span class="cx"> 
</span><del>-    // if we're not waiting on anything, resolve the master
-    if ( !remaining ) {
-    deferred.resolveWith( resolveContexts, resolveValues );
</del><ins>+/**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+ */
+function siblingCheck( a, b ) {
+    var cur = b &amp;&amp; a,
+        diff = cur &amp;&amp; a.nodeType === 1 &amp;&amp; b.nodeType === 1 &amp;&amp;
+            ( ~b.sourceIndex || MAX_NEGATIVE ) -
+            ( ~a.sourceIndex || MAX_NEGATIVE );
+
+    // Use IE sourceIndex if available on both nodes
+    if ( diff ) {
+        return diff;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return deferred.promise();
</del><ins>+    // Check if b follows a
+    if ( cur ) {
+        while ( (cur = cur.nextSibling) ) {
+            if ( cur === b ) {
+                return -1;
+            }
+        }
</ins><span class="cx">     }
</span><del>-});
-jQuery.support = (function() {
</del><span class="cx"> 
</span><del>-    var support, all, a,
-    input, select, fragment,
-    opt, eventName, isSupported, i,
-    div = document.createElement(&quot;div&quot;);
</del><ins>+    return a ? 1 : -1;
+}
</ins><span class="cx"> 
</span><del>-    // Setup
-    div.setAttribute( &quot;className&quot;, &quot;t&quot; );
-    div.innerHTML = &quot;  &lt;link/&gt;&lt;table&gt;&lt;/table&gt;&lt;a href='/a'&gt;a&lt;/a&gt;&lt;input type='checkbox'/&gt;&quot;;
</del><ins>+/**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+function createInputPseudo( type ) {
+    return function( elem ) {
+        var name = elem.nodeName.toLowerCase();
+        return name === &quot;input&quot; &amp;&amp; elem.type === type;
+    };
+}
</ins><span class="cx"> 
</span><del>-    // Support tests won't run in some limited or non-browser environments
-    all = div.getElementsByTagName(&quot;*&quot;);
-    a = div.getElementsByTagName(&quot;a&quot;)[ 0 ];
-    if ( !all || !a || !all.length ) {
-    return {};
-    }
</del><ins>+/**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+function createButtonPseudo( type ) {
+    return function( elem ) {
+        var name = elem.nodeName.toLowerCase();
+        return (name === &quot;input&quot; || name === &quot;button&quot;) &amp;&amp; elem.type === type;
+    };
+}
</ins><span class="cx"> 
</span><del>-    // First batch of tests
-    select = document.createElement(&quot;select&quot;);
-    opt = select.appendChild( document.createElement(&quot;option&quot;) );
-    input = div.getElementsByTagName(&quot;input&quot;)[ 0 ];
</del><ins>+/**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+function createPositionalPseudo( fn ) {
+    return markFunction(function( argument ) {
+        argument = +argument;
+        return markFunction(function( seed, matches ) {
+            var j,
+                matchIndexes = fn( [], seed.length, argument ),
+                i = matchIndexes.length;
</ins><span class="cx"> 
</span><del>-    a.style.cssText = &quot;top:1px;float:left;opacity:.5&quot;;
-    support = {
-    // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
-    getSetAttribute: div.className !== &quot;t&quot;,
</del><ins>+            // Match elements found at the specified indexes
+            while ( i-- ) {
+                if ( seed[ (j = matchIndexes[i]) ] ) {
+                    seed[j] = !(matches[j] = seed[j]);
+                }
+            }
+        });
+    });
+}
</ins><span class="cx"> 
</span><del>-    // IE strips leading whitespace when .innerHTML is used
-    leadingWhitespace: div.firstChild.nodeType === 3,
</del><ins>+/**
+ * Checks a node for validity as a Sizzle context
+ * @param {Element|Object=} context
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
+ */
+function testContext( context ) {
+    return context &amp;&amp; typeof context.getElementsByTagName !== strundefined &amp;&amp; context;
+}
</ins><span class="cx"> 
</span><del>-    // Make sure that tbody elements aren't automatically inserted
-    // IE will insert them into empty tables
-    tbody: !div.getElementsByTagName(&quot;tbody&quot;).length,
</del><ins>+// Expose support vars for convenience
+support = Sizzle.support = {};
</ins><span class="cx"> 
</span><del>-    // Make sure that link elements get serialized correctly by innerHTML
-    // This requires a wrapper element in IE
-    htmlSerialize: !!div.getElementsByTagName(&quot;link&quot;).length,
</del><ins>+/**
+ * Detects XML nodes
+ * @param {Element|Object} elem An element or a document
+ * @returns {Boolean} True iff elem is a non-HTML XML node
+ */
+isXML = Sizzle.isXML = function( elem ) {
+    // documentElement is verified for cases where it doesn't yet exist
+    // (such as loading iframes in IE - #4833)
+    var documentElement = elem &amp;&amp; (elem.ownerDocument || elem).documentElement;
+    return documentElement ? documentElement.nodeName !== &quot;HTML&quot; : false;
+};
</ins><span class="cx"> 
</span><del>-    // Get the style information from getAttribute
-    // (IE uses .cssText instead)
-    style: /top/.test( a.getAttribute(&quot;style&quot;) ),
</del><ins>+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+    var hasCompare,
+        doc = node ? node.ownerDocument || node : preferredDoc,
+        parent = doc.defaultView;
</ins><span class="cx"> 
</span><del>-    // Make sure that URLs aren't manipulated
-    // (IE normalizes it by default)
-    hrefNormalized: a.getAttribute(&quot;href&quot;) === &quot;/a&quot;,
</del><ins>+    // If no document and documentElement is available, return
+    if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+        return document;
+    }
</ins><span class="cx"> 
</span><del>-    // Make sure that element opacity exists
-    // (IE uses filter instead)
-    // Use a regex to work around a WebKit issue. See #5145
-    opacity: /^0.5/.test( a.style.opacity ),
</del><ins>+    // Set our document
+    document = doc;
+    docElem = doc.documentElement;
</ins><span class="cx"> 
</span><del>-    // Verify style float existence
-    // (IE uses styleFloat instead of cssFloat)
-    cssFloat: !!a.style.cssFloat,
</del><ins>+    // Support tests
+    documentIsHTML = !isXML( doc );
</ins><span class="cx"> 
</span><del>-    // Check the default checkbox/radio value (&quot;&quot; on WebKit; &quot;on&quot; elsewhere)
-    checkOn: !!input.value,
</del><ins>+    // Support: IE&gt;8
+    // If iframe document is assigned to &quot;document&quot; variable and if iframe has been reloaded,
+    // IE will throw &quot;permission denied&quot; error when accessing &quot;document&quot; variable, see jQuery #13936
+    // IE6-8 do not support the defaultView property so parent will be undefined
+    if ( parent &amp;&amp; parent !== parent.top ) {
+        // IE11 does not have attachEvent, so all must suffer
+        if ( parent.addEventListener ) {
+            parent.addEventListener( &quot;unload&quot;, function() {
+                setDocument();
+            }, false );
+        } else if ( parent.attachEvent ) {
+            parent.attachEvent( &quot;onunload&quot;, function() {
+                setDocument();
+            });
+        }
+    }
</ins><span class="cx"> 
</span><del>-    // Make sure that a selected-by-default option has a working selected property.
-    // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
-    optSelected: opt.selected,
</del><ins>+    /* Attributes
+    ---------------------------------------------------------------------- */
</ins><span class="cx"> 
</span><del>-    // Tests for enctype support on a form (#6743)
-    enctype: !!document.createElement(&quot;form&quot;).enctype,
</del><ins>+    // Support: IE&lt;8
+    // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
+    support.attributes = assert(function( div ) {
+        div.className = &quot;i&quot;;
+        return !div.getAttribute(&quot;className&quot;);
+    });
</ins><span class="cx"> 
</span><del>-    // Makes sure cloning an html5 element does not cause problems
-    // Where outerHTML is undefined, this still works
-    html5Clone: document.createElement(&quot;nav&quot;).cloneNode( true ).outerHTML !== &quot;&lt;:nav&gt;&lt;/:nav&gt;&quot;,
</del><ins>+    /* getElement(s)By*
+    ---------------------------------------------------------------------- */
</ins><span class="cx"> 
</span><del>-    // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode
-    boxModel: document.compatMode === &quot;CSS1Compat&quot;,
</del><ins>+    // Check if getElementsByTagName(&quot;*&quot;) returns only elements
+    support.getElementsByTagName = assert(function( div ) {
+        div.appendChild( doc.createComment(&quot;&quot;) );
+        return !div.getElementsByTagName(&quot;*&quot;).length;
+    });
</ins><span class="cx"> 
</span><del>-    // Will be defined later
-    deleteExpando: true,
-    noCloneEvent: true,
-    inlineBlockNeedsLayout: false,
-    shrinkWrapBlocks: false,
-    reliableMarginRight: true,
-    boxSizingReliable: true,
-    pixelPosition: false
-    };
</del><ins>+    // Check if getElementsByClassName can be trusted
+    support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) &amp;&amp; assert(function( div ) {
+        div.innerHTML = &quot;&lt;div class='a'&gt;&lt;/div&gt;&lt;div class='a i'&gt;&lt;/div&gt;&quot;;
</ins><span class="cx"> 
</span><del>-    // Make sure checked status is properly cloned
-    input.checked = true;
-    support.noCloneChecked = input.cloneNode( true ).checked;
</del><ins>+        // Support: Safari&lt;4
+        // Catch class over-caching
+        div.firstChild.className = &quot;i&quot;;
+        // Support: Opera&lt;10
+        // Catch gEBCN failure to find non-leading classes
+        return div.getElementsByClassName(&quot;i&quot;).length === 2;
+    });
</ins><span class="cx"> 
</span><del>-    // Make sure that the options inside disabled selects aren't marked as disabled
-    // (WebKit marks them as disabled)
-    select.disabled = true;
-    support.optDisabled = !opt.disabled;
</del><ins>+    // Support: IE&lt;10
+    // Check if getElementById returns elements by name
+    // The broken getElementById methods don't pick up programatically-set names,
+    // so use a roundabout getElementsByName test
+    support.getById = assert(function( div ) {
+        docElem.appendChild( div ).id = expando;
+        return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
+    });
</ins><span class="cx"> 
</span><del>-    // Support: IE&lt;9
-    try {
-    delete div.test;
-    } catch( e ) {
-    support.deleteExpando = false;
</del><ins>+    // ID find and filter
+    if ( support.getById ) {
+        Expr.find[&quot;ID&quot;] = function( id, context ) {
+            if ( typeof context.getElementById !== strundefined &amp;&amp; documentIsHTML ) {
+                var m = context.getElementById( id );
+                // Check parentNode to catch when Blackberry 4.6 returns
+                // nodes that are no longer in the document #6963
+                return m &amp;&amp; m.parentNode ? [m] : [];
+            }
+        };
+        Expr.filter[&quot;ID&quot;] = function( id ) {
+            var attrId = id.replace( runescape, funescape );
+            return function( elem ) {
+                return elem.getAttribute(&quot;id&quot;) === attrId;
+            };
+        };
+    } else {
+        // Support: IE6/7
+        // getElementById is not reliable as a find shortcut
+        delete Expr.find[&quot;ID&quot;];
+
+        Expr.filter[&quot;ID&quot;] =  function( id ) {
+            var attrId = id.replace( runescape, funescape );
+            return function( elem ) {
+                var node = typeof elem.getAttributeNode !== strundefined &amp;&amp; elem.getAttributeNode(&quot;id&quot;);
+                return node &amp;&amp; node.value === attrId;
+            };
+        };
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Check if we can trust getAttribute(&quot;value&quot;)
-    input = document.createElement(&quot;input&quot;);
-    input.setAttribute( &quot;value&quot;, &quot;&quot; );
-    support.input = input.getAttribute( &quot;value&quot; ) === &quot;&quot;;
</del><ins>+    // Tag
+    Expr.find[&quot;TAG&quot;] = support.getElementsByTagName ?
+        function( tag, context ) {
+            if ( typeof context.getElementsByTagName !== strundefined ) {
+                return context.getElementsByTagName( tag );
+            }
+        } :
+        function( tag, context ) {
+            var elem,
+                tmp = [],
+                i = 0,
+                results = context.getElementsByTagName( tag );
</ins><span class="cx"> 
</span><del>-    // Check if an input maintains its value after becoming a radio
-    input.value = &quot;t&quot;;
-    input.setAttribute( &quot;type&quot;, &quot;radio&quot; );
-    support.radioValue = input.value === &quot;t&quot;;
</del><ins>+            // Filter out possible comments
+            if ( tag === &quot;*&quot; ) {
+                while ( (elem = results[i++]) ) {
+                    if ( elem.nodeType === 1 ) {
+                        tmp.push( elem );
+                    }
+                }
</ins><span class="cx"> 
</span><del>-    // #11217 - WebKit loses check when the name is after the checked attribute
-    input.setAttribute( &quot;checked&quot;, &quot;t&quot; );
-    input.setAttribute( &quot;name&quot;, &quot;t&quot; );
</del><ins>+                return tmp;
+            }
+            return results;
+        };
</ins><span class="cx"> 
</span><del>-    fragment = document.createDocumentFragment();
-    fragment.appendChild( input );
</del><ins>+    // Class
+    Expr.find[&quot;CLASS&quot;] = support.getElementsByClassName &amp;&amp; function( className, context ) {
+        if ( typeof context.getElementsByClassName !== strundefined &amp;&amp; documentIsHTML ) {
+            return context.getElementsByClassName( className );
+        }
+    };
</ins><span class="cx"> 
</span><del>-    // Check if a disconnected checkbox will retain its checked
-    // value of true after appended to the DOM (IE6/7)
-    support.appendChecked = input.checked;
</del><ins>+    /* QSA/matchesSelector
+    ---------------------------------------------------------------------- */
</ins><span class="cx"> 
</span><del>-    // WebKit doesn't clone checked state correctly in fragments
-    support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
</del><ins>+    // QSA and matchesSelector support
</ins><span class="cx"> 
</span><del>-    // Support: IE&lt;9
-    // Opera does not clone events (and typeof div.attachEvent === undefined).
-    // IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
-    if ( div.attachEvent ) {
-    div.attachEvent( &quot;onclick&quot;, function() {
-    support.noCloneEvent = false;
-    });
</del><ins>+    // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+    rbuggyMatches = [];
</ins><span class="cx"> 
</span><del>-    div.cloneNode( true ).click();
-    }
</del><ins>+    // qSa(:focus) reports false when true (Chrome 21)
+    // We allow this because of a bug in IE8/9 that throws an error
+    // whenever `document.activeElement` is accessed on an iframe
+    // So, we allow :focus to pass through QSA all the time to avoid the IE error
+    // See http://bugs.jquery.com/ticket/13378
+    rbuggyQSA = [];
</ins><span class="cx"> 
</span><del>-    // Support: IE&lt;9 (lack submit/change bubble), Firefox 17+ (lack focusin event)
-    // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP), test/csp.php
-    for ( i in { submit: true, change: true, focusin: true }) {
-    div.setAttribute( eventName = &quot;on&quot; + i, &quot;t&quot; );
</del><ins>+    if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
+        // Build QSA regex
+        // Regex strategy adopted from Diego Perini
+        assert(function( div ) {
+            // Select is set to empty string on purpose
+            // This is to test IE's treatment of not explicitly
+            // setting a boolean content attribute,
+            // since its presence should be enough
+            // http://bugs.jquery.com/ticket/12359
+            div.innerHTML = &quot;&lt;select t=''&gt;&lt;option selected=''&gt;&lt;/option&gt;&lt;/select&gt;&quot;;
</ins><span class="cx"> 
</span><del>-    support[ i + &quot;Bubbles&quot; ] = eventName in window || div.attributes[ eventName ].expando === false;
-    }
</del><ins>+            // Support: IE8, Opera 10-12
+            // Nothing should be selected when empty strings follow ^= or $= or *=
+            if ( div.querySelectorAll(&quot;[t^='']&quot;).length ) {
+                rbuggyQSA.push( &quot;[*^$]=&quot; + whitespace + &quot;*(?:''|\&quot;\&quot;)&quot; );
+            }
</ins><span class="cx"> 
</span><del>-    div.style.backgroundClip = &quot;content-box&quot;;
-    div.cloneNode( true ).style.backgroundClip = &quot;&quot;;
-    support.clearCloneStyle = div.style.backgroundClip === &quot;content-box&quot;;
</del><ins>+            // Support: IE8
+            // Boolean attributes and &quot;value&quot; are not treated correctly
+            if ( !div.querySelectorAll(&quot;[selected]&quot;).length ) {
+                rbuggyQSA.push( &quot;\\[&quot; + whitespace + &quot;*(?:value|&quot; + booleans + &quot;)&quot; );
+            }
</ins><span class="cx"> 
</span><del>-    // Run tests that need a body at doc ready
-    jQuery(function() {
-    var container, marginDiv, tds,
-    divReset = &quot;padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;&quot;,
-    body = document.getElementsByTagName(&quot;body&quot;)[0];
</del><ins>+            // Webkit/Opera - :checked should return selected option elements
+            // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+            // IE8 throws error here and will not see later tests
+            if ( !div.querySelectorAll(&quot;:checked&quot;).length ) {
+                rbuggyQSA.push(&quot;:checked&quot;);
+            }
+        });
</ins><span class="cx"> 
</span><del>-    if ( !body ) {
-    // Return for frameset docs that don't have a body
-    return;
-    }
</del><ins>+        assert(function( div ) {
+            // Support: Windows 8 Native Apps
+            // The type and name attributes are restricted during .innerHTML assignment
+            var input = doc.createElement(&quot;input&quot;);
+            input.setAttribute( &quot;type&quot;, &quot;hidden&quot; );
+            div.appendChild( input ).setAttribute( &quot;name&quot;, &quot;D&quot; );
</ins><span class="cx"> 
</span><del>-    container = document.createElement(&quot;div&quot;);
-    container.style.cssText = &quot;border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px&quot;;
</del><ins>+            // Support: IE8
+            // Enforce case-sensitivity of name attribute
+            if ( div.querySelectorAll(&quot;[name=d]&quot;).length ) {
+                rbuggyQSA.push( &quot;name&quot; + whitespace + &quot;*[*^$|!~]?=&quot; );
+            }
</ins><span class="cx"> 
</span><del>-    body.appendChild( container ).appendChild( div );
</del><ins>+            // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+            // IE8 throws error here and will not see later tests
+            if ( !div.querySelectorAll(&quot;:enabled&quot;).length ) {
+                rbuggyQSA.push( &quot;:enabled&quot;, &quot;:disabled&quot; );
+            }
</ins><span class="cx"> 
</span><del>-    // Support: IE8
-    // Check if table cells still have offsetWidth/Height when they are set
-    // to display:none and there are still other visible table cells in a
-    // table row; if so, offsetWidth/Height are not reliable for use when
-    // determining if an element has been hidden directly using
-    // display:none (it is still safe to use offsets if a parent element is
-    // hidden; don safety goggles and see bug #4512 for more information).
-    div.innerHTML = &quot;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;t&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&quot;;
-    tds = div.getElementsByTagName(&quot;td&quot;);
-    tds[ 0 ].style.cssText = &quot;padding:0;margin:0;border:0;display:none&quot;;
-    isSupported = ( tds[ 0 ].offsetHeight === 0 );
</del><ins>+            // Opera 10-11 does not throw on post-comma invalid pseudos
+            div.querySelectorAll(&quot;*,:x&quot;);
+            rbuggyQSA.push(&quot;,.*:&quot;);
+        });
+    }
</ins><span class="cx"> 
</span><del>-    tds[ 0 ].style.display = &quot;&quot;;
-    tds[ 1 ].style.display = &quot;none&quot;;
</del><ins>+    if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
+        docElem.mozMatchesSelector ||
+        docElem.oMatchesSelector ||
+        docElem.msMatchesSelector) )) ) {
</ins><span class="cx"> 
</span><del>-    // Support: IE8
-    // Check if empty table cells still have offsetWidth/Height
-    support.reliableHiddenOffsets = isSupported &amp;&amp; ( tds[ 0 ].offsetHeight === 0 );
</del><ins>+        assert(function( div ) {
+            // Check to see if it's possible to do matchesSelector
+            // on a disconnected node (IE 9)
+            support.disconnectedMatch = matches.call( div, &quot;div&quot; );
</ins><span class="cx"> 
</span><del>-    // Check box-sizing and margin behavior
-    div.innerHTML = &quot;&quot;;
-    div.style.cssText = &quot;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;&quot;;
-    support.boxSizing = ( div.offsetWidth === 4 );
-    support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );
</del><ins>+            // This should fail with an exception
+            // Gecko does not error, returns false instead
+            matches.call( div, &quot;[s!='']:x&quot; );
+            rbuggyMatches.push( &quot;!=&quot;, pseudos );
+        });
+    }
</ins><span class="cx"> 
</span><del>-    // Use window.getComputedStyle because jsdom on node.js will break without it.
-    if ( window.getComputedStyle ) {
-    support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== &quot;1%&quot;;
-    support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: &quot;4px&quot; } ).width === &quot;4px&quot;;
</del><ins>+    rbuggyQSA = rbuggyQSA.length &amp;&amp; new RegExp( rbuggyQSA.join(&quot;|&quot;) );
+    rbuggyMatches = rbuggyMatches.length &amp;&amp; new RegExp( rbuggyMatches.join(&quot;|&quot;) );
</ins><span class="cx"> 
</span><del>-    // Check if div with explicit width and no margin-right incorrectly
-    // gets computed margin-right based on width of container. (#3333)
-    // Fails in WebKit before Feb 2011 nightlies
-    // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
-    marginDiv = div.appendChild( document.createElement(&quot;div&quot;) );
-    marginDiv.style.cssText = div.style.cssText = divReset;
-    marginDiv.style.marginRight = marginDiv.style.width = &quot;0&quot;;
-    div.style.width = &quot;1px&quot;;
</del><ins>+    /* Contains
+    ---------------------------------------------------------------------- */
+    hasCompare = rnative.test( docElem.compareDocumentPosition );
</ins><span class="cx"> 
</span><del>-    support.reliableMarginRight =
-    !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
-    }
</del><ins>+    // Element contains another
+    // Purposefully does not implement inclusive descendent
+    // As in, an element does not contain itself
+    contains = hasCompare || rnative.test( docElem.contains ) ?
+        function( a, b ) {
+            var adown = a.nodeType === 9 ? a.documentElement : a,
+                bup = b &amp;&amp; b.parentNode;
+            return a === bup || !!( bup &amp;&amp; bup.nodeType === 1 &amp;&amp; (
+                adown.contains ?
+                    adown.contains( bup ) :
+                    a.compareDocumentPosition &amp;&amp; a.compareDocumentPosition( bup ) &amp; 16
+            ));
+        } :
+        function( a, b ) {
+            if ( b ) {
+                while ( (b = b.parentNode) ) {
+                    if ( b === a ) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        };
</ins><span class="cx"> 
</span><del>-    if ( typeof div.style.zoom !== core_strundefined ) {
-    // Support: IE&lt;8
-    // Check if natively block-level elements act like inline-block
-    // elements when setting their display to 'inline' and giving
-    // them layout
-    div.innerHTML = &quot;&quot;;
-    div.style.cssText = divReset + &quot;width:1px;padding:1px;display:inline;zoom:1&quot;;
-    support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
</del><ins>+    /* Sorting
+    ---------------------------------------------------------------------- */
</ins><span class="cx"> 
</span><del>-    // Support: IE6
-    // Check if elements with layout shrink-wrap their children
-    div.style.display = &quot;block&quot;;
-    div.innerHTML = &quot;&lt;div&gt;&lt;/div&gt;&quot;;
-    div.firstChild.style.width = &quot;5px&quot;;
-    support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
</del><ins>+    // Document order sorting
+    sortOrder = hasCompare ?
+    function( a, b ) {
</ins><span class="cx"> 
</span><del>-    if ( support.inlineBlockNeedsLayout ) {
-    // Prevent IE 6 from affecting layout for positioned elements #11048
-    // Prevent IE from shrinking the body in IE 7 mode #12869
-    // Support: IE&lt;8
-    body.style.zoom = 1;
-    }
-    }
</del><ins>+        // Flag for duplicate removal
+        if ( a === b ) {
+            hasDuplicate = true;
+            return 0;
+        }
</ins><span class="cx"> 
</span><del>-    body.removeChild( container );
</del><ins>+        // Sort on method existence if only one input has compareDocumentPosition
+        var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
+        if ( compare ) {
+            return compare;
+        }
</ins><span class="cx"> 
</span><del>-    // Null elements to avoid leaks in IE
-    container = div = tds = marginDiv = null;
-    });
</del><ins>+        // Calculate position if both inputs belong to the same document
+        compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
+            a.compareDocumentPosition( b ) :
</ins><span class="cx"> 
</span><del>-    // Null elements to avoid leaks in IE
-    all = select = fragment = opt = a = input = null;
</del><ins>+            // Otherwise we know they are disconnected
+            1;
</ins><span class="cx"> 
</span><del>-    return support;
-})();
</del><ins>+        // Disconnected nodes
+        if ( compare &amp; 1 ||
+            (!support.sortDetached &amp;&amp; b.compareDocumentPosition( a ) === compare) ) {
</ins><span class="cx"> 
</span><del>-var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
-    rmultiDash = /([A-Z])/g;
</del><ins>+            // Choose the first element that is related to our preferred document
+            if ( a === doc || a.ownerDocument === preferredDoc &amp;&amp; contains(preferredDoc, a) ) {
+                return -1;
+            }
+            if ( b === doc || b.ownerDocument === preferredDoc &amp;&amp; contains(preferredDoc, b) ) {
+                return 1;
+            }
</ins><span class="cx"> 
</span><del>-function internalData( elem, name, data, pvt /* Internal Use Only */ ){
-    if ( !jQuery.acceptData( elem ) ) {
-    return;
-    }
</del><ins>+            // Maintain original order
+            return sortInput ?
+                ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
+                0;
+        }
</ins><span class="cx"> 
</span><del>-    var thisCache, ret,
-    internalKey = jQuery.expando,
-    getByName = typeof name === &quot;string&quot;,
</del><ins>+        return compare &amp; 4 ? -1 : 1;
+    } :
+    function( a, b ) {
+        // Exit early if the nodes are identical
+        if ( a === b ) {
+            hasDuplicate = true;
+            return 0;
+        }
</ins><span class="cx"> 
</span><del>-    // We have to handle DOM nodes and JS objects differently because IE6-7
-    // can't GC object references properly across the DOM-JS boundary
-    isNode = elem.nodeType,
</del><ins>+        var cur,
+            i = 0,
+            aup = a.parentNode,
+            bup = b.parentNode,
+            ap = [ a ],
+            bp = [ b ];
</ins><span class="cx"> 
</span><del>-    // Only DOM nodes need the global jQuery cache; JS object data is
-    // attached directly to the object so GC can occur automatically
-    cache = isNode ? jQuery.cache : elem,
</del><ins>+        // Parentless nodes are either documents or disconnected
+        if ( !aup || !bup ) {
+            return a === doc ? -1 :
+                b === doc ? 1 :
+                aup ? -1 :
+                bup ? 1 :
+                sortInput ?
+                ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
+                0;
</ins><span class="cx"> 
</span><del>-    // Only defining an ID for JS objects if its cache already exists allows
-    // the code to shortcut on the same path as a DOM node with no cache
-    id = isNode ? elem[ internalKey ] : elem[ internalKey ] &amp;&amp; internalKey;
</del><ins>+        // If the nodes are siblings, we can do a quick check
+        } else if ( aup === bup ) {
+            return siblingCheck( a, b );
+        }
</ins><span class="cx"> 
</span><del>-    // Avoid doing any more work than we need to when trying to get data on an
-    // object that has no data at all
-    if ( (!id || !cache[id] || (!pvt &amp;&amp; !cache[id].data)) &amp;&amp; getByName &amp;&amp; data === undefined ) {
-    return;
-    }
</del><ins>+        // Otherwise we need full lists of their ancestors for comparison
+        cur = a;
+        while ( (cur = cur.parentNode) ) {
+            ap.unshift( cur );
+        }
+        cur = b;
+        while ( (cur = cur.parentNode) ) {
+            bp.unshift( cur );
+        }
</ins><span class="cx"> 
</span><del>-    if ( !id ) {
-    // Only DOM nodes need a new unique ID for each element since their data
-    // ends up in the global cache
-    if ( isNode ) {
-    elem[ internalKey ] = id = core_deletedIds.pop() || jQuery.guid++;
-    } else {
-    id = internalKey;
-    }
-    }
</del><ins>+        // Walk down the tree looking for a discrepancy
+        while ( ap[i] === bp[i] ) {
+            i++;
+        }
</ins><span class="cx"> 
</span><del>-    if ( !cache[ id ] ) {
-    cache[ id ] = {};
</del><ins>+        return i ?
+            // Do a sibling check if the nodes have a common ancestor
+            siblingCheck( ap[i], bp[i] ) :
</ins><span class="cx"> 
</span><del>-    // Avoids exposing jQuery metadata on plain JS objects when the object
-    // is serialized using JSON.stringify
-    if ( !isNode ) {
-    cache[ id ].toJSON = jQuery.noop;
-    }
-    }
</del><ins>+            // Otherwise nodes in our document sort first
+            ap[i] === preferredDoc ? -1 :
+            bp[i] === preferredDoc ? 1 :
+            0;
+    };
</ins><span class="cx"> 
</span><del>-    // An object can be passed to jQuery.data instead of a key/value pair; this gets
-    // shallow copied over onto the existing cache
-    if ( typeof name === &quot;object&quot; || typeof name === &quot;function&quot; ) {
-    if ( pvt ) {
-    cache[ id ] = jQuery.extend( cache[ id ], name );
-    } else {
-    cache[ id ].data = jQuery.extend( cache[ id ].data, name );
-    }
-    }
</del><ins>+    return doc;
+};
</ins><span class="cx"> 
</span><del>-    thisCache = cache[ id ];
</del><ins>+Sizzle.matches = function( expr, elements ) {
+    return Sizzle( expr, null, null, elements );
+};
</ins><span class="cx"> 
</span><del>-    // jQuery data() is stored in a separate object inside the object's internal data
-    // cache in order to avoid key collisions between internal data and user-defined
-    // data.
-    if ( !pvt ) {
-    if ( !thisCache.data ) {
-    thisCache.data = {};
</del><ins>+Sizzle.matchesSelector = function( elem, expr ) {
+    // Set document vars if needed
+    if ( ( elem.ownerDocument || elem ) !== document ) {
+        setDocument( elem );
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    thisCache = thisCache.data;
-    }
</del><ins>+    // Make sure that attribute selectors are quoted
+    expr = expr.replace( rattributeQuotes, &quot;='$1']&quot; );
</ins><span class="cx"> 
</span><del>-    if ( data !== undefined ) {
-    thisCache[ jQuery.camelCase( name ) ] = data;
-    }
</del><ins>+    if ( support.matchesSelector &amp;&amp; documentIsHTML &amp;&amp;
+        ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &amp;&amp;
+        ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
</ins><span class="cx"> 
</span><del>-    // Check for both converted-to-camel and non-converted data property names
-    // If a data property was specified
-    if ( getByName ) {
</del><ins>+        try {
+            var ret = matches.call( elem, expr );
</ins><span class="cx"> 
</span><del>-    // First Try to find as-is property data
-    ret = thisCache[ name ];
-
-    // Test for null|undefined property data
-    if ( ret == null ) {
-
-    // Try to find the camelCased property
-    ret = thisCache[ jQuery.camelCase( name ) ];
</del><ins>+            // IE 9's matchesSelector returns false on disconnected nodes
+            if ( ret || support.disconnectedMatch ||
+                    // As well, disconnected nodes are said to be in a document
+                    // fragment in IE 9
+                    elem.document &amp;&amp; elem.document.nodeType !== 11 ) {
+                return ret;
+            }
+        } catch(e) {}
</ins><span class="cx">     }
</span><del>-    } else {
-    ret = thisCache;
-    }
</del><span class="cx"> 
</span><del>-    return ret;
-}
</del><ins>+    return Sizzle( expr, document, null, [elem] ).length &gt; 0;
+};
</ins><span class="cx"> 
</span><del>-function internalRemoveData( elem, name, pvt ) {
-    if ( !jQuery.acceptData( elem ) ) {
-    return;
</del><ins>+Sizzle.contains = function( context, elem ) {
+    // Set document vars if needed
+    if ( ( context.ownerDocument || context ) !== document ) {
+        setDocument( context );
</ins><span class="cx">     }
</span><ins>+    return contains( context, elem );
+};
</ins><span class="cx"> 
</span><del>-    var i, l, thisCache,
-    isNode = elem.nodeType,
-
-    // See jQuery.data for more information
-    cache = isNode ? jQuery.cache : elem,
-    id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
-
-    // If there is already no cache entry for this object, there is no
-    // purpose in continuing
-    if ( !cache[ id ] ) {
-    return;
</del><ins>+Sizzle.attr = function( elem, name ) {
+    // Set document vars if needed
+    if ( ( elem.ownerDocument || elem ) !== document ) {
+        setDocument( elem );
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if ( name ) {
</del><ins>+    var fn = Expr.attrHandle[ name.toLowerCase() ],
+        // Don't get fooled by Object.prototype properties (jQuery #13807)
+        val = fn &amp;&amp; hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+            fn( elem, name, !documentIsHTML ) :
+            undefined;
</ins><span class="cx"> 
</span><del>-    thisCache = pvt ? cache[ id ] : cache[ id ].data;
</del><ins>+    return val !== undefined ?
+        val :
+        support.attributes || !documentIsHTML ?
+            elem.getAttribute( name ) :
+            (val = elem.getAttributeNode(name)) &amp;&amp; val.specified ?
+                val.value :
+                null;
+};
</ins><span class="cx"> 
</span><del>-    if ( thisCache ) {
</del><ins>+Sizzle.error = function( msg ) {
+    throw new Error( &quot;Syntax error, unrecognized expression: &quot; + msg );
+};
</ins><span class="cx"> 
</span><del>-    // Support array or space separated string names for data keys
-    if ( !jQuery.isArray( name ) ) {
</del><ins>+/**
+ * Document sorting and removing duplicates
+ * @param {ArrayLike} results
+ */
+Sizzle.uniqueSort = function( results ) {
+    var elem,
+        duplicates = [],
+        j = 0,
+        i = 0;
</ins><span class="cx"> 
</span><del>-    // try the string as a key before any manipulation
-    if ( name in thisCache ) {
-    name = [ name ];
-    } else {
</del><ins>+    // Unless we *know* we can detect duplicates, assume their presence
+    hasDuplicate = !support.detectDuplicates;
+    sortInput = !support.sortStable &amp;&amp; results.slice( 0 );
+    results.sort( sortOrder );
</ins><span class="cx"> 
</span><del>-    // split the camel cased version by spaces unless a key with the spaces exists
-    name = jQuery.camelCase( name );
-    if ( name in thisCache ) {
-    name = [ name ];
-    } else {
-    name = name.split(&quot; &quot;);
</del><ins>+    if ( hasDuplicate ) {
+        while ( (elem = results[i++]) ) {
+            if ( elem === results[ i ] ) {
+                j = duplicates.push( i );
+            }
+        }
+        while ( j-- ) {
+            results.splice( duplicates[ j ], 1 );
+        }
</ins><span class="cx">     }
</span><del>-    }
-    } else {
-    // If &quot;name&quot; is an array of keys...
-    // When data is initially created, via (&quot;key&quot;, &quot;val&quot;) signature,
-    // keys will be converted to camelCase.
-    // Since there is no way to tell _how_ a key was added, remove
-    // both plain key and camelCase key. #12786
-    // This will only penalize the array argument path.
-    name = name.concat( jQuery.map( name, jQuery.camelCase ) );
-    }
</del><span class="cx"> 
</span><del>-    for ( i = 0, l = name.length; i &lt; l; i++ ) {
-    delete thisCache[ name[i] ];
-    }
</del><ins>+    // Clear input after sorting to release objects
+    // See https://github.com/jquery/sizzle/pull/225
+    sortInput = null;
</ins><span class="cx"> 
</span><del>-    // If there is no data left in the cache, we want to continue
-    // and let the cache object itself get destroyed
-    if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
-    return;
-    }
-    }
-    }
</del><ins>+    return results;
+};
</ins><span class="cx"> 
</span><del>-    // See jQuery.data for more information
-    if ( !pvt ) {
-    delete cache[ id ].data;
</del><ins>+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+    var node,
+        ret = &quot;&quot;,
+        i = 0,
+        nodeType = elem.nodeType;
</ins><span class="cx"> 
</span><del>-    // Don't destroy the parent cache unless the internal data object
-    // had been the only thing left in it
-    if ( !isEmptyDataObject( cache[ id ] ) ) {
-    return;
</del><ins>+    if ( !nodeType ) {
+        // If no nodeType, this is expected to be an array
+        while ( (node = elem[i++]) ) {
+            // Do not traverse comment nodes
+            ret += getText( node );
+        }
+    } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+        // Use textContent for elements
+        // innerText usage removed for consistency of new lines (jQuery #11153)
+        if ( typeof elem.textContent === &quot;string&quot; ) {
+            return elem.textContent;
+        } else {
+            // Traverse its children
+            for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+                ret += getText( elem );
+            }
+        }
+    } else if ( nodeType === 3 || nodeType === 4 ) {
+        return elem.nodeValue;
</ins><span class="cx">     }
</span><del>-    }
</del><ins>+    // Do not include comment or processing instruction nodes
</ins><span class="cx"> 
</span><del>-    // Destroy the cache
-    if ( isNode ) {
-    jQuery.cleanData( [ elem ], true );
</del><ins>+    return ret;
+};
</ins><span class="cx"> 
</span><del>-    // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
-    } else if ( jQuery.support.deleteExpando || cache != cache.window ) {
-    delete cache[ id ];
</del><ins>+Expr = Sizzle.selectors = {
</ins><span class="cx"> 
</span><del>-    // When all else fails, null
-    } else {
-    cache[ id ] = null;
-    }
-}
</del><ins>+    // Can be adjusted by the user
+    cacheLength: 50,
</ins><span class="cx"> 
</span><del>-jQuery.extend({
-    cache: {},
</del><ins>+    createPseudo: markFunction,
</ins><span class="cx"> 
</span><del>-    // Unique for each copy of jQuery on the page
-    // Non-digits removed to match rinlinejQuery
-    expando: &quot;jQuery&quot; + ( core_version + Math.random() ).replace( /\D/g, &quot;&quot; ),
</del><ins>+    match: matchExpr,
</ins><span class="cx"> 
</span><del>-    // The following elements throw uncatchable exceptions if you
-    // attempt to add expando properties to them.
-    noData: {
-    &quot;embed&quot;: true,
-    // Ban all objects except for Flash (which handle expandos)
-    &quot;object&quot;: &quot;clsid:D27CDB6E-AE6D-11cf-96B8-444553540000&quot;,
-    &quot;applet&quot;: true
-    },
</del><ins>+    attrHandle: {},
</ins><span class="cx"> 
</span><del>-    hasData: function( elem ) {
-    elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
-    return !!elem &amp;&amp; !isEmptyDataObject( elem );
-    },
</del><ins>+    find: {},
</ins><span class="cx"> 
</span><del>-    data: function( elem, name, data ) {
-    return internalData( elem, name, data );
</del><ins>+    relative: {
+        &quot;&gt;&quot;: { dir: &quot;parentNode&quot;, first: true },
+        &quot; &quot;: { dir: &quot;parentNode&quot; },
+        &quot;+&quot;: { dir: &quot;previousSibling&quot;, first: true },
+        &quot;~&quot;: { dir: &quot;previousSibling&quot; }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    removeData: function( elem, name ) {
-    return internalRemoveData( elem, name );
-    },
</del><ins>+    preFilter: {
+        &quot;ATTR&quot;: function( match ) {
+            match[1] = match[1].replace( runescape, funescape );
</ins><span class="cx"> 
</span><del>-    // For internal use only.
-    _data: function( elem, name, data ) {
-    return internalData( elem, name, data, true );
-    },
</del><ins>+            // Move the given value to match[3] whether quoted or unquoted
+            match[3] = ( match[4] || match[5] || &quot;&quot; ).replace( runescape, funescape );
</ins><span class="cx"> 
</span><del>-    _removeData: function( elem, name ) {
-    return internalRemoveData( elem, name, true );
-    },
</del><ins>+            if ( match[2] === &quot;~=&quot; ) {
+                match[3] = &quot; &quot; + match[3] + &quot; &quot;;
+            }
</ins><span class="cx"> 
</span><del>-    // A method for determining if a DOM node can handle the data expando
-    acceptData: function( elem ) {
-    // Do not set data on non-element because it will not be cleared (#8335).
-    if ( elem.nodeType &amp;&amp; elem.nodeType !== 1 &amp;&amp; elem.nodeType !== 9 ) {
-    return false;
-    }
</del><ins>+            return match.slice( 0, 4 );
+        },
</ins><span class="cx"> 
</span><del>-    var noData = elem.nodeName &amp;&amp; jQuery.noData[ elem.nodeName.toLowerCase() ];
</del><ins>+        &quot;CHILD&quot;: function( match ) {
+            /* matches from matchExpr[&quot;CHILD&quot;]
+                1 type (only|nth|...)
+                2 what (child|of-type)
+                3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+                4 xn-component of xn+y argument ([+-]?\d*n|)
+                5 sign of xn-component
+                6 x of xn-component
+                7 sign of y-component
+                8 y of y-component
+            */
+            match[1] = match[1].toLowerCase();
</ins><span class="cx"> 
</span><del>-    // nodes accept data unless otherwise specified; rejection can be conditional
-    return !noData || noData !== true &amp;&amp; elem.getAttribute(&quot;classid&quot;) === noData;
-    }
-});
</del><ins>+            if ( match[1].slice( 0, 3 ) === &quot;nth&quot; ) {
+                // nth-* requires argument
+                if ( !match[3] ) {
+                    Sizzle.error( match[0] );
+                }
</ins><span class="cx"> 
</span><del>-jQuery.fn.extend({
-    data: function( key, value ) {
-    var attrs, name,
-    elem = this[0],
-    i = 0,
-    data = null;
</del><ins>+                // numeric x and y parameters for Expr.filter.CHILD
+                // remember that false/true cast respectively to 0/1
+                match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === &quot;even&quot; || match[3] === &quot;odd&quot; ) );
+                match[5] = +( ( match[7] + match[8] ) || match[3] === &quot;odd&quot; );
</ins><span class="cx"> 
</span><del>-    // Gets all values
-    if ( key === undefined ) {
-    if ( this.length ) {
-    data = jQuery.data( elem );
</del><ins>+            // other types prohibit arguments
+            } else if ( match[3] ) {
+                Sizzle.error( match[0] );
+            }
</ins><span class="cx"> 
</span><del>-    if ( elem.nodeType === 1 &amp;&amp; !jQuery._data( elem, &quot;parsedAttrs&quot; ) ) {
-    attrs = elem.attributes;
-    for ( ; i &lt; attrs.length; i++ ) {
-    name = attrs[i].name;
</del><ins>+            return match;
+        },
</ins><span class="cx"> 
</span><del>-    if ( !name.indexOf( &quot;data-&quot; ) ) {
-    name = jQuery.camelCase( name.slice(5) );
</del><ins>+        &quot;PSEUDO&quot;: function( match ) {
+            var excess,
+                unquoted = !match[5] &amp;&amp; match[2];
</ins><span class="cx"> 
</span><del>-    dataAttr( elem, name, data[ name ] );
-    }
-    }
-    jQuery._data( elem, &quot;parsedAttrs&quot;, true );
-    }
-    }
</del><ins>+            if ( matchExpr[&quot;CHILD&quot;].test( match[0] ) ) {
+                return null;
+            }
</ins><span class="cx"> 
</span><del>-    return data;
-    }
</del><ins>+            // Accept quoted arguments as-is
+            if ( match[3] &amp;&amp; match[4] !== undefined ) {
+                match[2] = match[4];
</ins><span class="cx"> 
</span><del>-    // Sets multiple values
-    if ( typeof key === &quot;object&quot; ) {
-    return this.each(function() {
-    jQuery.data( this, key );
-    });
-    }
</del><ins>+            // Strip excess characters from unquoted arguments
+            } else if ( unquoted &amp;&amp; rpseudo.test( unquoted ) &amp;&amp;
+                // Get excess from tokenize (recursively)
+                (excess = tokenize( unquoted, true )) &amp;&amp;
+                // advance to the next closing parenthesis
+                (excess = unquoted.indexOf( &quot;)&quot;, unquoted.length - excess ) - unquoted.length) ) {
</ins><span class="cx"> 
</span><del>-    return jQuery.access( this, function( value ) {
</del><ins>+                // excess is a negative index
+                match[0] = match[0].slice( 0, excess );
+                match[2] = unquoted.slice( 0, excess );
+            }
</ins><span class="cx"> 
</span><del>-    if ( value === undefined ) {
-    // Try to fetch any internally stored data first
-    return elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null;
-    }
-
-    this.each(function() {
-    jQuery.data( this, key, value );
-    });
-    }, null, value, arguments.length &gt; 1, null, true );
</del><ins>+            // Return only captures needed by the pseudo filter method (type and argument)
+            return match.slice( 0, 3 );
+        }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    removeData: function( key ) {
-    return this.each(function() {
-    jQuery.removeData( this, key );
-    });
-    }
-});
</del><ins>+    filter: {
</ins><span class="cx"> 
</span><del>-function dataAttr( elem, key, data ) {
-    // If nothing was found internally, try to fetch any
-    // data from the HTML5 data-* attribute
-    if ( data === undefined &amp;&amp; elem.nodeType === 1 ) {
</del><ins>+        &quot;TAG&quot;: function( nodeNameSelector ) {
+            var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
+            return nodeNameSelector === &quot;*&quot; ?
+                function() { return true; } :
+                function( elem ) {
+                    return elem.nodeName &amp;&amp; elem.nodeName.toLowerCase() === nodeName;
+                };
+        },
</ins><span class="cx"> 
</span><del>-    var name = &quot;data-&quot; + key.replace( rmultiDash, &quot;-$1&quot; ).toLowerCase();
</del><ins>+        &quot;CLASS&quot;: function( className ) {
+            var pattern = classCache[ className + &quot; &quot; ];
</ins><span class="cx"> 
</span><del>-    data = elem.getAttribute( name );
</del><ins>+            return pattern ||
+                (pattern = new RegExp( &quot;(^|&quot; + whitespace + &quot;)&quot; + className + &quot;(&quot; + whitespace + &quot;|$)&quot; )) &amp;&amp;
+                classCache( className, function( elem ) {
+                    return pattern.test( typeof elem.className === &quot;string&quot; &amp;&amp; elem.className || typeof elem.getAttribute !== strundefined &amp;&amp; elem.getAttribute(&quot;class&quot;) || &quot;&quot; );
+                });
+        },
</ins><span class="cx"> 
</span><del>-    if ( typeof data === &quot;string&quot; ) {
-    try {
-    data = data === &quot;true&quot; ? true :
-    data === &quot;false&quot; ? false :
-    data === &quot;null&quot; ? null :
-    // Only convert to a number if it doesn't change the string
-    +data + &quot;&quot; === data ? +data :
-    rbrace.test( data ) ? jQuery.parseJSON( data ) :
-    data;
-    } catch( e ) {}
</del><ins>+        &quot;ATTR&quot;: function( name, operator, check ) {
+            return function( elem ) {
+                var result = Sizzle.attr( elem, name );
</ins><span class="cx"> 
</span><del>-    // Make sure we set the data so it isn't changed later
-    jQuery.data( elem, key, data );
</del><ins>+                if ( result == null ) {
+                    return operator === &quot;!=&quot;;
+                }
+                if ( !operator ) {
+                    return true;
+                }
</ins><span class="cx"> 
</span><del>-    } else {
-    data = undefined;
-    }
-    }
</del><ins>+                result += &quot;&quot;;
</ins><span class="cx"> 
</span><del>-    return data;
-}
</del><ins>+                return operator === &quot;=&quot; ? result === check :
+                    operator === &quot;!=&quot; ? result !== check :
+                    operator === &quot;^=&quot; ? check &amp;&amp; result.indexOf( check ) === 0 :
+                    operator === &quot;*=&quot; ? check &amp;&amp; result.indexOf( check ) &gt; -1 :
+                    operator === &quot;$=&quot; ? check &amp;&amp; result.slice( -check.length ) === check :
+                    operator === &quot;~=&quot; ? ( &quot; &quot; + result + &quot; &quot; ).indexOf( check ) &gt; -1 :
+                    operator === &quot;|=&quot; ? result === check || result.slice( 0, check.length + 1 ) === check + &quot;-&quot; :
+                    false;
+            };
+        },
</ins><span class="cx"> 
</span><del>-// checks a cache object for emptiness
-function isEmptyDataObject( obj ) {
-    var name;
-    for ( name in obj ) {
</del><ins>+        &quot;CHILD&quot;: function( type, what, argument, first, last ) {
+            var simple = type.slice( 0, 3 ) !== &quot;nth&quot;,
+                forward = type.slice( -4 ) !== &quot;last&quot;,
+                ofType = what === &quot;of-type&quot;;
</ins><span class="cx"> 
</span><del>-    // if the public data object is empty, the private is still empty
-    if ( name === &quot;data&quot; &amp;&amp; jQuery.isEmptyObject( obj[name] ) ) {
-    continue;
-    }
-    if ( name !== &quot;toJSON&quot; ) {
-    return false;
-    }
-    }
</del><ins>+            return first === 1 &amp;&amp; last === 0 ?
</ins><span class="cx"> 
</span><del>-    return true;
-}
-jQuery.extend({
-    queue: function( elem, type, data ) {
-    var queue;
</del><ins>+                // Shortcut for :nth-*(n)
+                function( elem ) {
+                    return !!elem.parentNode;
+                } :
</ins><span class="cx"> 
</span><del>-    if ( elem ) {
-    type = ( type || &quot;fx&quot; ) + &quot;queue&quot;;
-    queue = jQuery._data( elem, type );
</del><ins>+                function( elem, context, xml ) {
+                    var cache, outerCache, node, diff, nodeIndex, start,
+                        dir = simple !== forward ? &quot;nextSibling&quot; : &quot;previousSibling&quot;,
+                        parent = elem.parentNode,
+                        name = ofType &amp;&amp; elem.nodeName.toLowerCase(),
+                        useCache = !xml &amp;&amp; !ofType;
</ins><span class="cx"> 
</span><del>-    // Speed up dequeue by getting out quickly if this is just a lookup
-    if ( data ) {
-    if ( !queue || jQuery.isArray(data) ) {
-    queue = jQuery._data( elem, type, jQuery.makeArray(data) );
-    } else {
-    queue.push( data );
-    }
-    }
-    return queue || [];
-    }
-    },
</del><ins>+                    if ( parent ) {
</ins><span class="cx"> 
</span><del>-    dequeue: function( elem, type ) {
-    type = type || &quot;fx&quot;;
</del><ins>+                        // :(first|last|only)-(child|of-type)
+                        if ( simple ) {
+                            while ( dir ) {
+                                node = elem;
+                                while ( (node = node[ dir ]) ) {
+                                    if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
+                                        return false;
+                                    }
+                                }
+                                // Reverse direction for :only-* (if we haven't yet done so)
+                                start = dir = type === &quot;only&quot; &amp;&amp; !start &amp;&amp; &quot;nextSibling&quot;;
+                            }
+                            return true;
+                        }
</ins><span class="cx"> 
</span><del>-    var queue = jQuery.queue( elem, type ),
-    startLength = queue.length,
-    fn = queue.shift(),
-    hooks = jQuery._queueHooks( elem, type ),
-    next = function() {
-    jQuery.dequeue( elem, type );
-    };
</del><ins>+                        start = [ forward ? parent.firstChild : parent.lastChild ];
</ins><span class="cx"> 
</span><del>-    // If the fx queue is dequeued, always remove the progress sentinel
-    if ( fn === &quot;inprogress&quot; ) {
-    fn = queue.shift();
-    startLength--;
-    }
</del><ins>+                        // non-xml :nth-child(...) stores cache data on `parent`
+                        if ( forward &amp;&amp; useCache ) {
+                            // Seek `elem` from a previously-cached index
+                            outerCache = parent[ expando ] || (parent[ expando ] = {});
+                            cache = outerCache[ type ] || [];
+                            nodeIndex = cache[0] === dirruns &amp;&amp; cache[1];
+                            diff = cache[0] === dirruns &amp;&amp; cache[2];
+                            node = nodeIndex &amp;&amp; parent.childNodes[ nodeIndex ];
</ins><span class="cx"> 
</span><del>-    hooks.cur = fn;
-    if ( fn ) {
</del><ins>+                            while ( (node = ++nodeIndex &amp;&amp; node &amp;&amp; node[ dir ] ||
</ins><span class="cx"> 
</span><del>-    // Add a progress sentinel to prevent the fx queue from being
-    // automatically dequeued
-    if ( type === &quot;fx&quot; ) {
-    queue.unshift( &quot;inprogress&quot; );
-    }
</del><ins>+                                // Fallback to seeking `elem` from the start
+                                (diff = nodeIndex = 0) || start.pop()) ) {
</ins><span class="cx"> 
</span><del>-    // clear up the last queue stop function
-    delete hooks.stop;
-    fn.call( elem, next, hooks );
-    }
</del><ins>+                                // When found, cache indexes on `parent` and break
+                                if ( node.nodeType === 1 &amp;&amp; ++diff &amp;&amp; node === elem ) {
+                                    outerCache[ type ] = [ dirruns, nodeIndex, diff ];
+                                    break;
+                                }
+                            }
</ins><span class="cx"> 
</span><del>-    if ( !startLength &amp;&amp; hooks ) {
-    hooks.empty.fire();
-    }
-    },
</del><ins>+                        // Use previously-cached element index if available
+                        } else if ( useCache &amp;&amp; (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) &amp;&amp; cache[0] === dirruns ) {
+                            diff = cache[1];
</ins><span class="cx"> 
</span><del>-    // not intended for public consumption - generates a queueHooks object, or returns the current one
-    _queueHooks: function( elem, type ) {
-    var key = type + &quot;queueHooks&quot;;
-    return jQuery._data( elem, key ) || jQuery._data( elem, key, {
-    empty: jQuery.Callbacks(&quot;once memory&quot;).add(function() {
-    jQuery._removeData( elem, type + &quot;queue&quot; );
-    jQuery._removeData( elem, key );
-    })
-    });
-    }
-});
</del><ins>+                        // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
+                        } else {
+                            // Use the same loop as above to seek `elem` from the start
+                            while ( (node = ++nodeIndex &amp;&amp; node &amp;&amp; node[ dir ] ||
+                                (diff = nodeIndex = 0) || start.pop()) ) {
</ins><span class="cx"> 
</span><del>-jQuery.fn.extend({
-    queue: function( type, data ) {
-    var setter = 2;
</del><ins>+                                if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) &amp;&amp; ++diff ) {
+                                    // Cache the index of each encountered element
+                                    if ( useCache ) {
+                                        (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
+                                    }
</ins><span class="cx"> 
</span><del>-    if ( typeof type !== &quot;string&quot; ) {
-    data = type;
-    type = &quot;fx&quot;;
-    setter--;
-    }
</del><ins>+                                    if ( node === elem ) {
+                                        break;
+                                    }
+                                }
+                            }
+                        }
</ins><span class="cx"> 
</span><del>-    if ( arguments.length &lt; setter ) {
-    return jQuery.queue( this[0], type );
-    }
</del><ins>+                        // Incorporate the offset, then check against cycle size
+                        diff -= last;
+                        return diff === first || ( diff % first === 0 &amp;&amp; diff / first &gt;= 0 );
+                    }
+                };
+        },
</ins><span class="cx"> 
</span><del>-    return data === undefined ?
-    this :
-    this.each(function() {
-    var queue = jQuery.queue( this, type, data );
</del><ins>+        &quot;PSEUDO&quot;: function( pseudo, argument ) {
+            // pseudo-class names are case-insensitive
+            // http://www.w3.org/TR/selectors/#pseudo-classes
+            // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+            // Remember that setFilters inherits from pseudos
+            var args,
+                fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+                    Sizzle.error( &quot;unsupported pseudo: &quot; + pseudo );
</ins><span class="cx"> 
</span><del>-    // ensure a hooks for this queue
-    jQuery._queueHooks( this, type );
</del><ins>+            // The user may use createPseudo to indicate that
+            // arguments are needed to create the filter function
+            // just as Sizzle does
+            if ( fn[ expando ] ) {
+                return fn( argument );
+            }
</ins><span class="cx"> 
</span><del>-    if ( type === &quot;fx&quot; &amp;&amp; queue[0] !== &quot;inprogress&quot; ) {
-    jQuery.dequeue( this, type );
-    }
-    });
-    },
-    dequeue: function( type ) {
-    return this.each(function() {
-    jQuery.dequeue( this, type );
-    });
-    },
-    // Based off of the plugin by Clint Helfers, with permission.
-    // http://blindsignals.com/index.php/2009/07/jquery-delay/
-    delay: function( time, type ) {
-    time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
-    type = type || &quot;fx&quot;;
</del><ins>+            // But maintain support for old signatures
+            if ( fn.length &gt; 1 ) {
+                args = [ pseudo, pseudo, &quot;&quot;, argument ];
+                return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+                    markFunction(function( seed, matches ) {
+                        var idx,
+                            matched = fn( seed, argument ),
+                            i = matched.length;
+                        while ( i-- ) {
+                            idx = indexOf.call( seed, matched[i] );
+                            seed[ idx ] = !( matches[ idx ] = matched[i] );
+                        }
+                    }) :
+                    function( elem ) {
+                        return fn( elem, 0, args );
+                    };
+            }
</ins><span class="cx"> 
</span><del>-    return this.queue( type, function( next, hooks ) {
-    var timeout = setTimeout( next, time );
-    hooks.stop = function() {
-    clearTimeout( timeout );
-    };
-    });
</del><ins>+            return fn;
+        }
</ins><span class="cx">     },
</span><del>-    clearQueue: function( type ) {
-    return this.queue( type || &quot;fx&quot;, [] );
-    },
-    // Get a promise resolved when queues of a certain type
-    // are emptied (fx is the type by default)
-    promise: function( type, obj ) {
-    var tmp,
-    count = 1,
-    defer = jQuery.Deferred(),
-    elements = this,
-    i = this.length,
-    resolve = function() {
-    if ( !( --count ) ) {
-    defer.resolveWith( elements, [ elements ] );
-    }
-    };
</del><span class="cx"> 
</span><del>-    if ( typeof type !== &quot;string&quot; ) {
-    obj = type;
-    type = undefined;
-    }
-    type = type || &quot;fx&quot;;
</del><ins>+    pseudos: {
+        // Potentially complex pseudos
+        &quot;not&quot;: markFunction(function( selector ) {
+            // Trim the selector passed to compile
+            // to avoid treating leading and trailing
+            // spaces as combinators
+            var input = [],
+                results = [],
+                matcher = compile( selector.replace( rtrim, &quot;$1&quot; ) );
</ins><span class="cx"> 
</span><del>-    while( i-- ) {
-    tmp = jQuery._data( elements[ i ], type + &quot;queueHooks&quot; );
-    if ( tmp &amp;&amp; tmp.empty ) {
-    count++;
-    tmp.empty.add( resolve );
-    }
-    }
-    resolve();
-    return defer.promise( obj );
-    }
-});
-var nodeHook, boolHook,
-    rclass = /[\t\r\n]/g,
-    rreturn = /\r/g,
-    rfocusable = /^(?:input|select|textarea|button|object)$/i,
-    rclickable = /^(?:a|area)$/i,
-    rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,
-    ruseDefault = /^(?:checked|selected)$/i,
-    getSetAttribute = jQuery.support.getSetAttribute,
-    getSetInput = jQuery.support.input;
</del><ins>+            return matcher[ expando ] ?
+                markFunction(function( seed, matches, context, xml ) {
+                    var elem,
+                        unmatched = matcher( seed, null, xml, [] ),
+                        i = seed.length;
</ins><span class="cx"> 
</span><del>-jQuery.fn.extend({
-    attr: function( name, value ) {
-    return jQuery.access( this, jQuery.attr, name, value, arguments.length &gt; 1 );
-    },
</del><ins>+                    // Match elements unmatched by `matcher`
+                    while ( i-- ) {
+                        if ( (elem = unmatched[i]) ) {
+                            seed[i] = !(matches[i] = elem);
+                        }
+                    }
+                }) :
+                function( elem, context, xml ) {
+                    input[0] = elem;
+                    matcher( input, null, xml, results );
+                    return !results.pop();
+                };
+        }),
</ins><span class="cx"> 
</span><del>-    removeAttr: function( name ) {
-    return this.each(function() {
-    jQuery.removeAttr( this, name );
-    });
-    },
</del><ins>+        &quot;has&quot;: markFunction(function( selector ) {
+            return function( elem ) {
+                return Sizzle( selector, elem ).length &gt; 0;
+            };
+        }),
</ins><span class="cx"> 
</span><del>-    prop: function( name, value ) {
-    return jQuery.access( this, jQuery.prop, name, value, arguments.length &gt; 1 );
-    },
</del><ins>+        &quot;contains&quot;: markFunction(function( text ) {
+            return function( elem ) {
+                return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) &gt; -1;
+            };
+        }),
</ins><span class="cx"> 
</span><del>-    removeProp: function( name ) {
-    name = jQuery.propFix[ name ] || name;
-    return this.each(function() {
-    // try/catch handles cases where IE balks (such as removing a property on window)
-    try {
-    this[ name ] = undefined;
-    delete this[ name ];
-    } catch( e ) {}
-    });
-    },
</del><ins>+        // &quot;Whether an element is represented by a :lang() selector
+        // is based solely on the element's language value
+        // being equal to the identifier C,
+        // or beginning with the identifier C immediately followed by &quot;-&quot;.
+        // The matching of C against the element's language value is performed case-insensitively.
+        // The identifier C does not have to be a valid language name.&quot;
+        // http://www.w3.org/TR/selectors/#lang-pseudo
+        &quot;lang&quot;: markFunction( function( lang ) {
+            // lang value must be a valid identifier
+            if ( !ridentifier.test(lang || &quot;&quot;) ) {
+                Sizzle.error( &quot;unsupported lang: &quot; + lang );
+            }
+            lang = lang.replace( runescape, funescape ).toLowerCase();
+            return function( elem ) {
+                var elemLang;
+                do {
+                    if ( (elemLang = documentIsHTML ?
+                        elem.lang :
+                        elem.getAttribute(&quot;xml:lang&quot;) || elem.getAttribute(&quot;lang&quot;)) ) {
</ins><span class="cx"> 
</span><del>-    addClass: function( value ) {
-    var classes, elem, cur, clazz, j,
-    i = 0,
-    len = this.length,
-    proceed = typeof value === &quot;string&quot; &amp;&amp; value;
</del><ins>+                        elemLang = elemLang.toLowerCase();
+                        return elemLang === lang || elemLang.indexOf( lang + &quot;-&quot; ) === 0;
+                    }
+                } while ( (elem = elem.parentNode) &amp;&amp; elem.nodeType === 1 );
+                return false;
+            };
+        }),
</ins><span class="cx"> 
</span><del>-    if ( jQuery.isFunction( value ) ) {
-    return this.each(function( j ) {
-    jQuery( this ).addClass( value.call( this, j, this.className ) );
-    });
-    }
</del><ins>+        // Miscellaneous
+        &quot;target&quot;: function( elem ) {
+            var hash = window.location &amp;&amp; window.location.hash;
+            return hash &amp;&amp; hash.slice( 1 ) === elem.id;
+        },
</ins><span class="cx"> 
</span><del>-    if ( proceed ) {
-    // The disjunction here is for better compressibility (see removeClass)
-    classes = ( value || &quot;&quot; ).match( core_rnotwhite ) || [];
</del><ins>+        &quot;root&quot;: function( elem ) {
+            return elem === docElem;
+        },
</ins><span class="cx"> 
</span><del>-    for ( ; i &lt; len; i++ ) {
-    elem = this[ i ];
-    cur = elem.nodeType === 1 &amp;&amp; ( elem.className ?
-    ( &quot; &quot; + elem.className + &quot; &quot; ).replace( rclass, &quot; &quot; ) :
-    &quot; &quot;
-    );
</del><ins>+        &quot;focus&quot;: function( elem ) {
+            return elem === document.activeElement &amp;&amp; (!document.hasFocus || document.hasFocus()) &amp;&amp; !!(elem.type || elem.href || ~elem.tabIndex);
+        },
</ins><span class="cx"> 
</span><del>-    if ( cur ) {
-    j = 0;
-    while ( (clazz = classes[j++]) ) {
-    if ( cur.indexOf( &quot; &quot; + clazz + &quot; &quot; ) &lt; 0 ) {
-    cur += clazz + &quot; &quot;;
-    }
-    }
-    elem.className = jQuery.trim( cur );
</del><ins>+        // Boolean properties
+        &quot;enabled&quot;: function( elem ) {
+            return elem.disabled === false;
+        },
</ins><span class="cx"> 
</span><del>-    }
-    }
-    }
</del><ins>+        &quot;disabled&quot;: function( elem ) {
+            return elem.disabled === true;
+        },
</ins><span class="cx"> 
</span><del>-    return this;
-    },
</del><ins>+        &quot;checked&quot;: function( elem ) {
+            // In CSS3, :checked should return both checked and selected elements
+            // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+            var nodeName = elem.nodeName.toLowerCase();
+            return (nodeName === &quot;input&quot; &amp;&amp; !!elem.checked) || (nodeName === &quot;option&quot; &amp;&amp; !!elem.selected);
+        },
</ins><span class="cx"> 
</span><del>-    removeClass: function( value ) {
-    var classes, elem, cur, clazz, j,
-    i = 0,
-    len = this.length,
-    proceed = arguments.length === 0 || typeof value === &quot;string&quot; &amp;&amp; value;
</del><ins>+        &quot;selected&quot;: function( elem ) {
+            // Accessing this property makes selected-by-default
+            // options in Safari work properly
+            if ( elem.parentNode ) {
+                elem.parentNode.selectedIndex;
+            }
</ins><span class="cx"> 
</span><del>-    if ( jQuery.isFunction( value ) ) {
-    return this.each(function( j ) {
-    jQuery( this ).removeClass( value.call( this, j, this.className ) );
-    });
-    }
-    if ( proceed ) {
-    classes = ( value || &quot;&quot; ).match( core_rnotwhite ) || [];
</del><ins>+            return elem.selected === true;
+        },
</ins><span class="cx"> 
</span><del>-    for ( ; i &lt; len; i++ ) {
-    elem = this[ i ];
-    // This expression is here for better compressibility (see addClass)
-    cur = elem.nodeType === 1 &amp;&amp; ( elem.className ?
-    ( &quot; &quot; + elem.className + &quot; &quot; ).replace( rclass, &quot; &quot; ) :
-    &quot;&quot;
-    );
</del><ins>+        // Contents
+        &quot;empty&quot;: function( elem ) {
+            // http://www.w3.org/TR/selectors/#empty-pseudo
+            // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
+            //   but not by others (comment: 8; processing instruction: 7; etc.)
+            // nodeType &lt; 6 works because attributes (2) do not appear as children
+            for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+                if ( elem.nodeType &lt; 6 ) {
+                    return false;
+                }
+            }
+            return true;
+        },
</ins><span class="cx"> 
</span><del>-    if ( cur ) {
-    j = 0;
-    while ( (clazz = classes[j++]) ) {
-    // Remove *all* instances
-    while ( cur.indexOf( &quot; &quot; + clazz + &quot; &quot; ) &gt;= 0 ) {
-    cur = cur.replace( &quot; &quot; + clazz + &quot; &quot;, &quot; &quot; );
-    }
-    }
-    elem.className = value ? jQuery.trim( cur ) : &quot;&quot;;
-    }
-    }
-    }
</del><ins>+        &quot;parent&quot;: function( elem ) {
+            return !Expr.pseudos[&quot;empty&quot;]( elem );
+        },
</ins><span class="cx"> 
</span><del>-    return this;
-    },
</del><ins>+        // Element/input types
+        &quot;header&quot;: function( elem ) {
+            return rheader.test( elem.nodeName );
+        },
</ins><span class="cx"> 
</span><del>-    toggleClass: function( value, stateVal ) {
-    var type = typeof value,
-    isBool = typeof stateVal === &quot;boolean&quot;;
</del><ins>+        &quot;input&quot;: function( elem ) {
+            return rinputs.test( elem.nodeName );
+        },
</ins><span class="cx"> 
</span><del>-    if ( jQuery.isFunction( value ) ) {
-    return this.each(function( i ) {
-    jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
-    });
-    }
</del><ins>+        &quot;button&quot;: function( elem ) {
+            var name = elem.nodeName.toLowerCase();
+            return name === &quot;input&quot; &amp;&amp; elem.type === &quot;button&quot; || name === &quot;button&quot;;
+        },
</ins><span class="cx"> 
</span><del>-    return this.each(function() {
-    if ( type === &quot;string&quot; ) {
-    // toggle individual class names
-    var className,
-    i = 0,
-    self = jQuery( this ),
-    state = stateVal,
-    classNames = value.match( core_rnotwhite ) || [];
</del><ins>+        &quot;text&quot;: function( elem ) {
+            var attr;
+            return elem.nodeName.toLowerCase() === &quot;input&quot; &amp;&amp;
+                elem.type === &quot;text&quot; &amp;&amp;
</ins><span class="cx"> 
</span><del>-    while ( (className = classNames[ i++ ]) ) {
-    // check each className given, space separated list
-    state = isBool ? state : !self.hasClass( className );
-    self[ state ? &quot;addClass&quot; : &quot;removeClass&quot; ]( className );
-    }
</del><ins>+                // Support: IE&lt;8
+                // New HTML5 attribute values (e.g., &quot;search&quot;) appear with elem.type === &quot;text&quot;
+                ( (attr = elem.getAttribute(&quot;type&quot;)) == null || attr.toLowerCase() === &quot;text&quot; );
+        },
</ins><span class="cx"> 
</span><del>-    // Toggle whole class name
-    } else if ( type === core_strundefined || type === &quot;boolean&quot; ) {
-    if ( this.className ) {
-    // store className if set
-    jQuery._data( this, &quot;__className__&quot;, this.className );
-    }
</del><ins>+        // Position-in-collection
+        &quot;first&quot;: createPositionalPseudo(function() {
+            return [ 0 ];
+        }),
</ins><span class="cx"> 
</span><del>-    // If the element has a class name or if we're passed &quot;false&quot;,
-    // then remove the whole classname (if there was one, the above saved it).
-    // Otherwise bring back whatever was previously saved (if anything),
-    // falling back to the empty string if nothing was stored.
-    this.className = this.className || value === false ? &quot;&quot; : jQuery._data( this, &quot;__className__&quot; ) || &quot;&quot;;
-    }
-    });
-    },
</del><ins>+        &quot;last&quot;: createPositionalPseudo(function( matchIndexes, length ) {
+            return [ length - 1 ];
+        }),
</ins><span class="cx"> 
</span><del>-    hasClass: function( selector ) {
-    var className = &quot; &quot; + selector + &quot; &quot;,
-    i = 0,
-    l = this.length;
-    for ( ; i &lt; l; i++ ) {
-    if ( this[i].nodeType === 1 &amp;&amp; (&quot; &quot; + this[i].className + &quot; &quot;).replace(rclass, &quot; &quot;).indexOf( className ) &gt;= 0 ) {
-    return true;
-    }
-    }
</del><ins>+        &quot;eq&quot;: createPositionalPseudo(function( matchIndexes, length, argument ) {
+            return [ argument &lt; 0 ? argument + length : argument ];
+        }),
</ins><span class="cx"> 
</span><del>-    return false;
-    },
</del><ins>+        &quot;even&quot;: createPositionalPseudo(function( matchIndexes, length ) {
+            var i = 0;
+            for ( ; i &lt; length; i += 2 ) {
+                matchIndexes.push( i );
+            }
+            return matchIndexes;
+        }),
</ins><span class="cx"> 
</span><del>-    val: function( value ) {
-    var ret, hooks, isFunction,
-    elem = this[0];
</del><ins>+        &quot;odd&quot;: createPositionalPseudo(function( matchIndexes, length ) {
+            var i = 1;
+            for ( ; i &lt; length; i += 2 ) {
+                matchIndexes.push( i );
+            }
+            return matchIndexes;
+        }),
</ins><span class="cx"> 
</span><del>-    if ( !arguments.length ) {
-    if ( elem ) {
-    hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
</del><ins>+        &quot;lt&quot;: createPositionalPseudo(function( matchIndexes, length, argument ) {
+            var i = argument &lt; 0 ? argument + length : argument;
+            for ( ; --i &gt;= 0; ) {
+                matchIndexes.push( i );
+            }
+            return matchIndexes;
+        }),
</ins><span class="cx"> 
</span><del>-    if ( hooks &amp;&amp; &quot;get&quot; in hooks &amp;&amp; (ret = hooks.get( elem, &quot;value&quot; )) !== undefined ) {
-    return ret;
</del><ins>+        &quot;gt&quot;: createPositionalPseudo(function( matchIndexes, length, argument ) {
+            var i = argument &lt; 0 ? argument + length : argument;
+            for ( ; ++i &lt; length; ) {
+                matchIndexes.push( i );
+            }
+            return matchIndexes;
+        })
</ins><span class="cx">     }
</span><ins>+};
</ins><span class="cx"> 
</span><del>-    ret = elem.value;
</del><ins>+Expr.pseudos[&quot;nth&quot;] = Expr.pseudos[&quot;eq&quot;];
</ins><span class="cx"> 
</span><del>-    return typeof ret === &quot;string&quot; ?
-    // handle most common string cases
-    ret.replace(rreturn, &quot;&quot;) :
-    // handle cases where value is null/undef or number
-    ret == null ? &quot;&quot; : ret;
-    }
</del><ins>+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+    Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+    Expr.pseudos[ i ] = createButtonPseudo( i );
+}
</ins><span class="cx"> 
</span><del>-    return;
</del><ins>+// Easy API for creating new setFilters
+function setFilters() {}
+setFilters.prototype = Expr.filters = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+function tokenize( selector, parseOnly ) {
+    var matched, match, tokens, type,
+        soFar, groups, preFilters,
+        cached = tokenCache[ selector + &quot; &quot; ];
+
+    if ( cached ) {
+        return parseOnly ? 0 : cached.slice( 0 );
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    isFunction = jQuery.isFunction( value );
</del><ins>+    soFar = selector;
+    groups = [];
+    preFilters = Expr.preFilter;
</ins><span class="cx"> 
</span><del>-    return this.each(function( i ) {
-    var val,
-    self = jQuery(this);
</del><ins>+    while ( soFar ) {
</ins><span class="cx"> 
</span><del>-    if ( this.nodeType !== 1 ) {
-    return;
-    }
</del><ins>+        // Comma and first run
+        if ( !matched || (match = rcomma.exec( soFar )) ) {
+            if ( match ) {
+                // Don't consume trailing commas as valid
+                soFar = soFar.slice( match[0].length ) || soFar;
+            }
+            groups.push( (tokens = []) );
+        }
</ins><span class="cx"> 
</span><del>-    if ( isFunction ) {
-    val = value.call( this, i, self.val() );
-    } else {
-    val = value;
-    }
</del><ins>+        matched = false;
</ins><span class="cx"> 
</span><del>-    // Treat null/undefined as &quot;&quot;; convert numbers to string
-    if ( val == null ) {
-    val = &quot;&quot;;
-    } else if ( typeof val === &quot;number&quot; ) {
-    val += &quot;&quot;;
-    } else if ( jQuery.isArray( val ) ) {
-    val = jQuery.map(val, function ( value ) {
-    return value == null ? &quot;&quot; : value + &quot;&quot;;
-    });
-    }
</del><ins>+        // Combinators
+        if ( (match = rcombinators.exec( soFar )) ) {
+            matched = match.shift();
+            tokens.push({
+                value: matched,
+                // Cast descendant combinators to space
+                type: match[0].replace( rtrim, &quot; &quot; )
+            });
+            soFar = soFar.slice( matched.length );
+        }
</ins><span class="cx"> 
</span><del>-    hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
</del><ins>+        // Filters
+        for ( type in Expr.filter ) {
+            if ( (match = matchExpr[ type ].exec( soFar )) &amp;&amp; (!preFilters[ type ] ||
+                (match = preFilters[ type ]( match ))) ) {
+                matched = match.shift();
+                tokens.push({
+                    value: matched,
+                    type: type,
+                    matches: match
+                });
+                soFar = soFar.slice( matched.length );
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // If set returns undefined, fall back to normal setting
-    if ( !hooks || !(&quot;set&quot; in hooks) || hooks.set( this, val, &quot;value&quot; ) === undefined ) {
-    this.value = val;
</del><ins>+        if ( !matched ) {
+            break;
+        }
</ins><span class="cx">     }
</span><del>-    });
-    }
-});
</del><span class="cx"> 
</span><del>-jQuery.extend({
-    valHooks: {
-    option: {
-    get: function( elem ) {
-    // attributes.value is undefined in Blackberry 4.7 but
-    // uses .value. See #6932
-    var val = elem.attributes.value;
-    return !val || val.specified ? elem.value : elem.text;
</del><ins>+    // Return the length of the invalid excess
+    // if we're just parsing
+    // Otherwise, throw an error or return tokens
+    return parseOnly ?
+        soFar.length :
+        soFar ?
+            Sizzle.error( selector ) :
+            // Cache the tokens
+            tokenCache( selector, groups ).slice( 0 );
+}
+
+function toSelector( tokens ) {
+    var i = 0,
+        len = tokens.length,
+        selector = &quot;&quot;;
+    for ( ; i &lt; len; i++ ) {
+        selector += tokens[i].value;
</ins><span class="cx">     }
</span><del>-    },
-    select: {
-    get: function( elem ) {
-    var value, option,
-    options = elem.options,
-    index = elem.selectedIndex,
-    one = elem.type === &quot;select-one&quot; || index &lt; 0,
-    values = one ? null : [],
-    max = one ? index + 1 : options.length,
-    i = index &lt; 0 ?
-    max :
-    one ? index : 0;
</del><ins>+    return selector;
+}
</ins><span class="cx"> 
</span><del>-    // Loop through all the selected options
-    for ( ; i &lt; max; i++ ) {
-    option = options[ i ];
</del><ins>+function addCombinator( matcher, combinator, base ) {
+    var dir = combinator.dir,
+        checkNonElements = base &amp;&amp; dir === &quot;parentNode&quot;,
+        doneName = done++;
</ins><span class="cx"> 
</span><del>-    // oldIE doesn't update selected after form reset (#2551)
-    if ( ( option.selected || i === index ) &amp;&amp;
-    // Don't return options that are disabled or in a disabled optgroup
-    ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute(&quot;disabled&quot;) === null ) &amp;&amp;
-    ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, &quot;optgroup&quot; ) ) ) {
</del><ins>+    return combinator.first ?
+        // Check against closest ancestor/preceding element
+        function( elem, context, xml ) {
+            while ( (elem = elem[ dir ]) ) {
+                if ( elem.nodeType === 1 || checkNonElements ) {
+                    return matcher( elem, context, xml );
+                }
+            }
+        } :
</ins><span class="cx"> 
</span><del>-    // Get the specific value for the option
-    value = jQuery( option ).val();
</del><ins>+        // Check against all ancestor/preceding elements
+        function( elem, context, xml ) {
+            var oldCache, outerCache,
+                newCache = [ dirruns, doneName ];
</ins><span class="cx"> 
</span><del>-    // We don't need an array for one selects
-    if ( one ) {
-    return value;
-    }
</del><ins>+            // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
+            if ( xml ) {
+                while ( (elem = elem[ dir ]) ) {
+                    if ( elem.nodeType === 1 || checkNonElements ) {
+                        if ( matcher( elem, context, xml ) ) {
+                            return true;
+                        }
+                    }
+                }
+            } else {
+                while ( (elem = elem[ dir ]) ) {
+                    if ( elem.nodeType === 1 || checkNonElements ) {
+                        outerCache = elem[ expando ] || (elem[ expando ] = {});
+                        if ( (oldCache = outerCache[ dir ]) &amp;&amp;
+                            oldCache[ 0 ] === dirruns &amp;&amp; oldCache[ 1 ] === doneName ) {
</ins><span class="cx"> 
</span><del>-    // Multi-Selects return an array
-    values.push( value );
-    }
-    }
</del><ins>+                            // Assign to newCache so results back-propagate to previous elements
+                            return (newCache[ 2 ] = oldCache[ 2 ]);
+                        } else {
+                            // Reuse newcache so results back-propagate to previous elements
+                            outerCache[ dir ] = newCache;
</ins><span class="cx"> 
</span><del>-    return values;
-    },
</del><ins>+                            // A match means we're done; a fail means we have to keep checking
+                            if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+        };
+}
</ins><span class="cx"> 
</span><del>-    set: function( elem, value ) {
-    var values = jQuery.makeArray( value );
</del><ins>+function elementMatcher( matchers ) {
+    return matchers.length &gt; 1 ?
+        function( elem, context, xml ) {
+            var i = matchers.length;
+            while ( i-- ) {
+                if ( !matchers[i]( elem, context, xml ) ) {
+                    return false;
+                }
+            }
+            return true;
+        } :
+        matchers[0];
+}
</ins><span class="cx"> 
</span><del>-    jQuery(elem).find(&quot;option&quot;).each(function() {
-    this.selected = jQuery.inArray( jQuery(this).val(), values ) &gt;= 0;
-    });
</del><ins>+function condense( unmatched, map, filter, context, xml ) {
+    var elem,
+        newUnmatched = [],
+        i = 0,
+        len = unmatched.length,
+        mapped = map != null;
</ins><span class="cx"> 
</span><del>-    if ( !values.length ) {
-    elem.selectedIndex = -1;
</del><ins>+    for ( ; i &lt; len; i++ ) {
+        if ( (elem = unmatched[i]) ) {
+            if ( !filter || filter( elem, context, xml ) ) {
+                newUnmatched.push( elem );
+                if ( mapped ) {
+                    map.push( i );
+                }
+            }
+        }
</ins><span class="cx">     }
</span><del>-    return values;
-    }
-    }
-    },
</del><span class="cx"> 
</span><del>-    attr: function( elem, name, value ) {
-    var hooks, notxml, ret,
-    nType = elem.nodeType;
</del><ins>+    return newUnmatched;
+}
</ins><span class="cx"> 
</span><del>-    // don't get/set attributes on text, comment and attribute nodes
-    if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
-    return;
</del><ins>+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+    if ( postFilter &amp;&amp; !postFilter[ expando ] ) {
+        postFilter = setMatcher( postFilter );
</ins><span class="cx">     }
</span><del>-
-    // Fallback to prop when attributes are not supported
-    if ( typeof elem.getAttribute === core_strundefined ) {
-    return jQuery.prop( elem, name, value );
</del><ins>+    if ( postFinder &amp;&amp; !postFinder[ expando ] ) {
+        postFinder = setMatcher( postFinder, postSelector );
</ins><span class="cx">     }
</span><ins>+    return markFunction(function( seed, results, context, xml ) {
+        var temp, i, elem,
+            preMap = [],
+            postMap = [],
+            preexisting = results.length,
</ins><span class="cx"> 
</span><del>-    notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
</del><ins>+            // Get initial elements from seed or context
+            elems = seed || multipleContexts( selector || &quot;*&quot;, context.nodeType ? [ context ] : context, [] ),
</ins><span class="cx"> 
</span><del>-    // All attributes are lowercase
-    // Grab necessary hook if one is defined
-    if ( notxml ) {
-    name = name.toLowerCase();
-    hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
-    }
</del><ins>+            // Prefilter to get matcher input, preserving a map for seed-results synchronization
+            matcherIn = preFilter &amp;&amp; ( seed || !selector ) ?
+                condense( elems, preMap, preFilter, context, xml ) :
+                elems,
</ins><span class="cx"> 
</span><del>-    if ( value !== undefined ) {
</del><ins>+            matcherOut = matcher ?
+                // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+                postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
</ins><span class="cx"> 
</span><del>-    if ( value === null ) {
-    jQuery.removeAttr( elem, name );
</del><ins>+                    // ...intermediate processing is necessary
+                    [] :
</ins><span class="cx"> 
</span><del>-    } else if ( hooks &amp;&amp; notxml &amp;&amp; &quot;set&quot; in hooks &amp;&amp; (ret = hooks.set( elem, value, name )) !== undefined ) {
-    return ret;
</del><ins>+                    // ...otherwise use results directly
+                    results :
+                matcherIn;
</ins><span class="cx"> 
</span><del>-    } else {
-    elem.setAttribute( name, value + &quot;&quot; );
-    return value;
-    }
</del><ins>+        // Find primary matches
+        if ( matcher ) {
+            matcher( matcherIn, matcherOut, context, xml );
+        }
</ins><span class="cx"> 
</span><del>-    } else if ( hooks &amp;&amp; notxml &amp;&amp; &quot;get&quot; in hooks &amp;&amp; (ret = hooks.get( elem, name )) !== null ) {
-    return ret;
</del><ins>+        // Apply postFilter
+        if ( postFilter ) {
+            temp = condense( matcherOut, postMap );
+            postFilter( temp, [], context, xml );
</ins><span class="cx"> 
</span><del>-    } else {
</del><ins>+            // Un-match failing elements by moving them back to matcherIn
+            i = temp.length;
+            while ( i-- ) {
+                if ( (elem = temp[i]) ) {
+                    matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+                }
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // In IE9+, Flash objects don't have .getAttribute (#12945)
-    // Support: IE9+
-    if ( typeof elem.getAttribute !== core_strundefined ) {
-    ret =  elem.getAttribute( name );
-    }
</del><ins>+        if ( seed ) {
+            if ( postFinder || preFilter ) {
+                if ( postFinder ) {
+                    // Get the final matcherOut by condensing this intermediate into postFinder contexts
+                    temp = [];
+                    i = matcherOut.length;
+                    while ( i-- ) {
+                        if ( (elem = matcherOut[i]) ) {
+                            // Restore matcherIn since elem is not yet a final match
+                            temp.push( (matcherIn[i] = elem) );
+                        }
+                    }
+                    postFinder( null, (matcherOut = []), temp, xml );
+                }
</ins><span class="cx"> 
</span><del>-    // Non-existent attributes return null, we normalize to undefined
-    return ret == null ?
-    undefined :
-    ret;
-    }
-    },
</del><ins>+                // Move matched elements from seed to results to keep them synchronized
+                i = matcherOut.length;
+                while ( i-- ) {
+                    if ( (elem = matcherOut[i]) &amp;&amp;
+                        (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) &gt; -1 ) {
</ins><span class="cx"> 
</span><del>-    removeAttr: function( elem, value ) {
-    var name, propName,
-    i = 0,
-    attrNames = value &amp;&amp; value.match( core_rnotwhite );
</del><ins>+                        seed[temp] = !(results[temp] = elem);
+                    }
+                }
+            }
</ins><span class="cx"> 
</span><del>-    if ( attrNames &amp;&amp; elem.nodeType === 1 ) {
-    while ( (name = attrNames[i++]) ) {
-    propName = jQuery.propFix[ name ] || name;
</del><ins>+        // Add elements to results, through postFinder if defined
+        } else {
+            matcherOut = condense(
+                matcherOut === results ?
+                    matcherOut.splice( preexisting, matcherOut.length ) :
+                    matcherOut
+            );
+            if ( postFinder ) {
+                postFinder( null, results, matcherOut, xml );
+            } else {
+                push.apply( results, matcherOut );
+            }
+        }
+    });
+}
</ins><span class="cx"> 
</span><del>-    // Boolean attributes get special treatment (#10870)
-    if ( rboolean.test( name ) ) {
-    // Set corresponding property to false for boolean attributes
-    // Also clear defaultChecked/defaultSelected (if appropriate) for IE&lt;8
-    if ( !getSetAttribute &amp;&amp; ruseDefault.test( name ) ) {
-    elem[ jQuery.camelCase( &quot;default-&quot; + name ) ] =
-    elem[ propName ] = false;
-    } else {
-    elem[ propName ] = false;
-    }
</del><ins>+function matcherFromTokens( tokens ) {
+    var checkContext, matcher, j,
+        len = tokens.length,
+        leadingRelative = Expr.relative[ tokens[0].type ],
+        implicitRelative = leadingRelative || Expr.relative[&quot; &quot;],
+        i = leadingRelative ? 1 : 0,
</ins><span class="cx"> 
</span><del>-    // See #9699 for explanation of this approach (setting first, then removal)
-    } else {
-    jQuery.attr( elem, name, &quot;&quot; );
-    }
</del><ins>+        // The foundational matcher ensures that elements are reachable from top-level context(s)
+        matchContext = addCombinator( function( elem ) {
+            return elem === checkContext;
+        }, implicitRelative, true ),
+        matchAnyContext = addCombinator( function( elem ) {
+            return indexOf.call( checkContext, elem ) &gt; -1;
+        }, implicitRelative, true ),
+        matchers = [ function( elem, context, xml ) {
+            return ( !leadingRelative &amp;&amp; ( xml || context !== outermostContext ) ) || (
+                (checkContext = context).nodeType ?
+                    matchContext( elem, context, xml ) :
+                    matchAnyContext( elem, context, xml ) );
+        } ];
</ins><span class="cx"> 
</span><del>-    elem.removeAttribute( getSetAttribute ? name : propName );
-    }
-    }
-    },
</del><ins>+    for ( ; i &lt; len; i++ ) {
+        if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+            matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+        } else {
+            matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
</ins><span class="cx"> 
</span><del>-    attrHooks: {
-    type: {
-    set: function( elem, value ) {
-    if ( !jQuery.support.radioValue &amp;&amp; value === &quot;radio&quot; &amp;&amp; jQuery.nodeName(elem, &quot;input&quot;) ) {
-    // Setting the type on a radio button after the value resets the value in IE6-9
-    // Reset value to default in case type is set after value during creation
-    var val = elem.value;
-    elem.setAttribute( &quot;type&quot;, value );
-    if ( val ) {
-    elem.value = val;
</del><ins>+            // Return special upon seeing a positional matcher
+            if ( matcher[ expando ] ) {
+                // Find the next relative operator (if any) for proper handling
+                j = ++i;
+                for ( ; j &lt; len; j++ ) {
+                    if ( Expr.relative[ tokens[j].type ] ) {
+                        break;
+                    }
+                }
+                return setMatcher(
+                    i &gt; 1 &amp;&amp; elementMatcher( matchers ),
+                    i &gt; 1 &amp;&amp; toSelector(
+                        // If the preceding token was a descendant combinator, insert an implicit any-element `*`
+                        tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === &quot; &quot; ? &quot;*&quot; : &quot;&quot; })
+                    ).replace( rtrim, &quot;$1&quot; ),
+                    matcher,
+                    i &lt; j &amp;&amp; matcherFromTokens( tokens.slice( i, j ) ),
+                    j &lt; len &amp;&amp; matcherFromTokens( (tokens = tokens.slice( j )) ),
+                    j &lt; len &amp;&amp; toSelector( tokens )
+                );
+            }
+            matchers.push( matcher );
+        }
</ins><span class="cx">     }
</span><del>-    return value;
-    }
-    }
-    }
-    },
</del><span class="cx"> 
</span><del>-    propFix: {
-    tabindex: &quot;tabIndex&quot;,
-    readonly: &quot;readOnly&quot;,
-    &quot;for&quot;: &quot;htmlFor&quot;,
-    &quot;class&quot;: &quot;className&quot;,
-    maxlength: &quot;maxLength&quot;,
-    cellspacing: &quot;cellSpacing&quot;,
-    cellpadding: &quot;cellPadding&quot;,
-    rowspan: &quot;rowSpan&quot;,
-    colspan: &quot;colSpan&quot;,
-    usemap: &quot;useMap&quot;,
-    frameborder: &quot;frameBorder&quot;,
-    contenteditable: &quot;contentEditable&quot;
-    },
</del><ins>+    return elementMatcher( matchers );
+}
</ins><span class="cx"> 
</span><del>-    prop: function( elem, name, value ) {
-    var ret, hooks, notxml,
-    nType = elem.nodeType;
</del><ins>+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+    var bySet = setMatchers.length &gt; 0,
+        byElement = elementMatchers.length &gt; 0,
+        superMatcher = function( seed, context, xml, results, outermost ) {
+            var elem, j, matcher,
+                matchedCount = 0,
+                i = &quot;0&quot;,
+                unmatched = seed &amp;&amp; [],
+                setMatched = [],
+                contextBackup = outermostContext,
+                // We must always have either seed elements or outermost context
+                elems = seed || byElement &amp;&amp; Expr.find[&quot;TAG&quot;]( &quot;*&quot;, outermost ),
+                // Use integer dirruns iff this is the outermost matcher
+                dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
+                len = elems.length;
</ins><span class="cx"> 
</span><del>-    // don't get/set properties on text, comment and attribute nodes
-    if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
-    return;
-    }
</del><ins>+            if ( outermost ) {
+                outermostContext = context !== document &amp;&amp; context;
+            }
</ins><span class="cx"> 
</span><del>-    notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
</del><ins>+            // Add elements passing elementMatchers directly to results
+            // Keep `i` a string if there are no elements so `matchedCount` will be &quot;00&quot; below
+            // Support: IE&lt;9, Safari
+            // Tolerate NodeList properties (IE: &quot;length&quot;; Safari: &lt;number&gt;) matching elements by id
+            for ( ; i !== len &amp;&amp; (elem = elems[i]) != null; i++ ) {
+                if ( byElement &amp;&amp; elem ) {
+                    j = 0;
+                    while ( (matcher = elementMatchers[j++]) ) {
+                        if ( matcher( elem, context, xml ) ) {
+                            results.push( elem );
+                            break;
+                        }
+                    }
+                    if ( outermost ) {
+                        dirruns = dirrunsUnique;
+                    }
+                }
</ins><span class="cx"> 
</span><del>-    if ( notxml ) {
-    // Fix name and attach hooks
-    name = jQuery.propFix[ name ] || name;
-    hooks = jQuery.propHooks[ name ];
-    }
</del><ins>+                // Track unmatched elements for set filters
+                if ( bySet ) {
+                    // They will have gone through all possible matchers
+                    if ( (elem = !matcher &amp;&amp; elem) ) {
+                        matchedCount--;
+                    }
</ins><span class="cx"> 
</span><del>-    if ( value !== undefined ) {
-    if ( hooks &amp;&amp; &quot;set&quot; in hooks &amp;&amp; (ret = hooks.set( elem, value, name )) !== undefined ) {
-    return ret;
</del><ins>+                    // Lengthen the array for every element, matched or not
+                    if ( seed ) {
+                        unmatched.push( elem );
+                    }
+                }
+            }
</ins><span class="cx"> 
</span><del>-    } else {
-    return ( elem[ name ] = value );
-    }
</del><ins>+            // Apply set filters to unmatched elements
+            matchedCount += i;
+            if ( bySet &amp;&amp; i !== matchedCount ) {
+                j = 0;
+                while ( (matcher = setMatchers[j++]) ) {
+                    matcher( unmatched, setMatched, context, xml );
+                }
</ins><span class="cx"> 
</span><del>-    } else {
-    if ( hooks &amp;&amp; &quot;get&quot; in hooks &amp;&amp; (ret = hooks.get( elem, name )) !== null ) {
-    return ret;
</del><ins>+                if ( seed ) {
+                    // Reintegrate element matches to eliminate the need for sorting
+                    if ( matchedCount &gt; 0 ) {
+                        while ( i-- ) {
+                            if ( !(unmatched[i] || setMatched[i]) ) {
+                                setMatched[i] = pop.call( results );
+                            }
+                        }
+                    }
</ins><span class="cx"> 
</span><del>-    } else {
-    return elem[ name ];
-    }
-    }
-    },
</del><ins>+                    // Discard index placeholder values to get only actual matches
+                    setMatched = condense( setMatched );
+                }
</ins><span class="cx"> 
</span><del>-    propHooks: {
-    tabIndex: {
-    get: function( elem ) {
-    // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
-    // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
-    var attributeNode = elem.getAttributeNode(&quot;tabindex&quot;);
</del><ins>+                // Add matches to results
+                push.apply( results, setMatched );
</ins><span class="cx"> 
</span><del>-    return attributeNode &amp;&amp; attributeNode.specified ?
-    parseInt( attributeNode.value, 10 ) :
-    rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) &amp;&amp; elem.href ?
-    0 :
-    undefined;
-    }
-    }
-    }
-});
</del><ins>+                // Seedless set matches succeeding multiple successful matchers stipulate sorting
+                if ( outermost &amp;&amp; !seed &amp;&amp; setMatched.length &gt; 0 &amp;&amp;
+                    ( matchedCount + setMatchers.length ) &gt; 1 ) {
</ins><span class="cx"> 
</span><del>-// Hook for boolean attributes
-boolHook = {
-    get: function( elem, name ) {
-    var
-    // Use .prop to determine if this attribute is understood as boolean
-    prop = jQuery.prop( elem, name ),
</del><ins>+                    Sizzle.uniqueSort( results );
+                }
+            }
</ins><span class="cx"> 
</span><del>-    // Fetch it accordingly
-    attr = typeof prop === &quot;boolean&quot; &amp;&amp; elem.getAttribute( name ),
-    detail = typeof prop === &quot;boolean&quot; ?
</del><ins>+            // Override manipulation of globals by nested matchers
+            if ( outermost ) {
+                dirruns = dirrunsUnique;
+                outermostContext = contextBackup;
+            }
</ins><span class="cx"> 
</span><del>-    getSetInput &amp;&amp; getSetAttribute ?
-    attr != null :
-    // oldIE fabricates an empty string for missing boolean attributes
-    // and conflates checked/selected into attroperties
-    ruseDefault.test( name ) ?
-    elem[ jQuery.camelCase( &quot;default-&quot; + name ) ] :
-    !!attr :
</del><ins>+            return unmatched;
+        };
</ins><span class="cx"> 
</span><del>-    // fetch an attribute node for properties not recognized as boolean
-    elem.getAttributeNode( name );
</del><ins>+    return bySet ?
+        markFunction( superMatcher ) :
+        superMatcher;
+}
</ins><span class="cx"> 
</span><del>-    return detail &amp;&amp; detail.value !== false ?
-    name.toLowerCase() :
-    undefined;
-    },
-    set: function( elem, value, name ) {
-    if ( value === false ) {
-    // Remove boolean attributes when set to false
-    jQuery.removeAttr( elem, name );
-    } else if ( getSetInput &amp;&amp; getSetAttribute || !ruseDefault.test( name ) ) {
-    // IE&lt;8 needs the *property* name
-    elem.setAttribute( !getSetAttribute &amp;&amp; jQuery.propFix[ name ] || name, name );
</del><ins>+compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
+    var i,
+        setMatchers = [],
+        elementMatchers = [],
+        cached = compilerCache[ selector + &quot; &quot; ];
</ins><span class="cx"> 
</span><del>-    // Use defaultChecked and defaultSelected for oldIE
-    } else {
-    elem[ jQuery.camelCase( &quot;default-&quot; + name ) ] = elem[ name ] = true;
-    }
</del><ins>+    if ( !cached ) {
+        // Generate a function of recursive functions that can be used to check each element
+        if ( !group ) {
+            group = tokenize( selector );
+        }
+        i = group.length;
+        while ( i-- ) {
+            cached = matcherFromTokens( group[i] );
+            if ( cached[ expando ] ) {
+                setMatchers.push( cached );
+            } else {
+                elementMatchers.push( cached );
+            }
+        }
</ins><span class="cx"> 
</span><del>-    return name;
</del><ins>+        // Cache the compiled function
+        cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
</ins><span class="cx">     }
</span><ins>+    return cached;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-// fix oldIE value attroperty
-if ( !getSetInput || !getSetAttribute ) {
-    jQuery.attrHooks.value = {
-    get: function( elem, name ) {
-    var ret = elem.getAttributeNode( name );
-    return jQuery.nodeName( elem, &quot;input&quot; ) ?
-
-    // Ignore the value *property* by using defaultValue
-    elem.defaultValue :
-
-    ret &amp;&amp; ret.specified ? ret.value : undefined;
-    },
-    set: function( elem, value, name ) {
-    if ( jQuery.nodeName( elem, &quot;input&quot; ) ) {
-    // Does not return so that setAttribute is also used
-    elem.defaultValue = value;
-    } else {
-    // Use nodeHook if defined (#1954); otherwise setAttribute is fine
-    return nodeHook &amp;&amp; nodeHook.set( elem, value, name );
</del><ins>+function multipleContexts( selector, contexts, results ) {
+    var i = 0,
+        len = contexts.length;
+    for ( ; i &lt; len; i++ ) {
+        Sizzle( selector, contexts[i], results );
</ins><span class="cx">     }
</span><del>-    }
-    };
</del><ins>+    return results;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-// IE6/7 do not support getting/setting some attributes with get/setAttribute
-if ( !getSetAttribute ) {
</del><ins>+function select( selector, context, results, seed ) {
+    var i, tokens, token, type, find,
+        match = tokenize( selector );
</ins><span class="cx"> 
</span><del>-    // Use this for any attribute in IE6/7
-    // This fixes almost every IE6/7 issue
-    nodeHook = jQuery.valHooks.button = {
-    get: function( elem, name ) {
-    var ret = elem.getAttributeNode( name );
-    return ret &amp;&amp; ( name === &quot;id&quot; || name === &quot;name&quot; || name === &quot;coords&quot; ? ret.value !== &quot;&quot; : ret.specified ) ?
-    ret.value :
-    undefined;
-    },
-    set: function( elem, value, name ) {
-    // Set the existing or create a new attribute node
-    var ret = elem.getAttributeNode( name );
-    if ( !ret ) {
-    elem.setAttributeNode(
-    (ret = elem.ownerDocument.createAttribute( name ))
-    );
-    }
</del><ins>+    if ( !seed ) {
+        // Try to minimize operations if there is only one group
+        if ( match.length === 1 ) {
</ins><span class="cx"> 
</span><del>-    ret.value = value += &quot;&quot;;
</del><ins>+            // Take a shortcut and set the context if the root selector is an ID
+            tokens = match[0] = match[0].slice( 0 );
+            if ( tokens.length &gt; 2 &amp;&amp; (token = tokens[0]).type === &quot;ID&quot; &amp;&amp;
+                    support.getById &amp;&amp; context.nodeType === 9 &amp;&amp; documentIsHTML &amp;&amp;
+                    Expr.relative[ tokens[1].type ] ) {
</ins><span class="cx"> 
</span><del>-    // Break association with cloned elements by also using setAttribute (#9646)
-    return name === &quot;value&quot; || value === elem.getAttribute( name ) ?
-    value :
-    undefined;
-    }
-    };
</del><ins>+                context = ( Expr.find[&quot;ID&quot;]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
+                if ( !context ) {
+                    return results;
+                }
+                selector = selector.slice( tokens.shift().value.length );
+            }
</ins><span class="cx"> 
</span><del>-    // Set contenteditable to false on removals(#10429)
-    // Setting to empty string throws an error as an invalid value
-    jQuery.attrHooks.contenteditable = {
-    get: nodeHook.get,
-    set: function( elem, value, name ) {
-    nodeHook.set( elem, value === &quot;&quot; ? false : value, name );
-    }
-    };
</del><ins>+            // Fetch a seed set for right-to-left matching
+            i = matchExpr[&quot;needsContext&quot;].test( selector ) ? 0 : tokens.length;
+            while ( i-- ) {
+                token = tokens[i];
</ins><span class="cx"> 
</span><del>-    // Set width and height to auto instead of 0 on empty string( Bug #8150 )
-    // This is for removals
-    jQuery.each([ &quot;width&quot;, &quot;height&quot; ], function( i, name ) {
-    jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
-    set: function( elem, value ) {
-    if ( value === &quot;&quot; ) {
-    elem.setAttribute( name, &quot;auto&quot; );
-    return value;
</del><ins>+                // Abort if we hit a combinator
+                if ( Expr.relative[ (type = token.type) ] ) {
+                    break;
+                }
+                if ( (find = Expr.find[ type ]) ) {
+                    // Search, expanding context for leading sibling combinators
+                    if ( (seed = find(
+                        token.matches[0].replace( runescape, funescape ),
+                        rsibling.test( tokens[0].type ) &amp;&amp; testContext( context.parentNode ) || context
+                    )) ) {
+
+                        // If seed is empty or no tokens remain, we can return early
+                        tokens.splice( i, 1 );
+                        selector = seed.length &amp;&amp; toSelector( tokens );
+                        if ( !selector ) {
+                            push.apply( results, seed );
+                            return results;
+                        }
+
+                        break;
+                    }
+                }
+            }
+        }
</ins><span class="cx">     }
</span><del>-    }
-    });
-    });
</del><ins>+
+    // Compile and execute a filtering function
+    // Provide `match` to avoid retokenization if we modified the selector above
+    compile( selector, match )(
+        seed,
+        context,
+        !documentIsHTML,
+        results,
+        rsibling.test( selector ) &amp;&amp; testContext( context.parentNode ) || context
+    );
+    return results;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// One-time assignments
</ins><span class="cx"> 
</span><del>-// Some attributes require a special call on IE
</del><ins>+// Sort stability
+support.sortStable = expando.split(&quot;&quot;).sort( sortOrder ).join(&quot;&quot;) === expando;
+
+// Support: Chrome&lt;14
+// Always assume duplicates if they aren't passed to the comparison function
+support.detectDuplicates = !!hasDuplicate;
+
+// Initialize against the default document
+setDocument();
+
+// Support: Webkit&lt;537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+// Detached nodes confoundingly follow *each other*
+support.sortDetached = assert(function( div1 ) {
+    // Should return 1, but returns 4 (following)
+    return div1.compareDocumentPosition( document.createElement(&quot;div&quot;) ) &amp; 1;
+});
+
+// Support: IE&lt;8
+// Prevent attribute/property &quot;interpolation&quot;
</ins><span class="cx"> // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
</span><del>-if ( !jQuery.support.hrefNormalized ) {
-    jQuery.each([ &quot;href&quot;, &quot;src&quot;, &quot;width&quot;, &quot;height&quot; ], function( i, name ) {
-    jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
-    get: function( elem ) {
-    var ret = elem.getAttribute( name, 2 );
-    return ret == null ? undefined : ret;
-    }
</del><ins>+if ( !assert(function( div ) {
+    div.innerHTML = &quot;&lt;a href='#'&gt;&lt;/a&gt;&quot;;
+    return div.firstChild.getAttribute(&quot;href&quot;) === &quot;#&quot; ;
+}) ) {
+    addHandle( &quot;type|href|height|width&quot;, function( elem, name, isXML ) {
+        if ( !isXML ) {
+            return elem.getAttribute( name, name.toLowerCase() === &quot;type&quot; ? 1 : 2 );
+        }
</ins><span class="cx">     });
</span><del>-    });
</del><ins>+}
</ins><span class="cx"> 
</span><del>-    // href/src property should get the full normalized URL (#10299/#12915)
-    jQuery.each([ &quot;href&quot;, &quot;src&quot; ], function( i, name ) {
-    jQuery.propHooks[ name ] = {
-    get: function( elem ) {
-    return elem.getAttribute( name, 4 );
-    }
-    };
</del><ins>+// Support: IE&lt;9
+// Use defaultValue in place of getAttribute(&quot;value&quot;)
+if ( !support.attributes || !assert(function( div ) {
+    div.innerHTML = &quot;&lt;input/&gt;&quot;;
+    div.firstChild.setAttribute( &quot;value&quot;, &quot;&quot; );
+    return div.firstChild.getAttribute( &quot;value&quot; ) === &quot;&quot;;
+}) ) {
+    addHandle( &quot;value&quot;, function( elem, name, isXML ) {
+        if ( !isXML &amp;&amp; elem.nodeName.toLowerCase() === &quot;input&quot; ) {
+            return elem.defaultValue;
+        }
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-if ( !jQuery.support.style ) {
-    jQuery.attrHooks.style = {
-    get: function( elem ) {
-    // Return undefined in the case of empty string
-    // Note: IE uppercases css property names, but if we were to .toLowerCase()
-    // .cssText, that would destroy case senstitivity in URL's, like in &quot;background&quot;
-    return elem.style.cssText || undefined;
-    },
-    set: function( elem, value ) {
-    return ( elem.style.cssText = value + &quot;&quot; );
-    }
-    };
</del><ins>+// Support: IE&lt;9
+// Use getAttributeNode to fetch booleans when getAttribute lies
+if ( !assert(function( div ) {
+    return div.getAttribute(&quot;disabled&quot;) == null;
+}) ) {
+    addHandle( booleans, function( elem, name, isXML ) {
+        var val;
+        if ( !isXML ) {
+            return elem[ name ] === true ? name.toLowerCase() :
+                    (val = elem.getAttributeNode( name )) &amp;&amp; val.specified ?
+                    val.value :
+                null;
+        }
+    });
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-// Safari mis-reports the default selected property of an option
-// Accessing the parent's selectedIndex property fixes it
-if ( !jQuery.support.optSelected ) {
-    jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
-    get: function( elem ) {
-    var parent = elem.parentNode;
</del><ins>+return Sizzle;
</ins><span class="cx"> 
</span><del>-    if ( parent ) {
-    parent.selectedIndex;
</del><ins>+})( window );
</ins><span class="cx"> 
</span><del>-    // Make sure that it also works with optgroups, see #5701
-    if ( parent.parentNode ) {
-    parent.parentNode.selectedIndex;
</del><ins>+
+
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[&quot;:&quot;] = jQuery.expr.pseudos;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+
+var rneedsContext = jQuery.expr.match.needsContext;
+
+var rsingleTag = (/^&lt;(\w+)\s*\/?&gt;(?:&lt;\/\1&gt;|)$/);
+
+
+
+var risSimple = /^.[^:#\[\.,]*$/;
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, not ) {
+    if ( jQuery.isFunction( qualifier ) ) {
+        return jQuery.grep( elements, function( elem, i ) {
+            /* jshint -W018 */
+            return !!qualifier.call( elem, i, elem ) !== not;
+        });
+
</ins><span class="cx">     }
</span><ins>+
+    if ( qualifier.nodeType ) {
+        return jQuery.grep( elements, function( elem ) {
+            return ( elem === qualifier ) !== not;
+        });
+
</ins><span class="cx">     }
</span><del>-    return null;
</del><ins>+
+    if ( typeof qualifier === &quot;string&quot; ) {
+        if ( risSimple.test( qualifier ) ) {
+            return jQuery.filter( qualifier, elements, not );
+        }
+
+        qualifier = jQuery.filter( qualifier, elements );
</ins><span class="cx">     }
</span><ins>+
+    return jQuery.grep( elements, function( elem ) {
+        return ( indexOf.call( qualifier, elem ) &gt;= 0 ) !== not;
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// IE6/7 call enctype encoding
-if ( !jQuery.support.enctype ) {
-    jQuery.propFix.enctype = &quot;encoding&quot;;
-}
</del><ins>+jQuery.filter = function( expr, elems, not ) {
+    var elem = elems[ 0 ];
</ins><span class="cx"> 
</span><del>-// Radios and checkboxes getter/setter
-if ( !jQuery.support.checkOn ) {
-    jQuery.each([ &quot;radio&quot;, &quot;checkbox&quot; ], function() {
-    jQuery.valHooks[ this ] = {
-    get: function( elem ) {
-    // Handle the case where in Webkit &quot;&quot; is returned instead of &quot;on&quot; if a value isn't specified
-    return elem.getAttribute(&quot;value&quot;) === null ? &quot;on&quot; : elem.value;
</del><ins>+    if ( not ) {
+        expr = &quot;:not(&quot; + expr + &quot;)&quot;;
</ins><span class="cx">     }
</span><del>-    };
-    });
-}
-jQuery.each([ &quot;radio&quot;, &quot;checkbox&quot; ], function() {
-    jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
-    set: function( elem, value ) {
-    if ( jQuery.isArray( value ) ) {
-    return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) &gt;= 0 );
-    }
-    }
-    });
-});
-var rformElems = /^(?:input|select|textarea)$/i,
-    rkeyEvent = /^key/,
-    rmouseEvent = /^(?:mouse|contextmenu)|click/,
-    rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
-    rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
</del><span class="cx"> 
</span><del>-function returnTrue() {
-    return true;
-}
</del><ins>+    return elems.length === 1 &amp;&amp; elem.nodeType === 1 ?
+        jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
+        jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+            return elem.nodeType === 1;
+        }));
+};
</ins><span class="cx"> 
</span><del>-function returnFalse() {
-    return false;
-}
</del><ins>+jQuery.fn.extend({
+    find: function( selector ) {
+        var i,
+            len = this.length,
+            ret = [],
+            self = this;
</ins><span class="cx"> 
</span><del>-/*
- * Helper functions for managing events -- not part of the public interface.
- * Props to Dean Edwards' addEvent library for many of the ideas.
- */
-jQuery.event = {
</del><ins>+        if ( typeof selector !== &quot;string&quot; ) {
+            return this.pushStack( jQuery( selector ).filter(function() {
+                for ( i = 0; i &lt; len; i++ ) {
+                    if ( jQuery.contains( self[ i ], this ) ) {
+                        return true;
+                    }
+                }
+            }) );
+        }
</ins><span class="cx"> 
</span><del>-    global: {},
</del><ins>+        for ( i = 0; i &lt; len; i++ ) {
+            jQuery.find( selector, self[ i ], ret );
+        }
</ins><span class="cx"> 
</span><del>-    add: function( elem, types, handler, data, selector ) {
-    var tmp, events, t, handleObjIn,
-    special, eventHandle, handleObj,
-    handlers, type, namespaces, origType,
-    elemData = jQuery._data( elem );
</del><ins>+        // Needed because $( selector, context ) becomes $( context ).find( selector )
+        ret = this.pushStack( len &gt; 1 ? jQuery.unique( ret ) : ret );
+        ret.selector = this.selector ? this.selector + &quot; &quot; + selector : selector;
+        return ret;
+    },
+    filter: function( selector ) {
+        return this.pushStack( winnow(this, selector || [], false) );
+    },
+    not: function( selector ) {
+        return this.pushStack( winnow(this, selector || [], true) );
+    },
+    is: function( selector ) {
+        return !!winnow(
+            this,
</ins><span class="cx"> 
</span><del>-    // Don't attach events to noData or text/comment nodes (but allow plain objects)
-    if ( !elemData ) {
-    return;
</del><ins>+            // If this is a positional/relative selector, check membership in the returned set
+            // so $(&quot;p:first&quot;).is(&quot;p:last&quot;) won't return true for a doc with two &quot;p&quot;.
+            typeof selector === &quot;string&quot; &amp;&amp; rneedsContext.test( selector ) ?
+                jQuery( selector ) :
+                selector || [],
+            false
+        ).length;
</ins><span class="cx">     }
</span><ins>+});
</ins><span class="cx"> 
</span><del>-    // Caller can pass in an object of custom data in lieu of the handler
-    if ( handler.handler ) {
-    handleObjIn = handler;
-    handler = handleObjIn.handler;
-    selector = handleObjIn.selector;
-    }
</del><span class="cx"> 
</span><del>-    // Make sure that the handler has a unique ID, used to find/remove it later
-    if ( !handler.guid ) {
-    handler.guid = jQuery.guid++;
-    }
</del><ins>+// Initialize a jQuery object
</ins><span class="cx"> 
</span><del>-    // Init the element's event structure and main handler, if this is the first
-    if ( !(events = elemData.events) ) {
-    events = elemData.events = {};
-    }
-    if ( !(eventHandle = elemData.handle) ) {
-    eventHandle = elemData.handle = function( e ) {
-    // Discard the second event of a jQuery.event.trigger() and
-    // when an event is called after a page has unloaded
-    return typeof jQuery !== core_strundefined &amp;&amp; (!e || jQuery.event.triggered !== e.type) ?
-    jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
-    undefined;
-    };
-    // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
-    eventHandle.elem = elem;
-    }
</del><span class="cx"> 
</span><del>-    // Handle multiple events separated by a space
-    // jQuery(...).bind(&quot;mouseover mouseout&quot;, fn);
-    types = ( types || &quot;&quot; ).match( core_rnotwhite ) || [&quot;&quot;];
-    t = types.length;
-    while ( t-- ) {
-    tmp = rtypenamespace.exec( types[t] ) || [];
-    type = origType = tmp[1];
-    namespaces = ( tmp[2] || &quot;&quot; ).split( &quot;.&quot; ).sort();
</del><ins>+// A central reference to the root jQuery(document)
+var rootjQuery,
</ins><span class="cx"> 
</span><del>-    // If event changes its type, use the special event handlers for the changed type
-    special = jQuery.event.special[ type ] || {};
</del><ins>+    // A simple way to check for HTML strings
+    // Prioritize #id over &lt;tag&gt; to avoid XSS via location.hash (#9521)
+    // Strict HTML recognition (#11290: must start with &lt;)
+    rquickExpr = /^(?:\s*(&lt;[\w\W]+&gt;)[^&gt;]*|#([\w-]*))$/,
</ins><span class="cx"> 
</span><del>-    // If selector defined, determine special event api type, otherwise given type
-    type = ( selector ? special.delegateType : special.bindType ) || type;
</del><ins>+    init = jQuery.fn.init = function( selector, context ) {
+        var match, elem;
</ins><span class="cx"> 
</span><del>-    // Update special based on newly reset type
-    special = jQuery.event.special[ type ] || {};
</del><ins>+        // HANDLE: $(&quot;&quot;), $(null), $(undefined), $(false)
+        if ( !selector ) {
+            return this;
+        }
</ins><span class="cx"> 
</span><del>-    // handleObj is passed to all event handlers
-    handleObj = jQuery.extend({
-    type: type,
-    origType: origType,
-    data: data,
-    handler: handler,
-    guid: handler.guid,
-    selector: selector,
-    needsContext: selector &amp;&amp; jQuery.expr.match.needsContext.test( selector ),
-    namespace: namespaces.join(&quot;.&quot;)
-    }, handleObjIn );
</del><ins>+        // Handle HTML strings
+        if ( typeof selector === &quot;string&quot; ) {
+            if ( selector[0] === &quot;&lt;&quot; &amp;&amp; selector[ selector.length - 1 ] === &quot;&gt;&quot; &amp;&amp; selector.length &gt;= 3 ) {
+                // Assume that strings that start and end with &lt;&gt; are HTML and skip the regex check
+                match = [ null, selector, null ];
</ins><span class="cx"> 
</span><del>-    // Init the event handler queue if we're the first
-    if ( !(handlers = events[ type ]) ) {
-    handlers = events[ type ] = [];
-    handlers.delegateCount = 0;
</del><ins>+            } else {
+                match = rquickExpr.exec( selector );
+            }
</ins><span class="cx"> 
</span><del>-    // Only use addEventListener/attachEvent if the special events handler returns false
-    if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
-    // Bind the global event handler to the element
-    if ( elem.addEventListener ) {
-    elem.addEventListener( type, eventHandle, false );
</del><ins>+            // Match html or make sure no context is specified for #id
+            if ( match &amp;&amp; (match[1] || !context) ) {
</ins><span class="cx"> 
</span><del>-    } else if ( elem.attachEvent ) {
-    elem.attachEvent( &quot;on&quot; + type, eventHandle );
-    }
-    }
-    }
</del><ins>+                // HANDLE: $(html) -&gt; $(array)
+                if ( match[1] ) {
+                    context = context instanceof jQuery ? context[0] : context;
</ins><span class="cx"> 
</span><del>-    if ( special.add ) {
-    special.add.call( elem, handleObj );
</del><ins>+                    // scripts is true for back-compat
+                    // Intentionally let the error be thrown if parseHTML is not present
+                    jQuery.merge( this, jQuery.parseHTML(
+                        match[1],
+                        context &amp;&amp; context.nodeType ? context.ownerDocument || context : document,
+                        true
+                    ) );
</ins><span class="cx"> 
</span><del>-    if ( !handleObj.handler.guid ) {
-    handleObj.handler.guid = handler.guid;
-    }
-    }
</del><ins>+                    // HANDLE: $(html, props)
+                    if ( rsingleTag.test( match[1] ) &amp;&amp; jQuery.isPlainObject( context ) ) {
+                        for ( match in context ) {
+                            // Properties of context are called as methods if possible
+                            if ( jQuery.isFunction( this[ match ] ) ) {
+                                this[ match ]( context[ match ] );
</ins><span class="cx"> 
</span><del>-    // Add to the element's handler list, delegates in front
-    if ( selector ) {
-    handlers.splice( handlers.delegateCount++, 0, handleObj );
-    } else {
-    handlers.push( handleObj );
-    }
</del><ins>+                            // ...and otherwise set as attributes
+                            } else {
+                                this.attr( match, context[ match ] );
+                            }
+                        }
+                    }
</ins><span class="cx"> 
</span><del>-    // Keep track of which events have ever been used, for event optimization
-    jQuery.event.global[ type ] = true;
-    }
</del><ins>+                    return this;
</ins><span class="cx"> 
</span><del>-    // Nullify elem to prevent memory leaks in IE
-    elem = null;
-    },
</del><ins>+                // HANDLE: $(#id)
+                } else {
+                    elem = document.getElementById( match[2] );
</ins><span class="cx"> 
</span><del>-    // Detach an event or set of events from an element
-    remove: function( elem, types, handler, selector, mappedTypes ) {
-    var j, handleObj, tmp,
-    origCount, t, events,
-    special, handlers, type,
-    namespaces, origType,
-    elemData = jQuery.hasData( elem ) &amp;&amp; jQuery._data( elem );
</del><ins>+                    // Check parentNode to catch when Blackberry 4.6 returns
+                    // nodes that are no longer in the document #6963
+                    if ( elem &amp;&amp; elem.parentNode ) {
+                        // Inject the element directly into the jQuery object
+                        this.length = 1;
+                        this[0] = elem;
+                    }
</ins><span class="cx"> 
</span><del>-    if ( !elemData || !(events = elemData.events) ) {
-    return;
-    }
</del><ins>+                    this.context = document;
+                    this.selector = selector;
+                    return this;
+                }
</ins><span class="cx"> 
</span><del>-    // Once for each type.namespace in types; type may be omitted
-    types = ( types || &quot;&quot; ).match( core_rnotwhite ) || [&quot;&quot;];
-    t = types.length;
-    while ( t-- ) {
-    tmp = rtypenamespace.exec( types[t] ) || [];
-    type = origType = tmp[1];
-    namespaces = ( tmp[2] || &quot;&quot; ).split( &quot;.&quot; ).sort();
</del><ins>+            // HANDLE: $(expr, $(...))
+            } else if ( !context || context.jquery ) {
+                return ( context || rootjQuery ).find( selector );
</ins><span class="cx"> 
</span><del>-    // Unbind all events (on this namespace, if provided) for the element
-    if ( !type ) {
-    for ( type in events ) {
-    jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
-    }
-    continue;
-    }
</del><ins>+            // HANDLE: $(expr, context)
+            // (which is just equivalent to: $(context).find(expr)
+            } else {
+                return this.constructor( context ).find( selector );
+            }
</ins><span class="cx"> 
</span><del>-    special = jQuery.event.special[ type ] || {};
-    type = ( selector ? special.delegateType : special.bindType ) || type;
-    handlers = events[ type ] || [];
-    tmp = tmp[2] &amp;&amp; new RegExp( &quot;(^|\\.)&quot; + namespaces.join(&quot;\\.(?:.*\\.|)&quot;) + &quot;(\\.|$)&quot; );
</del><ins>+        // HANDLE: $(DOMElement)
+        } else if ( selector.nodeType ) {
+            this.context = this[0] = selector;
+            this.length = 1;
+            return this;
</ins><span class="cx"> 
</span><del>-    // Remove matching events
-    origCount = j = handlers.length;
-    while ( j-- ) {
-    handleObj = handlers[ j ];
</del><ins>+        // HANDLE: $(function)
+        // Shortcut for document ready
+        } else if ( jQuery.isFunction( selector ) ) {
+            return typeof rootjQuery.ready !== &quot;undefined&quot; ?
+                rootjQuery.ready( selector ) :
+                // Execute immediately if ready is not present
+                selector( jQuery );
+        }
</ins><span class="cx"> 
</span><del>-    if ( ( mappedTypes || origType === handleObj.origType ) &amp;&amp;
-    ( !handler || handler.guid === handleObj.guid ) &amp;&amp;
-    ( !tmp || tmp.test( handleObj.namespace ) ) &amp;&amp;
-    ( !selector || selector === handleObj.selector || selector === &quot;**&quot; &amp;&amp; handleObj.selector ) ) {
-    handlers.splice( j, 1 );
</del><ins>+        if ( selector.selector !== undefined ) {
+            this.selector = selector.selector;
+            this.context = selector.context;
+        }
</ins><span class="cx"> 
</span><del>-    if ( handleObj.selector ) {
-    handlers.delegateCount--;
-    }
-    if ( special.remove ) {
-    special.remove.call( elem, handleObj );
-    }
-    }
-    }
</del><ins>+        return jQuery.makeArray( selector, this );
+    };
</ins><span class="cx"> 
</span><del>-    // Remove generic event handler if we removed something and no more handlers exist
-    // (avoids potential for endless recursion during removal of special event handlers)
-    if ( origCount &amp;&amp; !handlers.length ) {
-    if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
-    jQuery.removeEvent( elem, type, elemData.handle );
-    }
</del><ins>+// Give the init function the jQuery prototype for later instantiation
+init.prototype = jQuery.fn;
</ins><span class="cx"> 
</span><del>-    delete events[ type ];
-    }
-    }
</del><ins>+// Initialize central reference
+rootjQuery = jQuery( document );
</ins><span class="cx"> 
</span><del>-    // Remove the expando if it's no longer used
-    if ( jQuery.isEmptyObject( events ) ) {
-    delete elemData.handle;
</del><span class="cx"> 
</span><del>-    // removeData also checks for emptiness and clears the expando if empty
-    // so use it instead of delete
-    jQuery._removeData( elem, &quot;events&quot; );
-    }
</del><ins>+var rparentsprev = /^(?:parents|prev(?:Until|All))/,
+    // methods guaranteed to produce a unique set when starting from a unique set
+    guaranteedUnique = {
+        children: true,
+        contents: true,
+        next: true,
+        prev: true
+    };
+
+jQuery.extend({
+    dir: function( elem, dir, until ) {
+        var matched = [],
+            truncate = until !== undefined;
+
+        while ( (elem = elem[ dir ]) &amp;&amp; elem.nodeType !== 9 ) {
+            if ( elem.nodeType === 1 ) {
+                if ( truncate &amp;&amp; jQuery( elem ).is( until ) ) {
+                    break;
+                }
+                matched.push( elem );
+            }
+        }
+        return matched;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    trigger: function( event, data, elem, onlyHandlers ) {
-    var handle, ontype, cur,
-    bubbleType, special, tmp, i,
-    eventPath = [ elem || document ],
-    type = core_hasOwn.call( event, &quot;type&quot; ) ? event.type : event,
-    namespaces = core_hasOwn.call( event, &quot;namespace&quot; ) ? event.namespace.split(&quot;.&quot;) : [];
</del><ins>+    sibling: function( n, elem ) {
+        var matched = [];
</ins><span class="cx"> 
</span><del>-    cur = tmp = elem = elem || document;
</del><ins>+        for ( ; n; n = n.nextSibling ) {
+            if ( n.nodeType === 1 &amp;&amp; n !== elem ) {
+                matched.push( n );
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // Don't do events on text and comment nodes
-    if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
-    return;
</del><ins>+        return matched;
</ins><span class="cx">     }
</span><ins>+});
</ins><span class="cx"> 
</span><del>-    // focus/blur morphs to focusin/out; ensure we're not firing them right now
-    if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
-    return;
-    }
</del><ins>+jQuery.fn.extend({
+    has: function( target ) {
+        var targets = jQuery( target, this ),
+            l = targets.length;
</ins><span class="cx"> 
</span><del>-    if ( type.indexOf(&quot;.&quot;) &gt;= 0 ) {
-    // Namespaced trigger; create a regexp to match event type in handle()
-    namespaces = type.split(&quot;.&quot;);
-    type = namespaces.shift();
-    namespaces.sort();
-    }
-    ontype = type.indexOf(&quot;:&quot;) &lt; 0 &amp;&amp; &quot;on&quot; + type;
</del><ins>+        return this.filter(function() {
+            var i = 0;
+            for ( ; i &lt; l; i++ ) {
+                if ( jQuery.contains( this, targets[i] ) ) {
+                    return true;
+                }
+            }
+        });
+    },
</ins><span class="cx"> 
</span><del>-    // Caller can pass in a jQuery.Event object, Object, or just an event type string
-    event = event[ jQuery.expando ] ?
-    event :
-    new jQuery.Event( type, typeof event === &quot;object&quot; &amp;&amp; event );
</del><ins>+    closest: function( selectors, context ) {
+        var cur,
+            i = 0,
+            l = this.length,
+            matched = [],
+            pos = rneedsContext.test( selectors ) || typeof selectors !== &quot;string&quot; ?
+                jQuery( selectors, context || this.context ) :
+                0;
</ins><span class="cx"> 
</span><del>-    event.isTrigger = true;
-    event.namespace = namespaces.join(&quot;.&quot;);
-    event.namespace_re = event.namespace ?
-    new RegExp( &quot;(^|\\.)&quot; + namespaces.join(&quot;\\.(?:.*\\.|)&quot;) + &quot;(\\.|$)&quot; ) :
-    null;
</del><ins>+        for ( ; i &lt; l; i++ ) {
+            for ( cur = this[i]; cur &amp;&amp; cur !== context; cur = cur.parentNode ) {
+                // Always skip document fragments
+                if ( cur.nodeType &lt; 11 &amp;&amp; (pos ?
+                    pos.index(cur) &gt; -1 :
</ins><span class="cx"> 
</span><del>-    // Clean up the event in case it is being reused
-    event.result = undefined;
-    if ( !event.target ) {
-    event.target = elem;
-    }
</del><ins>+                    // Don't pass non-elements to Sizzle
+                    cur.nodeType === 1 &amp;&amp;
+                        jQuery.find.matchesSelector(cur, selectors)) ) {
</ins><span class="cx"> 
</span><del>-    // Clone any incoming data and prepend the event, creating the handler arg list
-    data = data == null ?
-    [ event ] :
-    jQuery.makeArray( data, [ event ] );
</del><ins>+                    matched.push( cur );
+                    break;
+                }
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // Allow special events to draw outside the lines
-    special = jQuery.event.special[ type ] || {};
-    if ( !onlyHandlers &amp;&amp; special.trigger &amp;&amp; special.trigger.apply( elem, data ) === false ) {
-    return;
-    }
</del><ins>+        return this.pushStack( matched.length &gt; 1 ? jQuery.unique( matched ) : matched );
+    },
</ins><span class="cx"> 
</span><del>-    // Determine event propagation path in advance, per W3C events spec (#9951)
-    // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
-    if ( !onlyHandlers &amp;&amp; !special.noBubble &amp;&amp; !jQuery.isWindow( elem ) ) {
</del><ins>+    // Determine the position of an element within
+    // the matched set of elements
+    index: function( elem ) {
</ins><span class="cx"> 
</span><del>-    bubbleType = special.delegateType || type;
-    if ( !rfocusMorph.test( bubbleType + type ) ) {
-    cur = cur.parentNode;
-    }
-    for ( ; cur; cur = cur.parentNode ) {
-    eventPath.push( cur );
-    tmp = cur;
-    }
</del><ins>+        // No argument, return index in parent
+        if ( !elem ) {
+            return ( this[ 0 ] &amp;&amp; this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
+        }
</ins><span class="cx"> 
</span><del>-    // Only add window if we got to document (e.g., not plain obj or detached DOM)
-    if ( tmp === (elem.ownerDocument || document) ) {
-    eventPath.push( tmp.defaultView || tmp.parentWindow || window );
-    }
-    }
</del><ins>+        // index in selector
+        if ( typeof elem === &quot;string&quot; ) {
+            return indexOf.call( jQuery( elem ), this[ 0 ] );
+        }
</ins><span class="cx"> 
</span><del>-    // Fire handlers on the event path
-    i = 0;
-    while ( (cur = eventPath[i++]) &amp;&amp; !event.isPropagationStopped() ) {
</del><ins>+        // Locate the position of the desired element
+        return indexOf.call( this,
</ins><span class="cx"> 
</span><del>-    event.type = i &gt; 1 ?
-    bubbleType :
-    special.bindType || type;
</del><ins>+            // If it receives a jQuery object, the first element is used
+            elem.jquery ? elem[ 0 ] : elem
+        );
+    },
</ins><span class="cx"> 
</span><del>-    // jQuery handler
-    handle = ( jQuery._data( cur, &quot;events&quot; ) || {} )[ event.type ] &amp;&amp; jQuery._data( cur, &quot;handle&quot; );
-    if ( handle ) {
-    handle.apply( cur, data );
</del><ins>+    add: function( selector, context ) {
+        return this.pushStack(
+            jQuery.unique(
+                jQuery.merge( this.get(), jQuery( selector, context ) )
+            )
+        );
+    },
+
+    addBack: function( selector ) {
+        return this.add( selector == null ?
+            this.prevObject : this.prevObject.filter(selector)
+        );
</ins><span class="cx">     }
</span><ins>+});
</ins><span class="cx"> 
</span><del>-    // Native handler
-    handle = ontype &amp;&amp; cur[ ontype ];
-    if ( handle &amp;&amp; jQuery.acceptData( cur ) &amp;&amp; handle.apply &amp;&amp; handle.apply( cur, data ) === false ) {
-    event.preventDefault();
</del><ins>+function sibling( cur, dir ) {
+    while ( (cur = cur[dir]) &amp;&amp; cur.nodeType !== 1 ) {}
+    return cur;
+}
+
+jQuery.each({
+    parent: function( elem ) {
+        var parent = elem.parentNode;
+        return parent &amp;&amp; parent.nodeType !== 11 ? parent : null;
+    },
+    parents: function( elem ) {
+        return jQuery.dir( elem, &quot;parentNode&quot; );
+    },
+    parentsUntil: function( elem, i, until ) {
+        return jQuery.dir( elem, &quot;parentNode&quot;, until );
+    },
+    next: function( elem ) {
+        return sibling( elem, &quot;nextSibling&quot; );
+    },
+    prev: function( elem ) {
+        return sibling( elem, &quot;previousSibling&quot; );
+    },
+    nextAll: function( elem ) {
+        return jQuery.dir( elem, &quot;nextSibling&quot; );
+    },
+    prevAll: function( elem ) {
+        return jQuery.dir( elem, &quot;previousSibling&quot; );
+    },
+    nextUntil: function( elem, i, until ) {
+        return jQuery.dir( elem, &quot;nextSibling&quot;, until );
+    },
+    prevUntil: function( elem, i, until ) {
+        return jQuery.dir( elem, &quot;previousSibling&quot;, until );
+    },
+    siblings: function( elem ) {
+        return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
+    },
+    children: function( elem ) {
+        return jQuery.sibling( elem.firstChild );
+    },
+    contents: function( elem ) {
+        return elem.contentDocument || jQuery.merge( [], elem.childNodes );
</ins><span class="cx">     }
</span><del>-    }
-    event.type = type;
</del><ins>+}, function( name, fn ) {
+    jQuery.fn[ name ] = function( until, selector ) {
+        var matched = jQuery.map( this, fn, until );
</ins><span class="cx"> 
</span><del>-    // If nobody prevented the default action, do it now
-    if ( !onlyHandlers &amp;&amp; !event.isDefaultPrevented() ) {
</del><ins>+        if ( name.slice( -5 ) !== &quot;Until&quot; ) {
+            selector = until;
+        }
</ins><span class="cx"> 
</span><del>-    if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &amp;&amp;
-    !(type === &quot;click&quot; &amp;&amp; jQuery.nodeName( elem, &quot;a&quot; )) &amp;&amp; jQuery.acceptData( elem ) ) {
</del><ins>+        if ( selector &amp;&amp; typeof selector === &quot;string&quot; ) {
+            matched = jQuery.filter( selector, matched );
+        }
</ins><span class="cx"> 
</span><del>-    // Call a native DOM method on the target with the same name name as the event.
-    // Can't use an .isFunction() check here because IE6/7 fails that test.
-    // Don't do default actions on window, that's where global variables be (#6170)
-    if ( ontype &amp;&amp; elem[ type ] &amp;&amp; !jQuery.isWindow( elem ) ) {
</del><ins>+        if ( this.length &gt; 1 ) {
+            // Remove duplicates
+            if ( !guaranteedUnique[ name ] ) {
+                jQuery.unique( matched );
+            }
</ins><span class="cx"> 
</span><del>-    // Don't re-trigger an onFOO event when we call its FOO() method
-    tmp = elem[ ontype ];
</del><ins>+            // Reverse order for parents* and prev-derivatives
+            if ( rparentsprev.test( name ) ) {
+                matched.reverse();
+            }
+        }
</ins><span class="cx"> 
</span><del>-    if ( tmp ) {
-    elem[ ontype ] = null;
-    }
</del><ins>+        return this.pushStack( matched );
+    };
+});
+var rnotwhite = (/\S+/g);
</ins><span class="cx"> 
</span><del>-    // Prevent re-triggering of the same event, since we already bubbled it above
-    jQuery.event.triggered = type;
-    try {
-    elem[ type ]();
-    } catch ( e ) {
-    // IE&lt;9 dies on focus/blur to hidden element (#1486,#12518)
-    // only reproducible on winXP IE8 native, not IE9 in IE8 mode
-    }
-    jQuery.event.triggered = undefined;
</del><span class="cx"> 
</span><del>-    if ( tmp ) {
-    elem[ ontype ] = tmp;
-    }
-    }
-    }
-    }
</del><span class="cx"> 
</span><del>-    return event.result;
-    },
</del><ins>+// String to Object options format cache
+var optionsCache = {};
</ins><span class="cx"> 
</span><del>-    dispatch: function( event ) {
</del><ins>+// Convert String-formatted options into Object-formatted ones and store in cache
+function createOptions( options ) {
+    var object = optionsCache[ options ] = {};
+    jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
+        object[ flag ] = true;
+    });
+    return object;
+}
</ins><span class="cx"> 
</span><del>-    // Make a writable jQuery.Event from the native event object
-    event = jQuery.event.fix( event );
</del><ins>+/*
+ * Create a callback list using the following parameters:
+ *
+ *  options: an optional list of space-separated options that will change how
+ *           the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * &quot;fired&quot; multiple times.
+ *
+ * Possible options:
+ *
+ *  once:           will ensure the callback list can only be fired once (like a Deferred)
+ *
+ *  memory:         will keep track of previous values and will call any callback added
+ *                  after the list has been fired right away with the latest &quot;memorized&quot;
+ *                  values (like a Deferred)
+ *
+ *  unique:         will ensure a callback can only be added once (no duplicate in the list)
+ *
+ *  stopOnFalse:    interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
</ins><span class="cx"> 
</span><del>-    var i, ret, handleObj, matched, j,
-    handlerQueue = [],
-    args = core_slice.call( arguments ),
-    handlers = ( jQuery._data( this, &quot;events&quot; ) || {} )[ event.type ] || [],
-    special = jQuery.event.special[ event.type ] || {};
</del><ins>+    // Convert options from String-formatted to Object-formatted if needed
+    // (we check in cache first)
+    options = typeof options === &quot;string&quot; ?
+        ( optionsCache[ options ] || createOptions( options ) ) :
+        jQuery.extend( {}, options );
</ins><span class="cx"> 
</span><del>-    // Use the fix-ed jQuery.Event rather than the (read-only) native event
-    args[0] = event;
-    event.delegateTarget = this;
</del><ins>+    var // Last fire value (for non-forgettable lists)
+        memory,
+        // Flag to know if list was already fired
+        fired,
+        // Flag to know if list is currently firing
+        firing,
+        // First callback to fire (used internally by add and fireWith)
+        firingStart,
+        // End of the loop when firing
+        firingLength,
+        // Index of currently firing callback (modified by remove if needed)
+        firingIndex,
+        // Actual callback list
+        list = [],
+        // Stack of fire calls for repeatable lists
+        stack = !options.once &amp;&amp; [],
+        // Fire callbacks
+        fire = function( data ) {
+            memory = options.memory &amp;&amp; data;
+            fired = true;
+            firingIndex = firingStart || 0;
+            firingStart = 0;
+            firingLength = list.length;
+            firing = true;
+            for ( ; list &amp;&amp; firingIndex &lt; firingLength; firingIndex++ ) {
+                if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false &amp;&amp; options.stopOnFalse ) {
+                    memory = false; // To prevent further calls using add
+                    break;
+                }
+            }
+            firing = false;
+            if ( list ) {
+                if ( stack ) {
+                    if ( stack.length ) {
+                        fire( stack.shift() );
+                    }
+                } else if ( memory ) {
+                    list = [];
+                } else {
+                    self.disable();
+                }
+            }
+        },
+        // Actual Callbacks object
+        self = {
+            // Add a callback or a collection of callbacks to the list
+            add: function() {
+                if ( list ) {
+                    // First, we save the current length
+                    var start = list.length;
+                    (function add( args ) {
+                        jQuery.each( args, function( _, arg ) {
+                            var type = jQuery.type( arg );
+                            if ( type === &quot;function&quot; ) {
+                                if ( !options.unique || !self.has( arg ) ) {
+                                    list.push( arg );
+                                }
+                            } else if ( arg &amp;&amp; arg.length &amp;&amp; type !== &quot;string&quot; ) {
+                                // Inspect recursively
+                                add( arg );
+                            }
+                        });
+                    })( arguments );
+                    // Do we need to add the callbacks to the
+                    // current firing batch?
+                    if ( firing ) {
+                        firingLength = list.length;
+                    // With memory, if we're not firing then
+                    // we should call right away
+                    } else if ( memory ) {
+                        firingStart = start;
+                        fire( memory );
+                    }
+                }
+                return this;
+            },
+            // Remove a callback from the list
+            remove: function() {
+                if ( list ) {
+                    jQuery.each( arguments, function( _, arg ) {
+                        var index;
+                        while ( ( index = jQuery.inArray( arg, list, index ) ) &gt; -1 ) {
+                            list.splice( index, 1 );
+                            // Handle firing indexes
+                            if ( firing ) {
+                                if ( index &lt;= firingLength ) {
+                                    firingLength--;
+                                }
+                                if ( index &lt;= firingIndex ) {
+                                    firingIndex--;
+                                }
+                            }
+                        }
+                    });
+                }
+                return this;
+            },
+            // Check if a given callback is in the list.
+            // If no argument is given, return whether or not list has callbacks attached.
+            has: function( fn ) {
+                return fn ? jQuery.inArray( fn, list ) &gt; -1 : !!( list &amp;&amp; list.length );
+            },
+            // Remove all callbacks from the list
+            empty: function() {
+                list = [];
+                firingLength = 0;
+                return this;
+            },
+            // Have the list do nothing anymore
+            disable: function() {
+                list = stack = memory = undefined;
+                return this;
+            },
+            // Is it disabled?
+            disabled: function() {
+                return !list;
+            },
+            // Lock the list in its current state
+            lock: function() {
+                stack = undefined;
+                if ( !memory ) {
+                    self.disable();
+                }
+                return this;
+            },
+            // Is it locked?
+            locked: function() {
+                return !stack;
+            },
+            // Call all callbacks with the given context and arguments
+            fireWith: function( context, args ) {
+                if ( list &amp;&amp; ( !fired || stack ) ) {
+                    args = args || [];
+                    args = [ context, args.slice ? args.slice() : args ];
+                    if ( firing ) {
+                        stack.push( args );
+                    } else {
+                        fire( args );
+                    }
+                }
+                return this;
+            },
+            // Call all the callbacks with the given arguments
+            fire: function() {
+                self.fireWith( this, arguments );
+                return this;
+            },
+            // To know if the callbacks have already been called at least once
+            fired: function() {
+                return !!fired;
+            }
+        };
</ins><span class="cx"> 
</span><del>-    // Call the preDispatch hook for the mapped type, and let it bail if desired
-    if ( special.preDispatch &amp;&amp; special.preDispatch.call( this, event ) === false ) {
-    return;
-    }
</del><ins>+    return self;
+};
</ins><span class="cx"> 
</span><del>-    // Determine handlers
-    handlerQueue = jQuery.event.handlers.call( this, event, handlers );
</del><span class="cx"> 
</span><del>-    // Run delegates first; they may want to stop propagation beneath us
-    i = 0;
-    while ( (matched = handlerQueue[ i++ ]) &amp;&amp; !event.isPropagationStopped() ) {
-    event.currentTarget = matched.elem;
</del><ins>+jQuery.extend({
</ins><span class="cx"> 
</span><del>-    j = 0;
-    while ( (handleObj = matched.handlers[ j++ ]) &amp;&amp; !event.isImmediatePropagationStopped() ) {
</del><ins>+    Deferred: function( func ) {
+        var tuples = [
+                // action, add listener, listener list, final state
+                [ &quot;resolve&quot;, &quot;done&quot;, jQuery.Callbacks(&quot;once memory&quot;), &quot;resolved&quot; ],
+                [ &quot;reject&quot;, &quot;fail&quot;, jQuery.Callbacks(&quot;once memory&quot;), &quot;rejected&quot; ],
+                [ &quot;notify&quot;, &quot;progress&quot;, jQuery.Callbacks(&quot;memory&quot;) ]
+            ],
+            state = &quot;pending&quot;,
+            promise = {
+                state: function() {
+                    return state;
+                },
+                always: function() {
+                    deferred.done( arguments ).fail( arguments );
+                    return this;
+                },
+                then: function( /* fnDone, fnFail, fnProgress */ ) {
+                    var fns = arguments;
+                    return jQuery.Deferred(function( newDefer ) {
+                        jQuery.each( tuples, function( i, tuple ) {
+                            var fn = jQuery.isFunction( fns[ i ] ) &amp;&amp; fns[ i ];
+                            // deferred[ done | fail | progress ] for forwarding actions to newDefer
+                            deferred[ tuple[1] ](function() {
+                                var returned = fn &amp;&amp; fn.apply( this, arguments );
+                                if ( returned &amp;&amp; jQuery.isFunction( returned.promise ) ) {
+                                    returned.promise()
+                                        .done( newDefer.resolve )
+                                        .fail( newDefer.reject )
+                                        .progress( newDefer.notify );
+                                } else {
+                                    newDefer[ tuple[ 0 ] + &quot;With&quot; ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
+                                }
+                            });
+                        });
+                        fns = null;
+                    }).promise();
+                },
+                // Get a promise for this deferred
+                // If obj is provided, the promise aspect is added to the object
+                promise: function( obj ) {
+                    return obj != null ? jQuery.extend( obj, promise ) : promise;
+                }
+            },
+            deferred = {};
</ins><span class="cx"> 
</span><del>-    // Triggered event must either 1) have no namespace, or
-    // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
-    if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
</del><ins>+        // Keep pipe for back-compat
+        promise.pipe = promise.then;
</ins><span class="cx"> 
</span><del>-    event.handleObj = handleObj;
-    event.data = handleObj.data;
</del><ins>+        // Add list-specific methods
+        jQuery.each( tuples, function( i, tuple ) {
+            var list = tuple[ 2 ],
+                stateString = tuple[ 3 ];
</ins><span class="cx"> 
</span><del>-    ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
-    .apply( matched.elem, args );
</del><ins>+            // promise[ done | fail | progress ] = list.add
+            promise[ tuple[1] ] = list.add;
</ins><span class="cx"> 
</span><del>-    if ( ret !== undefined ) {
-    if ( (event.result = ret) === false ) {
-    event.preventDefault();
-    event.stopPropagation();
-    }
-    }
-    }
-    }
-    }
</del><ins>+            // Handle state
+            if ( stateString ) {
+                list.add(function() {
+                    // state = [ resolved | rejected ]
+                    state = stateString;
</ins><span class="cx"> 
</span><del>-    // Call the postDispatch hook for the mapped type
-    if ( special.postDispatch ) {
-    special.postDispatch.call( this, event );
-    }
</del><ins>+                // [ reject_list | resolve_list ].disable; progress_list.lock
+                }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
+            }
</ins><span class="cx"> 
</span><del>-    return event.result;
-    },
</del><ins>+            // deferred[ resolve | reject | notify ]
+            deferred[ tuple[0] ] = function() {
+                deferred[ tuple[0] + &quot;With&quot; ]( this === deferred ? promise : this, arguments );
+                return this;
+            };
+            deferred[ tuple[0] + &quot;With&quot; ] = list.fireWith;
+        });
</ins><span class="cx"> 
</span><del>-    handlers: function( event, handlers ) {
-    var sel, handleObj, matches, i,
-    handlerQueue = [],
-    delegateCount = handlers.delegateCount,
-    cur = event.target;
</del><ins>+        // Make the deferred a promise
+        promise.promise( deferred );
</ins><span class="cx"> 
</span><del>-    // Find delegate handlers
-    // Black-hole SVG &lt;use&gt; instance trees (#13180)
-    // Avoid non-left-click bubbling in Firefox (#3861)
-    if ( delegateCount &amp;&amp; cur.nodeType &amp;&amp; (!event.button || event.type !== &quot;click&quot;) ) {
</del><ins>+        // Call given func if any
+        if ( func ) {
+            func.call( deferred, deferred );
+        }
</ins><span class="cx"> 
</span><del>-    for ( ; cur != this; cur = cur.parentNode || this ) {
</del><ins>+        // All done!
+        return deferred;
+    },
</ins><span class="cx"> 
</span><del>-    // Don't check non-elements (#13208)
-    // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
-    if ( cur.nodeType === 1 &amp;&amp; (cur.disabled !== true || event.type !== &quot;click&quot;) ) {
-    matches = [];
-    for ( i = 0; i &lt; delegateCount; i++ ) {
-    handleObj = handlers[ i ];
</del><ins>+    // Deferred helper
+    when: function( subordinate /* , ..., subordinateN */ ) {
+        var i = 0,
+            resolveValues = slice.call( arguments ),
+            length = resolveValues.length,
</ins><span class="cx"> 
</span><del>-    // Don't conflict with Object.prototype properties (#13203)
-    sel = handleObj.selector + &quot; &quot;;
</del><ins>+            // the count of uncompleted subordinates
+            remaining = length !== 1 || ( subordinate &amp;&amp; jQuery.isFunction( subordinate.promise ) ) ? length : 0,
</ins><span class="cx"> 
</span><del>-    if ( matches[ sel ] === undefined ) {
-    matches[ sel ] = handleObj.needsContext ?
-    jQuery( sel, this ).index( cur ) &gt;= 0 :
-    jQuery.find( sel, this, null, [ cur ] ).length;
-    }
-    if ( matches[ sel ] ) {
-    matches.push( handleObj );
-    }
-    }
-    if ( matches.length ) {
-    handlerQueue.push({ elem: cur, handlers: matches });
-    }
-    }
-    }
-    }
</del><ins>+            // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
+            deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
</ins><span class="cx"> 
</span><del>-    // Add the remaining (directly-bound) handlers
-    if ( delegateCount &lt; handlers.length ) {
-    handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
-    }
</del><ins>+            // Update function for both resolve and progress values
+            updateFunc = function( i, contexts, values ) {
+                return function( value ) {
+                    contexts[ i ] = this;
+                    values[ i ] = arguments.length &gt; 1 ? slice.call( arguments ) : value;
+                    if ( values === progressValues ) {
+                        deferred.notifyWith( contexts, values );
+                    } else if ( !( --remaining ) ) {
+                        deferred.resolveWith( contexts, values );
+                    }
+                };
+            },
</ins><span class="cx"> 
</span><del>-    return handlerQueue;
-    },
</del><ins>+            progressValues, progressContexts, resolveContexts;
</ins><span class="cx"> 
</span><del>-    fix: function( event ) {
-    if ( event[ jQuery.expando ] ) {
-    return event;
-    }
</del><ins>+        // add listeners to Deferred subordinates; treat others as resolved
+        if ( length &gt; 1 ) {
+            progressValues = new Array( length );
+            progressContexts = new Array( length );
+            resolveContexts = new Array( length );
+            for ( ; i &lt; length; i++ ) {
+                if ( resolveValues[ i ] &amp;&amp; jQuery.isFunction( resolveValues[ i ].promise ) ) {
+                    resolveValues[ i ].promise()
+                        .done( updateFunc( i, resolveContexts, resolveValues ) )
+                        .fail( deferred.reject )
+                        .progress( updateFunc( i, progressContexts, progressValues ) );
+                } else {
+                    --remaining;
+                }
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // Create a writable copy of the event object and normalize some properties
-    var i, prop, copy,
-    type = event.type,
-    originalEvent = event,
-    fixHook = this.fixHooks[ type ];
</del><ins>+        // if we're not waiting on anything, resolve the master
+        if ( !remaining ) {
+            deferred.resolveWith( resolveContexts, resolveValues );
+        }
</ins><span class="cx"> 
</span><del>-    if ( !fixHook ) {
-    this.fixHooks[ type ] = fixHook =
-    rmouseEvent.test( type ) ? this.mouseHooks :
-    rkeyEvent.test( type ) ? this.keyHooks :
-    {};
</del><ins>+        return deferred.promise();
</ins><span class="cx">     }
</span><del>-    copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
</del><ins>+});
</ins><span class="cx"> 
</span><del>-    event = new jQuery.Event( originalEvent );
</del><span class="cx"> 
</span><del>-    i = copy.length;
-    while ( i-- ) {
-    prop = copy[ i ];
-    event[ prop ] = originalEvent[ prop ];
-    }
</del><ins>+// The deferred used on DOM ready
+var readyList;
</ins><span class="cx"> 
</span><del>-    // Support: IE&lt;9
-    // Fix target property (#1925)
-    if ( !event.target ) {
-    event.target = originalEvent.srcElement || document;
-    }
</del><ins>+jQuery.fn.ready = function( fn ) {
+    // Add the callback
+    jQuery.ready.promise().done( fn );
</ins><span class="cx"> 
</span><del>-    // Support: Chrome 23+, Safari?
-    // Target should not be a text node (#504, #13143)
-    if ( event.target.nodeType === 3 ) {
-    event.target = event.target.parentNode;
-    }
</del><ins>+    return this;
+};
</ins><span class="cx"> 
</span><del>-    // Support: IE&lt;9
-    // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
-    event.metaKey = !!event.metaKey;
</del><ins>+jQuery.extend({
+    // Is the DOM ready to be used? Set to true once it occurs.
+    isReady: false,
</ins><span class="cx"> 
</span><del>-    return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
</del><ins>+    // A counter to track how many items to wait for before
+    // the ready event fires. See #6781
+    readyWait: 1,
+
+    // Hold (or release) the ready event
+    holdReady: function( hold ) {
+        if ( hold ) {
+            jQuery.readyWait++;
+        } else {
+            jQuery.ready( true );
+        }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    // Includes some event props shared by KeyEvent and MouseEvent
-    props: &quot;altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which&quot;.split(&quot; &quot;),
</del><ins>+    // Handle when the DOM is ready
+    ready: function( wait ) {
</ins><span class="cx"> 
</span><del>-    fixHooks: {},
</del><ins>+        // Abort if there are pending holds or we're already ready
+        if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+            return;
+        }
</ins><span class="cx"> 
</span><del>-    keyHooks: {
-    props: &quot;char charCode key keyCode&quot;.split(&quot; &quot;),
-    filter: function( event, original ) {
</del><ins>+        // Remember that the DOM is ready
+        jQuery.isReady = true;
</ins><span class="cx"> 
</span><del>-    // Add which for key events
-    if ( event.which == null ) {
-    event.which = original.charCode != null ? original.charCode : original.keyCode;
-    }
</del><ins>+        // If a normal DOM Ready event fired, decrement, and wait if need be
+        if ( wait !== true &amp;&amp; --jQuery.readyWait &gt; 0 ) {
+            return;
+        }
</ins><span class="cx"> 
</span><del>-    return event;
</del><ins>+        // If there are functions bound, to execute
+        readyList.resolveWith( document, [ jQuery ] );
+
+        // Trigger any bound ready events
+        if ( jQuery.fn.trigger ) {
+            jQuery( document ).trigger(&quot;ready&quot;).off(&quot;ready&quot;);
+        }
</ins><span class="cx">     }
</span><del>-    },
</del><ins>+});
</ins><span class="cx"> 
</span><del>-    mouseHooks: {
-    props: &quot;button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement&quot;.split(&quot; &quot;),
-    filter: function( event, original ) {
-    var body, eventDoc, doc,
-    button = original.button,
-    fromElement = original.fromElement;
</del><ins>+/**
+ * The ready event handler and self cleanup method
+ */
+function completed() {
+    document.removeEventListener( &quot;DOMContentLoaded&quot;, completed, false );
+    window.removeEventListener( &quot;load&quot;, completed, false );
+    jQuery.ready();
+}
</ins><span class="cx"> 
</span><del>-    // Calculate pageX/Y if missing and clientX/Y available
-    if ( event.pageX == null &amp;&amp; original.clientX != null ) {
-    eventDoc = event.target.ownerDocument || document;
-    doc = eventDoc.documentElement;
-    body = eventDoc.body;
</del><ins>+jQuery.ready.promise = function( obj ) {
+    if ( !readyList ) {
</ins><span class="cx"> 
</span><del>-    event.pageX = original.clientX + ( doc &amp;&amp; doc.scrollLeft || body &amp;&amp; body.scrollLeft || 0 ) - ( doc &amp;&amp; doc.clientLeft || body &amp;&amp; body.clientLeft || 0 );
-    event.pageY = original.clientY + ( doc &amp;&amp; doc.scrollTop  || body &amp;&amp; body.scrollTop  || 0 ) - ( doc &amp;&amp; doc.clientTop  || body &amp;&amp; body.clientTop  || 0 );
-    }
</del><ins>+        readyList = jQuery.Deferred();
</ins><span class="cx"> 
</span><del>-    // Add relatedTarget, if necessary
-    if ( !event.relatedTarget &amp;&amp; fromElement ) {
-    event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
-    }
</del><ins>+        // Catch cases where $(document).ready() is called after the browser event has already occurred.
+        // we once tried to use readyState &quot;interactive&quot; here, but it caused issues like the one
+        // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
+        if ( document.readyState === &quot;complete&quot; ) {
+            // Handle it asynchronously to allow scripts the opportunity to delay ready
+            setTimeout( jQuery.ready );
</ins><span class="cx"> 
</span><del>-    // Add which for click: 1 === left; 2 === middle; 3 === right
-    // Note: button is not normalized, so don't use it
-    if ( !event.which &amp;&amp; button !== undefined ) {
-    event.which = ( button &amp; 1 ? 1 : ( button &amp; 2 ? 3 : ( button &amp; 4 ? 2 : 0 ) ) );
-    }
</del><ins>+        } else {
</ins><span class="cx"> 
</span><del>-    return event;
-    }
-    },
</del><ins>+            // Use the handy event callback
+            document.addEventListener( &quot;DOMContentLoaded&quot;, completed, false );
</ins><span class="cx"> 
</span><del>-    special: {
-    load: {
-    // Prevent triggered image.load events from bubbling to window.load
-    noBubble: true
-    },
-    click: {
-    // For checkbox, fire native event so checked state will be right
-    trigger: function() {
-    if ( jQuery.nodeName( this, &quot;input&quot; ) &amp;&amp; this.type === &quot;checkbox&quot; &amp;&amp; this.click ) {
-    this.click();
-    return false;
</del><ins>+            // A fallback to window.onload, that will always work
+            window.addEventListener( &quot;load&quot;, completed, false );
+        }
</ins><span class="cx">     }
</span><del>-    }
-    },
-    focus: {
-    // Fire native event if possible so blur/focus sequence is correct
-    trigger: function() {
-    if ( this !== document.activeElement &amp;&amp; this.focus ) {
-    try {
-    this.focus();
-    return false;
-    } catch ( e ) {
-    // Support: IE&lt;9
-    // If we error on focus to hidden element (#1486, #12518),
-    // let .trigger() run the handlers
-    }
-    }
-    },
-    delegateType: &quot;focusin&quot;
-    },
-    blur: {
-    trigger: function() {
-    if ( this === document.activeElement &amp;&amp; this.blur ) {
-    this.blur();
-    return false;
-    }
-    },
-    delegateType: &quot;focusout&quot;
-    },
</del><ins>+    return readyList.promise( obj );
+};
</ins><span class="cx"> 
</span><del>-    beforeunload: {
-    postDispatch: function( event ) {
</del><ins>+// Kick off the DOM ready check even if the user does not
+jQuery.ready.promise();
</ins><span class="cx"> 
</span><del>-    // Even when returnValue equals to undefined Firefox will still show alert
-    if ( event.result !== undefined ) {
-    event.originalEvent.returnValue = event.result;
-    }
-    }
-    }
-    },
</del><span class="cx"> 
</span><del>-    simulate: function( type, elem, event, bubble ) {
-    // Piggyback on a donor event to simulate a different one.
-    // Fake originalEvent to avoid donor's stopPropagation, but if the
-    // simulated event prevents default then we do the same on the donor.
-    var e = jQuery.extend(
-    new jQuery.Event(),
-    event,
-    { type: type,
-    isSimulated: true,
-    originalEvent: {}
-    }
-    );
-    if ( bubble ) {
-    jQuery.event.trigger( e, null, elem );
-    } else {
-    jQuery.event.dispatch.call( elem, e );
-    }
-    if ( e.isDefaultPrevented() ) {
-    event.preventDefault();
-    }
-    }
-};
</del><span class="cx"> 
</span><del>-jQuery.removeEvent = document.removeEventListener ?
-    function( elem, type, handle ) {
-    if ( elem.removeEventListener ) {
-    elem.removeEventListener( type, handle, false );
-    }
-    } :
-    function( elem, type, handle ) {
-    var name = &quot;on&quot; + type;
</del><span class="cx"> 
</span><del>-    if ( elem.detachEvent ) {
</del><ins>+// Multifunctional method to get and set values of a collection
+// The value/s can optionally be executed if it's a function
+var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
+    var i = 0,
+        len = elems.length,
+        bulk = key == null;
</ins><span class="cx"> 
</span><del>-    // #8545, #7054, preventing memory leaks for custom events in IE6-8
-    // detachEvent needed property on element, by name of that event, to properly expose it to GC
-    if ( typeof elem[ name ] === core_strundefined ) {
-    elem[ name ] = null;
-    }
</del><ins>+    // Sets many values
+    if ( jQuery.type( key ) === &quot;object&quot; ) {
+        chainable = true;
+        for ( i in key ) {
+            jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
+        }
</ins><span class="cx"> 
</span><del>-    elem.detachEvent( name, handle );
-    }
-    };
</del><ins>+    // Sets one value
+    } else if ( value !== undefined ) {
+        chainable = true;
</ins><span class="cx"> 
</span><del>-jQuery.Event = function( src, props ) {
-    // Allow instantiation without the 'new' keyword
-    if ( !(this instanceof jQuery.Event) ) {
-    return new jQuery.Event( src, props );
-    }
</del><ins>+        if ( !jQuery.isFunction( value ) ) {
+            raw = true;
+        }
</ins><span class="cx"> 
</span><del>-    // Event object
-    if ( src &amp;&amp; src.type ) {
-    this.originalEvent = src;
-    this.type = src.type;
</del><ins>+        if ( bulk ) {
+            // Bulk operations run against the entire set
+            if ( raw ) {
+                fn.call( elems, value );
+                fn = null;
</ins><span class="cx"> 
</span><del>-    // Events bubbling up the document may have been marked as prevented
-    // by a handler lower down the tree; reflect the correct value.
-    this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
-    src.getPreventDefault &amp;&amp; src.getPreventDefault() ) ? returnTrue : returnFalse;
</del><ins>+            // ...except when executing function values
+            } else {
+                bulk = fn;
+                fn = function( elem, key, value ) {
+                    return bulk.call( jQuery( elem ), value );
+                };
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // Event type
-    } else {
-    this.type = src;
</del><ins>+        if ( fn ) {
+            for ( ; i &lt; len; i++ ) {
+                fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
+            }
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Put explicitly provided properties onto the event object
-    if ( props ) {
-    jQuery.extend( this, props );
-    }
</del><ins>+    return chainable ?
+        elems :
</ins><span class="cx"> 
</span><del>-    // Create a timestamp if incoming event doesn't have one
-    this.timeStamp = src &amp;&amp; src.timeStamp || jQuery.now();
</del><ins>+        // Gets
+        bulk ?
+            fn.call( elems ) :
+            len ? fn( elems[0], key ) : emptyGet;
+};
</ins><span class="cx"> 
</span><del>-    // Mark it as fixed
-    this[ jQuery.expando ] = true;
</del><ins>+
+/**
+ * Determines whether an object can have data
+ */
+jQuery.acceptData = function( owner ) {
+    // Accepts only:
+    //  - Node
+    //    - Node.ELEMENT_NODE
+    //    - Node.DOCUMENT_NODE
+    //  - Object
+    //    - Any
+    /* jshint -W018 */
+    return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
-// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
-jQuery.Event.prototype = {
-    isDefaultPrevented: returnFalse,
-    isPropagationStopped: returnFalse,
-    isImmediatePropagationStopped: returnFalse,
</del><span class="cx"> 
</span><del>-    preventDefault: function() {
-    var e = this.originalEvent;
</del><ins>+function Data() {
+    // Support: Android &lt; 4,
+    // Old WebKit does not have Object.preventExtensions/freeze method,
+    // return new empty object instead with no [[set]] accessor
+    Object.defineProperty( this.cache = {}, 0, {
+        get: function() {
+            return {};
+        }
+    });
</ins><span class="cx"> 
</span><del>-    this.isDefaultPrevented = returnTrue;
-    if ( !e ) {
-    return;
-    }
</del><ins>+    this.expando = jQuery.expando + Math.random();
+}
</ins><span class="cx"> 
</span><del>-    // If preventDefault exists, run it on the original event
-    if ( e.preventDefault ) {
-    e.preventDefault();
</del><ins>+Data.uid = 1;
+Data.accepts = jQuery.acceptData;
</ins><span class="cx"> 
</span><del>-    // Support: IE
-    // Otherwise set the returnValue property of the original event to false
-    } else {
-    e.returnValue = false;
-    }
-    },
-    stopPropagation: function() {
-    var e = this.originalEvent;
</del><ins>+Data.prototype = {
+    key: function( owner ) {
+        // We can accept data for non-element nodes in modern browsers,
+        // but we should not, see #8335.
+        // Always return the key for a frozen object.
+        if ( !Data.accepts( owner ) ) {
+            return 0;
+        }
</ins><span class="cx"> 
</span><del>-    this.isPropagationStopped = returnTrue;
-    if ( !e ) {
-    return;
-    }
-    // If stopPropagation exists, run it on the original event
-    if ( e.stopPropagation ) {
-    e.stopPropagation();
-    }
</del><ins>+        var descriptor = {},
+            // Check if the owner object already has a cache key
+            unlock = owner[ this.expando ];
</ins><span class="cx"> 
</span><del>-    // Support: IE
-    // Set the cancelBubble property of the original event to true
-    e.cancelBubble = true;
-    },
-    stopImmediatePropagation: function() {
-    this.isImmediatePropagationStopped = returnTrue;
-    this.stopPropagation();
-    }
-};
</del><ins>+        // If not, create one
+        if ( !unlock ) {
+            unlock = Data.uid++;
</ins><span class="cx"> 
</span><del>-// Create mouseenter/leave events using mouseover/out and event-time checks
-jQuery.each({
-    mouseenter: &quot;mouseover&quot;,
-    mouseleave: &quot;mouseout&quot;
-}, function( orig, fix ) {
-    jQuery.event.special[ orig ] = {
-    delegateType: fix,
-    bindType: fix,
</del><ins>+            // Secure it in a non-enumerable, non-writable property
+            try {
+                descriptor[ this.expando ] = { value: unlock };
+                Object.defineProperties( owner, descriptor );
</ins><span class="cx"> 
</span><del>-    handle: function( event ) {
-    var ret,
-    target = this,
-    related = event.relatedTarget,
-    handleObj = event.handleObj;
</del><ins>+            // Support: Android &lt; 4
+            // Fallback to a less secure definition
+            } catch ( e ) {
+                descriptor[ this.expando ] = unlock;
+                jQuery.extend( owner, descriptor );
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // For mousenter/leave call the handler if related is outside the target.
-    // NB: No relatedTarget if the mouse left/entered the browser window
-    if ( !related || (related !== target &amp;&amp; !jQuery.contains( target, related )) ) {
-    event.type = handleObj.origType;
-    ret = handleObj.handler.apply( this, arguments );
-    event.type = fix;
-    }
-    return ret;
-    }
-    };
-});
</del><ins>+        // Ensure the cache object
+        if ( !this.cache[ unlock ] ) {
+            this.cache[ unlock ] = {};
+        }
</ins><span class="cx"> 
</span><del>-// IE submit delegation
-if ( !jQuery.support.submitBubbles ) {
</del><ins>+        return unlock;
+    },
+    set: function( owner, data, value ) {
+        var prop,
+            // There may be an unlock assigned to this node,
+            // if there is no entry for this &quot;owner&quot;, create one inline
+            // and set the unlock as though an owner entry had always existed
+            unlock = this.key( owner ),
+            cache = this.cache[ unlock ];
</ins><span class="cx"> 
</span><del>-    jQuery.event.special.submit = {
-    setup: function() {
-    // Only need this for delegated form submit events
-    if ( jQuery.nodeName( this, &quot;form&quot; ) ) {
-    return false;
-    }
</del><ins>+        // Handle: [ owner, key, value ] args
+        if ( typeof data === &quot;string&quot; ) {
+            cache[ data ] = value;
</ins><span class="cx"> 
</span><del>-    // Lazy-add a submit handler when a descendant form may potentially be submitted
-    jQuery.event.add( this, &quot;click._submit keypress._submit&quot;, function( e ) {
-    // Node name check avoids a VML-related crash in IE (#9807)
-    var elem = e.target,
-    form = jQuery.nodeName( elem, &quot;input&quot; ) || jQuery.nodeName( elem, &quot;button&quot; ) ? elem.form : undefined;
-    if ( form &amp;&amp; !jQuery._data( form, &quot;submitBubbles&quot; ) ) {
-    jQuery.event.add( form, &quot;submit._submit&quot;, function( event ) {
-    event._submit_bubble = true;
-    });
-    jQuery._data( form, &quot;submitBubbles&quot;, true );
-    }
-    });
-    // return undefined since we don't need an event listener
</del><ins>+        // Handle: [ owner, { properties } ] args
+        } else {
+            // Fresh assignments by object are shallow copied
+            if ( jQuery.isEmptyObject( cache ) ) {
+                jQuery.extend( this.cache[ unlock ], data );
+            // Otherwise, copy the properties one-by-one to the cache object
+            } else {
+                for ( prop in data ) {
+                    cache[ prop ] = data[ prop ];
+                }
+            }
+        }
+        return cache;
</ins><span class="cx">     },
</span><ins>+    get: function( owner, key ) {
+        // Either a valid cache is found, or will be created.
+        // New caches will be created and the unlock returned,
+        // allowing direct access to the newly created
+        // empty data object. A valid owner object must be provided.
+        var cache = this.cache[ this.key( owner ) ];
</ins><span class="cx"> 
</span><del>-    postDispatch: function( event ) {
-    // If form was submitted by the user, bubble the event up the tree
-    if ( event._submit_bubble ) {
-    delete event._submit_bubble;
-    if ( this.parentNode &amp;&amp; !event.isTrigger ) {
-    jQuery.event.simulate( &quot;submit&quot;, this.parentNode, event, true );
-    }
-    }
</del><ins>+        return key === undefined ?
+            cache : cache[ key ];
</ins><span class="cx">     },
</span><ins>+    access: function( owner, key, value ) {
+        var stored;
+        // In cases where either:
+        //
+        //   1. No key was specified
+        //   2. A string key was specified, but no value provided
+        //
+        // Take the &quot;read&quot; path and allow the get method to determine
+        // which value to return, respectively either:
+        //
+        //   1. The entire cache object
+        //   2. The data stored at the key
+        //
+        if ( key === undefined ||
+                ((key &amp;&amp; typeof key === &quot;string&quot;) &amp;&amp; value === undefined) ) {
</ins><span class="cx"> 
</span><del>-    teardown: function() {
-    // Only need this for delegated form submit events
-    if ( jQuery.nodeName( this, &quot;form&quot; ) ) {
-    return false;
-    }
</del><ins>+            stored = this.get( owner, key );
</ins><span class="cx"> 
</span><del>-    // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
-    jQuery.event.remove( this, &quot;._submit&quot; );
-    }
-    };
-}
</del><ins>+            return stored !== undefined ?
+                stored : this.get( owner, jQuery.camelCase(key) );
+        }
</ins><span class="cx"> 
</span><del>-// IE change delegation and checkbox/radio fix
-if ( !jQuery.support.changeBubbles ) {
</del><ins>+        // [*]When the key is not a string, or both a key and value
+        // are specified, set or extend (existing objects) with either:
+        //
+        //   1. An object of properties
+        //   2. A key and value
+        //
+        this.set( owner, key, value );
</ins><span class="cx"> 
</span><del>-    jQuery.event.special.change = {
</del><ins>+        // Since the &quot;set&quot; path can have two possible entry points
+        // return the expected data based on which path was taken[*]
+        return value !== undefined ? value : key;
+    },
+    remove: function( owner, key ) {
+        var i, name, camel,
+            unlock = this.key( owner ),
+            cache = this.cache[ unlock ];
</ins><span class="cx"> 
</span><del>-    setup: function() {
</del><ins>+        if ( key === undefined ) {
+            this.cache[ unlock ] = {};
</ins><span class="cx"> 
</span><del>-    if ( rformElems.test( this.nodeName ) ) {
-    // IE doesn't fire change on a check/radio until blur; trigger it on click
-    // after a propertychange. Eat the blur-change in special.change.handle.
-    // This still fires onchange a second time for check/radio after blur.
-    if ( this.type === &quot;checkbox&quot; || this.type === &quot;radio&quot; ) {
-    jQuery.event.add( this, &quot;propertychange._change&quot;, function( event ) {
-    if ( event.originalEvent.propertyName === &quot;checked&quot; ) {
-    this._just_changed = true;
-    }
-    });
-    jQuery.event.add( this, &quot;click._change&quot;, function( event ) {
-    if ( this._just_changed &amp;&amp; !event.isTrigger ) {
-    this._just_changed = false;
-    }
-    // Allow triggered, simulated change events (#11500)
-    jQuery.event.simulate( &quot;change&quot;, this, event, true );
-    });
-    }
-    return false;
-    }
-    // Delegated event; lazy-add a change handler on descendant inputs
-    jQuery.event.add( this, &quot;beforeactivate._change&quot;, function( e ) {
-    var elem = e.target;
</del><ins>+        } else {
+            // Support array or space separated string of keys
+            if ( jQuery.isArray( key ) ) {
+                // If &quot;name&quot; is an array of keys...
+                // When data is initially created, via (&quot;key&quot;, &quot;val&quot;) signature,
+                // keys will be converted to camelCase.
+                // Since there is no way to tell _how_ a key was added, remove
+                // both plain key and camelCase key. #12786
+                // This will only penalize the array argument path.
+                name = key.concat( key.map( jQuery.camelCase ) );
+            } else {
+                camel = jQuery.camelCase( key );
+                // Try the string as a key before any manipulation
+                if ( key in cache ) {
+                    name = [ key, camel ];
+                } else {
+                    // If a key with the spaces exists, use it.
+                    // Otherwise, create an array by matching non-whitespace
+                    name = camel;
+                    name = name in cache ?
+                        [ name ] : ( name.match( rnotwhite ) || [] );
+                }
+            }
</ins><span class="cx"> 
</span><del>-    if ( rformElems.test( elem.nodeName ) &amp;&amp; !jQuery._data( elem, &quot;changeBubbles&quot; ) ) {
-    jQuery.event.add( elem, &quot;change._change&quot;, function( event ) {
-    if ( this.parentNode &amp;&amp; !event.isSimulated &amp;&amp; !event.isTrigger ) {
-    jQuery.event.simulate( &quot;change&quot;, this.parentNode, event, true );
-    }
-    });
-    jQuery._data( elem, &quot;changeBubbles&quot;, true );
-    }
-    });
</del><ins>+            i = name.length;
+            while ( i-- ) {
+                delete cache[ name[ i ] ];
+            }
+        }
</ins><span class="cx">     },
</span><del>-
-    handle: function( event ) {
-    var elem = event.target;
-
-    // Swallow native change events from checkbox/radio, we already triggered them above
-    if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== &quot;radio&quot; &amp;&amp; elem.type !== &quot;checkbox&quot;) ) {
-    return event.handleObj.handler.apply( this, arguments );
-    }
</del><ins>+    hasData: function( owner ) {
+        return !jQuery.isEmptyObject(
+            this.cache[ owner[ this.expando ] ] || {}
+        );
</ins><span class="cx">     },
</span><ins>+    discard: function( owner ) {
+        if ( owner[ this.expando ] ) {
+            delete this.cache[ owner[ this.expando ] ];
+        }
+    }
+};
+var data_priv = new Data();
</ins><span class="cx"> 
</span><del>-    teardown: function() {
-    jQuery.event.remove( this, &quot;._change&quot; );
</del><ins>+var data_user = new Data();
</ins><span class="cx"> 
</span><del>-    return !rformElems.test( this.nodeName );
-    }
-    };
-}
</del><span class="cx"> 
</span><del>-// Create &quot;bubbling&quot; focus and blur events
-if ( !jQuery.support.focusinBubbles ) {
-    jQuery.each({ focus: &quot;focusin&quot;, blur: &quot;focusout&quot; }, function( orig, fix ) {
</del><span class="cx"> 
</span><del>-    // Attach a single capturing handler while someone wants focusin/focusout
-    var attaches = 0,
-    handler = function( event ) {
-    jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
-    };
</del><ins>+/*
+    Implementation Summary
</ins><span class="cx"> 
</span><del>-    jQuery.event.special[ fix ] = {
-    setup: function() {
-    if ( attaches++ === 0 ) {
-    document.addEventListener( orig, handler, true );
-    }
-    },
-    teardown: function() {
-    if ( --attaches === 0 ) {
-    document.removeEventListener( orig, handler, true );
-    }
-    }
-    };
-    });
-}
</del><ins>+    1. Enforce API surface and semantic compatibility with 1.9.x branch
+    2. Improve the module's maintainability by reducing the storage
+        paths to a single mechanism.
+    3. Use the same single mechanism to support &quot;private&quot; and &quot;user&quot; data.
+    4. _Never_ expose &quot;private&quot; data to user code (TODO: Drop _data, _removeData)
+    5. Avoid exposing implementation details on user objects (eg. expando properties)
+    6. Provide a clear path for implementation upgrade to WeakMap in 2014
+*/
+var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+    rmultiDash = /([A-Z])/g;
</ins><span class="cx"> 
</span><del>-jQuery.fn.extend({
</del><ins>+function dataAttr( elem, key, data ) {
+    var name;
</ins><span class="cx"> 
</span><del>-    on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
-    var type, origFn;
</del><ins>+    // If nothing was found internally, try to fetch any
+    // data from the HTML5 data-* attribute
+    if ( data === undefined &amp;&amp; elem.nodeType === 1 ) {
+        name = &quot;data-&quot; + key.replace( rmultiDash, &quot;-$1&quot; ).toLowerCase();
+        data = elem.getAttribute( name );
</ins><span class="cx"> 
</span><del>-    // Types can be a map of types/handlers
-    if ( typeof types === &quot;object&quot; ) {
-    // ( types-Object, selector, data )
-    if ( typeof selector !== &quot;string&quot; ) {
-    // ( types-Object, data )
-    data = data || selector;
-    selector = undefined;
-    }
-    for ( type in types ) {
-    this.on( type, selector, data, types[ type ], one );
-    }
-    return this;
-    }
</del><ins>+        if ( typeof data === &quot;string&quot; ) {
+            try {
+                data = data === &quot;true&quot; ? true :
+                    data === &quot;false&quot; ? false :
+                    data === &quot;null&quot; ? null :
+                    // Only convert to a number if it doesn't change the string
+                    +data + &quot;&quot; === data ? +data :
+                    rbrace.test( data ) ? jQuery.parseJSON( data ) :
+                    data;
+            } catch( e ) {}
</ins><span class="cx"> 
</span><del>-    if ( data == null &amp;&amp; fn == null ) {
-    // ( types, fn )
-    fn = selector;
-    data = selector = undefined;
-    } else if ( fn == null ) {
-    if ( typeof selector === &quot;string&quot; ) {
-    // ( types, selector, fn )
-    fn = data;
-    data = undefined;
-    } else {
-    // ( types, data, fn )
-    fn = data;
-    data = selector;
-    selector = undefined;
</del><ins>+            // Make sure we set the data so it isn't changed later
+            data_user.set( elem, key, data );
+        } else {
+            data = undefined;
+        }
</ins><span class="cx">     }
</span><del>-    }
-    if ( fn === false ) {
-    fn = returnFalse;
-    } else if ( !fn ) {
-    return this;
-    }
</del><ins>+    return data;
+}
</ins><span class="cx"> 
</span><del>-    if ( one === 1 ) {
-    origFn = fn;
-    fn = function( event ) {
-    // Can use an empty set, since event contains the info
-    jQuery().off( event );
-    return origFn.apply( this, arguments );
-    };
-    // Use same guid so caller can remove using origFn
-    fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
-    }
-    return this.each( function() {
-    jQuery.event.add( this, types, fn, data, selector );
-    });
</del><ins>+jQuery.extend({
+    hasData: function( elem ) {
+        return data_user.hasData( elem ) || data_priv.hasData( elem );
</ins><span class="cx">     },
</span><del>-    one: function( types, selector, data, fn ) {
-    return this.on( types, selector, data, fn, 1 );
-    },
-    off: function( types, selector, fn ) {
-    var handleObj, type;
-    if ( types &amp;&amp; types.preventDefault &amp;&amp; types.handleObj ) {
-    // ( event )  dispatched jQuery.Event
-    handleObj = types.handleObj;
-    jQuery( types.delegateTarget ).off(
-    handleObj.namespace ? handleObj.origType + &quot;.&quot; + handleObj.namespace : handleObj.origType,
-    handleObj.selector,
-    handleObj.handler
-    );
-    return this;
-    }
-    if ( typeof types === &quot;object&quot; ) {
-    // ( types-object [, selector] )
-    for ( type in types ) {
-    this.off( type, selector, types[ type ] );
-    }
-    return this;
-    }
-    if ( selector === false || typeof selector === &quot;function&quot; ) {
-    // ( types [, fn] )
-    fn = selector;
-    selector = undefined;
-    }
-    if ( fn === false ) {
-    fn = returnFalse;
-    }
-    return this.each(function() {
-    jQuery.event.remove( this, types, fn, selector );
-    });
-    },
</del><span class="cx"> 
</span><del>-    bind: function( types, data, fn ) {
-    return this.on( types, null, data, fn );
</del><ins>+    data: function( elem, name, data ) {
+        return data_user.access( elem, name, data );
</ins><span class="cx">     },
</span><del>-    unbind: function( types, fn ) {
-    return this.off( types, null, fn );
-    },
</del><span class="cx"> 
</span><del>-    delegate: function( selector, types, data, fn ) {
-    return this.on( types, selector, data, fn );
</del><ins>+    removeData: function( elem, name ) {
+        data_user.remove( elem, name );
</ins><span class="cx">     },
</span><del>-    undelegate: function( selector, types, fn ) {
-    // ( namespace ) or ( selector, types [, fn] )
-    return arguments.length === 1 ? this.off( selector, &quot;**&quot; ) : this.off( types, selector || &quot;**&quot;, fn );
-    },
</del><span class="cx"> 
</span><del>-    trigger: function( type, data ) {
-    return this.each(function() {
-    jQuery.event.trigger( type, data, this );
-    });
</del><ins>+    // TODO: Now that all calls to _data and _removeData have been replaced
+    // with direct calls to data_priv methods, these can be deprecated.
+    _data: function( elem, name, data ) {
+        return data_priv.access( elem, name, data );
</ins><span class="cx">     },
</span><del>-    triggerHandler: function( type, data ) {
-    var elem = this[0];
-    if ( elem ) {
-    return jQuery.event.trigger( type, data, elem, true );
</del><ins>+
+    _removeData: function( elem, name ) {
+        data_priv.remove( elem, name );
</ins><span class="cx">     }
</span><del>-    }
</del><span class="cx"> });
</span><del>-/*!
- * Sizzle CSS Selector Engine
- * Copyright 2012 jQuery Foundation and other contributors
- * Released under the MIT license
- * http://sizzlejs.com/
- */
-(function( window, undefined ) {
</del><span class="cx"> 
</span><del>-var i,
-    cachedruns,
-    Expr,
-    getText,
-    isXML,
-    compile,
-    hasDuplicate,
-    outermostContext,
</del><ins>+jQuery.fn.extend({
+    data: function( key, value ) {
+        var i, name, data,
+            elem = this[ 0 ],
+            attrs = elem &amp;&amp; elem.attributes;
</ins><span class="cx"> 
</span><del>-    // Local document vars
-    setDocument,
-    document,
-    docElem,
-    documentIsXML,
-    rbuggyQSA,
-    rbuggyMatches,
-    matches,
-    contains,
-    sortOrder,
</del><ins>+        // Gets all values
+        if ( key === undefined ) {
+            if ( this.length ) {
+                data = data_user.get( elem );
</ins><span class="cx"> 
</span><del>-    // Instance-specific data
-    expando = &quot;sizzle&quot; + -(new Date()),
-    preferredDoc = window.document,
-    support = {},
-    dirruns = 0,
-    done = 0,
-    classCache = createCache(),
-    tokenCache = createCache(),
-    compilerCache = createCache(),
</del><ins>+                if ( elem.nodeType === 1 &amp;&amp; !data_priv.get( elem, &quot;hasDataAttrs&quot; ) ) {
+                    i = attrs.length;
+                    while ( i-- ) {
+                        name = attrs[ i ].name;
</ins><span class="cx"> 
</span><del>-    // General-purpose constants
-    strundefined = typeof undefined,
-    MAX_NEGATIVE = 1 &lt;&lt; 31,
</del><ins>+                        if ( name.indexOf( &quot;data-&quot; ) === 0 ) {
+                            name = jQuery.camelCase( name.slice(5) );
+                            dataAttr( elem, name, data[ name ] );
+                        }
+                    }
+                    data_priv.set( elem, &quot;hasDataAttrs&quot;, true );
+                }
+            }
</ins><span class="cx"> 
</span><del>-    // Array methods
-    arr = [],
-    pop = arr.pop,
-    push = arr.push,
-    slice = arr.slice,
-    // Use a stripped-down indexOf if we can't use a native one
-    indexOf = arr.indexOf || function( elem ) {
-    var i = 0,
-    len = this.length;
-    for ( ; i &lt; len; i++ ) {
-    if ( this[i] === elem ) {
-    return i;
-    }
-    }
-    return -1;
-    },
</del><ins>+            return data;
+        }
</ins><span class="cx"> 
</span><ins>+        // Sets multiple values
+        if ( typeof key === &quot;object&quot; ) {
+            return this.each(function() {
+                data_user.set( this, key );
+            });
+        }
</ins><span class="cx"> 
</span><del>-    // Regular expressions
</del><ins>+        return access( this, function( value ) {
+            var data,
+                camelKey = jQuery.camelCase( key );
</ins><span class="cx"> 
</span><del>-    // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
-    whitespace = &quot;[\\x20\\t\\r\\n\\f]&quot;,
-    // http://www.w3.org/TR/css3-syntax/#characters
-    characterEncoding = &quot;(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+&quot;,
</del><ins>+            // The calling jQuery object (element matches) is not empty
+            // (and therefore has an element appears at this[ 0 ]) and the
+            // `value` parameter was not undefined. An empty jQuery object
+            // will result in `undefined` for elem = this[ 0 ] which will
+            // throw an exception if an attempt to read a data cache is made.
+            if ( elem &amp;&amp; value === undefined ) {
+                // Attempt to get data from the cache
+                // with the key as-is
+                data = data_user.get( elem, key );
+                if ( data !== undefined ) {
+                    return data;
+                }
</ins><span class="cx"> 
</span><del>-    // Loosely modeled on CSS identifier characters
-    // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
-    // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
-    identifier = characterEncoding.replace( &quot;w&quot;, &quot;w#&quot; ),
</del><ins>+                // Attempt to get data from the cache
+                // with the key camelized
+                data = data_user.get( elem, camelKey );
+                if ( data !== undefined ) {
+                    return data;
+                }
</ins><span class="cx"> 
</span><del>-    // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
-    operators = &quot;([*^$|!~]?=)&quot;,
-    attributes = &quot;\\[&quot; + whitespace + &quot;*(&quot; + characterEncoding + &quot;)&quot; + whitespace +
-    &quot;*(?:&quot; + operators + whitespace + &quot;*(?:(['\&quot;])((?:\\\\.|[^\\\\])*?)\\3|(&quot; + identifier + &quot;)|)|)&quot; + whitespace + &quot;*\\]&quot;,
</del><ins>+                // Attempt to &quot;discover&quot; the data in
+                // HTML5 custom data-* attrs
+                data = dataAttr( elem, camelKey, undefined );
+                if ( data !== undefined ) {
+                    return data;
+                }
</ins><span class="cx"> 
</span><del>-    // Prefer arguments quoted,
-    //   then not containing pseudos/brackets,
-    //   then attribute selectors/non-parenthetical expressions,
-    //   then anything else
-    // These preferences are here to reduce the number of selectors
-    //   needing tokenize in the PSEUDO preFilter
-    pseudos = &quot;:(&quot; + characterEncoding + &quot;)(?:\\(((['\&quot;])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|&quot; + attributes.replace( 3, 8 ) + &quot;)*)|.*)\\)|)&quot;,
</del><ins>+                // We tried really hard, but the data doesn't exist.
+                return;
+            }
</ins><span class="cx"> 
</span><del>-    // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
-    rtrim = new RegExp( &quot;^&quot; + whitespace + &quot;+|((?:^|[^\\\\])(?:\\\\.)*)&quot; + whitespace + &quot;+$&quot;, &quot;g&quot; ),
</del><ins>+            // Set the data...
+            this.each(function() {
+                // First, attempt to store a copy or reference of any
+                // data that might've been store with a camelCased key.
+                var data = data_user.get( this, camelKey );
</ins><span class="cx"> 
</span><del>-    rcomma = new RegExp( &quot;^&quot; + whitespace + &quot;*,&quot; + whitespace + &quot;*&quot; ),
-    rcombinators = new RegExp( &quot;^&quot; + whitespace + &quot;*([\\x20\\t\\r\\n\\f&gt;+~])&quot; + whitespace + &quot;*&quot; ),
-    rpseudo = new RegExp( pseudos ),
-    ridentifier = new RegExp( &quot;^&quot; + identifier + &quot;$&quot; ),
</del><ins>+                // For HTML5 data-* attribute interop, we have to
+                // store property names with dashes in a camelCase form.
+                // This might not apply to all properties...*
+                data_user.set( this, camelKey, value );
</ins><span class="cx"> 
</span><del>-    matchExpr = {
-    &quot;ID&quot;: new RegExp( &quot;^#(&quot; + characterEncoding + &quot;)&quot; ),
-    &quot;CLASS&quot;: new RegExp( &quot;^\\.(&quot; + characterEncoding + &quot;)&quot; ),
-    &quot;NAME&quot;: new RegExp( &quot;^\\[name=['\&quot;]?(&quot; + characterEncoding + &quot;)['\&quot;]?\\]&quot; ),
-    &quot;TAG&quot;: new RegExp( &quot;^(&quot; + characterEncoding.replace( &quot;w&quot;, &quot;w*&quot; ) + &quot;)&quot; ),
-    &quot;ATTR&quot;: new RegExp( &quot;^&quot; + attributes ),
-    &quot;PSEUDO&quot;: new RegExp( &quot;^&quot; + pseudos ),
-    &quot;CHILD&quot;: new RegExp( &quot;^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(&quot; + whitespace +
-    &quot;*(even|odd|(([+-]|)(\\d*)n|)&quot; + whitespace + &quot;*(?:([+-]|)&quot; + whitespace +
-    &quot;*(\\d+)|))&quot; + whitespace + &quot;*\\)|)&quot;, &quot;i&quot; ),
-    // For use in libraries implementing .is()
-    // We use this for POS matching in `select`
-    &quot;needsContext&quot;: new RegExp( &quot;^&quot; + whitespace + &quot;*[&gt;+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(&quot; +
-    whitespace + &quot;*((?:-\\d)?\\d*)&quot; + whitespace + &quot;*\\)|)(?=[^-]|$)&quot;, &quot;i&quot; )
</del><ins>+                // *... In the case of properties that might _actually_
+                // have dashes, we need to also store a copy of that
+                // unchanged property.
+                if ( key.indexOf(&quot;-&quot;) !== -1 &amp;&amp; data !== undefined ) {
+                    data_user.set( this, key, value );
+                }
+            });
+        }, null, value, arguments.length &gt; 1, null, true );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    rsibling = /[\x20\t\r\n\f]*[+~]/,
</del><ins>+    removeData: function( key ) {
+        return this.each(function() {
+            data_user.remove( this, key );
+        });
+    }
+});
</ins><span class="cx"> 
</span><del>-    rnative = /^[^{]+\{\s*\[native code/,
</del><span class="cx"> 
</span><del>-    // Easily-parseable/retrievable ID or TAG or CLASS selectors
-    rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
</del><ins>+jQuery.extend({
+    queue: function( elem, type, data ) {
+        var queue;
</ins><span class="cx"> 
</span><del>-    rinputs = /^(?:input|select|textarea|button)$/i,
-    rheader = /^h\d$/i,
</del><ins>+        if ( elem ) {
+            type = ( type || &quot;fx&quot; ) + &quot;queue&quot;;
+            queue = data_priv.get( elem, type );
</ins><span class="cx"> 
</span><del>-    rescape = /'|\\/g,
-    rattributeQuotes = /\=[\x20\t\r\n\f]*([^'&quot;\]]*)[\x20\t\r\n\f]*\]/g,
</del><ins>+            // Speed up dequeue by getting out quickly if this is just a lookup
+            if ( data ) {
+                if ( !queue || jQuery.isArray( data ) ) {
+                    queue = data_priv.access( elem, type, jQuery.makeArray(data) );
+                } else {
+                    queue.push( data );
+                }
+            }
+            return queue || [];
+        }
+    },
</ins><span class="cx"> 
</span><del>-    // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
-    runescape = /\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,
-    funescape = function( _, escaped ) {
-    var high = &quot;0x&quot; + escaped - 0x10000;
-    // NaN means non-codepoint
-    return high !== high ?
-    escaped :
-    // BMP codepoint
-    high &lt; 0 ?
-    String.fromCharCode( high + 0x10000 ) :
-    // Supplemental Plane codepoint (surrogate pair)
-    String.fromCharCode( high &gt;&gt; 10 | 0xD800, high &amp; 0x3FF | 0xDC00 );
-    };
</del><ins>+    dequeue: function( elem, type ) {
+        type = type || &quot;fx&quot;;
</ins><span class="cx"> 
</span><del>-// Use a stripped-down slice if we can't use a native one
-try {
-    slice.call( preferredDoc.documentElement.childNodes, 0 )[0].nodeType;
-} catch ( e ) {
-    slice = function( i ) {
-    var elem,
-    results = [];
-    while ( (elem = this[i++]) ) {
-    results.push( elem );
-    }
-    return results;
-    };
-}
</del><ins>+        var queue = jQuery.queue( elem, type ),
+            startLength = queue.length,
+            fn = queue.shift(),
+            hooks = jQuery._queueHooks( elem, type ),
+            next = function() {
+                jQuery.dequeue( elem, type );
+            };
</ins><span class="cx"> 
</span><del>-/**
- * For feature detection
- * @param {Function} fn The function to test for native support
- */
-function isNative( fn ) {
-    return rnative.test( fn + &quot;&quot; );
-}
</del><ins>+        // If the fx queue is dequeued, always remove the progress sentinel
+        if ( fn === &quot;inprogress&quot; ) {
+            fn = queue.shift();
+            startLength--;
+        }
</ins><span class="cx"> 
</span><del>-/**
- * Create key-value caches of limited size
- * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
- *    property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
- *    deleting the oldest entry
- */
-function createCache() {
-    var cache,
-    keys = [];
</del><ins>+        if ( fn ) {
</ins><span class="cx"> 
</span><del>-    return (cache = function( key, value ) {
-    // Use (key + &quot; &quot;) to avoid collision with native prototype properties (see Issue #157)
-    if ( keys.push( key += &quot; &quot; ) &gt; Expr.cacheLength ) {
-    // Only keep the most recent entries
-    delete cache[ keys.shift() ];
-    }
-    return (cache[ key ] = value);
-    });
-}
</del><ins>+            // Add a progress sentinel to prevent the fx queue from being
+            // automatically dequeued
+            if ( type === &quot;fx&quot; ) {
+                queue.unshift( &quot;inprogress&quot; );
+            }
</ins><span class="cx"> 
</span><del>-/**
- * Mark a function for special use by Sizzle
- * @param {Function} fn The function to mark
- */
-function markFunction( fn ) {
-    fn[ expando ] = true;
-    return fn;
-}
</del><ins>+            // clear up the last queue stop function
+            delete hooks.stop;
+            fn.call( elem, next, hooks );
+        }
</ins><span class="cx"> 
</span><del>-/**
- * Support testing using an element
- * @param {Function} fn Passed the created div and expects a boolean result
- */
-function assert( fn ) {
-    var div = document.createElement(&quot;div&quot;);
</del><ins>+        if ( !startLength &amp;&amp; hooks ) {
+            hooks.empty.fire();
+        }
+    },
</ins><span class="cx"> 
</span><del>-    try {
-    return fn( div );
-    } catch (e) {
-    return false;
-    } finally {
-    // release memory in IE
-    div = null;
</del><ins>+    // not intended for public consumption - generates a queueHooks object, or returns the current one
+    _queueHooks: function( elem, type ) {
+        var key = type + &quot;queueHooks&quot;;
+        return data_priv.get( elem, key ) || data_priv.access( elem, key, {
+            empty: jQuery.Callbacks(&quot;once memory&quot;).add(function() {
+                data_priv.remove( elem, [ type + &quot;queue&quot;, key ] );
+            })
+        });
</ins><span class="cx">     }
</span><del>-}
</del><ins>+});
</ins><span class="cx"> 
</span><del>-function Sizzle( selector, context, results, seed ) {
-    var match, elem, m, nodeType,
-    // QSA vars
-    i, groups, old, nid, newContext, newSelector;
</del><ins>+jQuery.fn.extend({
+    queue: function( type, data ) {
+        var setter = 2;
</ins><span class="cx"> 
</span><del>-    if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
-    setDocument( context );
-    }
</del><ins>+        if ( typeof type !== &quot;string&quot; ) {
+            data = type;
+            type = &quot;fx&quot;;
+            setter--;
+        }
</ins><span class="cx"> 
</span><del>-    context = context || document;
-    results = results || [];
</del><ins>+        if ( arguments.length &lt; setter ) {
+            return jQuery.queue( this[0], type );
+        }
</ins><span class="cx"> 
</span><del>-    if ( !selector || typeof selector !== &quot;string&quot; ) {
-    return results;
-    }
</del><ins>+        return data === undefined ?
+            this :
+            this.each(function() {
+                var queue = jQuery.queue( this, type, data );
</ins><span class="cx"> 
</span><del>-    if ( (nodeType = context.nodeType) !== 1 &amp;&amp; nodeType !== 9 ) {
-    return [];
-    }
</del><ins>+                // ensure a hooks for this queue
+                jQuery._queueHooks( this, type );
</ins><span class="cx"> 
</span><del>-    if ( !documentIsXML &amp;&amp; !seed ) {
</del><ins>+                if ( type === &quot;fx&quot; &amp;&amp; queue[0] !== &quot;inprogress&quot; ) {
+                    jQuery.dequeue( this, type );
+                }
+            });
+    },
+    dequeue: function( type ) {
+        return this.each(function() {
+            jQuery.dequeue( this, type );
+        });
+    },
+    clearQueue: function( type ) {
+        return this.queue( type || &quot;fx&quot;, [] );
+    },
+    // Get a promise resolved when queues of a certain type
+    // are emptied (fx is the type by default)
+    promise: function( type, obj ) {
+        var tmp,
+            count = 1,
+            defer = jQuery.Deferred(),
+            elements = this,
+            i = this.length,
+            resolve = function() {
+                if ( !( --count ) ) {
+                    defer.resolveWith( elements, [ elements ] );
+                }
+            };
</ins><span class="cx"> 
</span><del>-    // Shortcuts
-    if ( (match = rquickExpr.exec( selector )) ) {
-    // Speed-up: Sizzle(&quot;#ID&quot;)
-    if ( (m = match[1]) ) {
-    if ( nodeType === 9 ) {
-    elem = context.getElementById( m );
-    // Check parentNode to catch when Blackberry 4.6 returns
-    // nodes that are no longer in the document #6963
-    if ( elem &amp;&amp; elem.parentNode ) {
-    // Handle the case where IE, Opera, and Webkit return items
-    // by name instead of ID
-    if ( elem.id === m ) {
-    results.push( elem );
-    return results;
</del><ins>+        if ( typeof type !== &quot;string&quot; ) {
+            obj = type;
+            type = undefined;
+        }
+        type = type || &quot;fx&quot;;
+
+        while ( i-- ) {
+            tmp = data_priv.get( elements[ i ], type + &quot;queueHooks&quot; );
+            if ( tmp &amp;&amp; tmp.empty ) {
+                count++;
+                tmp.empty.add( resolve );
+            }
+        }
+        resolve();
+        return defer.promise( obj );
</ins><span class="cx">     }
</span><del>-    } else {
-    return results;
-    }
-    } else {
-    // Context is not a document
-    if ( context.ownerDocument &amp;&amp; (elem = context.ownerDocument.getElementById( m )) &amp;&amp;
-    contains( context, elem ) &amp;&amp; elem.id === m ) {
-    results.push( elem );
-    return results;
-    }
-    }
</del><ins>+});
+var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
</ins><span class="cx"> 
</span><del>-    // Speed-up: Sizzle(&quot;TAG&quot;)
-    } else if ( match[2] ) {
-    push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
-    return results;
</del><ins>+var cssExpand = [ &quot;Top&quot;, &quot;Right&quot;, &quot;Bottom&quot;, &quot;Left&quot; ];
</ins><span class="cx"> 
</span><del>-    // Speed-up: Sizzle(&quot;.CLASS&quot;)
-    } else if ( (m = match[3]) &amp;&amp; support.getByClassName &amp;&amp; context.getElementsByClassName ) {
-    push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
-    return results;
-    }
-    }
</del><ins>+var isHidden = function( elem, el ) {
+        // isHidden might be called from jQuery#filter function;
+        // in that case, element will be second argument
+        elem = el || elem;
+        return jQuery.css( elem, &quot;display&quot; ) === &quot;none&quot; || !jQuery.contains( elem.ownerDocument, elem );
+    };
</ins><span class="cx"> 
</span><del>-    // QSA path
-    if ( support.qsa &amp;&amp; !rbuggyQSA.test(selector) ) {
-    old = true;
-    nid = expando;
-    newContext = context;
-    newSelector = nodeType === 9 &amp;&amp; selector;
</del><ins>+var rcheckableType = (/^(?:checkbox|radio)$/i);
</ins><span class="cx"> 
</span><del>-    // qSA works strangely on Element-rooted queries
-    // We can work around this by specifying an extra ID on the root
-    // and working up from there (Thanks to Andrew Dupont for the technique)
-    // IE 8 doesn't work on object elements
-    if ( nodeType === 1 &amp;&amp; context.nodeName.toLowerCase() !== &quot;object&quot; ) {
-    groups = tokenize( selector );
</del><span class="cx"> 
</span><del>-    if ( (old = context.getAttribute(&quot;id&quot;)) ) {
-    nid = old.replace( rescape, &quot;\\$&amp;&quot; );
-    } else {
-    context.setAttribute( &quot;id&quot;, nid );
-    }
-    nid = &quot;[id='&quot; + nid + &quot;'] &quot;;
</del><span class="cx"> 
</span><del>-    i = groups.length;
-    while ( i-- ) {
-    groups[i] = nid + toSelector( groups[i] );
-    }
-    newContext = rsibling.test( selector ) &amp;&amp; context.parentNode || context;
-    newSelector = groups.join(&quot;,&quot;);
-    }
</del><ins>+(function() {
+    var fragment = document.createDocumentFragment(),
+        div = fragment.appendChild( document.createElement( &quot;div&quot; ) );
</ins><span class="cx"> 
</span><del>-    if ( newSelector ) {
-    try {
-    push.apply( results, slice.call( newContext.querySelectorAll(
-    newSelector
-    ), 0 ) );
-    return results;
-    } catch(qsaError) {
-    } finally {
-    if ( !old ) {
-    context.removeAttribute(&quot;id&quot;);
-    }
-    }
-    }
-    }
-    }
</del><ins>+    // #11217 - WebKit loses check when the name is after the checked attribute
+    div.innerHTML = &quot;&lt;input type='radio' checked='checked' name='t'/&gt;&quot;;
</ins><span class="cx"> 
</span><del>-    // All others
-    return select( selector.replace( rtrim, &quot;$1&quot; ), context, results, seed );
-}
</del><ins>+    // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
+    // old WebKit doesn't clone checked state correctly in fragments
+    support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
</ins><span class="cx"> 
</span><del>-/**
- * Detect xml
- * @param {Element|Object} elem An element or a document
- */
-isXML = Sizzle.isXML = function( elem ) {
-    // documentElement is verified for cases where it doesn't yet exist
-    // (such as loading iframes in IE - #4833)
-    var documentElement = elem &amp;&amp; (elem.ownerDocument || elem).documentElement;
-    return documentElement ? documentElement.nodeName !== &quot;HTML&quot; : false;
-};
</del><ins>+    // Make sure textarea (and checkbox) defaultValue is properly cloned
+    // Support: IE9-IE11+
+    div.innerHTML = &quot;&lt;textarea&gt;x&lt;/textarea&gt;&quot;;
+    support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
+})();
+var strundefined = typeof undefined;
</ins><span class="cx"> 
</span><del>-/**
- * Sets document-related variables once based on the current document
- * @param {Element|Object} [doc] An element or document object to use to set the document
- * @returns {Object} Returns the current document
- */
-setDocument = Sizzle.setDocument = function( node ) {
-    var doc = node ? node.ownerDocument || node : preferredDoc;
</del><span class="cx"> 
</span><del>-    // If no document and documentElement is available, return
-    if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
-    return document;
-    }
</del><span class="cx"> 
</span><del>-    // Set our document
-    document = doc;
-    docElem = doc.documentElement;
</del><ins>+support.focusinBubbles = &quot;onfocusin&quot; in window;
</ins><span class="cx"> 
</span><del>-    // Support tests
-    documentIsXML = isXML( doc );
</del><span class="cx"> 
</span><del>-    // Check if getElementsByTagName(&quot;*&quot;) returns only elements
-    support.tagNameNoComments = assert(function( div ) {
-    div.appendChild( doc.createComment(&quot;&quot;) );
-    return !div.getElementsByTagName(&quot;*&quot;).length;
-    });
</del><ins>+var
+    rkeyEvent = /^key/,
+    rmouseEvent = /^(?:mouse|contextmenu)|click/,
+    rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+    rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
</ins><span class="cx"> 
</span><del>-    // Check if attributes should be retrieved by attribute nodes
-    support.attributes = assert(function( div ) {
-    div.innerHTML = &quot;&lt;select&gt;&lt;/select&gt;&quot;;
-    var type = typeof div.lastChild.getAttribute(&quot;multiple&quot;);
-    // IE8 returns a string for some attributes even when not present
-    return type !== &quot;boolean&quot; &amp;&amp; type !== &quot;string&quot;;
-    });
</del><ins>+function returnTrue() {
+    return true;
+}
</ins><span class="cx"> 
</span><del>-    // Check if getElementsByClassName can be trusted
-    support.getByClassName = assert(function( div ) {
-    // Opera can't find a second classname (in 9.6)
-    div.innerHTML = &quot;&lt;div class='hidden e'&gt;&lt;/div&gt;&lt;div class='hidden'&gt;&lt;/div&gt;&quot;;
-    if ( !div.getElementsByClassName || !div.getElementsByClassName(&quot;e&quot;).length ) {
</del><ins>+function returnFalse() {
</ins><span class="cx">     return false;
</span><del>-    }
</del><ins>+}
</ins><span class="cx"> 
</span><del>-    // Safari 3.2 caches class attributes and doesn't catch changes
-    div.lastChild.className = &quot;e&quot;;
-    return div.getElementsByClassName(&quot;e&quot;).length === 2;
-    });
</del><ins>+function safeActiveElement() {
+    try {
+        return document.activeElement;
+    } catch ( err ) { }
+}
</ins><span class="cx"> 
</span><del>-    // Check if getElementById returns elements by name
-    // Check if getElementsByName privileges form controls or returns elements by ID
-    support.getByName = assert(function( div ) {
-    // Inject content
-    div.id = expando + 0;
-    div.innerHTML = &quot;&lt;a name='&quot; + expando + &quot;'&gt;&lt;/a&gt;&lt;div name='&quot; + expando + &quot;'&gt;&lt;/div&gt;&quot;;
-    docElem.insertBefore( div, docElem.firstChild );
</del><ins>+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
</ins><span class="cx"> 
</span><del>-    // Test
-    var pass = doc.getElementsByName &amp;&amp;
-    // buggy browsers will return fewer than the correct 2
-    doc.getElementsByName( expando ).length === 2 +
-    // buggy browsers will return more than the correct 0
-    doc.getElementsByName( expando + 0 ).length;
-    support.getIdNotName = !doc.getElementById( expando );
</del><ins>+    global: {},
</ins><span class="cx"> 
</span><del>-    // Cleanup
-    docElem.removeChild( div );
</del><ins>+    add: function( elem, types, handler, data, selector ) {
</ins><span class="cx"> 
</span><del>-    return pass;
-    });
</del><ins>+        var handleObjIn, eventHandle, tmp,
+            events, t, handleObj,
+            special, handlers, type, namespaces, origType,
+            elemData = data_priv.get( elem );
</ins><span class="cx"> 
</span><del>-    // IE6/7 return modified attributes
-    Expr.attrHandle = assert(function( div ) {
-    div.innerHTML = &quot;&lt;a href='#'&gt;&lt;/a&gt;&quot;;
-    return div.firstChild &amp;&amp; typeof div.firstChild.getAttribute !== strundefined &amp;&amp;
-    div.firstChild.getAttribute(&quot;href&quot;) === &quot;#&quot;;
-    }) ?
-    {} :
-    {
-    &quot;href&quot;: function( elem ) {
-    return elem.getAttribute( &quot;href&quot;, 2 );
-    },
-    &quot;type&quot;: function( elem ) {
-    return elem.getAttribute(&quot;type&quot;);
-    }
-    };
</del><ins>+        // Don't attach events to noData or text/comment nodes (but allow plain objects)
+        if ( !elemData ) {
+            return;
+        }
</ins><span class="cx"> 
</span><del>-    // ID find and filter
-    if ( support.getIdNotName ) {
-    Expr.find[&quot;ID&quot;] = function( id, context ) {
-    if ( typeof context.getElementById !== strundefined &amp;&amp; !documentIsXML ) {
-    var m = context.getElementById( id );
-    // Check parentNode to catch when Blackberry 4.6 returns
-    // nodes that are no longer in the document #6963
-    return m &amp;&amp; m.parentNode ? [m] : [];
-    }
-    };
-    Expr.filter[&quot;ID&quot;] = function( id ) {
-    var attrId = id.replace( runescape, funescape );
-    return function( elem ) {
-    return elem.getAttribute(&quot;id&quot;) === attrId;
-    };
-    };
-    } else {
-    Expr.find[&quot;ID&quot;] = function( id, context ) {
-    if ( typeof context.getElementById !== strundefined &amp;&amp; !documentIsXML ) {
-    var m = context.getElementById( id );
</del><ins>+        // Caller can pass in an object of custom data in lieu of the handler
+        if ( handler.handler ) {
+            handleObjIn = handler;
+            handler = handleObjIn.handler;
+            selector = handleObjIn.selector;
+        }
</ins><span class="cx"> 
</span><del>-    return m ?
-    m.id === id || typeof m.getAttributeNode !== strundefined &amp;&amp; m.getAttributeNode(&quot;id&quot;).value === id ?
-    [m] :
-    undefined :
-    [];
-    }
-    };
-    Expr.filter[&quot;ID&quot;] =  function( id ) {
-    var attrId = id.replace( runescape, funescape );
-    return function( elem ) {
-    var node = typeof elem.getAttributeNode !== strundefined &amp;&amp; elem.getAttributeNode(&quot;id&quot;);
-    return node &amp;&amp; node.value === attrId;
-    };
-    };
-    }
</del><ins>+        // Make sure that the handler has a unique ID, used to find/remove it later
+        if ( !handler.guid ) {
+            handler.guid = jQuery.guid++;
+        }
</ins><span class="cx"> 
</span><del>-    // Tag
-    Expr.find[&quot;TAG&quot;] = support.tagNameNoComments ?
-    function( tag, context ) {
-    if ( typeof context.getElementsByTagName !== strundefined ) {
-    return context.getElementsByTagName( tag );
-    }
-    } :
-    function( tag, context ) {
-    var elem,
-    tmp = [],
-    i = 0,
-    results = context.getElementsByTagName( tag );
</del><ins>+        // Init the element's event structure and main handler, if this is the first
+        if ( !(events = elemData.events) ) {
+            events = elemData.events = {};
+        }
+        if ( !(eventHandle = elemData.handle) ) {
+            eventHandle = elemData.handle = function( e ) {
+                // Discard the second event of a jQuery.event.trigger() and
+                // when an event is called after a page has unloaded
+                return typeof jQuery !== strundefined &amp;&amp; jQuery.event.triggered !== e.type ?
+                    jQuery.event.dispatch.apply( elem, arguments ) : undefined;
+            };
+        }
</ins><span class="cx"> 
</span><del>-    // Filter out possible comments
-    if ( tag === &quot;*&quot; ) {
-    while ( (elem = results[i++]) ) {
-    if ( elem.nodeType === 1 ) {
-    tmp.push( elem );
-    }
-    }
</del><ins>+        // Handle multiple events separated by a space
+        types = ( types || &quot;&quot; ).match( rnotwhite ) || [ &quot;&quot; ];
+        t = types.length;
+        while ( t-- ) {
+            tmp = rtypenamespace.exec( types[t] ) || [];
+            type = origType = tmp[1];
+            namespaces = ( tmp[2] || &quot;&quot; ).split( &quot;.&quot; ).sort();
</ins><span class="cx"> 
</span><del>-    return tmp;
-    }
-    return results;
-    };
</del><ins>+            // There *must* be a type, no attaching namespace-only handlers
+            if ( !type ) {
+                continue;
+            }
</ins><span class="cx"> 
</span><del>-    // Name
-    Expr.find[&quot;NAME&quot;] = support.getByName &amp;&amp; function( tag, context ) {
-    if ( typeof context.getElementsByName !== strundefined ) {
-    return context.getElementsByName( name );
-    }
-    };
</del><ins>+            // If event changes its type, use the special event handlers for the changed type
+            special = jQuery.event.special[ type ] || {};
</ins><span class="cx"> 
</span><del>-    // Class
-    Expr.find[&quot;CLASS&quot;] = support.getByClassName &amp;&amp; function( className, context ) {
-    if ( typeof context.getElementsByClassName !== strundefined &amp;&amp; !documentIsXML ) {
-    return context.getElementsByClassName( className );
-    }
-    };
</del><ins>+            // If selector defined, determine special event api type, otherwise given type
+            type = ( selector ? special.delegateType : special.bindType ) || type;
</ins><span class="cx"> 
</span><del>-    // QSA and matchesSelector support
</del><ins>+            // Update special based on newly reset type
+            special = jQuery.event.special[ type ] || {};
</ins><span class="cx"> 
</span><del>-    // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
-    rbuggyMatches = [];
</del><ins>+            // handleObj is passed to all event handlers
+            handleObj = jQuery.extend({
+                type: type,
+                origType: origType,
+                data: data,
+                handler: handler,
+                guid: handler.guid,
+                selector: selector,
+                needsContext: selector &amp;&amp; jQuery.expr.match.needsContext.test( selector ),
+                namespace: namespaces.join(&quot;.&quot;)
+            }, handleObjIn );
</ins><span class="cx"> 
</span><del>-    // qSa(:focus) reports false when true (Chrome 21),
-    // no need to also add to buggyMatches since matches checks buggyQSA
-    // A support test would require too much code (would include document ready)
-    rbuggyQSA = [ &quot;:focus&quot; ];
</del><ins>+            // Init the event handler queue if we're the first
+            if ( !(handlers = events[ type ]) ) {
+                handlers = events[ type ] = [];
+                handlers.delegateCount = 0;
</ins><span class="cx"> 
</span><del>-    if ( (support.qsa = isNative(doc.querySelectorAll)) ) {
-    // Build QSA regex
-    // Regex strategy adopted from Diego Perini
-    assert(function( div ) {
-    // Select is set to empty string on purpose
-    // This is to test IE's treatment of not explictly
-    // setting a boolean content attribute,
-    // since its presence should be enough
-    // http://bugs.jquery.com/ticket/12359
-    div.innerHTML = &quot;&lt;select&gt;&lt;option selected=''&gt;&lt;/option&gt;&lt;/select&gt;&quot;;
</del><ins>+                // Only use addEventListener if the special events handler returns false
+                if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+                    if ( elem.addEventListener ) {
+                        elem.addEventListener( type, eventHandle, false );
+                    }
+                }
+            }
</ins><span class="cx"> 
</span><del>-    // IE8 - Some boolean attributes are not treated correctly
-    if ( !div.querySelectorAll(&quot;[selected]&quot;).length ) {
-    rbuggyQSA.push( &quot;\\[&quot; + whitespace + &quot;*(?:checked|disabled|ismap|multiple|readonly|selected|value)&quot; );
-    }
</del><ins>+            if ( special.add ) {
+                special.add.call( elem, handleObj );
</ins><span class="cx"> 
</span><del>-    // Webkit/Opera - :checked should return selected option elements
-    // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
-    // IE8 throws error here and will not see later tests
-    if ( !div.querySelectorAll(&quot;:checked&quot;).length ) {
-    rbuggyQSA.push(&quot;:checked&quot;);
-    }
-    });
</del><ins>+                if ( !handleObj.handler.guid ) {
+                    handleObj.handler.guid = handler.guid;
+                }
+            }
</ins><span class="cx"> 
</span><del>-    assert(function( div ) {
</del><ins>+            // Add to the element's handler list, delegates in front
+            if ( selector ) {
+                handlers.splice( handlers.delegateCount++, 0, handleObj );
+            } else {
+                handlers.push( handleObj );
+            }
</ins><span class="cx"> 
</span><del>-    // Opera 10-12/IE8 - ^= $= *= and empty values
-    // Should not select anything
-    div.innerHTML = &quot;&lt;input type='hidden' i=''/&gt;&quot;;
-    if ( div.querySelectorAll(&quot;[i^='']&quot;).length ) {
-    rbuggyQSA.push( &quot;[*^$]=&quot; + whitespace + &quot;*(?:\&quot;\&quot;|'')&quot; );
-    }
</del><ins>+            // Keep track of which events have ever been used, for event optimization
+            jQuery.event.global[ type ] = true;
+        }
</ins><span class="cx"> 
</span><del>-    // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
-    // IE8 throws error here and will not see later tests
-    if ( !div.querySelectorAll(&quot;:enabled&quot;).length ) {
-    rbuggyQSA.push( &quot;:enabled&quot;, &quot;:disabled&quot; );
-    }
</del><ins>+    },
</ins><span class="cx"> 
</span><del>-    // Opera 10-11 does not throw on post-comma invalid pseudos
-    div.querySelectorAll(&quot;*,:x&quot;);
-    rbuggyQSA.push(&quot;,.*:&quot;);
-    });
-    }
</del><ins>+    // Detach an event or set of events from an element
+    remove: function( elem, types, handler, selector, mappedTypes ) {
</ins><span class="cx"> 
</span><del>-    if ( (support.matchesSelector = isNative( (matches = docElem.matchesSelector ||
-    docElem.mozMatchesSelector ||
-    docElem.webkitMatchesSelector ||
-    docElem.oMatchesSelector ||
-    docElem.msMatchesSelector) )) ) {
</del><ins>+        var j, origCount, tmp,
+            events, t, handleObj,
+            special, handlers, type, namespaces, origType,
+            elemData = data_priv.hasData( elem ) &amp;&amp; data_priv.get( elem );
</ins><span class="cx"> 
</span><del>-    assert(function( div ) {
-    // Check to see if it's possible to do matchesSelector
-    // on a disconnected node (IE 9)
-    support.disconnectedMatch = matches.call( div, &quot;div&quot; );
</del><ins>+        if ( !elemData || !(events = elemData.events) ) {
+            return;
+        }
</ins><span class="cx"> 
</span><del>-    // This should fail with an exception
-    // Gecko does not error, returns false instead
-    matches.call( div, &quot;[s!='']:x&quot; );
-    rbuggyMatches.push( &quot;!=&quot;, pseudos );
-    });
-    }
</del><ins>+        // Once for each type.namespace in types; type may be omitted
+        types = ( types || &quot;&quot; ).match( rnotwhite ) || [ &quot;&quot; ];
+        t = types.length;
+        while ( t-- ) {
+            tmp = rtypenamespace.exec( types[t] ) || [];
+            type = origType = tmp[1];
+            namespaces = ( tmp[2] || &quot;&quot; ).split( &quot;.&quot; ).sort();
</ins><span class="cx"> 
</span><del>-    rbuggyQSA = new RegExp( rbuggyQSA.join(&quot;|&quot;) );
-    rbuggyMatches = new RegExp( rbuggyMatches.join(&quot;|&quot;) );
</del><ins>+            // Unbind all events (on this namespace, if provided) for the element
+            if ( !type ) {
+                for ( type in events ) {
+                    jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+                }
+                continue;
+            }
</ins><span class="cx"> 
</span><del>-    // Element contains another
-    // Purposefully does not implement inclusive descendent
-    // As in, an element does not contain itself
-    contains = isNative(docElem.contains) || docElem.compareDocumentPosition ?
-    function( a, b ) {
-    var adown = a.nodeType === 9 ? a.documentElement : a,
-    bup = b &amp;&amp; b.parentNode;
-    return a === bup || !!( bup &amp;&amp; bup.nodeType === 1 &amp;&amp; (
-    adown.contains ?
-    adown.contains( bup ) :
-    a.compareDocumentPosition &amp;&amp; a.compareDocumentPosition( bup ) &amp; 16
-    ));
-    } :
-    function( a, b ) {
-    if ( b ) {
-    while ( (b = b.parentNode) ) {
-    if ( b === a ) {
-    return true;
-    }
-    }
-    }
-    return false;
-    };
</del><ins>+            special = jQuery.event.special[ type ] || {};
+            type = ( selector ? special.delegateType : special.bindType ) || type;
+            handlers = events[ type ] || [];
+            tmp = tmp[2] &amp;&amp; new RegExp( &quot;(^|\\.)&quot; + namespaces.join(&quot;\\.(?:.*\\.|)&quot;) + &quot;(\\.|$)&quot; );
</ins><span class="cx"> 
</span><del>-    // Document order sorting
-    sortOrder = docElem.compareDocumentPosition ?
-    function( a, b ) {
-    var compare;
</del><ins>+            // Remove matching events
+            origCount = j = handlers.length;
+            while ( j-- ) {
+                handleObj = handlers[ j ];
</ins><span class="cx"> 
</span><del>-    if ( a === b ) {
-    hasDuplicate = true;
-    return 0;
-    }
</del><ins>+                if ( ( mappedTypes || origType === handleObj.origType ) &amp;&amp;
+                    ( !handler || handler.guid === handleObj.guid ) &amp;&amp;
+                    ( !tmp || tmp.test( handleObj.namespace ) ) &amp;&amp;
+                    ( !selector || selector === handleObj.selector || selector === &quot;**&quot; &amp;&amp; handleObj.selector ) ) {
+                    handlers.splice( j, 1 );
</ins><span class="cx"> 
</span><del>-    if ( (compare = b.compareDocumentPosition &amp;&amp; a.compareDocumentPosition &amp;&amp; a.compareDocumentPosition( b )) ) {
-    if ( compare &amp; 1 || a.parentNode &amp;&amp; a.parentNode.nodeType === 11 ) {
-    if ( a === doc || contains( preferredDoc, a ) ) {
-    return -1;
-    }
-    if ( b === doc || contains( preferredDoc, b ) ) {
-    return 1;
-    }
-    return 0;
-    }
-    return compare &amp; 4 ? -1 : 1;
-    }
</del><ins>+                    if ( handleObj.selector ) {
+                        handlers.delegateCount--;
+                    }
+                    if ( special.remove ) {
+                        special.remove.call( elem, handleObj );
+                    }
+                }
+            }
</ins><span class="cx"> 
</span><del>-    return a.compareDocumentPosition ? -1 : 1;
-    } :
-    function( a, b ) {
-    var cur,
-    i = 0,
-    aup = a.parentNode,
-    bup = b.parentNode,
-    ap = [ a ],
-    bp = [ b ];
</del><ins>+            // Remove generic event handler if we removed something and no more handlers exist
+            // (avoids potential for endless recursion during removal of special event handlers)
+            if ( origCount &amp;&amp; !handlers.length ) {
+                if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+                    jQuery.removeEvent( elem, type, elemData.handle );
+                }
</ins><span class="cx"> 
</span><del>-    // Exit early if the nodes are identical
-    if ( a === b ) {
-    hasDuplicate = true;
-    return 0;
</del><ins>+                delete events[ type ];
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // Parentless nodes are either documents or disconnected
-    } else if ( !aup || !bup ) {
-    return a === doc ? -1 :
-    b === doc ? 1 :
-    aup ? -1 :
-    bup ? 1 :
-    0;
</del><ins>+        // Remove the expando if it's no longer used
+        if ( jQuery.isEmptyObject( events ) ) {
+            delete elemData.handle;
+            data_priv.remove( elem, &quot;events&quot; );
+        }
+    },
</ins><span class="cx"> 
</span><del>-    // If the nodes are siblings, we can do a quick check
-    } else if ( aup === bup ) {
-    return siblingCheck( a, b );
-    }
</del><ins>+    trigger: function( event, data, elem, onlyHandlers ) {
</ins><span class="cx"> 
</span><del>-    // Otherwise we need full lists of their ancestors for comparison
-    cur = a;
-    while ( (cur = cur.parentNode) ) {
-    ap.unshift( cur );
-    }
-    cur = b;
-    while ( (cur = cur.parentNode) ) {
-    bp.unshift( cur );
-    }
</del><ins>+        var i, cur, tmp, bubbleType, ontype, handle, special,
+            eventPath = [ elem || document ],
+            type = hasOwn.call( event, &quot;type&quot; ) ? event.type : event,
+            namespaces = hasOwn.call( event, &quot;namespace&quot; ) ? event.namespace.split(&quot;.&quot;) : [];
</ins><span class="cx"> 
</span><del>-    // Walk down the tree looking for a discrepancy
-    while ( ap[i] === bp[i] ) {
-    i++;
-    }
</del><ins>+        cur = tmp = elem = elem || document;
</ins><span class="cx"> 
</span><del>-    return i ?
-    // Do a sibling check if the nodes have a common ancestor
-    siblingCheck( ap[i], bp[i] ) :
</del><ins>+        // Don't do events on text and comment nodes
+        if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+            return;
+        }
</ins><span class="cx"> 
</span><del>-    // Otherwise nodes in our document sort first
-    ap[i] === preferredDoc ? -1 :
-    bp[i] === preferredDoc ? 1 :
-    0;
-    };
</del><ins>+        // focus/blur morphs to focusin/out; ensure we're not firing them right now
+        if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
+            return;
+        }
</ins><span class="cx"> 
</span><del>-    // Always assume the presence of duplicates if sort doesn't
-    // pass them to our comparison function (as in Google Chrome).
-    hasDuplicate = false;
-    [0, 0].sort( sortOrder );
-    support.detectDuplicates = hasDuplicate;
</del><ins>+        if ( type.indexOf(&quot;.&quot;) &gt;= 0 ) {
+            // Namespaced trigger; create a regexp to match event type in handle()
+            namespaces = type.split(&quot;.&quot;);
+            type = namespaces.shift();
+            namespaces.sort();
+        }
+        ontype = type.indexOf(&quot;:&quot;) &lt; 0 &amp;&amp; &quot;on&quot; + type;
</ins><span class="cx"> 
</span><del>-    return document;
-};
</del><ins>+        // Caller can pass in a jQuery.Event object, Object, or just an event type string
+        event = event[ jQuery.expando ] ?
+            event :
+            new jQuery.Event( type, typeof event === &quot;object&quot; &amp;&amp; event );
</ins><span class="cx"> 
</span><del>-Sizzle.matches = function( expr, elements ) {
-    return Sizzle( expr, null, null, elements );
-};
</del><ins>+        // Trigger bitmask: &amp; 1 for native handlers; &amp; 2 for jQuery (always true)
+        event.isTrigger = onlyHandlers ? 2 : 3;
+        event.namespace = namespaces.join(&quot;.&quot;);
+        event.namespace_re = event.namespace ?
+            new RegExp( &quot;(^|\\.)&quot; + namespaces.join(&quot;\\.(?:.*\\.|)&quot;) + &quot;(\\.|$)&quot; ) :
+            null;
</ins><span class="cx"> 
</span><del>-Sizzle.matchesSelector = function( elem, expr ) {
-    // Set document vars if needed
-    if ( ( elem.ownerDocument || elem ) !== document ) {
-    setDocument( elem );
-    }
</del><ins>+        // Clean up the event in case it is being reused
+        event.result = undefined;
+        if ( !event.target ) {
+            event.target = elem;
+        }
</ins><span class="cx"> 
</span><del>-    // Make sure that attribute selectors are quoted
-    expr = expr.replace( rattributeQuotes, &quot;='$1']&quot; );
</del><ins>+        // Clone any incoming data and prepend the event, creating the handler arg list
+        data = data == null ?
+            [ event ] :
+            jQuery.makeArray( data, [ event ] );
</ins><span class="cx"> 
</span><del>-    // rbuggyQSA always contains :focus, so no need for an existence check
-    if ( support.matchesSelector &amp;&amp; !documentIsXML &amp;&amp; (!rbuggyMatches || !rbuggyMatches.test(expr)) &amp;&amp; !rbuggyQSA.test(expr) ) {
-    try {
-    var ret = matches.call( elem, expr );
</del><ins>+        // Allow special events to draw outside the lines
+        special = jQuery.event.special[ type ] || {};
+        if ( !onlyHandlers &amp;&amp; special.trigger &amp;&amp; special.trigger.apply( elem, data ) === false ) {
+            return;
+        }
</ins><span class="cx"> 
</span><del>-    // IE 9's matchesSelector returns false on disconnected nodes
-    if ( ret || support.disconnectedMatch ||
-    // As well, disconnected nodes are said to be in a document
-    // fragment in IE 9
-    elem.document &amp;&amp; elem.document.nodeType !== 11 ) {
-    return ret;
-    }
-    } catch(e) {}
-    }
</del><ins>+        // Determine event propagation path in advance, per W3C events spec (#9951)
+        // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
+        if ( !onlyHandlers &amp;&amp; !special.noBubble &amp;&amp; !jQuery.isWindow( elem ) ) {
</ins><span class="cx"> 
</span><del>-    return Sizzle( expr, document, null, [elem] ).length &gt; 0;
-};
</del><ins>+            bubbleType = special.delegateType || type;
+            if ( !rfocusMorph.test( bubbleType + type ) ) {
+                cur = cur.parentNode;
+            }
+            for ( ; cur; cur = cur.parentNode ) {
+                eventPath.push( cur );
+                tmp = cur;
+            }
</ins><span class="cx"> 
</span><del>-Sizzle.contains = function( context, elem ) {
-    // Set document vars if needed
-    if ( ( context.ownerDocument || context ) !== document ) {
-    setDocument( context );
-    }
-    return contains( context, elem );
-};
</del><ins>+            // Only add window if we got to document (e.g., not plain obj or detached DOM)
+            if ( tmp === (elem.ownerDocument || document) ) {
+                eventPath.push( tmp.defaultView || tmp.parentWindow || window );
+            }
+        }
</ins><span class="cx"> 
</span><del>-Sizzle.attr = function( elem, name ) {
-    var val;
</del><ins>+        // Fire handlers on the event path
+        i = 0;
+        while ( (cur = eventPath[i++]) &amp;&amp; !event.isPropagationStopped() ) {
</ins><span class="cx"> 
</span><del>-    // Set document vars if needed
-    if ( ( elem.ownerDocument || elem ) !== document ) {
-    setDocument( elem );
-    }
</del><ins>+            event.type = i &gt; 1 ?
+                bubbleType :
+                special.bindType || type;
</ins><span class="cx"> 
</span><del>-    if ( !documentIsXML ) {
-    name = name.toLowerCase();
-    }
-    if ( (val = Expr.attrHandle[ name ]) ) {
-    return val( elem );
-    }
-    if ( documentIsXML || support.attributes ) {
-    return elem.getAttribute( name );
-    }
-    return ( (val = elem.getAttributeNode( name )) || elem.getAttribute( name ) ) &amp;&amp; elem[ name ] === true ?
-    name :
-    val &amp;&amp; val.specified ? val.value : null;
-};
</del><ins>+            // jQuery handler
+            handle = ( data_priv.get( cur, &quot;events&quot; ) || {} )[ event.type ] &amp;&amp; data_priv.get( cur, &quot;handle&quot; );
+            if ( handle ) {
+                handle.apply( cur, data );
+            }
</ins><span class="cx"> 
</span><del>-Sizzle.error = function( msg ) {
-    throw new Error( &quot;Syntax error, unrecognized expression: &quot; + msg );
-};
</del><ins>+            // Native handler
+            handle = ontype &amp;&amp; cur[ ontype ];
+            if ( handle &amp;&amp; handle.apply &amp;&amp; jQuery.acceptData( cur ) ) {
+                event.result = handle.apply( cur, data );
+                if ( event.result === false ) {
+                    event.preventDefault();
+                }
+            }
+        }
+        event.type = type;
</ins><span class="cx"> 
</span><del>-// Document sorting and removing duplicates
-Sizzle.uniqueSort = function( results ) {
-    var elem,
-    duplicates = [],
-    i = 1,
-    j = 0;
</del><ins>+        // If nobody prevented the default action, do it now
+        if ( !onlyHandlers &amp;&amp; !event.isDefaultPrevented() ) {
</ins><span class="cx"> 
</span><del>-    // Unless we *know* we can detect duplicates, assume their presence
-    hasDuplicate = !support.detectDuplicates;
-    results.sort( sortOrder );
</del><ins>+            if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &amp;&amp;
+                jQuery.acceptData( elem ) ) {
</ins><span class="cx"> 
</span><del>-    if ( hasDuplicate ) {
-    for ( ; (elem = results[i]); i++ ) {
-    if ( elem === results[ i - 1 ] ) {
-    j = duplicates.push( i );
-    }
-    }
-    while ( j-- ) {
-    results.splice( duplicates[ j ], 1 );
-    }
-    }
</del><ins>+                // Call a native DOM method on the target with the same name name as the event.
+                // Don't do default actions on window, that's where global variables be (#6170)
+                if ( ontype &amp;&amp; jQuery.isFunction( elem[ type ] ) &amp;&amp; !jQuery.isWindow( elem ) ) {
</ins><span class="cx"> 
</span><del>-    return results;
-};
</del><ins>+                    // Don't re-trigger an onFOO event when we call its FOO() method
+                    tmp = elem[ ontype ];
</ins><span class="cx"> 
</span><del>-function siblingCheck( a, b ) {
-    var cur = b &amp;&amp; a,
-    diff = cur &amp;&amp; ( ~b.sourceIndex || MAX_NEGATIVE ) - ( ~a.sourceIndex || MAX_NEGATIVE );
</del><ins>+                    if ( tmp ) {
+                        elem[ ontype ] = null;
+                    }
</ins><span class="cx"> 
</span><del>-    // Use IE sourceIndex if available on both nodes
-    if ( diff ) {
-    return diff;
-    }
</del><ins>+                    // Prevent re-triggering of the same event, since we already bubbled it above
+                    jQuery.event.triggered = type;
+                    elem[ type ]();
+                    jQuery.event.triggered = undefined;
</ins><span class="cx"> 
</span><del>-    // Check if b follows a
-    if ( cur ) {
-    while ( (cur = cur.nextSibling) ) {
-    if ( cur === b ) {
-    return -1;
-    }
-    }
-    }
</del><ins>+                    if ( tmp ) {
+                        elem[ ontype ] = tmp;
+                    }
+                }
+            }
+        }
</ins><span class="cx"> 
</span><del>-    return a ? 1 : -1;
-}
</del><ins>+        return event.result;
+    },
</ins><span class="cx"> 
</span><del>-// Returns a function to use in pseudos for input types
-function createInputPseudo( type ) {
-    return function( elem ) {
-    var name = elem.nodeName.toLowerCase();
-    return name === &quot;input&quot; &amp;&amp; elem.type === type;
-    };
-}
</del><ins>+    dispatch: function( event ) {
</ins><span class="cx"> 
</span><del>-// Returns a function to use in pseudos for buttons
-function createButtonPseudo( type ) {
-    return function( elem ) {
-    var name = elem.nodeName.toLowerCase();
-    return (name === &quot;input&quot; || name === &quot;button&quot;) &amp;&amp; elem.type === type;
-    };
-}
</del><ins>+        // Make a writable jQuery.Event from the native event object
+        event = jQuery.event.fix( event );
</ins><span class="cx"> 
</span><del>-// Returns a function to use in pseudos for positionals
-function createPositionalPseudo( fn ) {
-    return markFunction(function( argument ) {
-    argument = +argument;
-    return markFunction(function( seed, matches ) {
-    var j,
-    matchIndexes = fn( [], seed.length, argument ),
-    i = matchIndexes.length;
</del><ins>+        var i, j, ret, matched, handleObj,
+            handlerQueue = [],
+            args = slice.call( arguments ),
+            handlers = ( data_priv.get( this, &quot;events&quot; ) || {} )[ event.type ] || [],
+            special = jQuery.event.special[ event.type ] || {};
</ins><span class="cx"> 
</span><del>-    // Match elements found at the specified indexes
-    while ( i-- ) {
-    if ( seed[ (j = matchIndexes[i]) ] ) {
-    seed[j] = !(matches[j] = seed[j]);
-    }
-    }
-    });
-    });
-}
</del><ins>+        // Use the fix-ed jQuery.Event rather than the (read-only) native event
+        args[0] = event;
+        event.delegateTarget = this;
</ins><span class="cx"> 
</span><del>-/**
- * Utility function for retrieving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
-getText = Sizzle.getText = function( elem ) {
-    var node,
-    ret = &quot;&quot;,
-    i = 0,
-    nodeType = elem.nodeType;
</del><ins>+        // Call the preDispatch hook for the mapped type, and let it bail if desired
+        if ( special.preDispatch &amp;&amp; special.preDispatch.call( this, event ) === false ) {
+            return;
+        }
</ins><span class="cx"> 
</span><del>-    if ( !nodeType ) {
-    // If no nodeType, this is expected to be an array
-    for ( ; (node = elem[i]); i++ ) {
-    // Do not traverse comment nodes
-    ret += getText( node );
-    }
-    } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
-    // Use textContent for elements
-    // innerText usage removed for consistency of new lines (see #11153)
-    if ( typeof elem.textContent === &quot;string&quot; ) {
-    return elem.textContent;
-    } else {
-    // Traverse its children
-    for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
-    ret += getText( elem );
-    }
-    }
-    } else if ( nodeType === 3 || nodeType === 4 ) {
-    return elem.nodeValue;
-    }
-    // Do not include comment or processing instruction nodes
</del><ins>+        // Determine handlers
+        handlerQueue = jQuery.event.handlers.call( this, event, handlers );
</ins><span class="cx"> 
</span><del>-    return ret;
-};
</del><ins>+        // Run delegates first; they may want to stop propagation beneath us
+        i = 0;
+        while ( (matched = handlerQueue[ i++ ]) &amp;&amp; !event.isPropagationStopped() ) {
+            event.currentTarget = matched.elem;
</ins><span class="cx"> 
</span><del>-Expr = Sizzle.selectors = {
</del><ins>+            j = 0;
+            while ( (handleObj = matched.handlers[ j++ ]) &amp;&amp; !event.isImmediatePropagationStopped() ) {
</ins><span class="cx"> 
</span><del>-    // Can be adjusted by the user
-    cacheLength: 50,
</del><ins>+                // Triggered event must either 1) have no namespace, or
+                // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
+                if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
</ins><span class="cx"> 
</span><del>-    createPseudo: markFunction,
</del><ins>+                    event.handleObj = handleObj;
+                    event.data = handleObj.data;
</ins><span class="cx"> 
</span><del>-    match: matchExpr,
</del><ins>+                    ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
+                            .apply( matched.elem, args );
</ins><span class="cx"> 
</span><del>-    find: {},
</del><ins>+                    if ( ret !== undefined ) {
+                        if ( (event.result = ret) === false ) {
+                            event.preventDefault();
+                            event.stopPropagation();
+                        }
+                    }
+                }
+            }
+        }
</ins><span class="cx"> 
</span><del>-    relative: {
-    &quot;&gt;&quot;: { dir: &quot;parentNode&quot;, first: true },
-    &quot; &quot;: { dir: &quot;parentNode&quot; },
-    &quot;+&quot;: { dir: &quot;previousSibling&quot;, first: true },
-    &quot;~&quot;: { dir: &quot;previousSibling&quot; }
</del><ins>+        // Call the postDispatch hook for the mapped type
+        if ( special.postDispatch ) {
+            special.postDispatch.call( this, event );
+        }
+
+        return event.result;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    preFilter: {
-    &quot;ATTR&quot;: function( match ) {
-    match[1] = match[1].replace( runescape, funescape );
</del><ins>+    handlers: function( event, handlers ) {
+        var i, matches, sel, handleObj,
+            handlerQueue = [],
+            delegateCount = handlers.delegateCount,
+            cur = event.target;
</ins><span class="cx"> 
</span><del>-    // Move the given value to match[3] whether quoted or unquoted
-    match[3] = ( match[4] || match[5] || &quot;&quot; ).replace( runescape, funescape );
</del><ins>+        // Find delegate handlers
+        // Black-hole SVG &lt;use&gt; instance trees (#13180)
+        // Avoid non-left-click bubbling in Firefox (#3861)
+        if ( delegateCount &amp;&amp; cur.nodeType &amp;&amp; (!event.button || event.type !== &quot;click&quot;) ) {
</ins><span class="cx"> 
</span><del>-    if ( match[2] === &quot;~=&quot; ) {
-    match[3] = &quot; &quot; + match[3] + &quot; &quot;;
-    }
</del><ins>+            for ( ; cur !== this; cur = cur.parentNode || this ) {
</ins><span class="cx"> 
</span><del>-    return match.slice( 0, 4 );
-    },
</del><ins>+                // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+                if ( cur.disabled !== true || event.type !== &quot;click&quot; ) {
+                    matches = [];
+                    for ( i = 0; i &lt; delegateCount; i++ ) {
+                        handleObj = handlers[ i ];
</ins><span class="cx"> 
</span><del>-    &quot;CHILD&quot;: function( match ) {
-    /* matches from matchExpr[&quot;CHILD&quot;]
-    1 type (only|nth|...)
-    2 what (child|of-type)
-    3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
-    4 xn-component of xn+y argument ([+-]?\d*n|)
-    5 sign of xn-component
-    6 x of xn-component
-    7 sign of y-component
-    8 y of y-component
-    */
-    match[1] = match[1].toLowerCase();
</del><ins>+                        // Don't conflict with Object.prototype properties (#13203)
+                        sel = handleObj.selector + &quot; &quot;;
</ins><span class="cx"> 
</span><del>-    if ( match[1].slice( 0, 3 ) === &quot;nth&quot; ) {
-    // nth-* requires argument
-    if ( !match[3] ) {
-    Sizzle.error( match[0] );
-    }
</del><ins>+                        if ( matches[ sel ] === undefined ) {
+                            matches[ sel ] = handleObj.needsContext ?
+                                jQuery( sel, this ).index( cur ) &gt;= 0 :
+                                jQuery.find( sel, this, null, [ cur ] ).length;
+                        }
+                        if ( matches[ sel ] ) {
+                            matches.push( handleObj );
+                        }
+                    }
+                    if ( matches.length ) {
+                        handlerQueue.push({ elem: cur, handlers: matches });
+                    }
+                }
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // numeric x and y parameters for Expr.filter.CHILD
-    // remember that false/true cast respectively to 0/1
-    match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === &quot;even&quot; || match[3] === &quot;odd&quot; ) );
-    match[5] = +( ( match[7] + match[8] ) || match[3] === &quot;odd&quot; );
</del><ins>+        // Add the remaining (directly-bound) handlers
+        if ( delegateCount &lt; handlers.length ) {
+            handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
+        }
</ins><span class="cx"> 
</span><del>-    // other types prohibit arguments
-    } else if ( match[3] ) {
-    Sizzle.error( match[0] );
-    }
-
-    return match;
</del><ins>+        return handlerQueue;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    &quot;PSEUDO&quot;: function( match ) {
-    var excess,
-    unquoted = !match[5] &amp;&amp; match[2];
</del><ins>+    // Includes some event props shared by KeyEvent and MouseEvent
+    props: &quot;altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which&quot;.split(&quot; &quot;),
</ins><span class="cx"> 
</span><del>-    if ( matchExpr[&quot;CHILD&quot;].test( match[0] ) ) {
-    return null;
-    }
</del><ins>+    fixHooks: {},
</ins><span class="cx"> 
</span><del>-    // Accept quoted arguments as-is
-    if ( match[4] ) {
-    match[2] = match[4];
</del><ins>+    keyHooks: {
+        props: &quot;char charCode key keyCode&quot;.split(&quot; &quot;),
+        filter: function( event, original ) {
</ins><span class="cx"> 
</span><del>-    // Strip excess characters from unquoted arguments
-    } else if ( unquoted &amp;&amp; rpseudo.test( unquoted ) &amp;&amp;
-    // Get excess from tokenize (recursively)
-    (excess = tokenize( unquoted, true )) &amp;&amp;
-    // advance to the next closing parenthesis
-    (excess = unquoted.indexOf( &quot;)&quot;, unquoted.length - excess ) - unquoted.length) ) {
</del><ins>+            // Add which for key events
+            if ( event.which == null ) {
+                event.which = original.charCode != null ? original.charCode : original.keyCode;
+            }
</ins><span class="cx"> 
</span><del>-    // excess is a negative index
-    match[0] = match[0].slice( 0, excess );
-    match[2] = unquoted.slice( 0, excess );
-    }
-
-    // Return only captures needed by the pseudo filter method (type and argument)
-    return match.slice( 0, 3 );
-    }
</del><ins>+            return event;
+        }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    filter: {
</del><ins>+    mouseHooks: {
+        props: &quot;button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement&quot;.split(&quot; &quot;),
+        filter: function( event, original ) {
+            var eventDoc, doc, body,
+                button = original.button;
</ins><span class="cx"> 
</span><del>-    &quot;TAG&quot;: function( nodeName ) {
-    if ( nodeName === &quot;*&quot; ) {
-    return function() { return true; };
-    }
</del><ins>+            // Calculate pageX/Y if missing and clientX/Y available
+            if ( event.pageX == null &amp;&amp; original.clientX != null ) {
+                eventDoc = event.target.ownerDocument || document;
+                doc = eventDoc.documentElement;
+                body = eventDoc.body;
</ins><span class="cx"> 
</span><del>-    nodeName = nodeName.replace( runescape, funescape ).toLowerCase();
-    return function( elem ) {
-    return elem.nodeName &amp;&amp; elem.nodeName.toLowerCase() === nodeName;
-    };
-    },
</del><ins>+                event.pageX = original.clientX + ( doc &amp;&amp; doc.scrollLeft || body &amp;&amp; body.scrollLeft || 0 ) - ( doc &amp;&amp; doc.clientLeft || body &amp;&amp; body.clientLeft || 0 );
+                event.pageY = original.clientY + ( doc &amp;&amp; doc.scrollTop  || body &amp;&amp; body.scrollTop  || 0 ) - ( doc &amp;&amp; doc.clientTop  || body &amp;&amp; body.clientTop  || 0 );
+            }
</ins><span class="cx"> 
</span><del>-    &quot;CLASS&quot;: function( className ) {
-    var pattern = classCache[ className + &quot; &quot; ];
</del><ins>+            // Add which for click: 1 === left; 2 === middle; 3 === right
+            // Note: button is not normalized, so don't use it
+            if ( !event.which &amp;&amp; button !== undefined ) {
+                event.which = ( button &amp; 1 ? 1 : ( button &amp; 2 ? 3 : ( button &amp; 4 ? 2 : 0 ) ) );
+            }
</ins><span class="cx"> 
</span><del>-    return pattern ||
-    (pattern = new RegExp( &quot;(^|&quot; + whitespace + &quot;)&quot; + className + &quot;(&quot; + whitespace + &quot;|$)&quot; )) &amp;&amp;
-    classCache( className, function( elem ) {
-    return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined &amp;&amp; elem.getAttribute(&quot;class&quot;)) || &quot;&quot; );
-    });
</del><ins>+            return event;
+        }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    &quot;ATTR&quot;: function( name, operator, check ) {
-    return function( elem ) {
-    var result = Sizzle.attr( elem, name );
</del><ins>+    fix: function( event ) {
+        if ( event[ jQuery.expando ] ) {
+            return event;
+        }
</ins><span class="cx"> 
</span><del>-    if ( result == null ) {
-    return operator === &quot;!=&quot;;
-    }
-    if ( !operator ) {
-    return true;
-    }
</del><ins>+        // Create a writable copy of the event object and normalize some properties
+        var i, prop, copy,
+            type = event.type,
+            originalEvent = event,
+            fixHook = this.fixHooks[ type ];
</ins><span class="cx"> 
</span><del>-    result += &quot;&quot;;
</del><ins>+        if ( !fixHook ) {
+            this.fixHooks[ type ] = fixHook =
+                rmouseEvent.test( type ) ? this.mouseHooks :
+                rkeyEvent.test( type ) ? this.keyHooks :
+                {};
+        }
+        copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
</ins><span class="cx"> 
</span><del>-    return operator === &quot;=&quot; ? result === check :
-    operator === &quot;!=&quot; ? result !== check :
-    operator === &quot;^=&quot; ? check &amp;&amp; result.indexOf( check ) === 0 :
-    operator === &quot;*=&quot; ? check &amp;&amp; result.indexOf( check ) &gt; -1 :
-    operator === &quot;$=&quot; ? check &amp;&amp; result.slice( -check.length ) === check :
-    operator === &quot;~=&quot; ? ( &quot; &quot; + result + &quot; &quot; ).indexOf( check ) &gt; -1 :
-    operator === &quot;|=&quot; ? result === check || result.slice( 0, check.length + 1 ) === check + &quot;-&quot; :
-    false;
-    };
-    },
</del><ins>+        event = new jQuery.Event( originalEvent );
</ins><span class="cx"> 
</span><del>-    &quot;CHILD&quot;: function( type, what, argument, first, last ) {
-    var simple = type.slice( 0, 3 ) !== &quot;nth&quot;,
-    forward = type.slice( -4 ) !== &quot;last&quot;,
-    ofType = what === &quot;of-type&quot;;
</del><ins>+        i = copy.length;
+        while ( i-- ) {
+            prop = copy[ i ];
+            event[ prop ] = originalEvent[ prop ];
+        }
</ins><span class="cx"> 
</span><del>-    return first === 1 &amp;&amp; last === 0 ?
</del><ins>+        // Support: Cordova 2.5 (WebKit) (#13255)
+        // All events should have a target; Cordova deviceready doesn't
+        if ( !event.target ) {
+            event.target = document;
+        }
</ins><span class="cx"> 
</span><del>-    // Shortcut for :nth-*(n)
-    function( elem ) {
-    return !!elem.parentNode;
-    } :
</del><ins>+        // Support: Safari 6.0+, Chrome &lt; 28
+        // Target should not be a text node (#504, #13143)
+        if ( event.target.nodeType === 3 ) {
+            event.target = event.target.parentNode;
+        }
</ins><span class="cx"> 
</span><del>-    function( elem, context, xml ) {
-    var cache, outerCache, node, diff, nodeIndex, start,
-    dir = simple !== forward ? &quot;nextSibling&quot; : &quot;previousSibling&quot;,
-    parent = elem.parentNode,
-    name = ofType &amp;&amp; elem.nodeName.toLowerCase(),
-    useCache = !xml &amp;&amp; !ofType;
</del><ins>+        return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
+    },
</ins><span class="cx"> 
</span><del>-    if ( parent ) {
</del><ins>+    special: {
+        load: {
+            // Prevent triggered image.load events from bubbling to window.load
+            noBubble: true
+        },
+        focus: {
+            // Fire native event if possible so blur/focus sequence is correct
+            trigger: function() {
+                if ( this !== safeActiveElement() &amp;&amp; this.focus ) {
+                    this.focus();
+                    return false;
+                }
+            },
+            delegateType: &quot;focusin&quot;
+        },
+        blur: {
+            trigger: function() {
+                if ( this === safeActiveElement() &amp;&amp; this.blur ) {
+                    this.blur();
+                    return false;
+                }
+            },
+            delegateType: &quot;focusout&quot;
+        },
+        click: {
+            // For checkbox, fire native event so checked state will be right
+            trigger: function() {
+                if ( this.type === &quot;checkbox&quot; &amp;&amp; this.click &amp;&amp; jQuery.nodeName( this, &quot;input&quot; ) ) {
+                    this.click();
+                    return false;
+                }
+            },
</ins><span class="cx"> 
</span><del>-    // :(first|last|only)-(child|of-type)
-    if ( simple ) {
-    while ( dir ) {
-    node = elem;
-    while ( (node = node[ dir ]) ) {
-    if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
-    return false;
-    }
-    }
-    // Reverse direction for :only-* (if we haven't yet done so)
-    start = dir = type === &quot;only&quot; &amp;&amp; !start &amp;&amp; &quot;nextSibling&quot;;
-    }
-    return true;
-    }
</del><ins>+            // For cross-browser consistency, don't fire native .click() on links
+            _default: function( event ) {
+                return jQuery.nodeName( event.target, &quot;a&quot; );
+            }
+        },
</ins><span class="cx"> 
</span><del>-    start = [ forward ? parent.firstChild : parent.lastChild ];
</del><ins>+        beforeunload: {
+            postDispatch: function( event ) {
</ins><span class="cx"> 
</span><del>-    // non-xml :nth-child(...) stores cache data on `parent`
-    if ( forward &amp;&amp; useCache ) {
-    // Seek `elem` from a previously-cached index
-    outerCache = parent[ expando ] || (parent[ expando ] = {});
-    cache = outerCache[ type ] || [];
-    nodeIndex = cache[0] === dirruns &amp;&amp; cache[1];
-    diff = cache[0] === dirruns &amp;&amp; cache[2];
-    node = nodeIndex &amp;&amp; parent.childNodes[ nodeIndex ];
</del><ins>+                // Support: Firefox 20+
+                // Firefox doesn't alert if the returnValue field is not set.
+                if ( event.result !== undefined ) {
+                    event.originalEvent.returnValue = event.result;
+                }
+            }
+        }
+    },
</ins><span class="cx"> 
</span><del>-    while ( (node = ++nodeIndex &amp;&amp; node &amp;&amp; node[ dir ] ||
</del><ins>+    simulate: function( type, elem, event, bubble ) {
+        // Piggyback on a donor event to simulate a different one.
+        // Fake originalEvent to avoid donor's stopPropagation, but if the
+        // simulated event prevents default then we do the same on the donor.
+        var e = jQuery.extend(
+            new jQuery.Event(),
+            event,
+            {
+                type: type,
+                isSimulated: true,
+                originalEvent: {}
+            }
+        );
+        if ( bubble ) {
+            jQuery.event.trigger( e, null, elem );
+        } else {
+            jQuery.event.dispatch.call( elem, e );
+        }
+        if ( e.isDefaultPrevented() ) {
+            event.preventDefault();
+        }
+    }
+};
</ins><span class="cx"> 
</span><del>-    // Fallback to seeking `elem` from the start
-    (diff = nodeIndex = 0) || start.pop()) ) {
</del><ins>+jQuery.removeEvent = function( elem, type, handle ) {
+    if ( elem.removeEventListener ) {
+        elem.removeEventListener( type, handle, false );
+    }
+};
</ins><span class="cx"> 
</span><del>-    // When found, cache indexes on `parent` and break
-    if ( node.nodeType === 1 &amp;&amp; ++diff &amp;&amp; node === elem ) {
-    outerCache[ type ] = [ dirruns, nodeIndex, diff ];
-    break;
</del><ins>+jQuery.Event = function( src, props ) {
+    // Allow instantiation without the 'new' keyword
+    if ( !(this instanceof jQuery.Event) ) {
+        return new jQuery.Event( src, props );
</ins><span class="cx">     }
</span><del>-    }
</del><span class="cx"> 
</span><del>-    // Use previously-cached element index if available
-    } else if ( useCache &amp;&amp; (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) &amp;&amp; cache[0] === dirruns ) {
-    diff = cache[1];
</del><ins>+    // Event object
+    if ( src &amp;&amp; src.type ) {
+        this.originalEvent = src;
+        this.type = src.type;
</ins><span class="cx"> 
</span><del>-    // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
-    } else {
-    // Use the same loop as above to seek `elem` from the start
-    while ( (node = ++nodeIndex &amp;&amp; node &amp;&amp; node[ dir ] ||
-    (diff = nodeIndex = 0) || start.pop()) ) {
</del><ins>+        // Events bubbling up the document may have been marked as prevented
+        // by a handler lower down the tree; reflect the correct value.
+        this.isDefaultPrevented = src.defaultPrevented ||
+                // Support: Android &lt; 4.0
+                src.defaultPrevented === undefined &amp;&amp;
+                src.getPreventDefault &amp;&amp; src.getPreventDefault() ?
+            returnTrue :
+            returnFalse;
</ins><span class="cx"> 
</span><del>-    if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) &amp;&amp; ++diff ) {
-    // Cache the index of each encountered element
-    if ( useCache ) {
-    (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
</del><ins>+    // Event type
+    } else {
+        this.type = src;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if ( node === elem ) {
-    break;
</del><ins>+    // Put explicitly provided properties onto the event object
+    if ( props ) {
+        jQuery.extend( this, props );
</ins><span class="cx">     }
</span><del>-    }
-    }
-    }
</del><span class="cx"> 
</span><del>-    // Incorporate the offset, then check against cycle size
-    diff -= last;
-    return diff === first || ( diff % first === 0 &amp;&amp; diff / first &gt;= 0 );
-    }
-    };
-    },
</del><ins>+    // Create a timestamp if incoming event doesn't have one
+    this.timeStamp = src &amp;&amp; src.timeStamp || jQuery.now();
</ins><span class="cx"> 
</span><del>-    &quot;PSEUDO&quot;: function( pseudo, argument ) {
-    // pseudo-class names are case-insensitive
-    // http://www.w3.org/TR/selectors/#pseudo-classes
-    // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
-    // Remember that setFilters inherits from pseudos
-    var args,
-    fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
-    Sizzle.error( &quot;unsupported pseudo: &quot; + pseudo );
</del><ins>+    // Mark it as fixed
+    this[ jQuery.expando ] = true;
+};
</ins><span class="cx"> 
</span><del>-    // The user may use createPseudo to indicate that
-    // arguments are needed to create the filter function
-    // just as Sizzle does
-    if ( fn[ expando ] ) {
-    return fn( argument );
-    }
</del><ins>+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+    isDefaultPrevented: returnFalse,
+    isPropagationStopped: returnFalse,
+    isImmediatePropagationStopped: returnFalse,
</ins><span class="cx"> 
</span><del>-    // But maintain support for old signatures
-    if ( fn.length &gt; 1 ) {
-    args = [ pseudo, pseudo, &quot;&quot;, argument ];
-    return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
-    markFunction(function( seed, matches ) {
-    var idx,
-    matched = fn( seed, argument ),
-    i = matched.length;
-    while ( i-- ) {
-    idx = indexOf.call( seed, matched[i] );
-    seed[ idx ] = !( matches[ idx ] = matched[i] );
-    }
-    }) :
-    function( elem ) {
-    return fn( elem, 0, args );
-    };
-    }
</del><ins>+    preventDefault: function() {
+        var e = this.originalEvent;
</ins><span class="cx"> 
</span><del>-    return fn;
-    }
</del><ins>+        this.isDefaultPrevented = returnTrue;
+
+        if ( e &amp;&amp; e.preventDefault ) {
+            e.preventDefault();
+        }
</ins><span class="cx">     },
</span><ins>+    stopPropagation: function() {
+        var e = this.originalEvent;
</ins><span class="cx"> 
</span><del>-    pseudos: {
-    // Potentially complex pseudos
-    &quot;not&quot;: markFunction(function( selector ) {
-    // Trim the selector passed to compile
-    // to avoid treating leading and trailing
-    // spaces as combinators
-    var input = [],
-    results = [],
-    matcher = compile( selector.replace( rtrim, &quot;$1&quot; ) );
</del><ins>+        this.isPropagationStopped = returnTrue;
</ins><span class="cx"> 
</span><del>-    return matcher[ expando ] ?
-    markFunction(function( seed, matches, context, xml ) {
-    var elem,
-    unmatched = matcher( seed, null, xml, [] ),
-    i = seed.length;
-
-    // Match elements unmatched by `matcher`
-    while ( i-- ) {
-    if ( (elem = unmatched[i]) ) {
-    seed[i] = !(matches[i] = elem);
</del><ins>+        if ( e &amp;&amp; e.stopPropagation ) {
+            e.stopPropagation();
+        }
+    },
+    stopImmediatePropagation: function() {
+        this.isImmediatePropagationStopped = returnTrue;
+        this.stopPropagation();
</ins><span class="cx">     }
</span><del>-    }
-    }) :
-    function( elem, context, xml ) {
-    input[0] = elem;
-    matcher( input, null, xml, results );
-    return !results.pop();
-    };
-    }),
</del><ins>+};
</ins><span class="cx"> 
</span><del>-    &quot;has&quot;: markFunction(function( selector ) {
-    return function( elem ) {
-    return Sizzle( selector, elem ).length &gt; 0;
-    };
-    }),
</del><ins>+// Create mouseenter/leave events using mouseover/out and event-time checks
+// Support: Chrome 15+
+jQuery.each({
+    mouseenter: &quot;mouseover&quot;,
+    mouseleave: &quot;mouseout&quot;
+}, function( orig, fix ) {
+    jQuery.event.special[ orig ] = {
+        delegateType: fix,
+        bindType: fix,
</ins><span class="cx"> 
</span><del>-    &quot;contains&quot;: markFunction(function( text ) {
-    return function( elem ) {
-    return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) &gt; -1;
</del><ins>+        handle: function( event ) {
+            var ret,
+                target = this,
+                related = event.relatedTarget,
+                handleObj = event.handleObj;
+
+            // For mousenter/leave call the handler if related is outside the target.
+            // NB: No relatedTarget if the mouse left/entered the browser window
+            if ( !related || (related !== target &amp;&amp; !jQuery.contains( target, related )) ) {
+                event.type = handleObj.origType;
+                ret = handleObj.handler.apply( this, arguments );
+                event.type = fix;
+            }
+            return ret;
+        }
</ins><span class="cx">     };
</span><del>-    }),
</del><ins>+});
</ins><span class="cx"> 
</span><del>-    // &quot;Whether an element is represented by a :lang() selector
-    // is based solely on the element's language value
-    // being equal to the identifier C,
-    // or beginning with the identifier C immediately followed by &quot;-&quot;.
-    // The matching of C against the element's language value is performed case-insensitively.
-    // The identifier C does not have to be a valid language name.&quot;
-    // http://www.w3.org/TR/selectors/#lang-pseudo
-    &quot;lang&quot;: markFunction( function( lang ) {
-    // lang value must be a valid identifider
-    if ( !ridentifier.test(lang || &quot;&quot;) ) {
-    Sizzle.error( &quot;unsupported lang: &quot; + lang );
-    }
-    lang = lang.replace( runescape, funescape ).toLowerCase();
-    return function( elem ) {
-    var elemLang;
-    do {
-    if ( (elemLang = documentIsXML ?
-    elem.getAttribute(&quot;xml:lang&quot;) || elem.getAttribute(&quot;lang&quot;) :
-    elem.lang) ) {
</del><ins>+// Create &quot;bubbling&quot; focus and blur events
+// Support: Firefox, Chrome, Safari
+if ( !support.focusinBubbles ) {
+    jQuery.each({ focus: &quot;focusin&quot;, blur: &quot;focusout&quot; }, function( orig, fix ) {
</ins><span class="cx"> 
</span><del>-    elemLang = elemLang.toLowerCase();
-    return elemLang === lang || elemLang.indexOf( lang + &quot;-&quot; ) === 0;
-    }
-    } while ( (elem = elem.parentNode) &amp;&amp; elem.nodeType === 1 );
-    return false;
-    };
-    }),
</del><ins>+        // Attach a single capturing handler on the document while someone wants focusin/focusout
+        var handler = function( event ) {
+                jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
+            };
</ins><span class="cx"> 
</span><del>-    // Miscellaneous
-    &quot;target&quot;: function( elem ) {
-    var hash = window.location &amp;&amp; window.location.hash;
-    return hash &amp;&amp; hash.slice( 1 ) === elem.id;
-    },
</del><ins>+        jQuery.event.special[ fix ] = {
+            setup: function() {
+                var doc = this.ownerDocument || this,
+                    attaches = data_priv.access( doc, fix );
</ins><span class="cx"> 
</span><del>-    &quot;root&quot;: function( elem ) {
-    return elem === docElem;
-    },
</del><ins>+                if ( !attaches ) {
+                    doc.addEventListener( orig, handler, true );
+                }
+                data_priv.access( doc, fix, ( attaches || 0 ) + 1 );
+            },
+            teardown: function() {
+                var doc = this.ownerDocument || this,
+                    attaches = data_priv.access( doc, fix ) - 1;
</ins><span class="cx"> 
</span><del>-    &quot;focus&quot;: function( elem ) {
-    return elem === document.activeElement &amp;&amp; (!document.hasFocus || document.hasFocus()) &amp;&amp; !!(elem.type || elem.href || ~elem.tabIndex);
-    },
</del><ins>+                if ( !attaches ) {
+                    doc.removeEventListener( orig, handler, true );
+                    data_priv.remove( doc, fix );
</ins><span class="cx"> 
</span><del>-    // Boolean properties
-    &quot;enabled&quot;: function( elem ) {
-    return elem.disabled === false;
-    },
</del><ins>+                } else {
+                    data_priv.access( doc, fix, attaches );
+                }
+            }
+        };
+    });
+}
</ins><span class="cx"> 
</span><del>-    &quot;disabled&quot;: function( elem ) {
-    return elem.disabled === true;
-    },
</del><ins>+jQuery.fn.extend({
</ins><span class="cx"> 
</span><del>-    &quot;checked&quot;: function( elem ) {
-    // In CSS3, :checked should return both checked and selected elements
-    // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
-    var nodeName = elem.nodeName.toLowerCase();
-    return (nodeName === &quot;input&quot; &amp;&amp; !!elem.checked) || (nodeName === &quot;option&quot; &amp;&amp; !!elem.selected);
-    },
</del><ins>+    on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
+        var origFn, type;
</ins><span class="cx"> 
</span><del>-    &quot;selected&quot;: function( elem ) {
-    // Accessing this property makes selected-by-default
-    // options in Safari work properly
-    if ( elem.parentNode ) {
-    elem.parentNode.selectedIndex;
-    }
</del><ins>+        // Types can be a map of types/handlers
+        if ( typeof types === &quot;object&quot; ) {
+            // ( types-Object, selector, data )
+            if ( typeof selector !== &quot;string&quot; ) {
+                // ( types-Object, data )
+                data = data || selector;
+                selector = undefined;
+            }
+            for ( type in types ) {
+                this.on( type, selector, data, types[ type ], one );
+            }
+            return this;
+        }
</ins><span class="cx"> 
</span><del>-    return elem.selected === true;
-    },
</del><ins>+        if ( data == null &amp;&amp; fn == null ) {
+            // ( types, fn )
+            fn = selector;
+            data = selector = undefined;
+        } else if ( fn == null ) {
+            if ( typeof selector === &quot;string&quot; ) {
+                // ( types, selector, fn )
+                fn = data;
+                data = undefined;
+            } else {
+                // ( types, data, fn )
+                fn = data;
+                data = selector;
+                selector = undefined;
+            }
+        }
+        if ( fn === false ) {
+            fn = returnFalse;
+        } else if ( !fn ) {
+            return this;
+        }
</ins><span class="cx"> 
</span><del>-    // Contents
-    &quot;empty&quot;: function( elem ) {
-    // http://www.w3.org/TR/selectors/#empty-pseudo
-    // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
-    //   not comment, processing instructions, or others
-    // Thanks to Diego Perini for the nodeName shortcut
-    //   Greater than &quot;@&quot; means alpha characters (specifically not starting with &quot;#&quot; or &quot;?&quot;)
-    for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
-    if ( elem.nodeName &gt; &quot;@&quot; || elem.nodeType === 3 || elem.nodeType === 4 ) {
-    return false;
-    }
-    }
-    return true;
</del><ins>+        if ( one === 1 ) {
+            origFn = fn;
+            fn = function( event ) {
+                // Can use an empty set, since event contains the info
+                jQuery().off( event );
+                return origFn.apply( this, arguments );
+            };
+            // Use same guid so caller can remove using origFn
+            fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+        }
+        return this.each( function() {
+            jQuery.event.add( this, types, fn, data, selector );
+        });
</ins><span class="cx">     },
</span><del>-
-    &quot;parent&quot;: function( elem ) {
-    return !Expr.pseudos[&quot;empty&quot;]( elem );
</del><ins>+    one: function( types, selector, data, fn ) {
+        return this.on( types, selector, data, fn, 1 );
</ins><span class="cx">     },
</span><del>-
-    // Element/input types
-    &quot;header&quot;: function( elem ) {
-    return rheader.test( elem.nodeName );
</del><ins>+    off: function( types, selector, fn ) {
+        var handleObj, type;
+        if ( types &amp;&amp; types.preventDefault &amp;&amp; types.handleObj ) {
+            // ( event )  dispatched jQuery.Event
+            handleObj = types.handleObj;
+            jQuery( types.delegateTarget ).off(
+                handleObj.namespace ? handleObj.origType + &quot;.&quot; + handleObj.namespace : handleObj.origType,
+                handleObj.selector,
+                handleObj.handler
+            );
+            return this;
+        }
+        if ( typeof types === &quot;object&quot; ) {
+            // ( types-object [, selector] )
+            for ( type in types ) {
+                this.off( type, selector, types[ type ] );
+            }
+            return this;
+        }
+        if ( selector === false || typeof selector === &quot;function&quot; ) {
+            // ( types [, fn] )
+            fn = selector;
+            selector = undefined;
+        }
+        if ( fn === false ) {
+            fn = returnFalse;
+        }
+        return this.each(function() {
+            jQuery.event.remove( this, types, fn, selector );
+        });
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    &quot;input&quot;: function( elem ) {
-    return rinputs.test( elem.nodeName );
</del><ins>+    trigger: function( type, data ) {
+        return this.each(function() {
+            jQuery.event.trigger( type, data, this );
+        });
</ins><span class="cx">     },
</span><ins>+    triggerHandler: function( type, data ) {
+        var elem = this[0];
+        if ( elem ) {
+            return jQuery.event.trigger( type, data, elem, true );
+        }
+    }
+});
</ins><span class="cx"> 
</span><del>-    &quot;button&quot;: function( elem ) {
-    var name = elem.nodeName.toLowerCase();
-    return name === &quot;input&quot; &amp;&amp; elem.type === &quot;button&quot; || name === &quot;button&quot;;
-    },
</del><span class="cx"> 
</span><del>-    &quot;text&quot;: function( elem ) {
-    var attr;
-    // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
-    // use getAttribute instead to test this case
-    return elem.nodeName.toLowerCase() === &quot;input&quot; &amp;&amp;
-    elem.type === &quot;text&quot; &amp;&amp;
-    ( (attr = elem.getAttribute(&quot;type&quot;)) == null || attr.toLowerCase() === elem.type );
-    },
</del><ins>+var
+    rxhtmlTag = /&lt;(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^&gt;]*)\/&gt;/gi,
+    rtagName = /&lt;([\w:]+)/,
+    rhtml = /&lt;|&amp;#?\w+;/,
+    rnoInnerhtml = /&lt;(?:script|style|link)/i,
+    // checked=&quot;checked&quot; or checked
+    rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+    rscriptType = /^$|\/(?:java|ecma)script/i,
+    rscriptTypeMasked = /^true\/(.*)/,
+    rcleanScript = /^\s*&lt;!(?:\[CDATA\[|--)|(?:\]\]|--)&gt;\s*$/g,
</ins><span class="cx"> 
</span><del>-    // Position-in-collection
-    &quot;first&quot;: createPositionalPseudo(function() {
-    return [ 0 ];
-    }),
</del><ins>+    // We have to close these tags to support XHTML (#13200)
+    wrapMap = {
</ins><span class="cx"> 
</span><del>-    &quot;last&quot;: createPositionalPseudo(function( matchIndexes, length ) {
-    return [ length - 1 ];
-    }),
</del><ins>+        // Support: IE 9
+        option: [ 1, &quot;&lt;select multiple='multiple'&gt;&quot;, &quot;&lt;/select&gt;&quot; ],
</ins><span class="cx"> 
</span><del>-    &quot;eq&quot;: createPositionalPseudo(function( matchIndexes, length, argument ) {
-    return [ argument &lt; 0 ? argument + length : argument ];
-    }),
</del><ins>+        thead: [ 1, &quot;&lt;table&gt;&quot;, &quot;&lt;/table&gt;&quot; ],
+        col: [ 2, &quot;&lt;table&gt;&lt;colgroup&gt;&quot;, &quot;&lt;/colgroup&gt;&lt;/table&gt;&quot; ],
+        tr: [ 2, &quot;&lt;table&gt;&lt;tbody&gt;&quot;, &quot;&lt;/tbody&gt;&lt;/table&gt;&quot; ],
+        td: [ 3, &quot;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&quot;, &quot;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&quot; ],
</ins><span class="cx"> 
</span><del>-    &quot;even&quot;: createPositionalPseudo(function( matchIndexes, length ) {
-    var i = 0;
-    for ( ; i &lt; length; i += 2 ) {
-    matchIndexes.push( i );
-    }
-    return matchIndexes;
-    }),
</del><ins>+        _default: [ 0, &quot;&quot;, &quot;&quot; ]
+    };
</ins><span class="cx"> 
</span><del>-    &quot;odd&quot;: createPositionalPseudo(function( matchIndexes, length ) {
-    var i = 1;
-    for ( ; i &lt; length; i += 2 ) {
-    matchIndexes.push( i );
-    }
-    return matchIndexes;
-    }),
</del><ins>+// Support: IE 9
+wrapMap.optgroup = wrapMap.option;
</ins><span class="cx"> 
</span><del>-    &quot;lt&quot;: createPositionalPseudo(function( matchIndexes, length, argument ) {
-    var i = argument &lt; 0 ? argument + length : argument;
-    for ( ; --i &gt;= 0; ) {
-    matchIndexes.push( i );
-    }
-    return matchIndexes;
-    }),
</del><ins>+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
</ins><span class="cx"> 
</span><del>-    &quot;gt&quot;: createPositionalPseudo(function( matchIndexes, length, argument ) {
-    var i = argument &lt; 0 ? argument + length : argument;
-    for ( ; ++i &lt; length; ) {
-    matchIndexes.push( i );
-    }
-    return matchIndexes;
-    })
-    }
-};
</del><ins>+// Support: 1.x compatibility
+// Manipulating tables requires a tbody
+function manipulationTarget( elem, content ) {
+    return jQuery.nodeName( elem, &quot;table&quot; ) &amp;&amp;
+        jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, &quot;tr&quot; ) ?
</ins><span class="cx"> 
</span><del>-// Add button/input type pseudos
-for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
-    Expr.pseudos[ i ] = createInputPseudo( i );
</del><ins>+        elem.getElementsByTagName(&quot;tbody&quot;)[0] ||
+            elem.appendChild( elem.ownerDocument.createElement(&quot;tbody&quot;) ) :
+        elem;
</ins><span class="cx"> }
</span><del>-for ( i in { submit: true, reset: true } ) {
-    Expr.pseudos[ i ] = createButtonPseudo( i );
</del><ins>+
+// Replace/restore the type attribute of script elements for safe DOM manipulation
+function disableScript( elem ) {
+    elem.type = (elem.getAttribute(&quot;type&quot;) !== null) + &quot;/&quot; + elem.type;
+    return elem;
</ins><span class="cx"> }
</span><ins>+function restoreScript( elem ) {
+    var match = rscriptTypeMasked.exec( elem.type );
</ins><span class="cx"> 
</span><del>-function tokenize( selector, parseOnly ) {
-    var matched, match, tokens, type,
-    soFar, groups, preFilters,
-    cached = tokenCache[ selector + &quot; &quot; ];
-
-    if ( cached ) {
-    return parseOnly ? 0 : cached.slice( 0 );
</del><ins>+    if ( match ) {
+        elem.type = match[ 1 ];
+    } else {
+        elem.removeAttribute(&quot;type&quot;);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    soFar = selector;
-    groups = [];
-    preFilters = Expr.preFilter;
</del><ins>+    return elem;
+}
</ins><span class="cx"> 
</span><del>-    while ( soFar ) {
</del><ins>+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+    var i = 0,
+        l = elems.length;
</ins><span class="cx"> 
</span><del>-    // Comma and first run
-    if ( !matched || (match = rcomma.exec( soFar )) ) {
-    if ( match ) {
-    // Don't consume trailing commas as valid
-    soFar = soFar.slice( match[0].length ) || soFar;
</del><ins>+    for ( ; i &lt; l; i++ ) {
+        data_priv.set(
+            elems[ i ], &quot;globalEval&quot;, !refElements || data_priv.get( refElements[ i ], &quot;globalEval&quot; )
+        );
</ins><span class="cx">     }
</span><del>-    groups.push( tokens = [] );
-    }
</del><ins>+}
</ins><span class="cx"> 
</span><del>-    matched = false;
</del><ins>+function cloneCopyEvent( src, dest ) {
+    var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
</ins><span class="cx"> 
</span><del>-    // Combinators
-    if ( (match = rcombinators.exec( soFar )) ) {
-    matched = match.shift();
-    tokens.push( {
-    value: matched,
-    // Cast descendant combinators to space
-    type: match[0].replace( rtrim, &quot; &quot; )
-    } );
-    soFar = soFar.slice( matched.length );
</del><ins>+    if ( dest.nodeType !== 1 ) {
+        return;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Filters
-    for ( type in Expr.filter ) {
-    if ( (match = matchExpr[ type ].exec( soFar )) &amp;&amp; (!preFilters[ type ] ||
-    (match = preFilters[ type ]( match ))) ) {
-    matched = match.shift();
-    tokens.push( {
-    value: matched,
-    type: type,
-    matches: match
-    } );
-    soFar = soFar.slice( matched.length );
-    }
-    }
</del><ins>+    // 1. Copy private data: events, handlers, etc.
+    if ( data_priv.hasData( src ) ) {
+        pdataOld = data_priv.access( src );
+        pdataCur = data_priv.set( dest, pdataOld );
+        events = pdataOld.events;
</ins><span class="cx"> 
</span><del>-    if ( !matched ) {
-    break;
</del><ins>+        if ( events ) {
+            delete pdataCur.handle;
+            pdataCur.events = {};
+
+            for ( type in events ) {
+                for ( i = 0, l = events[ type ].length; i &lt; l; i++ ) {
+                    jQuery.event.add( dest, type, events[ type ][ i ] );
+                }
+            }
+        }
</ins><span class="cx">     }
</span><del>-    }
</del><span class="cx"> 
</span><del>-    // Return the length of the invalid excess
-    // if we're just parsing
-    // Otherwise, throw an error or return tokens
-    return parseOnly ?
-    soFar.length :
-    soFar ?
-    Sizzle.error( selector ) :
-    // Cache the tokens
-    tokenCache( selector, groups ).slice( 0 );
-}
</del><ins>+    // 2. Copy user data
+    if ( data_user.hasData( src ) ) {
+        udataOld = data_user.access( src );
+        udataCur = jQuery.extend( {}, udataOld );
</ins><span class="cx"> 
</span><del>-function toSelector( tokens ) {
-    var i = 0,
-    len = tokens.length,
-    selector = &quot;&quot;;
-    for ( ; i &lt; len; i++ ) {
-    selector += tokens[i].value;
</del><ins>+        data_user.set( dest, udataCur );
</ins><span class="cx">     }
</span><del>-    return selector;
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-function addCombinator( matcher, combinator, base ) {
-    var dir = combinator.dir,
-    checkNonElements = base &amp;&amp; dir === &quot;parentNode&quot;,
-    doneName = done++;
</del><ins>+function getAll( context, tag ) {
+    var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || &quot;*&quot; ) :
+            context.querySelectorAll ? context.querySelectorAll( tag || &quot;*&quot; ) :
+            [];
</ins><span class="cx"> 
</span><del>-    return combinator.first ?
-    // Check against closest ancestor/preceding element
-    function( elem, context, xml ) {
-    while ( (elem = elem[ dir ]) ) {
-    if ( elem.nodeType === 1 || checkNonElements ) {
-    return matcher( elem, context, xml );
-    }
-    }
-    } :
</del><ins>+    return tag === undefined || tag &amp;&amp; jQuery.nodeName( context, tag ) ?
+        jQuery.merge( [ context ], ret ) :
+        ret;
+}
</ins><span class="cx"> 
</span><del>-    // Check against all ancestor/preceding elements
-    function( elem, context, xml ) {
-    var data, cache, outerCache,
-    dirkey = dirruns + &quot; &quot; + doneName;
</del><ins>+// Support: IE &gt;= 9
+function fixInput( src, dest ) {
+    var nodeName = dest.nodeName.toLowerCase();
</ins><span class="cx"> 
</span><del>-    // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
-    if ( xml ) {
-    while ( (elem = elem[ dir ]) ) {
-    if ( elem.nodeType === 1 || checkNonElements ) {
-    if ( matcher( elem, context, xml ) ) {
-    return true;
-    }
-    }
-    }
-    } else {
-    while ( (elem = elem[ dir ]) ) {
-    if ( elem.nodeType === 1 || checkNonElements ) {
-    outerCache = elem[ expando ] || (elem[ expando ] = {});
-    if ( (cache = outerCache[ dir ]) &amp;&amp; cache[0] === dirkey ) {
-    if ( (data = cache[1]) === true || data === cachedruns ) {
-    return data === true;
-    }
-    } else {
-    cache = outerCache[ dir ] = [ dirkey ];
-    cache[1] = matcher( elem, context, xml ) || cachedruns;
-    if ( cache[1] === true ) {
-    return true;
-    }
-    }
-    }
-    }
-    }
-    };
-}
</del><ins>+    // Fails to persist the checked state of a cloned checkbox or radio button.
+    if ( nodeName === &quot;input&quot; &amp;&amp; rcheckableType.test( src.type ) ) {
+        dest.checked = src.checked;
</ins><span class="cx"> 
</span><del>-function elementMatcher( matchers ) {
-    return matchers.length &gt; 1 ?
-    function( elem, context, xml ) {
-    var i = matchers.length;
-    while ( i-- ) {
-    if ( !matchers[i]( elem, context, xml ) ) {
-    return false;
</del><ins>+    // Fails to return the selected option to the default selected state when cloning options
+    } else if ( nodeName === &quot;input&quot; || nodeName === &quot;textarea&quot; ) {
+        dest.defaultValue = src.defaultValue;
</ins><span class="cx">     }
</span><del>-    }
-    return true;
-    } :
-    matchers[0];
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-function condense( unmatched, map, filter, context, xml ) {
-    var elem,
-    newUnmatched = [],
-    i = 0,
-    len = unmatched.length,
-    mapped = map != null;
</del><ins>+jQuery.extend({
+    clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+        var i, l, srcElements, destElements,
+            clone = elem.cloneNode( true ),
+            inPage = jQuery.contains( elem.ownerDocument, elem );
</ins><span class="cx"> 
</span><del>-    for ( ; i &lt; len; i++ ) {
-    if ( (elem = unmatched[i]) ) {
-    if ( !filter || filter( elem, context, xml ) ) {
-    newUnmatched.push( elem );
-    if ( mapped ) {
-    map.push( i );
-    }
-    }
-    }
-    }
</del><ins>+        // Support: IE &gt;= 9
+        // Fix Cloning issues
+        if ( !support.noCloneChecked &amp;&amp; ( elem.nodeType === 1 || elem.nodeType === 11 ) &amp;&amp;
+                !jQuery.isXMLDoc( elem ) ) {
</ins><span class="cx"> 
</span><del>-    return newUnmatched;
-}
</del><ins>+            // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
+            destElements = getAll( clone );
+            srcElements = getAll( elem );
</ins><span class="cx"> 
</span><del>-function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
-    if ( postFilter &amp;&amp; !postFilter[ expando ] ) {
-    postFilter = setMatcher( postFilter );
-    }
-    if ( postFinder &amp;&amp; !postFinder[ expando ] ) {
-    postFinder = setMatcher( postFinder, postSelector );
-    }
-    return markFunction(function( seed, results, context, xml ) {
-    var temp, i, elem,
-    preMap = [],
-    postMap = [],
-    preexisting = results.length,
</del><ins>+            for ( i = 0, l = srcElements.length; i &lt; l; i++ ) {
+                fixInput( srcElements[ i ], destElements[ i ] );
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // Get initial elements from seed or context
-    elems = seed || multipleContexts( selector || &quot;*&quot;, context.nodeType ? [ context ] : context, [] ),
</del><ins>+        // Copy the events from the original to the clone
+        if ( dataAndEvents ) {
+            if ( deepDataAndEvents ) {
+                srcElements = srcElements || getAll( elem );
+                destElements = destElements || getAll( clone );
</ins><span class="cx"> 
</span><del>-    // Prefilter to get matcher input, preserving a map for seed-results synchronization
-    matcherIn = preFilter &amp;&amp; ( seed || !selector ) ?
-    condense( elems, preMap, preFilter, context, xml ) :
-    elems,
</del><ins>+                for ( i = 0, l = srcElements.length; i &lt; l; i++ ) {
+                    cloneCopyEvent( srcElements[ i ], destElements[ i ] );
+                }
+            } else {
+                cloneCopyEvent( elem, clone );
+            }
+        }
</ins><span class="cx"> 
</span><del>-    matcherOut = matcher ?
-    // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
-    postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
</del><ins>+        // Preserve script evaluation history
+        destElements = getAll( clone, &quot;script&quot; );
+        if ( destElements.length &gt; 0 ) {
+            setGlobalEval( destElements, !inPage &amp;&amp; getAll( elem, &quot;script&quot; ) );
+        }
</ins><span class="cx"> 
</span><del>-    // ...intermediate processing is necessary
-    [] :
</del><ins>+        // Return the cloned set
+        return clone;
+    },
</ins><span class="cx"> 
</span><del>-    // ...otherwise use results directly
-    results :
-    matcherIn;
</del><ins>+    buildFragment: function( elems, context, scripts, selection ) {
+        var elem, tmp, tag, wrap, contains, j,
+            fragment = context.createDocumentFragment(),
+            nodes = [],
+            i = 0,
+            l = elems.length;
</ins><span class="cx"> 
</span><del>-    // Find primary matches
-    if ( matcher ) {
-    matcher( matcherIn, matcherOut, context, xml );
-    }
</del><ins>+        for ( ; i &lt; l; i++ ) {
+            elem = elems[ i ];
</ins><span class="cx"> 
</span><del>-    // Apply postFilter
-    if ( postFilter ) {
-    temp = condense( matcherOut, postMap );
-    postFilter( temp, [], context, xml );
</del><ins>+            if ( elem || elem === 0 ) {
</ins><span class="cx"> 
</span><del>-    // Un-match failing elements by moving them back to matcherIn
-    i = temp.length;
-    while ( i-- ) {
-    if ( (elem = temp[i]) ) {
-    matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
-    }
-    }
-    }
</del><ins>+                // Add nodes directly
+                if ( jQuery.type( elem ) === &quot;object&quot; ) {
+                    // Support: QtWebKit
+                    // jQuery.merge because push.apply(_, arraylike) throws
+                    jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
</ins><span class="cx"> 
</span><del>-    if ( seed ) {
-    if ( postFinder || preFilter ) {
-    if ( postFinder ) {
-    // Get the final matcherOut by condensing this intermediate into postFinder contexts
-    temp = [];
-    i = matcherOut.length;
-    while ( i-- ) {
-    if ( (elem = matcherOut[i]) ) {
-    // Restore matcherIn since elem is not yet a final match
-    temp.push( (matcherIn[i] = elem) );
-    }
-    }
-    postFinder( null, (matcherOut = []), temp, xml );
-    }
</del><ins>+                // Convert non-html into a text node
+                } else if ( !rhtml.test( elem ) ) {
+                    nodes.push( context.createTextNode( elem ) );
</ins><span class="cx"> 
</span><del>-    // Move matched elements from seed to results to keep them synchronized
-    i = matcherOut.length;
-    while ( i-- ) {
-    if ( (elem = matcherOut[i]) &amp;&amp;
-    (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) &gt; -1 ) {
</del><ins>+                // Convert html into DOM nodes
+                } else {
+                    tmp = tmp || fragment.appendChild( context.createElement(&quot;div&quot;) );
</ins><span class="cx"> 
</span><del>-    seed[temp] = !(results[temp] = elem);
-    }
-    }
-    }
</del><ins>+                    // Deserialize a standard representation
+                    tag = ( rtagName.exec( elem ) || [ &quot;&quot;, &quot;&quot; ] )[ 1 ].toLowerCase();
+                    wrap = wrapMap[ tag ] || wrapMap._default;
+                    tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, &quot;&lt;$1&gt;&lt;/$2&gt;&quot; ) + wrap[ 2 ];
</ins><span class="cx"> 
</span><del>-    // Add elements to results, through postFinder if defined
-    } else {
-    matcherOut = condense(
-    matcherOut === results ?
-    matcherOut.splice( preexisting, matcherOut.length ) :
-    matcherOut
-    );
-    if ( postFinder ) {
-    postFinder( null, results, matcherOut, xml );
-    } else {
-    push.apply( results, matcherOut );
-    }
-    }
-    });
-}
</del><ins>+                    // Descend through wrappers to the right content
+                    j = wrap[ 0 ];
+                    while ( j-- ) {
+                        tmp = tmp.lastChild;
+                    }
</ins><span class="cx"> 
</span><del>-function matcherFromTokens( tokens ) {
-    var checkContext, matcher, j,
-    len = tokens.length,
-    leadingRelative = Expr.relative[ tokens[0].type ],
-    implicitRelative = leadingRelative || Expr.relative[&quot; &quot;],
-    i = leadingRelative ? 1 : 0,
</del><ins>+                    // Support: QtWebKit
+                    // jQuery.merge because push.apply(_, arraylike) throws
+                    jQuery.merge( nodes, tmp.childNodes );
</ins><span class="cx"> 
</span><del>-    // The foundational matcher ensures that elements are reachable from top-level context(s)
-    matchContext = addCombinator( function( elem ) {
-    return elem === checkContext;
-    }, implicitRelative, true ),
-    matchAnyContext = addCombinator( function( elem ) {
-    return indexOf.call( checkContext, elem ) &gt; -1;
-    }, implicitRelative, true ),
-    matchers = [ function( elem, context, xml ) {
-    return ( !leadingRelative &amp;&amp; ( xml || context !== outermostContext ) ) || (
-    (checkContext = context).nodeType ?
-    matchContext( elem, context, xml ) :
-    matchAnyContext( elem, context, xml ) );
-    } ];
</del><ins>+                    // Remember the top-level container
+                    tmp = fragment.firstChild;
</ins><span class="cx"> 
</span><del>-    for ( ; i &lt; len; i++ ) {
-    if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
-    matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
-    } else {
-    matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
</del><ins>+                    // Fixes #12346
+                    // Support: Webkit, IE
+                    tmp.textContent = &quot;&quot;;
+                }
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // Return special upon seeing a positional matcher
-    if ( matcher[ expando ] ) {
-    // Find the next relative operator (if any) for proper handling
-    j = ++i;
-    for ( ; j &lt; len; j++ ) {
-    if ( Expr.relative[ tokens[j].type ] ) {
-    break;
-    }
-    }
-    return setMatcher(
-    i &gt; 1 &amp;&amp; elementMatcher( matchers ),
-    i &gt; 1 &amp;&amp; toSelector( tokens.slice( 0, i - 1 ) ).replace( rtrim, &quot;$1&quot; ),
-    matcher,
-    i &lt; j &amp;&amp; matcherFromTokens( tokens.slice( i, j ) ),
-    j &lt; len &amp;&amp; matcherFromTokens( (tokens = tokens.slice( j )) ),
-    j &lt; len &amp;&amp; toSelector( tokens )
-    );
-    }
-    matchers.push( matcher );
-    }
-    }
</del><ins>+        // Remove wrapper from fragment
+        fragment.textContent = &quot;&quot;;
</ins><span class="cx"> 
</span><del>-    return elementMatcher( matchers );
-}
</del><ins>+        i = 0;
+        while ( (elem = nodes[ i++ ]) ) {
</ins><span class="cx"> 
</span><del>-function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
-    // A counter to specify which element is currently being matched
-    var matcherCachedRuns = 0,
-    bySet = setMatchers.length &gt; 0,
-    byElement = elementMatchers.length &gt; 0,
-    superMatcher = function( seed, context, xml, results, expandContext ) {
-    var elem, j, matcher,
-    setMatched = [],
-    matchedCount = 0,
-    i = &quot;0&quot;,
-    unmatched = seed &amp;&amp; [],
-    outermost = expandContext != null,
-    contextBackup = outermostContext,
-    // We must always have either seed elements or context
-    elems = seed || byElement &amp;&amp; Expr.find[&quot;TAG&quot;]( &quot;*&quot;, expandContext &amp;&amp; context.parentNode || context ),
-    // Use integer dirruns iff this is the outermost matcher
-    dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1);
</del><ins>+            // #4087 - If origin and destination elements are the same, and this is
+            // that element, do not do anything
+            if ( selection &amp;&amp; jQuery.inArray( elem, selection ) !== -1 ) {
+                continue;
+            }
</ins><span class="cx"> 
</span><del>-    if ( outermost ) {
-    outermostContext = context !== document &amp;&amp; context;
-    cachedruns = matcherCachedRuns;
-    }
</del><ins>+            contains = jQuery.contains( elem.ownerDocument, elem );
</ins><span class="cx"> 
</span><del>-    // Add elements passing elementMatchers directly to results
-    // Keep `i` a string if there are no elements so `matchedCount` will be &quot;00&quot; below
-    for ( ; (elem = elems[i]) != null; i++ ) {
-    if ( byElement &amp;&amp; elem ) {
-    j = 0;
-    while ( (matcher = elementMatchers[j++]) ) {
-    if ( matcher( elem, context, xml ) ) {
-    results.push( elem );
-    break;
-    }
-    }
-    if ( outermost ) {
-    dirruns = dirrunsUnique;
-    cachedruns = ++matcherCachedRuns;
-    }
-    }
</del><ins>+            // Append to fragment
+            tmp = getAll( fragment.appendChild( elem ), &quot;script&quot; );
</ins><span class="cx"> 
</span><del>-    // Track unmatched elements for set filters
-    if ( bySet ) {
-    // They will have gone through all possible matchers
-    if ( (elem = !matcher &amp;&amp; elem) ) {
-    matchedCount--;
-    }
</del><ins>+            // Preserve script evaluation history
+            if ( contains ) {
+                setGlobalEval( tmp );
+            }
</ins><span class="cx"> 
</span><del>-    // Lengthen the array for every element, matched or not
-    if ( seed ) {
-    unmatched.push( elem );
-    }
-    }
-    }
</del><ins>+            // Capture executables
+            if ( scripts ) {
+                j = 0;
+                while ( (elem = tmp[ j++ ]) ) {
+                    if ( rscriptType.test( elem.type || &quot;&quot; ) ) {
+                        scripts.push( elem );
+                    }
+                }
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // Apply set filters to unmatched elements
-    matchedCount += i;
-    if ( bySet &amp;&amp; i !== matchedCount ) {
-    j = 0;
-    while ( (matcher = setMatchers[j++]) ) {
-    matcher( unmatched, setMatched, context, xml );
-    }
</del><ins>+        return fragment;
+    },
</ins><span class="cx"> 
</span><del>-    if ( seed ) {
-    // Reintegrate element matches to eliminate the need for sorting
-    if ( matchedCount &gt; 0 ) {
-    while ( i-- ) {
-    if ( !(unmatched[i] || setMatched[i]) ) {
-    setMatched[i] = pop.call( results );
-    }
-    }
-    }
</del><ins>+    cleanData: function( elems ) {
+        var data, elem, events, type, key, j,
+            special = jQuery.event.special,
+            i = 0;
</ins><span class="cx"> 
</span><del>-    // Discard index placeholder values to get only actual matches
-    setMatched = condense( setMatched );
-    }
</del><ins>+        for ( ; (elem = elems[ i ]) !== undefined; i++ ) {
+            if ( jQuery.acceptData( elem ) ) {
+                key = elem[ data_priv.expando ];
</ins><span class="cx"> 
</span><del>-    // Add matches to results
-    push.apply( results, setMatched );
</del><ins>+                if ( key &amp;&amp; (data = data_priv.cache[ key ]) ) {
+                    events = Object.keys( data.events || {} );
+                    if ( events.length ) {
+                        for ( j = 0; (type = events[j]) !== undefined; j++ ) {
+                            if ( special[ type ] ) {
+                                jQuery.event.remove( elem, type );
</ins><span class="cx"> 
</span><del>-    // Seedless set matches succeeding multiple successful matchers stipulate sorting
-    if ( outermost &amp;&amp; !seed &amp;&amp; setMatched.length &gt; 0 &amp;&amp;
-    ( matchedCount + setMatchers.length ) &gt; 1 ) {
-
-    Sizzle.uniqueSort( results );
</del><ins>+                            // This is a shortcut to avoid jQuery.event.remove's overhead
+                            } else {
+                                jQuery.removeEvent( elem, type, data.handle );
+                            }
+                        }
+                    }
+                    if ( data_priv.cache[ key ] ) {
+                        // Discard any remaining `private` data
+                        delete data_priv.cache[ key ];
+                    }
+                }
+            }
+            // Discard any remaining `user` data
+            delete data_user.cache[ elem[ data_user.expando ] ];
+        }
</ins><span class="cx">     }
</span><del>-    }
</del><ins>+});
</ins><span class="cx"> 
</span><del>-    // Override manipulation of globals by nested matchers
-    if ( outermost ) {
-    dirruns = dirrunsUnique;
-    outermostContext = contextBackup;
-    }
</del><ins>+jQuery.fn.extend({
+    text: function( value ) {
+        return access( this, function( value ) {
+            return value === undefined ?
+                jQuery.text( this ) :
+                this.empty().each(function() {
+                    if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+                        this.textContent = value;
+                    }
+                });
+        }, null, value, arguments.length );
+    },
</ins><span class="cx"> 
</span><del>-    return unmatched;
-    };
</del><ins>+    append: function() {
+        return this.domManip( arguments, function( elem ) {
+            if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+                var target = manipulationTarget( this, elem );
+                target.appendChild( elem );
+            }
+        });
+    },
</ins><span class="cx"> 
</span><del>-    return bySet ?
-    markFunction( superMatcher ) :
-    superMatcher;
-}
</del><ins>+    prepend: function() {
+        return this.domManip( arguments, function( elem ) {
+            if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+                var target = manipulationTarget( this, elem );
+                target.insertBefore( elem, target.firstChild );
+            }
+        });
+    },
</ins><span class="cx"> 
</span><del>-compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
-    var i,
-    setMatchers = [],
-    elementMatchers = [],
-    cached = compilerCache[ selector + &quot; &quot; ];
</del><ins>+    before: function() {
+        return this.domManip( arguments, function( elem ) {
+            if ( this.parentNode ) {
+                this.parentNode.insertBefore( elem, this );
+            }
+        });
+    },
</ins><span class="cx"> 
</span><del>-    if ( !cached ) {
-    // Generate a function of recursive functions that can be used to check each element
-    if ( !group ) {
-    group = tokenize( selector );
-    }
-    i = group.length;
-    while ( i-- ) {
-    cached = matcherFromTokens( group[i] );
-    if ( cached[ expando ] ) {
-    setMatchers.push( cached );
-    } else {
-    elementMatchers.push( cached );
-    }
-    }
</del><ins>+    after: function() {
+        return this.domManip( arguments, function( elem ) {
+            if ( this.parentNode ) {
+                this.parentNode.insertBefore( elem, this.nextSibling );
+            }
+        });
+    },
</ins><span class="cx"> 
</span><del>-    // Cache the compiled function
-    cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
-    }
-    return cached;
-};
</del><ins>+    remove: function( selector, keepData /* Internal Use Only */ ) {
+        var elem,
+            elems = selector ? jQuery.filter( selector, this ) : this,
+            i = 0;
</ins><span class="cx"> 
</span><del>-function multipleContexts( selector, contexts, results ) {
-    var i = 0,
-    len = contexts.length;
-    for ( ; i &lt; len; i++ ) {
-    Sizzle( selector, contexts[i], results );
-    }
-    return results;
-}
</del><ins>+        for ( ; (elem = elems[i]) != null; i++ ) {
+            if ( !keepData &amp;&amp; elem.nodeType === 1 ) {
+                jQuery.cleanData( getAll( elem ) );
+            }
</ins><span class="cx"> 
</span><del>-function select( selector, context, results, seed ) {
-    var i, tokens, token, type, find,
-    match = tokenize( selector );
</del><ins>+            if ( elem.parentNode ) {
+                if ( keepData &amp;&amp; jQuery.contains( elem.ownerDocument, elem ) ) {
+                    setGlobalEval( getAll( elem, &quot;script&quot; ) );
+                }
+                elem.parentNode.removeChild( elem );
+            }
+        }
</ins><span class="cx"> 
</span><del>-    if ( !seed ) {
-    // Try to minimize operations if there is only one group
-    if ( match.length === 1 ) {
</del><ins>+        return this;
+    },
</ins><span class="cx"> 
</span><del>-    // Take a shortcut and set the context if the root selector is an ID
-    tokens = match[0] = match[0].slice( 0 );
-    if ( tokens.length &gt; 2 &amp;&amp; (token = tokens[0]).type === &quot;ID&quot; &amp;&amp;
-    context.nodeType === 9 &amp;&amp; !documentIsXML &amp;&amp;
-    Expr.relative[ tokens[1].type ] ) {
</del><ins>+    empty: function() {
+        var elem,
+            i = 0;
</ins><span class="cx"> 
</span><del>-    context = Expr.find[&quot;ID&quot;]( token.matches[0].replace( runescape, funescape ), context )[0];
-    if ( !context ) {
-    return results;
-    }
</del><ins>+        for ( ; (elem = this[i]) != null; i++ ) {
+            if ( elem.nodeType === 1 ) {
</ins><span class="cx"> 
</span><del>-    selector = selector.slice( tokens.shift().value.length );
-    }
</del><ins>+                // Prevent memory leaks
+                jQuery.cleanData( getAll( elem, false ) );
</ins><span class="cx"> 
</span><del>-    // Fetch a seed set for right-to-left matching
-    i = matchExpr[&quot;needsContext&quot;].test( selector ) ? 0 : tokens.length;
-    while ( i-- ) {
-    token = tokens[i];
</del><ins>+                // Remove any remaining nodes
+                elem.textContent = &quot;&quot;;
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // Abort if we hit a combinator
-    if ( Expr.relative[ (type = token.type) ] ) {
-    break;
-    }
-    if ( (find = Expr.find[ type ]) ) {
-    // Search, expanding context for leading sibling combinators
-    if ( (seed = find(
-    token.matches[0].replace( runescape, funescape ),
-    rsibling.test( tokens[0].type ) &amp;&amp; context.parentNode || context
-    )) ) {
</del><ins>+        return this;
+    },
</ins><span class="cx"> 
</span><del>-    // If seed is empty or no tokens remain, we can return early
-    tokens.splice( i, 1 );
-    selector = seed.length &amp;&amp; toSelector( tokens );
-    if ( !selector ) {
-    push.apply( results, slice.call( seed, 0 ) );
-    return results;
-    }
</del><ins>+    clone: function( dataAndEvents, deepDataAndEvents ) {
+        dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+        deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
</ins><span class="cx"> 
</span><del>-    break;
-    }
-    }
-    }
-    }
-    }
</del><ins>+        return this.map(function() {
+            return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+        });
+    },
</ins><span class="cx"> 
</span><del>-    // Compile and execute a filtering function
-    // Provide `match` to avoid retokenization if we modified the selector above
-    compile( selector, match )(
-    seed,
-    context,
-    documentIsXML,
-    results,
-    rsibling.test( selector )
-    );
-    return results;
-}
</del><ins>+    html: function( value ) {
+        return access( this, function( value ) {
+            var elem = this[ 0 ] || {},
+                i = 0,
+                l = this.length;
</ins><span class="cx"> 
</span><del>-// Deprecated
-Expr.pseudos[&quot;nth&quot;] = Expr.pseudos[&quot;eq&quot;];
</del><ins>+            if ( value === undefined &amp;&amp; elem.nodeType === 1 ) {
+                return elem.innerHTML;
+            }
</ins><span class="cx"> 
</span><del>-// Easy API for creating new setFilters
-function setFilters() {}
-Expr.filters = setFilters.prototype = Expr.pseudos;
-Expr.setFilters = new setFilters();
</del><ins>+            // See if we can take a shortcut and just use innerHTML
+            if ( typeof value === &quot;string&quot; &amp;&amp; !rnoInnerhtml.test( value ) &amp;&amp;
+                !wrapMap[ ( rtagName.exec( value ) || [ &quot;&quot;, &quot;&quot; ] )[ 1 ].toLowerCase() ] ) {
</ins><span class="cx"> 
</span><del>-// Initialize with the default document
-setDocument();
</del><ins>+                value = value.replace( rxhtmlTag, &quot;&lt;$1&gt;&lt;/$2&gt;&quot; );
</ins><span class="cx"> 
</span><del>-// Override sizzle attribute retrieval
-Sizzle.attr = jQuery.attr;
-jQuery.find = Sizzle;
-jQuery.expr = Sizzle.selectors;
-jQuery.expr[&quot;:&quot;] = jQuery.expr.pseudos;
-jQuery.unique = Sizzle.uniqueSort;
-jQuery.text = Sizzle.getText;
-jQuery.isXMLDoc = Sizzle.isXML;
-jQuery.contains = Sizzle.contains;
</del><ins>+                try {
+                    for ( ; i &lt; l; i++ ) {
+                        elem = this[ i ] || {};
</ins><span class="cx"> 
</span><ins>+                        // Remove element nodes and prevent memory leaks
+                        if ( elem.nodeType === 1 ) {
+                            jQuery.cleanData( getAll( elem, false ) );
+                            elem.innerHTML = value;
+                        }
+                    }
</ins><span class="cx"> 
</span><del>-})( window );
-var runtil = /Until$/,
-    rparentsprev = /^(?:parents|prev(?:Until|All))/,
-    isSimple = /^.[^:#\[\.,]*$/,
-    rneedsContext = jQuery.expr.match.needsContext,
-    // methods guaranteed to produce a unique set when starting from a unique set
-    guaranteedUnique = {
-    children: true,
-    contents: true,
-    next: true,
-    prev: true
-    };
</del><ins>+                    elem = 0;
</ins><span class="cx"> 
</span><del>-jQuery.fn.extend({
-    find: function( selector ) {
-    var i, ret, self,
-    len = this.length;
</del><ins>+                // If using innerHTML throws an exception, use the fallback method
+                } catch( e ) {}
+            }
</ins><span class="cx"> 
</span><del>-    if ( typeof selector !== &quot;string&quot; ) {
-    self = this;
-    return this.pushStack( jQuery( selector ).filter(function() {
-    for ( i = 0; i &lt; len; i++ ) {
-    if ( jQuery.contains( self[ i ], this ) ) {
-    return true;
-    }
-    }
-    }) );
-    }
</del><ins>+            if ( elem ) {
+                this.empty().append( value );
+            }
+        }, null, value, arguments.length );
+    },
</ins><span class="cx"> 
</span><del>-    ret = [];
-    for ( i = 0; i &lt; len; i++ ) {
-    jQuery.find( selector, this[ i ], ret );
-    }
</del><ins>+    replaceWith: function() {
+        var arg = arguments[ 0 ];
</ins><span class="cx"> 
</span><del>-    // Needed because $( selector, context ) becomes $( context ).find( selector )
-    ret = this.pushStack( len &gt; 1 ? jQuery.unique( ret ) : ret );
-    ret.selector = ( this.selector ? this.selector + &quot; &quot; : &quot;&quot; ) + selector;
-    return ret;
-    },
</del><ins>+        // Make the changes, replacing each context element with the new content
+        this.domManip( arguments, function( elem ) {
+            arg = this.parentNode;
</ins><span class="cx"> 
</span><del>-    has: function( target ) {
-    var i,
-    targets = jQuery( target, this ),
-    len = targets.length;
</del><ins>+            jQuery.cleanData( getAll( this ) );
</ins><span class="cx"> 
</span><del>-    return this.filter(function() {
-    for ( i = 0; i &lt; len; i++ ) {
-    if ( jQuery.contains( this, targets[i] ) ) {
-    return true;
-    }
-    }
-    });
-    },
</del><ins>+            if ( arg ) {
+                arg.replaceChild( elem, this );
+            }
+        });
</ins><span class="cx"> 
</span><del>-    not: function( selector ) {
-    return this.pushStack( winnow(this, selector, false) );
</del><ins>+        // Force removal if there was no new content (e.g., from empty arguments)
+        return arg &amp;&amp; (arg.length || arg.nodeType) ? this : this.remove();
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    filter: function( selector ) {
-    return this.pushStack( winnow(this, selector, true) );
</del><ins>+    detach: function( selector ) {
+        return this.remove( selector, true );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    is: function( selector ) {
-    return !!selector &amp;&amp; (
-    typeof selector === &quot;string&quot; ?
-    // If this is a positional/relative selector, check membership in the returned set
-    // so $(&quot;p:first&quot;).is(&quot;p:last&quot;) won't return true for a doc with two &quot;p&quot;.
-    rneedsContext.test( selector ) ?
-    jQuery( selector, this.context ).index( this[0] ) &gt;= 0 :
-    jQuery.filter( selector, this ).length &gt; 0 :
-    this.filter( selector ).length &gt; 0 );
-    },
</del><ins>+    domManip: function( args, callback ) {
</ins><span class="cx"> 
</span><del>-    closest: function( selectors, context ) {
-    var cur,
-    i = 0,
-    l = this.length,
-    ret = [],
-    pos = rneedsContext.test( selectors ) || typeof selectors !== &quot;string&quot; ?
-    jQuery( selectors, context || this.context ) :
-    0;
</del><ins>+        // Flatten any nested arrays
+        args = concat.apply( [], args );
</ins><span class="cx"> 
</span><del>-    for ( ; i &lt; l; i++ ) {
-    cur = this[i];
</del><ins>+        var fragment, first, scripts, hasScripts, node, doc,
+            i = 0,
+            l = this.length,
+            set = this,
+            iNoClone = l - 1,
+            value = args[ 0 ],
+            isFunction = jQuery.isFunction( value );
</ins><span class="cx"> 
</span><del>-    while ( cur &amp;&amp; cur.ownerDocument &amp;&amp; cur !== context &amp;&amp; cur.nodeType !== 11 ) {
-    if ( pos ? pos.index(cur) &gt; -1 : jQuery.find.matchesSelector(cur, selectors) ) {
-    ret.push( cur );
-    break;
-    }
-    cur = cur.parentNode;
-    }
-    }
</del><ins>+        // We can't cloneNode fragments that contain checked, in WebKit
+        if ( isFunction ||
+                ( l &gt; 1 &amp;&amp; typeof value === &quot;string&quot; &amp;&amp;
+                    !support.checkClone &amp;&amp; rchecked.test( value ) ) ) {
+            return this.each(function( index ) {
+                var self = set.eq( index );
+                if ( isFunction ) {
+                    args[ 0 ] = value.call( this, index, self.html() );
+                }
+                self.domManip( args, callback );
+            });
+        }
</ins><span class="cx"> 
</span><del>-    return this.pushStack( ret.length &gt; 1 ? jQuery.unique( ret ) : ret );
-    },
</del><ins>+        if ( l ) {
+            fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
+            first = fragment.firstChild;
</ins><span class="cx"> 
</span><del>-    // Determine the position of an element within
-    // the matched set of elements
-    index: function( elem ) {
</del><ins>+            if ( fragment.childNodes.length === 1 ) {
+                fragment = first;
+            }
</ins><span class="cx"> 
</span><del>-    // No argument, return index in parent
-    if ( !elem ) {
-    return ( this[0] &amp;&amp; this[0].parentNode ) ? this.first().prevAll().length : -1;
-    }
</del><ins>+            if ( first ) {
+                scripts = jQuery.map( getAll( fragment, &quot;script&quot; ), disableScript );
+                hasScripts = scripts.length;
</ins><span class="cx"> 
</span><del>-    // index in selector
-    if ( typeof elem === &quot;string&quot; ) {
-    return jQuery.inArray( this[0], jQuery( elem ) );
-    }
</del><ins>+                // Use the original fragment for the last item instead of the first because it can end up
+                // being emptied incorrectly in certain situations (#8070).
+                for ( ; i &lt; l; i++ ) {
+                    node = fragment;
</ins><span class="cx"> 
</span><del>-    // Locate the position of the desired element
-    return jQuery.inArray(
-    // If it receives a jQuery object, the first element is used
-    elem.jquery ? elem[0] : elem, this );
-    },
</del><ins>+                    if ( i !== iNoClone ) {
+                        node = jQuery.clone( node, true, true );
</ins><span class="cx"> 
</span><del>-    add: function( selector, context ) {
-    var set = typeof selector === &quot;string&quot; ?
-    jQuery( selector, context ) :
-    jQuery.makeArray( selector &amp;&amp; selector.nodeType ? [ selector ] : selector ),
-    all = jQuery.merge( this.get(), set );
</del><ins>+                        // Keep references to cloned scripts for later restoration
+                        if ( hasScripts ) {
+                            // Support: QtWebKit
+                            // jQuery.merge because push.apply(_, arraylike) throws
+                            jQuery.merge( scripts, getAll( node, &quot;script&quot; ) );
+                        }
+                    }
</ins><span class="cx"> 
</span><del>-    return this.pushStack( jQuery.unique(all) );
-    },
</del><ins>+                    callback.call( this[ i ], node, i );
+                }
</ins><span class="cx"> 
</span><del>-    addBack: function( selector ) {
-    return this.add( selector == null ?
-    this.prevObject : this.prevObject.filter(selector)
-    );
</del><ins>+                if ( hasScripts ) {
+                    doc = scripts[ scripts.length - 1 ].ownerDocument;
+
+                    // Reenable scripts
+                    jQuery.map( scripts, restoreScript );
+
+                    // Evaluate executable scripts on first document insertion
+                    for ( i = 0; i &lt; hasScripts; i++ ) {
+                        node = scripts[ i ];
+                        if ( rscriptType.test( node.type || &quot;&quot; ) &amp;&amp;
+                            !data_priv.access( node, &quot;globalEval&quot; ) &amp;&amp; jQuery.contains( doc, node ) ) {
+
+                            if ( node.src ) {
+                                // Optional AJAX dependency, but won't run scripts if not present
+                                if ( jQuery._evalUrl ) {
+                                    jQuery._evalUrl( node.src );
+                                }
+                            } else {
+                                jQuery.globalEval( node.textContent.replace( rcleanScript, &quot;&quot; ) );
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return this;
</ins><span class="cx">     }
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-jQuery.fn.andSelf = jQuery.fn.addBack;
</del><ins>+jQuery.each({
+    appendTo: &quot;append&quot;,
+    prependTo: &quot;prepend&quot;,
+    insertBefore: &quot;before&quot;,
+    insertAfter: &quot;after&quot;,
+    replaceAll: &quot;replaceWith&quot;
+}, function( name, original ) {
+    jQuery.fn[ name ] = function( selector ) {
+        var elems,
+            ret = [],
+            insert = jQuery( selector ),
+            last = insert.length - 1,
+            i = 0;
</ins><span class="cx"> 
</span><del>-function sibling( cur, dir ) {
-    do {
-    cur = cur[ dir ];
-    } while ( cur &amp;&amp; cur.nodeType !== 1 );
</del><ins>+        for ( ; i &lt;= last; i++ ) {
+            elems = i === last ? this : this.clone( true );
+            jQuery( insert[ i ] )[ original ]( elems );
</ins><span class="cx"> 
</span><del>-    return cur;
</del><ins>+            // Support: QtWebKit
+            // .get() because push.apply(_, arraylike) throws
+            push.apply( ret, elems.get() );
+        }
+
+        return this.pushStack( ret );
+    };
+});
+
+
+var iframe,
+    elemdisplay = {};
+
+/**
+ * Retrieve the actual display of a element
+ * @param {String} name nodeName of the element
+ * @param {Object} doc Document object
+ */
+// Called only from within defaultDisplay
+function actualDisplay( name, doc ) {
+    var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
+
+        // getDefaultComputedStyle might be reliably used only on attached element
+        display = window.getDefaultComputedStyle ?
+
+            // Use of this method is a temporary fix (more like optmization) until something better comes along,
+            // since it was removed from specification and supported only in FF
+            window.getDefaultComputedStyle( elem[ 0 ] ).display : jQuery.css( elem[ 0 ], &quot;display&quot; );
+
+    // We don't have any data stored on the element,
+    // so use &quot;detach&quot; method as fast way to get rid of the element
+    elem.detach();
+
+    return display;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-jQuery.each({
-    parent: function( elem ) {
-    var parent = elem.parentNode;
-    return parent &amp;&amp; parent.nodeType !== 11 ? parent : null;
-    },
-    parents: function( elem ) {
-    return jQuery.dir( elem, &quot;parentNode&quot; );
-    },
-    parentsUntil: function( elem, i, until ) {
-    return jQuery.dir( elem, &quot;parentNode&quot;, until );
-    },
-    next: function( elem ) {
-    return sibling( elem, &quot;nextSibling&quot; );
-    },
-    prev: function( elem ) {
-    return sibling( elem, &quot;previousSibling&quot; );
-    },
-    nextAll: function( elem ) {
-    return jQuery.dir( elem, &quot;nextSibling&quot; );
-    },
-    prevAll: function( elem ) {
-    return jQuery.dir( elem, &quot;previousSibling&quot; );
-    },
-    nextUntil: function( elem, i, until ) {
-    return jQuery.dir( elem, &quot;nextSibling&quot;, until );
-    },
-    prevUntil: function( elem, i, until ) {
-    return jQuery.dir( elem, &quot;previousSibling&quot;, until );
-    },
-    siblings: function( elem ) {
-    return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
-    },
-    children: function( elem ) {
-    return jQuery.sibling( elem.firstChild );
-    },
-    contents: function( elem ) {
-    return jQuery.nodeName( elem, &quot;iframe&quot; ) ?
-    elem.contentDocument || elem.contentWindow.document :
-    jQuery.merge( [], elem.childNodes );
-    }
-}, function( name, fn ) {
-    jQuery.fn[ name ] = function( until, selector ) {
-    var ret = jQuery.map( this, fn, until );
</del><ins>+/**
+ * Try to determine the default display value of an element
+ * @param {String} nodeName
+ */
+function defaultDisplay( nodeName ) {
+    var doc = document,
+        display = elemdisplay[ nodeName ];
</ins><span class="cx"> 
</span><del>-    if ( !runtil.test( name ) ) {
-    selector = until;
-    }
</del><ins>+    if ( !display ) {
+        display = actualDisplay( nodeName, doc );
</ins><span class="cx"> 
</span><del>-    if ( selector &amp;&amp; typeof selector === &quot;string&quot; ) {
-    ret = jQuery.filter( selector, ret );
-    }
</del><ins>+        // If the simple way fails, read from inside an iframe
+        if ( display === &quot;none&quot; || !display ) {
</ins><span class="cx"> 
</span><del>-    ret = this.length &gt; 1 &amp;&amp; !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
</del><ins>+            // Use the already-created iframe if possible
+            iframe = (iframe || jQuery( &quot;&lt;iframe frameborder='0' width='0' height='0'/&gt;&quot; )).appendTo( doc.documentElement );
</ins><span class="cx"> 
</span><del>-    if ( this.length &gt; 1 &amp;&amp; rparentsprev.test( name ) ) {
-    ret = ret.reverse();
-    }
</del><ins>+            // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
+            doc = iframe[ 0 ].contentDocument;
</ins><span class="cx"> 
</span><del>-    return this.pushStack( ret );
-    };
-});
</del><ins>+            // Support: IE
+            doc.write();
+            doc.close();
</ins><span class="cx"> 
</span><del>-jQuery.extend({
-    filter: function( expr, elems, not ) {
-    if ( not ) {
-    expr = &quot;:not(&quot; + expr + &quot;)&quot;;
</del><ins>+            display = actualDisplay( nodeName, doc );
+            iframe.detach();
+        }
+
+        // Store the correct default display
+        elemdisplay[ nodeName ] = display;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return elems.length === 1 ?
-    jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
-    jQuery.find.matches(expr, elems);
-    },
</del><ins>+    return display;
+}
+var rmargin = (/^margin/);
</ins><span class="cx"> 
</span><del>-    dir: function( elem, dir, until ) {
-    var matched = [],
-    cur = elem[ dir ];
</del><ins>+var rnumnonpx = new RegExp( &quot;^(&quot; + pnum + &quot;)(?!px)[a-z%]+$&quot;, &quot;i&quot; );
</ins><span class="cx"> 
</span><del>-    while ( cur &amp;&amp; cur.nodeType !== 9 &amp;&amp; (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
-    if ( cur.nodeType === 1 ) {
-    matched.push( cur );
-    }
-    cur = cur[dir];
-    }
-    return matched;
-    },
</del><ins>+var getStyles = function( elem ) {
+        return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
+    };
</ins><span class="cx"> 
</span><del>-    sibling: function( n, elem ) {
-    var r = [];
</del><span class="cx"> 
</span><del>-    for ( ; n; n = n.nextSibling ) {
-    if ( n.nodeType === 1 &amp;&amp; n !== elem ) {
-    r.push( n );
-    }
-    }
</del><span class="cx"> 
</span><del>-    return r;
</del><ins>+function curCSS( elem, name, computed ) {
+    var width, minWidth, maxWidth, ret,
+        style = elem.style;
+
+    computed = computed || getStyles( elem );
+
+    // Support: IE9
+    // getPropertyValue is only needed for .css('filter') in IE9, see #12537
+    if ( computed ) {
+        ret = computed.getPropertyValue( name ) || computed[ name ];
</ins><span class="cx">     }
</span><del>-});
</del><span class="cx"> 
</span><del>-// Implement the identical functionality for filter and not
-function winnow( elements, qualifier, keep ) {
</del><ins>+    if ( computed ) {
</ins><span class="cx"> 
</span><del>-    // Can't pass null or undefined to indexOf in Firefox 4
-    // Set to 0 to skip string check
-    qualifier = qualifier || 0;
</del><ins>+        if ( ret === &quot;&quot; &amp;&amp; !jQuery.contains( elem.ownerDocument, elem ) ) {
+            ret = jQuery.style( elem, name );
+        }
</ins><span class="cx"> 
</span><del>-    if ( jQuery.isFunction( qualifier ) ) {
-    return jQuery.grep(elements, function( elem, i ) {
-    var retVal = !!qualifier.call( elem, i, elem );
-    return retVal === keep;
-    });
</del><ins>+        // Support: iOS &lt; 6
+        // A tribute to the &quot;awesome hack by Dean Edwards&quot;
+        // iOS &lt; 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
+        // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
+        if ( rnumnonpx.test( ret ) &amp;&amp; rmargin.test( name ) ) {
</ins><span class="cx"> 
</span><del>-    } else if ( qualifier.nodeType ) {
-    return jQuery.grep(elements, function( elem ) {
-    return ( elem === qualifier ) === keep;
-    });
</del><ins>+            // Remember the original values
+            width = style.width;
+            minWidth = style.minWidth;
+            maxWidth = style.maxWidth;
</ins><span class="cx"> 
</span><del>-    } else if ( typeof qualifier === &quot;string&quot; ) {
-    var filtered = jQuery.grep(elements, function( elem ) {
-    return elem.nodeType === 1;
-    });
</del><ins>+            // Put in the new values to get a computed value out
+            style.minWidth = style.maxWidth = style.width = ret;
+            ret = computed.width;
</ins><span class="cx"> 
</span><del>-    if ( isSimple.test( qualifier ) ) {
-    return jQuery.filter(qualifier, filtered, !keep);
-    } else {
-    qualifier = jQuery.filter( qualifier, filtered );
</del><ins>+            // Revert the changed values
+            style.width = width;
+            style.minWidth = minWidth;
+            style.maxWidth = maxWidth;
+        }
</ins><span class="cx">     }
</span><del>-    }
</del><span class="cx"> 
</span><del>-    return jQuery.grep(elements, function( elem ) {
-    return ( jQuery.inArray( elem, qualifier ) &gt;= 0 ) === keep;
-    });
</del><ins>+    return ret !== undefined ?
+        // Support: IE
+        // IE returns zIndex value as an integer.
+        ret + &quot;&quot; :
+        ret;
</ins><span class="cx"> }
</span><del>-function createSafeFragment( document ) {
-    var list = nodeNames.split( &quot;|&quot; ),
-    safeFrag = document.createDocumentFragment();
</del><span class="cx"> 
</span><del>-    if ( safeFrag.createElement ) {
-    while ( list.length ) {
-    safeFrag.createElement(
-    list.pop()
-    );
-    }
-    }
-    return safeFrag;
</del><ins>+
+function addGetHookIf( conditionFn, hookFn ) {
+    // Define the hook, we'll check on the first run if it's really needed.
+    return {
+        get: function() {
+            if ( conditionFn() ) {
+                // Hook not needed (or it's not possible to use it due to missing dependency),
+                // remove it.
+                // Since there are no other hooks for marginRight, remove the whole object.
+                delete this.get;
+                return;
+            }
+
+            // Hook needed; redefine it so that the support test is not executed again.
+
+            return (this.get = hookFn).apply( this, arguments );
+        }
+    };
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-var nodeNames = &quot;abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|&quot; +
-    &quot;header|hgroup|mark|meter|nav|output|progress|section|summary|time|video&quot;,
-    rinlinejQuery = / jQuery\d+=&quot;(?:null|\d+)&quot;/g,
-    rnoshimcache = new RegExp(&quot;&lt;(?:&quot; + nodeNames + &quot;)[\\s/&gt;]&quot;, &quot;i&quot;),
-    rleadingWhitespace = /^\s+/,
-    rxhtmlTag = /&lt;(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^&gt;]*)\/&gt;/gi,
-    rtagName = /&lt;([\w:]+)/,
-    rtbody = /&lt;tbody/i,
-    rhtml = /&lt;|&amp;#?\w+;/,
-    rnoInnerhtml = /&lt;(?:script|style|link)/i,
-    manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
-    // checked=&quot;checked&quot; or checked
-    rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
-    rscriptType = /^$|\/(?:java|ecma)script/i,
-    rscriptTypeMasked = /^true\/(.*)/,
-    rcleanScript = /^\s*&lt;!(?:\[CDATA\[|--)|(?:\]\]|--)&gt;\s*$/g,
</del><span class="cx"> 
</span><del>-    // We have to close these tags to support XHTML (#13200)
-    wrapMap = {
-    option: [ 1, &quot;&lt;select multiple='multiple'&gt;&quot;, &quot;&lt;/select&gt;&quot; ],
-    legend: [ 1, &quot;&lt;fieldset&gt;&quot;, &quot;&lt;/fieldset&gt;&quot; ],
-    area: [ 1, &quot;&lt;map&gt;&quot;, &quot;&lt;/map&gt;&quot; ],
-    param: [ 1, &quot;&lt;object&gt;&quot;, &quot;&lt;/object&gt;&quot; ],
-    thead: [ 1, &quot;&lt;table&gt;&quot;, &quot;&lt;/table&gt;&quot; ],
-    tr: [ 2, &quot;&lt;table&gt;&lt;tbody&gt;&quot;, &quot;&lt;/tbody&gt;&lt;/table&gt;&quot; ],
-    col: [ 2, &quot;&lt;table&gt;&lt;tbody&gt;&lt;/tbody&gt;&lt;colgroup&gt;&quot;, &quot;&lt;/colgroup&gt;&lt;/table&gt;&quot; ],
-    td: [ 3, &quot;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&quot;, &quot;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&quot; ],
</del><ins>+(function() {
+    var pixelPositionVal, boxSizingReliableVal,
+        // Support: Firefox, Android 2.3 (Prefixed box-sizing versions).
+        divReset = &quot;padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;&quot; +
+            &quot;-moz-box-sizing:content-box;box-sizing:content-box&quot;,
+        docElem = document.documentElement,
+        container = document.createElement( &quot;div&quot; ),
+        div = document.createElement( &quot;div&quot; );
</ins><span class="cx"> 
</span><del>-    // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
-    // unless wrapped in a div with non-breaking characters in front of it.
-    _default: jQuery.support.htmlSerialize ? [ 0, &quot;&quot;, &quot;&quot; ] : [ 1, &quot;X&lt;div&gt;&quot;, &quot;&lt;/div&gt;&quot;  ]
-    },
-    safeFragment = createSafeFragment( document ),
-    fragmentDiv = safeFragment.appendChild( document.createElement(&quot;div&quot;) );
</del><ins>+    div.style.backgroundClip = &quot;content-box&quot;;
+    div.cloneNode( true ).style.backgroundClip = &quot;&quot;;
+    support.clearCloneStyle = div.style.backgroundClip === &quot;content-box&quot;;
</ins><span class="cx"> 
</span><del>-wrapMap.optgroup = wrapMap.option;
-wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
-wrapMap.th = wrapMap.td;
</del><ins>+    container.style.cssText = &quot;border:0;width:0;height:0;position:absolute;top:0;left:-9999px;&quot; +
+        &quot;margin-top:1px&quot;;
+    container.appendChild( div );
</ins><span class="cx"> 
</span><del>-jQuery.fn.extend({
-    text: function( value ) {
-    return jQuery.access( this, function( value ) {
-    return value === undefined ?
-    jQuery.text( this ) :
-    this.empty().append( ( this[0] &amp;&amp; this[0].ownerDocument || document ).createTextNode( value ) );
-    }, null, value, arguments.length );
-    },
</del><ins>+    // Executing both pixelPosition &amp; boxSizingReliable tests require only one layout
+    // so they're executed at the same time to save the second computation.
+    function computePixelPositionAndBoxSizingReliable() {
+        // Support: Firefox, Android 2.3 (Prefixed box-sizing versions).
+        div.style.cssText = &quot;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;&quot; +
+            &quot;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;&quot; +
+            &quot;position:absolute;top:1%&quot;;
+        docElem.appendChild( container );
</ins><span class="cx"> 
</span><del>-    wrapAll: function( html ) {
-    if ( jQuery.isFunction( html ) ) {
-    return this.each(function(i) {
-    jQuery(this).wrapAll( html.call(this, i) );
-    });
</del><ins>+        var divStyle = window.getComputedStyle( div, null );
+        pixelPositionVal = divStyle.top !== &quot;1%&quot;;
+        boxSizingReliableVal = divStyle.width === &quot;4px&quot;;
+
+        docElem.removeChild( container );
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if ( this[0] ) {
-    // The elements to wrap the target around
-    var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
</del><ins>+    // Use window.getComputedStyle because jsdom on node.js will break without it.
+    if ( window.getComputedStyle ) {
+        jQuery.extend(support, {
+            pixelPosition: function() {
+                // This test is executed only once but we still do memoizing
+                // since we can use the boxSizingReliable pre-computing.
+                // No need to check if the test was already performed, though.
+                computePixelPositionAndBoxSizingReliable();
+                return pixelPositionVal;
+            },
+            boxSizingReliable: function() {
+                if ( boxSizingReliableVal == null ) {
+                    computePixelPositionAndBoxSizingReliable();
+                }
+                return boxSizingReliableVal;
+            },
+            reliableMarginRight: function() {
+                // Support: Android 2.3
+                // Check if div with explicit width and no margin-right incorrectly
+                // gets computed margin-right based on width of container. (#3333)
+                // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+                // This support function is only executed once so no memoizing is needed.
+                var ret,
+                    marginDiv = div.appendChild( document.createElement( &quot;div&quot; ) );
+                marginDiv.style.cssText = div.style.cssText = divReset;
+                marginDiv.style.marginRight = marginDiv.style.width = &quot;0&quot;;
+                div.style.width = &quot;1px&quot;;
+                docElem.appendChild( container );
</ins><span class="cx"> 
</span><del>-    if ( this[0].parentNode ) {
-    wrap.insertBefore( this[0] );
-    }
</del><ins>+                ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight );
</ins><span class="cx"> 
</span><del>-    wrap.map(function() {
-    var elem = this;
</del><ins>+                docElem.removeChild( container );
</ins><span class="cx"> 
</span><del>-    while ( elem.firstChild &amp;&amp; elem.firstChild.nodeType === 1 ) {
-    elem = elem.firstChild;
</del><ins>+                // Clean up the div for other support tests.
+                div.innerHTML = &quot;&quot;;
+
+                return ret;
+            }
+        });
</ins><span class="cx">     }
</span><ins>+})();
</ins><span class="cx"> 
</span><del>-    return elem;
-    }).append( this );
</del><ins>+
+// A method for quickly swapping in/out CSS properties to get correct calculations.
+jQuery.swap = function( elem, options, callback, args ) {
+    var ret, name,
+        old = {};
+
+    // Remember the old values, and insert the new ones
+    for ( name in options ) {
+        old[ name ] = elem.style[ name ];
+        elem.style[ name ] = options[ name ];
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return this;
-    },
</del><ins>+    ret = callback.apply( elem, args || [] );
</ins><span class="cx"> 
</span><del>-    wrapInner: function( html ) {
-    if ( jQuery.isFunction( html ) ) {
-    return this.each(function(i) {
-    jQuery(this).wrapInner( html.call(this, i) );
-    });
</del><ins>+    // Revert the old values
+    for ( name in options ) {
+        elem.style[ name ] = old[ name ];
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return this.each(function() {
-    var self = jQuery( this ),
-    contents = self.contents();
</del><ins>+    return ret;
+};
</ins><span class="cx"> 
</span><del>-    if ( contents.length ) {
-    contents.wrapAll( html );
</del><span class="cx"> 
</span><del>-    } else {
-    self.append( html );
-    }
-    });
</del><ins>+var
+    // swappable if display is none or starts with table except &quot;table&quot;, &quot;table-cell&quot;, or &quot;table-caption&quot;
+    // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+    rdisplayswap = /^(none|table(?!-c[ea]).+)/,
+    rnumsplit = new RegExp( &quot;^(&quot; + pnum + &quot;)(.*)$&quot;, &quot;i&quot; ),
+    rrelNum = new RegExp( &quot;^([+-])=(&quot; + pnum + &quot;)&quot;, &quot;i&quot; ),
+
+    cssShow = { position: &quot;absolute&quot;, visibility: &quot;hidden&quot;, display: &quot;block&quot; },
+    cssNormalTransform = {
+        letterSpacing: 0,
+        fontWeight: 400
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    wrap: function( html ) {
-    var isFunction = jQuery.isFunction( html );
</del><ins>+    cssPrefixes = [ &quot;Webkit&quot;, &quot;O&quot;, &quot;Moz&quot;, &quot;ms&quot; ];
</ins><span class="cx"> 
</span><del>-    return this.each(function(i) {
-    jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
-    });
-    },
</del><ins>+// return a css property mapped to a potentially vendor prefixed property
+function vendorPropName( style, name ) {
</ins><span class="cx"> 
</span><del>-    unwrap: function() {
-    return this.parent().each(function() {
-    if ( !jQuery.nodeName( this, &quot;body&quot; ) ) {
-    jQuery( this ).replaceWith( this.childNodes );
</del><ins>+    // shortcut for names that are not vendor prefixed
+    if ( name in style ) {
+        return name;
</ins><span class="cx">     }
</span><del>-    }).end();
-    },
</del><span class="cx"> 
</span><del>-    append: function() {
-    return this.domManip(arguments, true, function( elem ) {
-    if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
-    this.appendChild( elem );
-    }
-    });
-    },
</del><ins>+    // check for vendor prefixed names
+    var capName = name[0].toUpperCase() + name.slice(1),
+        origName = name,
+        i = cssPrefixes.length;
</ins><span class="cx"> 
</span><del>-    prepend: function() {
-    return this.domManip(arguments, true, function( elem ) {
-    if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
-    this.insertBefore( elem, this.firstChild );
</del><ins>+    while ( i-- ) {
+        name = cssPrefixes[ i ] + capName;
+        if ( name in style ) {
+            return name;
+        }
</ins><span class="cx">     }
</span><del>-    });
-    },
</del><span class="cx"> 
</span><del>-    before: function() {
-    return this.domManip( arguments, false, function( elem ) {
-    if ( this.parentNode ) {
-    this.parentNode.insertBefore( elem, this );
-    }
-    });
-    },
</del><ins>+    return origName;
+}
</ins><span class="cx"> 
</span><del>-    after: function() {
-    return this.domManip( arguments, false, function( elem ) {
-    if ( this.parentNode ) {
-    this.parentNode.insertBefore( elem, this.nextSibling );
-    }
-    });
-    },
</del><ins>+function setPositiveNumber( elem, value, subtract ) {
+    var matches = rnumsplit.exec( value );
+    return matches ?
+        // Guard against undefined &quot;subtract&quot;, e.g., when used as in cssHooks
+        Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || &quot;px&quot; ) :
+        value;
+}
</ins><span class="cx"> 
</span><del>-    // keepData is for internal use only--do not document
-    remove: function( selector, keepData ) {
-    var elem,
-    i = 0;
</del><ins>+function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
+    var i = extra === ( isBorderBox ? &quot;border&quot; : &quot;content&quot; ) ?
+        // If we already have the right measurement, avoid augmentation
+        4 :
+        // Otherwise initialize for horizontal or vertical properties
+        name === &quot;width&quot; ? 1 : 0,
</ins><span class="cx"> 
</span><del>-    for ( ; (elem = this[i]) != null; i++ ) {
-    if ( !selector || jQuery.filter( selector, [ elem ] ).length &gt; 0 ) {
-    if ( !keepData &amp;&amp; elem.nodeType === 1 ) {
-    jQuery.cleanData( getAll( elem ) );
-    }
</del><ins>+        val = 0;
</ins><span class="cx"> 
</span><del>-    if ( elem.parentNode ) {
-    if ( keepData &amp;&amp; jQuery.contains( elem.ownerDocument, elem ) ) {
-    setGlobalEval( getAll( elem, &quot;script&quot; ) );
</del><ins>+    for ( ; i &lt; 4; i += 2 ) {
+        // both box models exclude margin, so add it if we want it
+        if ( extra === &quot;margin&quot; ) {
+            val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
+        }
+
+        if ( isBorderBox ) {
+            // border-box includes padding, so remove it if we want content
+            if ( extra === &quot;content&quot; ) {
+                val -= jQuery.css( elem, &quot;padding&quot; + cssExpand[ i ], true, styles );
+            }
+
+            // at this point, extra isn't border nor margin, so remove border
+            if ( extra !== &quot;margin&quot; ) {
+                val -= jQuery.css( elem, &quot;border&quot; + cssExpand[ i ] + &quot;Width&quot;, true, styles );
+            }
+        } else {
+            // at this point, extra isn't content, so add padding
+            val += jQuery.css( elem, &quot;padding&quot; + cssExpand[ i ], true, styles );
+
+            // at this point, extra isn't content nor padding, so add border
+            if ( extra !== &quot;padding&quot; ) {
+                val += jQuery.css( elem, &quot;border&quot; + cssExpand[ i ] + &quot;Width&quot;, true, styles );
+            }
+        }
</ins><span class="cx">     }
</span><del>-    elem.parentNode.removeChild( elem );
-    }
-    }
-    }
</del><span class="cx"> 
</span><del>-    return this;
-    },
</del><ins>+    return val;
+}
</ins><span class="cx"> 
</span><del>-    empty: function() {
-    var elem,
-    i = 0;
</del><ins>+function getWidthOrHeight( elem, name, extra ) {
</ins><span class="cx"> 
</span><del>-    for ( ; (elem = this[i]) != null; i++ ) {
-    // Remove element nodes and prevent memory leaks
-    if ( elem.nodeType === 1 ) {
-    jQuery.cleanData( getAll( elem, false ) );
</del><ins>+    // Start with offset property, which is equivalent to the border-box value
+    var valueIsBorderBox = true,
+        val = name === &quot;width&quot; ? elem.offsetWidth : elem.offsetHeight,
+        styles = getStyles( elem ),
+        isBorderBox = jQuery.css( elem, &quot;boxSizing&quot;, false, styles ) === &quot;border-box&quot;;
+
+    // some non-html elements return undefined for offsetWidth, so check for null/undefined
+    // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
+    // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
+    if ( val &lt;= 0 || val == null ) {
+        // Fall back to computed then uncomputed css if necessary
+        val = curCSS( elem, name, styles );
+        if ( val &lt; 0 || val == null ) {
+            val = elem.style[ name ];
+        }
+
+        // Computed unit is not pixels. Stop here and return.
+        if ( rnumnonpx.test(val) ) {
+            return val;
+        }
+
+        // we need the check for style in case a browser which returns unreliable values
+        // for getComputedStyle silently falls back to the reliable elem.style
+        valueIsBorderBox = isBorderBox &amp;&amp;
+            ( support.boxSizingReliable() || val === elem.style[ name ] );
+
+        // Normalize &quot;&quot;, auto, and prepare for extra
+        val = parseFloat( val ) || 0;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Remove any remaining nodes
-    while ( elem.firstChild ) {
-    elem.removeChild( elem.firstChild );
</del><ins>+    // use the active box-sizing model to add/subtract irrelevant styles
+    return ( val +
+        augmentWidthOrHeight(
+            elem,
+            name,
+            extra || ( isBorderBox ? &quot;border&quot; : &quot;content&quot; ),
+            valueIsBorderBox,
+            styles
+        )
+    ) + &quot;px&quot;;
+}
+
+function showHide( elements, show ) {
+    var display, elem, hidden,
+        values = [],
+        index = 0,
+        length = elements.length;
+
+    for ( ; index &lt; length; index++ ) {
+        elem = elements[ index ];
+        if ( !elem.style ) {
+            continue;
+        }
+
+        values[ index ] = data_priv.get( elem, &quot;olddisplay&quot; );
+        display = elem.style.display;
+        if ( show ) {
+            // Reset the inline display of this element to learn if it is
+            // being hidden by cascaded rules or not
+            if ( !values[ index ] &amp;&amp; display === &quot;none&quot; ) {
+                elem.style.display = &quot;&quot;;
+            }
+
+            // Set elements which have been overridden with display: none
+            // in a stylesheet to whatever the default browser style is
+            // for such an element
+            if ( elem.style.display === &quot;&quot; &amp;&amp; isHidden( elem ) ) {
+                values[ index ] = data_priv.access( elem, &quot;olddisplay&quot;, defaultDisplay(elem.nodeName) );
+            }
+        } else {
+
+            if ( !values[ index ] ) {
+                hidden = isHidden( elem );
+
+                if ( display &amp;&amp; display !== &quot;none&quot; || !hidden ) {
+                    data_priv.set( elem, &quot;olddisplay&quot;, hidden ? display : jQuery.css(elem, &quot;display&quot;) );
+                }
+            }
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // If this is a select, ensure that it displays empty (#12336)
-    // Support: IE&lt;9
-    if ( elem.options &amp;&amp; jQuery.nodeName( elem, &quot;select&quot; ) ) {
-    elem.options.length = 0;
</del><ins>+    // Set the display of most of the elements in a second loop
+    // to avoid the constant reflow
+    for ( index = 0; index &lt; length; index++ ) {
+        elem = elements[ index ];
+        if ( !elem.style ) {
+            continue;
+        }
+        if ( !show || elem.style.display === &quot;none&quot; || elem.style.display === &quot;&quot; ) {
+            elem.style.display = show ? values[ index ] || &quot;&quot; : &quot;none&quot;;
+        }
</ins><span class="cx">     }
</span><del>-    }
</del><span class="cx"> 
</span><del>-    return this;
</del><ins>+    return elements;
+}
+
+jQuery.extend({
+    // Add in style property hooks for overriding the default
+    // behavior of getting and setting a style property
+    cssHooks: {
+        opacity: {
+            get: function( elem, computed ) {
+                if ( computed ) {
+                    // We should always get a number back from opacity
+                    var ret = curCSS( elem, &quot;opacity&quot; );
+                    return ret === &quot;&quot; ? &quot;1&quot; : ret;
+                }
+            }
+        }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    clone: function( dataAndEvents, deepDataAndEvents ) {
-    dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
-    deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
</del><ins>+    // Don't automatically add &quot;px&quot; to these possibly-unitless properties
+    cssNumber: {
+        &quot;columnCount&quot;: true,
+        &quot;fillOpacity&quot;: true,
+        &quot;fontWeight&quot;: true,
+        &quot;lineHeight&quot;: true,
+        &quot;opacity&quot;: true,
+        &quot;order&quot;: true,
+        &quot;orphans&quot;: true,
+        &quot;widows&quot;: true,
+        &quot;zIndex&quot;: true,
+        &quot;zoom&quot;: true
+    },
</ins><span class="cx"> 
</span><del>-    return this.map( function () {
-    return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
-    });
</del><ins>+    // Add in properties whose names you wish to fix before
+    // setting or getting the value
+    cssProps: {
+        // normalize float css property
+        &quot;float&quot;: &quot;cssFloat&quot;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    html: function( value ) {
-    return jQuery.access( this, function( value ) {
-    var elem = this[0] || {},
-    i = 0,
-    l = this.length;
</del><ins>+    // Get and set the style property on a DOM Node
+    style: function( elem, name, value, extra ) {
+        // Don't set styles on text and comment nodes
+        if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+            return;
+        }
</ins><span class="cx"> 
</span><del>-    if ( value === undefined ) {
-    return elem.nodeType === 1 ?
-    elem.innerHTML.replace( rinlinejQuery, &quot;&quot; ) :
-    undefined;
-    }
</del><ins>+        // Make sure that we're working with the right name
+        var ret, type, hooks,
+            origName = jQuery.camelCase( name ),
+            style = elem.style;
</ins><span class="cx"> 
</span><del>-    // See if we can take a shortcut and just use innerHTML
-    if ( typeof value === &quot;string&quot; &amp;&amp; !rnoInnerhtml.test( value ) &amp;&amp;
-    ( jQuery.support.htmlSerialize || !rnoshimcache.test( value )  ) &amp;&amp;
-    ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &amp;&amp;
-    !wrapMap[ ( rtagName.exec( value ) || [&quot;&quot;, &quot;&quot;] )[1].toLowerCase() ] ) {
</del><ins>+        name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
</ins><span class="cx"> 
</span><del>-    value = value.replace( rxhtmlTag, &quot;&lt;$1&gt;&lt;/$2&gt;&quot; );
</del><ins>+        // gets hook for the prefixed version
+        // followed by the unprefixed version
+        hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
</ins><span class="cx"> 
</span><del>-    try {
-    for (; i &lt; l; i++ ) {
-    // Remove element nodes and prevent memory leaks
-    elem = this[i] || {};
-    if ( elem.nodeType === 1 ) {
-    jQuery.cleanData( getAll( elem, false ) );
-    elem.innerHTML = value;
-    }
-    }
</del><ins>+        // Check if we're setting a value
+        if ( value !== undefined ) {
+            type = typeof value;
</ins><span class="cx"> 
</span><del>-    elem = 0;
</del><ins>+            // convert relative number strings (+= or -=) to relative numbers. #7345
+            if ( type === &quot;string&quot; &amp;&amp; (ret = rrelNum.exec( value )) ) {
+                value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
+                // Fixes bug #9237
+                type = &quot;number&quot;;
+            }
</ins><span class="cx"> 
</span><del>-    // If using innerHTML throws an exception, use the fallback method
-    } catch(e) {}
-    }
</del><ins>+            // Make sure that null and NaN values aren't set. See: #7116
+            if ( value == null || value !== value ) {
+                return;
+            }
</ins><span class="cx"> 
</span><del>-    if ( elem ) {
-    this.empty().append( value );
-    }
-    }, null, value, arguments.length );
-    },
</del><ins>+            // If a number was passed in, add 'px' to the (except for certain CSS properties)
+            if ( type === &quot;number&quot; &amp;&amp; !jQuery.cssNumber[ origName ] ) {
+                value += &quot;px&quot;;
+            }
</ins><span class="cx"> 
</span><del>-    replaceWith: function( value ) {
-    var isFunc = jQuery.isFunction( value );
</del><ins>+            // Fixes #8908, it can be done more correctly by specifying setters in cssHooks,
+            // but it would mean to define eight (for every problematic property) identical functions
+            if ( !support.clearCloneStyle &amp;&amp; value === &quot;&quot; &amp;&amp; name.indexOf( &quot;background&quot; ) === 0 ) {
+                style[ name ] = &quot;inherit&quot;;
+            }
</ins><span class="cx"> 
</span><del>-    // Make sure that the elements are removed from the DOM before they are inserted
-    // this can help fix replacing a parent with child elements
-    if ( !isFunc &amp;&amp; typeof value !== &quot;string&quot; ) {
-    value = jQuery( value ).not( this ).detach();
-    }
</del><ins>+            // If a hook was provided, use that value, otherwise just set the specified value
+            if ( !hooks || !(&quot;set&quot; in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
+                // Support: Chrome, Safari
+                // Setting style to blank string required to delete &quot;style: x !important;&quot;
+                style[ name ] = &quot;&quot;;
+                style[ name ] = value;
+            }
</ins><span class="cx"> 
</span><del>-    return this.domManip( [ value ], true, function( elem ) {
-    var next = this.nextSibling,
-    parent = this.parentNode;
</del><ins>+        } else {
+            // If a hook was provided get the non-computed value from there
+            if ( hooks &amp;&amp; &quot;get&quot; in hooks &amp;&amp; (ret = hooks.get( elem, false, extra )) !== undefined ) {
+                return ret;
+            }
</ins><span class="cx"> 
</span><del>-    if ( parent ) {
-    jQuery( this ).remove();
-    parent.insertBefore( elem, next );
-    }
-    });
</del><ins>+            // Otherwise just get the value from the style object
+            return style[ name ];
+        }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    detach: function( selector ) {
-    return this.remove( selector, true );
-    },
</del><ins>+    css: function( elem, name, extra, styles ) {
+        var val, num, hooks,
+            origName = jQuery.camelCase( name );
</ins><span class="cx"> 
</span><del>-    domManip: function( args, table, callback ) {
</del><ins>+        // Make sure that we're working with the right name
+        name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
</ins><span class="cx"> 
</span><del>-    // Flatten any nested arrays
-    args = core_concat.apply( [], args );
</del><ins>+        // gets hook for the prefixed version
+        // followed by the unprefixed version
+        hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
</ins><span class="cx"> 
</span><del>-    var first, node, hasScripts,
-    scripts, doc, fragment,
-    i = 0,
-    l = this.length,
-    set = this,
-    iNoClone = l - 1,
-    value = args[0],
-    isFunction = jQuery.isFunction( value );
</del><ins>+        // If a hook was provided get the computed value from there
+        if ( hooks &amp;&amp; &quot;get&quot; in hooks ) {
+            val = hooks.get( elem, true, extra );
+        }
</ins><span class="cx"> 
</span><del>-    // We can't cloneNode fragments that contain checked, in WebKit
-    if ( isFunction || !( l &lt;= 1 || typeof value !== &quot;string&quot; || jQuery.support.checkClone || !rchecked.test( value ) ) ) {
-    return this.each(function( index ) {
-    var self = set.eq( index );
-    if ( isFunction ) {
-    args[0] = value.call( this, index, table ? self.html() : undefined );
</del><ins>+        // Otherwise, if a way to get the computed value exists, use that
+        if ( val === undefined ) {
+            val = curCSS( elem, name, styles );
+        }
+
+        //convert &quot;normal&quot; to computed value
+        if ( val === &quot;normal&quot; &amp;&amp; name in cssNormalTransform ) {
+            val = cssNormalTransform[ name ];
+        }
+
+        // Return, converting to number if forced or a qualifier was provided and val looks numeric
+        if ( extra === &quot;&quot; || extra ) {
+            num = parseFloat( val );
+            return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
+        }
+        return val;
</ins><span class="cx">     }
</span><del>-    self.domManip( args, table, callback );
-    });
-    }
</del><ins>+});
</ins><span class="cx"> 
</span><del>-    if ( l ) {
-    fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
-    first = fragment.firstChild;
</del><ins>+jQuery.each([ &quot;height&quot;, &quot;width&quot; ], function( i, name ) {
+    jQuery.cssHooks[ name ] = {
+        get: function( elem, computed, extra ) {
+            if ( computed ) {
+                // certain elements can have dimension info if we invisibly show them
+                // however, it must have a current display style that would benefit from this
+                return elem.offsetWidth === 0 &amp;&amp; rdisplayswap.test( jQuery.css( elem, &quot;display&quot; ) ) ?
+                    jQuery.swap( elem, cssShow, function() {
+                        return getWidthOrHeight( elem, name, extra );
+                    }) :
+                    getWidthOrHeight( elem, name, extra );
+            }
+        },
</ins><span class="cx"> 
</span><del>-    if ( fragment.childNodes.length === 1 ) {
-    fragment = first;
</del><ins>+        set: function( elem, value, extra ) {
+            var styles = extra &amp;&amp; getStyles( elem );
+            return setPositiveNumber( elem, value, extra ?
+                augmentWidthOrHeight(
+                    elem,
+                    name,
+                    extra,
+                    jQuery.css( elem, &quot;boxSizing&quot;, false, styles ) === &quot;border-box&quot;,
+                    styles
+                ) : 0
+            );
+        }
+    };
+});
+
+// Support: Android 2.3
+jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
+    function( elem, computed ) {
+        if ( computed ) {
+            // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+            // Work around by temporarily setting element display to inline-block
+            return jQuery.swap( elem, { &quot;display&quot;: &quot;inline-block&quot; },
+                curCSS, [ elem, &quot;marginRight&quot; ] );
+        }
</ins><span class="cx">     }
</span><ins>+);
</ins><span class="cx"> 
</span><del>-    if ( first ) {
-    table = table &amp;&amp; jQuery.nodeName( first, &quot;tr&quot; );
-    scripts = jQuery.map( getAll( fragment, &quot;script&quot; ), disableScript );
-    hasScripts = scripts.length;
</del><ins>+// These hooks are used by animate to expand properties
+jQuery.each({
+    margin: &quot;&quot;,
+    padding: &quot;&quot;,
+    border: &quot;Width&quot;
+}, function( prefix, suffix ) {
+    jQuery.cssHooks[ prefix + suffix ] = {
+        expand: function( value ) {
+            var i = 0,
+                expanded = {},
</ins><span class="cx"> 
</span><del>-    // Use the original fragment for the last item instead of the first because it can end up
-    // being emptied incorrectly in certain situations (#8070).
-    for ( ; i &lt; l; i++ ) {
-    node = fragment;
</del><ins>+                // assumes a single number if not a string
+                parts = typeof value === &quot;string&quot; ? value.split(&quot; &quot;) : [ value ];
</ins><span class="cx"> 
</span><del>-    if ( i !== iNoClone ) {
-    node = jQuery.clone( node, true, true );
</del><ins>+            for ( ; i &lt; 4; i++ ) {
+                expanded[ prefix + cssExpand[ i ] + suffix ] =
+                    parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
+            }
</ins><span class="cx"> 
</span><del>-    // Keep references to cloned scripts for later restoration
-    if ( hasScripts ) {
-    jQuery.merge( scripts, getAll( node, &quot;script&quot; ) );
-    }
-    }
</del><ins>+            return expanded;
+        }
+    };
</ins><span class="cx"> 
</span><del>-    callback.call(
-    table &amp;&amp; jQuery.nodeName( this[i], &quot;table&quot; ) ?
-    findOrAppend( this[i], &quot;tbody&quot; ) :
-    this[i],
-    node,
-    i
-    );
</del><ins>+    if ( !rmargin.test( prefix ) ) {
+        jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
</ins><span class="cx">     }
</span><ins>+});
</ins><span class="cx"> 
</span><del>-    if ( hasScripts ) {
-    doc = scripts[ scripts.length - 1 ].ownerDocument;
</del><ins>+jQuery.fn.extend({
+    css: function( name, value ) {
+        return access( this, function( elem, name, value ) {
+            var styles, len,
+                map = {},
+                i = 0;
</ins><span class="cx"> 
</span><del>-    // Reenable scripts
-    jQuery.map( scripts, restoreScript );
</del><ins>+            if ( jQuery.isArray( name ) ) {
+                styles = getStyles( elem );
+                len = name.length;
</ins><span class="cx"> 
</span><del>-    // Evaluate executable scripts on first document insertion
-    for ( i = 0; i &lt; hasScripts; i++ ) {
-    node = scripts[ i ];
-    if ( rscriptType.test( node.type || &quot;&quot; ) &amp;&amp;
-    !jQuery._data( node, &quot;globalEval&quot; ) &amp;&amp; jQuery.contains( doc, node ) ) {
</del><ins>+                for ( ; i &lt; len; i++ ) {
+                    map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
+                }
</ins><span class="cx"> 
</span><del>-    if ( node.src ) {
-    // Hope ajax is available...
-    jQuery.ajax({
-    url: node.src,
-    type: &quot;GET&quot;,
-    dataType: &quot;script&quot;,
-    async: false,
-    global: false,
-    &quot;throws&quot;: true
-    });
-    } else {
-    jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || &quot;&quot; ).replace( rcleanScript, &quot;&quot; ) );
-    }
-    }
-    }
-    }
</del><ins>+                return map;
+            }
</ins><span class="cx"> 
</span><del>-    // Fix #11809: Avoid leaking memory
-    fragment = first = null;
-    }
-    }
</del><ins>+            return value !== undefined ?
+                jQuery.style( elem, name, value ) :
+                jQuery.css( elem, name );
+        }, name, value, arguments.length &gt; 1 );
+    },
+    show: function() {
+        return showHide( this, true );
+    },
+    hide: function() {
+        return showHide( this );
+    },
+    toggle: function( state ) {
+        if ( typeof state === &quot;boolean&quot; ) {
+            return state ? this.show() : this.hide();
+        }
</ins><span class="cx"> 
</span><del>-    return this;
</del><ins>+        return this.each(function() {
+            if ( isHidden( this ) ) {
+                jQuery( this ).show();
+            } else {
+                jQuery( this ).hide();
+            }
+        });
</ins><span class="cx">     }
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-function findOrAppend( elem, tag ) {
-    return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );
-}
</del><span class="cx"> 
</span><del>-// Replace/restore the type attribute of script elements for safe DOM manipulation
-function disableScript( elem ) {
-    var attr = elem.getAttributeNode(&quot;type&quot;);
-    elem.type = ( attr &amp;&amp; attr.specified ) + &quot;/&quot; + elem.type;
-    return elem;
</del><ins>+function Tween( elem, options, prop, end, easing ) {
+    return new Tween.prototype.init( elem, options, prop, end, easing );
</ins><span class="cx"> }
</span><del>-function restoreScript( elem ) {
-    var match = rscriptTypeMasked.exec( elem.type );
-    if ( match ) {
-    elem.type = match[1];
-    } else {
-    elem.removeAttribute(&quot;type&quot;);
-    }
-    return elem;
-}
</del><ins>+jQuery.Tween = Tween;
</ins><span class="cx"> 
</span><del>-// Mark scripts as having already been evaluated
-function setGlobalEval( elems, refElements ) {
-    var elem,
-    i = 0;
-    for ( ; (elem = elems[i]) != null; i++ ) {
-    jQuery._data( elem, &quot;globalEval&quot;, !refElements || jQuery._data( refElements[i], &quot;globalEval&quot; ) );
-    }
-}
</del><ins>+Tween.prototype = {
+    constructor: Tween,
+    init: function( elem, options, prop, end, easing, unit ) {
+        this.elem = elem;
+        this.prop = prop;
+        this.easing = easing || &quot;swing&quot;;
+        this.options = options;
+        this.start = this.now = this.cur();
+        this.end = end;
+        this.unit = unit || ( jQuery.cssNumber[ prop ] ? &quot;&quot; : &quot;px&quot; );
+    },
+    cur: function() {
+        var hooks = Tween.propHooks[ this.prop ];
</ins><span class="cx"> 
</span><del>-function cloneCopyEvent( src, dest ) {
</del><ins>+        return hooks &amp;&amp; hooks.get ?
+            hooks.get( this ) :
+            Tween.propHooks._default.get( this );
+    },
+    run: function( percent ) {
+        var eased,
+            hooks = Tween.propHooks[ this.prop ];
</ins><span class="cx"> 
</span><del>-    if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
-    return;
</del><ins>+        if ( this.options.duration ) {
+            this.pos = eased = jQuery.easing[ this.easing ](
+                percent, this.options.duration * percent, 0, 1, this.options.duration
+            );
+        } else {
+            this.pos = eased = percent;
+        }
+        this.now = ( this.end - this.start ) * eased + this.start;
+
+        if ( this.options.step ) {
+            this.options.step.call( this.elem, this.now, this );
+        }
+
+        if ( hooks &amp;&amp; hooks.set ) {
+            hooks.set( this );
+        } else {
+            Tween.propHooks._default.set( this );
+        }
+        return this;
</ins><span class="cx">     }
</span><ins>+};
</ins><span class="cx"> 
</span><del>-    var type, i, l,
-    oldData = jQuery._data( src ),
-    curData = jQuery._data( dest, oldData ),
-    events = oldData.events;
</del><ins>+Tween.prototype.init.prototype = Tween.prototype;
</ins><span class="cx"> 
</span><del>-    if ( events ) {
-    delete curData.handle;
-    curData.events = {};
</del><ins>+Tween.propHooks = {
+    _default: {
+        get: function( tween ) {
+            var result;
</ins><span class="cx"> 
</span><del>-    for ( type in events ) {
-    for ( i = 0, l = events[ type ].length; i &lt; l; i++ ) {
-    jQuery.event.add( dest, type, events[ type ][ i ] );
-    }
-    }
-    }
</del><ins>+            if ( tween.elem[ tween.prop ] != null &amp;&amp;
+                (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
+                return tween.elem[ tween.prop ];
+            }
</ins><span class="cx"> 
</span><del>-    // make the cloned public data object a copy from the original
-    if ( curData.data ) {
-    curData.data = jQuery.extend( {}, curData.data );
</del><ins>+            // passing an empty string as a 3rd parameter to .css will automatically
+            // attempt a parseFloat and fallback to a string if the parse fails
+            // so, simple values such as &quot;10px&quot; are parsed to Float.
+            // complex values such as &quot;rotate(1rad)&quot; are returned as is.
+            result = jQuery.css( tween.elem, tween.prop, &quot;&quot; );
+            // Empty strings, null, undefined and &quot;auto&quot; are converted to 0.
+            return !result || result === &quot;auto&quot; ? 0 : result;
+        },
+        set: function( tween ) {
+            // use step hook for back compat - use cssHook if its there - use .style if its
+            // available and use plain properties where available
+            if ( jQuery.fx.step[ tween.prop ] ) {
+                jQuery.fx.step[ tween.prop ]( tween );
+            } else if ( tween.elem.style &amp;&amp; ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
+                jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
+            } else {
+                tween.elem[ tween.prop ] = tween.now;
+            }
+        }
</ins><span class="cx">     }
</span><del>-}
</del><ins>+};
</ins><span class="cx"> 
</span><del>-function fixCloneNodeIssues( src, dest ) {
-    var nodeName, e, data;
</del><ins>+// Support: IE9
+// Panic based approach to setting things on disconnected nodes
</ins><span class="cx"> 
</span><del>-    // We do not need to do anything for non-Elements
-    if ( dest.nodeType !== 1 ) {
-    return;
</del><ins>+Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+    set: function( tween ) {
+        if ( tween.elem.nodeType &amp;&amp; tween.elem.parentNode ) {
+            tween.elem[ tween.prop ] = tween.now;
+        }
</ins><span class="cx">     }
</span><ins>+};
</ins><span class="cx"> 
</span><del>-    nodeName = dest.nodeName.toLowerCase();
</del><ins>+jQuery.easing = {
+    linear: function( p ) {
+        return p;
+    },
+    swing: function( p ) {
+        return 0.5 - Math.cos( p * Math.PI ) / 2;
+    }
+};
</ins><span class="cx"> 
</span><del>-    // IE6-8 copies events bound via attachEvent when using cloneNode.
-    if ( !jQuery.support.noCloneEvent &amp;&amp; dest[ jQuery.expando ] ) {
-    data = jQuery._data( dest );
</del><ins>+jQuery.fx = Tween.prototype.init;
</ins><span class="cx"> 
</span><del>-    for ( e in data.events ) {
-    jQuery.removeEvent( dest, e, data.handle );
-    }
</del><ins>+// Back Compat &lt;1.8 extension point
+jQuery.fx.step = {};
</ins><span class="cx"> 
</span><del>-    // Event data gets referenced instead of copied if the expando gets copied too
-    dest.removeAttribute( jQuery.expando );
-    }
</del><span class="cx"> 
</span><del>-    // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
-    if ( nodeName === &quot;script&quot; &amp;&amp; dest.text !== src.text ) {
-    disableScript( dest ).text = src.text;
-    restoreScript( dest );
</del><span class="cx"> 
</span><del>-    // IE6-10 improperly clones children of object elements using classid.
-    // IE10 throws NoModificationAllowedError if parent is null, #12132.
-    } else if ( nodeName === &quot;object&quot; ) {
-    if ( dest.parentNode ) {
-    dest.outerHTML = src.outerHTML;
-    }
</del><span class="cx"> 
</span><del>-    // This path appears unavoidable for IE9. When cloning an object
-    // element in IE9, the outerHTML strategy above is not sufficient.
-    // If the src has innerHTML and the destination does not,
-    // copy the src.innerHTML into the dest.innerHTML. #10324
-    if ( jQuery.support.html5Clone &amp;&amp; ( src.innerHTML &amp;&amp; !jQuery.trim(dest.innerHTML) ) ) {
-    dest.innerHTML = src.innerHTML;
-    }
</del><ins>+var
+    fxNow, timerId,
+    rfxtypes = /^(?:toggle|show|hide)$/,
+    rfxnum = new RegExp( &quot;^(?:([+-])=|)(&quot; + pnum + &quot;)([a-z%]*)$&quot;, &quot;i&quot; ),
+    rrun = /queueHooks$/,
+    animationPrefilters = [ defaultPrefilter ],
+    tweeners = {
+        &quot;*&quot;: [ function( prop, value ) {
+            var tween = this.createTween( prop, value ),
+                target = tween.cur(),
+                parts = rfxnum.exec( value ),
+                unit = parts &amp;&amp; parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? &quot;&quot; : &quot;px&quot; ),
</ins><span class="cx"> 
</span><del>-    } else if ( nodeName === &quot;input&quot; &amp;&amp; manipulation_rcheckableType.test( src.type ) ) {
-    // IE6-8 fails to persist the checked state of a cloned checkbox
-    // or radio button. Worse, IE6-7 fail to give the cloned element
-    // a checked appearance if the defaultChecked value isn't also set
</del><ins>+                // Starting value computation is required for potential unit mismatches
+                start = ( jQuery.cssNumber[ prop ] || unit !== &quot;px&quot; &amp;&amp; +target ) &amp;&amp;
+                    rfxnum.exec( jQuery.css( tween.elem, prop ) ),
+                scale = 1,
+                maxIterations = 20;
</ins><span class="cx"> 
</span><del>-    dest.defaultChecked = dest.checked = src.checked;
</del><ins>+            if ( start &amp;&amp; start[ 3 ] !== unit ) {
+                // Trust units reported by jQuery.css
+                unit = unit || start[ 3 ];
</ins><span class="cx"> 
</span><del>-    // IE6-7 get confused and end up setting the value of a cloned
-    // checkbox/radio button to an empty string instead of &quot;on&quot;
-    if ( dest.value !== src.value ) {
-    dest.value = src.value;
-    }
</del><ins>+                // Make sure we update the tween properties later on
+                parts = parts || [];
</ins><span class="cx"> 
</span><del>-    // IE6-8 fails to return the selected option to the default selected
-    // state when cloning options
-    } else if ( nodeName === &quot;option&quot; ) {
-    dest.defaultSelected = dest.selected = src.defaultSelected;
</del><ins>+                // Iteratively approximate from a nonzero starting point
+                start = +target || 1;
</ins><span class="cx"> 
</span><del>-    // IE6-8 fails to set the defaultValue to the correct value when
-    // cloning other types of input fields
-    } else if ( nodeName === &quot;input&quot; || nodeName === &quot;textarea&quot; ) {
-    dest.defaultValue = src.defaultValue;
-    }
-}
</del><ins>+                do {
+                    // If previous iteration zeroed out, double until we get *something*
+                    // Use a string for doubling factor so we don't accidentally see scale as unchanged below
+                    scale = scale || &quot;.5&quot;;
</ins><span class="cx"> 
</span><del>-jQuery.each({
-    appendTo: &quot;append&quot;,
-    prependTo: &quot;prepend&quot;,
-    insertBefore: &quot;before&quot;,
-    insertAfter: &quot;after&quot;,
-    replaceAll: &quot;replaceWith&quot;
-}, function( name, original ) {
-    jQuery.fn[ name ] = function( selector ) {
-    var elems,
-    i = 0,
-    ret = [],
-    insert = jQuery( selector ),
-    last = insert.length - 1;
</del><ins>+                    // Adjust and apply
+                    start = start / scale;
+                    jQuery.style( tween.elem, prop, start + unit );
</ins><span class="cx"> 
</span><del>-    for ( ; i &lt;= last; i++ ) {
-    elems = i === last ? this : this.clone(true);
-    jQuery( insert[i] )[ original ]( elems );
</del><ins>+                // Update scale, tolerating zero or NaN from tween.cur()
+                // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
+                } while ( scale !== (scale = tween.cur() / target) &amp;&amp; scale !== 1 &amp;&amp; --maxIterations );
+            }
</ins><span class="cx"> 
</span><del>-    // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
-    core_push.apply( ret, elems.get() );
-    }
</del><ins>+            // Update tween properties
+            if ( parts ) {
+                start = tween.start = +start || +target || 0;
+                tween.unit = unit;
+                // If a +=/-= token was provided, we're doing a relative animation
+                tween.end = parts[ 1 ] ?
+                    start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
+                    +parts[ 2 ];
+            }
</ins><span class="cx"> 
</span><del>-    return this.pushStack( ret );
</del><ins>+            return tween;
+        } ]
</ins><span class="cx">     };
</span><del>-});
</del><span class="cx"> 
</span><del>-function getAll( context, tag ) {
-    var elems, elem,
-    i = 0,
-    found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || &quot;*&quot; ) :
-    typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || &quot;*&quot; ) :
-    undefined;
</del><ins>+// Animations created synchronously will run synchronously
+function createFxNow() {
+    setTimeout(function() {
+        fxNow = undefined;
+    });
+    return ( fxNow = jQuery.now() );
+}
</ins><span class="cx"> 
</span><del>-    if ( !found ) {
-    for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
-    if ( !tag || jQuery.nodeName( elem, tag ) ) {
-    found.push( elem );
-    } else {
-    jQuery.merge( found, getAll( elem, tag ) );
</del><ins>+// Generate parameters to create a standard animation
+function genFx( type, includeWidth ) {
+    var which,
+        i = 0,
+        attrs = { height: type };
+
+    // if we include width, step value is 1 to do all cssExpand values,
+    // if we don't include width, step value is 2 to skip over Left and Right
+    includeWidth = includeWidth ? 1 : 0;
+    for ( ; i &lt; 4 ; i += 2 - includeWidth ) {
+        which = cssExpand[ i ];
+        attrs[ &quot;margin&quot; + which ] = attrs[ &quot;padding&quot; + which ] = type;
</ins><span class="cx">     }
</span><ins>+
+    if ( includeWidth ) {
+        attrs.opacity = attrs.width = type;
</ins><span class="cx">     }
</span><del>-    }
</del><span class="cx"> 
</span><del>-    return tag === undefined || tag &amp;&amp; jQuery.nodeName( context, tag ) ?
-    jQuery.merge( [ context ], found ) :
-    found;
</del><ins>+    return attrs;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-// Used in buildFragment, fixes the defaultChecked property
-function fixDefaultChecked( elem ) {
-    if ( manipulation_rcheckableType.test( elem.type ) ) {
-    elem.defaultChecked = elem.checked;
</del><ins>+function createTween( value, prop, animation ) {
+    var tween,
+        collection = ( tweeners[ prop ] || [] ).concat( tweeners[ &quot;*&quot; ] ),
+        index = 0,
+        length = collection.length;
+    for ( ; index &lt; length; index++ ) {
+        if ( (tween = collection[ index ].call( animation, prop, value )) ) {
+
+            // we're done with this property
+            return tween;
+        }
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-jQuery.extend({
-    clone: function( elem, dataAndEvents, deepDataAndEvents ) {
-    var destElements, node, clone, i, srcElements,
-    inPage = jQuery.contains( elem.ownerDocument, elem );
</del><ins>+function defaultPrefilter( elem, props, opts ) {
+    /* jshint validthis: true */
+    var prop, value, toggle, tween, hooks, oldfire, display,
+        anim = this,
+        orig = {},
+        style = elem.style,
+        hidden = elem.nodeType &amp;&amp; isHidden( elem ),
+        dataShow = data_priv.get( elem, &quot;fxshow&quot; );
</ins><span class="cx"> 
</span><del>-    if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( &quot;&lt;&quot; + elem.nodeName + &quot;&gt;&quot; ) ) {
-    clone = elem.cloneNode( true );
</del><ins>+    // handle queue: false promises
+    if ( !opts.queue ) {
+        hooks = jQuery._queueHooks( elem, &quot;fx&quot; );
+        if ( hooks.unqueued == null ) {
+            hooks.unqueued = 0;
+            oldfire = hooks.empty.fire;
+            hooks.empty.fire = function() {
+                if ( !hooks.unqueued ) {
+                    oldfire();
+                }
+            };
+        }
+        hooks.unqueued++;
</ins><span class="cx"> 
</span><del>-    // IE&lt;=8 does not properly clone detached, unknown element nodes
-    } else {
-    fragmentDiv.innerHTML = elem.outerHTML;
-    fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
</del><ins>+        anim.always(function() {
+            // doing this makes sure that the complete handler will be called
+            // before this completes
+            anim.always(function() {
+                hooks.unqueued--;
+                if ( !jQuery.queue( elem, &quot;fx&quot; ).length ) {
+                    hooks.empty.fire();
+                }
+            });
+        });
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &amp;&amp;
-    (elem.nodeType === 1 || elem.nodeType === 11) &amp;&amp; !jQuery.isXMLDoc(elem) ) {
</del><ins>+    // height/width overflow pass
+    if ( elem.nodeType === 1 &amp;&amp; ( &quot;height&quot; in props || &quot;width&quot; in props ) ) {
+        // Make sure that nothing sneaks out
+        // Record all 3 overflow attributes because IE9-10 do not
+        // change the overflow attribute when overflowX and
+        // overflowY are set to the same value
+        opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
</ins><span class="cx"> 
</span><del>-    // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
-    destElements = getAll( clone );
-    srcElements = getAll( elem );
</del><ins>+        // Set display property to inline-block for height/width
+        // animations on inline elements that are having width/height animated
+        display = jQuery.css( elem, &quot;display&quot; );
+        // Get default display if display is currently &quot;none&quot;
+        if ( display === &quot;none&quot; ) {
+            display = defaultDisplay( elem.nodeName );
+        }
+        if ( display === &quot;inline&quot; &amp;&amp;
+                jQuery.css( elem, &quot;float&quot; ) === &quot;none&quot; ) {
</ins><span class="cx"> 
</span><del>-    // Fix all IE cloning issues
-    for ( i = 0; (node = srcElements[i]) != null; ++i ) {
-    // Ensure that the destination node is not null; Fixes #9587
-    if ( destElements[i] ) {
-    fixCloneNodeIssues( node, destElements[i] );
</del><ins>+            style.display = &quot;inline-block&quot;;
+        }
</ins><span class="cx">     }
</span><ins>+
+    if ( opts.overflow ) {
+        style.overflow = &quot;hidden&quot;;
+        anim.always(function() {
+            style.overflow = opts.overflow[ 0 ];
+            style.overflowX = opts.overflow[ 1 ];
+            style.overflowY = opts.overflow[ 2 ];
+        });
</ins><span class="cx">     }
</span><del>-    }
</del><span class="cx"> 
</span><del>-    // Copy the events from the original to the clone
-    if ( dataAndEvents ) {
-    if ( deepDataAndEvents ) {
-    srcElements = srcElements || getAll( elem );
-    destElements = destElements || getAll( clone );
</del><ins>+    // show/hide pass
+    for ( prop in props ) {
+        value = props[ prop ];
+        if ( rfxtypes.exec( value ) ) {
+            delete props[ prop ];
+            toggle = toggle || value === &quot;toggle&quot;;
+            if ( value === ( hidden ? &quot;hide&quot; : &quot;show&quot; ) ) {
</ins><span class="cx"> 
</span><del>-    for ( i = 0; (node = srcElements[i]) != null; i++ ) {
-    cloneCopyEvent( node, destElements[i] );
</del><ins>+                // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
+                if ( value === &quot;show&quot; &amp;&amp; dataShow &amp;&amp; dataShow[ prop ] !== undefined ) {
+                    hidden = true;
+                } else {
+                    continue;
+                }
+            }
+            orig[ prop ] = dataShow &amp;&amp; dataShow[ prop ] || jQuery.style( elem, prop );
+        }
</ins><span class="cx">     }
</span><del>-    } else {
-    cloneCopyEvent( elem, clone );
-    }
-    }
</del><span class="cx"> 
</span><del>-    // Preserve script evaluation history
-    destElements = getAll( clone, &quot;script&quot; );
-    if ( destElements.length &gt; 0 ) {
-    setGlobalEval( destElements, !inPage &amp;&amp; getAll( elem, &quot;script&quot; ) );
-    }
</del><ins>+    if ( !jQuery.isEmptyObject( orig ) ) {
+        if ( dataShow ) {
+            if ( &quot;hidden&quot; in dataShow ) {
+                hidden = dataShow.hidden;
+            }
+        } else {
+            dataShow = data_priv.access( elem, &quot;fxshow&quot;, {} );
+        }
</ins><span class="cx"> 
</span><del>-    destElements = srcElements = node = null;
</del><ins>+        // store state if its toggle - enables .stop().toggle() to &quot;reverse&quot;
+        if ( toggle ) {
+            dataShow.hidden = !hidden;
+        }
+        if ( hidden ) {
+            jQuery( elem ).show();
+        } else {
+            anim.done(function() {
+                jQuery( elem ).hide();
+            });
+        }
+        anim.done(function() {
+            var prop;
</ins><span class="cx"> 
</span><del>-    // Return the cloned set
-    return clone;
-    },
</del><ins>+            data_priv.remove( elem, &quot;fxshow&quot; );
+            for ( prop in orig ) {
+                jQuery.style( elem, prop, orig[ prop ] );
+            }
+        });
+        for ( prop in orig ) {
+            tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
</ins><span class="cx"> 
</span><del>-    buildFragment: function( elems, context, scripts, selection ) {
-    var j, elem, contains,
-    tmp, tag, tbody, wrap,
-    l = elems.length,
</del><ins>+            if ( !( prop in dataShow ) ) {
+                dataShow[ prop ] = tween.start;
+                if ( hidden ) {
+                    tween.end = tween.start;
+                    tween.start = prop === &quot;width&quot; || prop === &quot;height&quot; ? 1 : 0;
+                }
+            }
+        }
+    }
+}
</ins><span class="cx"> 
</span><del>-    // Ensure a safe fragment
-    safe = createSafeFragment( context ),
</del><ins>+function propFilter( props, specialEasing ) {
+    var index, name, easing, value, hooks;
</ins><span class="cx"> 
</span><del>-    nodes = [],
-    i = 0;
</del><ins>+    // camelCase, specialEasing and expand cssHook pass
+    for ( index in props ) {
+        name = jQuery.camelCase( index );
+        easing = specialEasing[ name ];
+        value = props[ index ];
+        if ( jQuery.isArray( value ) ) {
+            easing = value[ 1 ];
+            value = props[ index ] = value[ 0 ];
+        }
</ins><span class="cx"> 
</span><del>-    for ( ; i &lt; l; i++ ) {
-    elem = elems[ i ];
</del><ins>+        if ( index !== name ) {
+            props[ name ] = value;
+            delete props[ index ];
+        }
</ins><span class="cx"> 
</span><del>-    if ( elem || elem === 0 ) {
</del><ins>+        hooks = jQuery.cssHooks[ name ];
+        if ( hooks &amp;&amp; &quot;expand&quot; in hooks ) {
+            value = hooks.expand( value );
+            delete props[ name ];
</ins><span class="cx"> 
</span><del>-    // Add nodes directly
-    if ( jQuery.type( elem ) === &quot;object&quot; ) {
-    jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
</del><ins>+            // not quite $.extend, this wont overwrite keys already present.
+            // also - reusing 'index' from above because we have the correct &quot;name&quot;
+            for ( index in value ) {
+                if ( !( index in props ) ) {
+                    props[ index ] = value[ index ];
+                    specialEasing[ index ] = easing;
+                }
+            }
+        } else {
+            specialEasing[ name ] = easing;
+        }
+    }
+}
</ins><span class="cx"> 
</span><del>-    // Convert non-html into a text node
-    } else if ( !rhtml.test( elem ) ) {
-    nodes.push( context.createTextNode( elem ) );
</del><ins>+function Animation( elem, properties, options ) {
+    var result,
+        stopped,
+        index = 0,
+        length = animationPrefilters.length,
+        deferred = jQuery.Deferred().always( function() {
+            // don't match elem in the :animated selector
+            delete tick.elem;
+        }),
+        tick = function() {
+            if ( stopped ) {
+                return false;
+            }
+            var currentTime = fxNow || createFxNow(),
+                remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
+                // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
+                temp = remaining / animation.duration || 0,
+                percent = 1 - temp,
+                index = 0,
+                length = animation.tweens.length;
</ins><span class="cx"> 
</span><del>-    // Convert html into DOM nodes
-    } else {
-    tmp = tmp || safe.appendChild( context.createElement(&quot;div&quot;) );
</del><ins>+            for ( ; index &lt; length ; index++ ) {
+                animation.tweens[ index ].run( percent );
+            }
</ins><span class="cx"> 
</span><del>-    // Deserialize a standard representation
-    tag = ( rtagName.exec( elem ) || [&quot;&quot;, &quot;&quot;] )[1].toLowerCase();
-    wrap = wrapMap[ tag ] || wrapMap._default;
</del><ins>+            deferred.notifyWith( elem, [ animation, percent, remaining ]);
</ins><span class="cx"> 
</span><del>-    tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, &quot;&lt;$1&gt;&lt;/$2&gt;&quot; ) + wrap[2];
</del><ins>+            if ( percent &lt; 1 &amp;&amp; length ) {
+                return remaining;
+            } else {
+                deferred.resolveWith( elem, [ animation ] );
+                return false;
+            }
+        },
+        animation = deferred.promise({
+            elem: elem,
+            props: jQuery.extend( {}, properties ),
+            opts: jQuery.extend( true, { specialEasing: {} }, options ),
+            originalProperties: properties,
+            originalOptions: options,
+            startTime: fxNow || createFxNow(),
+            duration: options.duration,
+            tweens: [],
+            createTween: function( prop, end ) {
+                var tween = jQuery.Tween( elem, animation.opts, prop, end,
+                        animation.opts.specialEasing[ prop ] || animation.opts.easing );
+                animation.tweens.push( tween );
+                return tween;
+            },
+            stop: function( gotoEnd ) {
+                var index = 0,
+                    // if we are going to the end, we want to run all the tweens
+                    // otherwise we skip this part
+                    length = gotoEnd ? animation.tweens.length : 0;
+                if ( stopped ) {
+                    return this;
+                }
+                stopped = true;
+                for ( ; index &lt; length ; index++ ) {
+                    animation.tweens[ index ].run( 1 );
+                }
</ins><span class="cx"> 
</span><del>-    // Descend through wrappers to the right content
-    j = wrap[0];
-    while ( j-- ) {
-    tmp = tmp.lastChild;
</del><ins>+                // resolve when we played the last frame
+                // otherwise, reject
+                if ( gotoEnd ) {
+                    deferred.resolveWith( elem, [ animation, gotoEnd ] );
+                } else {
+                    deferred.rejectWith( elem, [ animation, gotoEnd ] );
+                }
+                return this;
+            }
+        }),
+        props = animation.props;
+
+    propFilter( props, animation.opts.specialEasing );
+
+    for ( ; index &lt; length ; index++ ) {
+        result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
+        if ( result ) {
+            return result;
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Manually add leading whitespace removed by IE
-    if ( !jQuery.support.leadingWhitespace &amp;&amp; rleadingWhitespace.test( elem ) ) {
-    nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
</del><ins>+    jQuery.map( props, createTween, animation );
+
+    if ( jQuery.isFunction( animation.opts.start ) ) {
+        animation.opts.start.call( elem, animation );
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Remove IE's autoinserted &lt;tbody&gt; from table fragments
-    if ( !jQuery.support.tbody ) {
</del><ins>+    jQuery.fx.timer(
+        jQuery.extend( tick, {
+            elem: elem,
+            anim: animation,
+            queue: animation.opts.queue
+        })
+    );
</ins><span class="cx"> 
</span><del>-    // String was a &lt;table&gt;, *may* have spurious &lt;tbody&gt;
-    elem = tag === &quot;table&quot; &amp;&amp; !rtbody.test( elem ) ?
-    tmp.firstChild :
</del><ins>+    // attach callbacks from options
+    return animation.progress( animation.opts.progress )
+        .done( animation.opts.done, animation.opts.complete )
+        .fail( animation.opts.fail )
+        .always( animation.opts.always );
+}
</ins><span class="cx"> 
</span><del>-    // String was a bare &lt;thead&gt; or &lt;tfoot&gt;
-    wrap[1] === &quot;&lt;table&gt;&quot; &amp;&amp; !rtbody.test( elem ) ?
-    tmp :
-    0;
</del><ins>+jQuery.Animation = jQuery.extend( Animation, {
</ins><span class="cx"> 
</span><del>-    j = elem &amp;&amp; elem.childNodes.length;
-    while ( j-- ) {
-    if ( jQuery.nodeName( (tbody = elem.childNodes[j]), &quot;tbody&quot; ) &amp;&amp; !tbody.childNodes.length ) {
-    elem.removeChild( tbody );
-    }
-    }
-    }
</del><ins>+    tweener: function( props, callback ) {
+        if ( jQuery.isFunction( props ) ) {
+            callback = props;
+            props = [ &quot;*&quot; ];
+        } else {
+            props = props.split(&quot; &quot;);
+        }
</ins><span class="cx"> 
</span><del>-    jQuery.merge( nodes, tmp.childNodes );
</del><ins>+        var prop,
+            index = 0,
+            length = props.length;
</ins><span class="cx"> 
</span><del>-    // Fix #12392 for WebKit and IE &gt; 9
-    tmp.textContent = &quot;&quot;;
</del><ins>+        for ( ; index &lt; length ; index++ ) {
+            prop = props[ index ];
+            tweeners[ prop ] = tweeners[ prop ] || [];
+            tweeners[ prop ].unshift( callback );
+        }
+    },
</ins><span class="cx"> 
</span><del>-    // Fix #12392 for oldIE
-    while ( tmp.firstChild ) {
-    tmp.removeChild( tmp.firstChild );
</del><ins>+    prefilter: function( callback, prepend ) {
+        if ( prepend ) {
+            animationPrefilters.unshift( callback );
+        } else {
+            animationPrefilters.push( callback );
+        }
</ins><span class="cx">     }
</span><ins>+});
</ins><span class="cx"> 
</span><del>-    // Remember the top-level container for proper cleanup
-    tmp = safe.lastChild;
-    }
-    }
-    }
</del><ins>+jQuery.speed = function( speed, easing, fn ) {
+    var opt = speed &amp;&amp; typeof speed === &quot;object&quot; ? jQuery.extend( {}, speed ) : {
+        complete: fn || !fn &amp;&amp; easing ||
+            jQuery.isFunction( speed ) &amp;&amp; speed,
+        duration: speed,
+        easing: fn &amp;&amp; easing || easing &amp;&amp; !jQuery.isFunction( easing ) &amp;&amp; easing
+    };
</ins><span class="cx"> 
</span><del>-    // Fix #11356: Clear elements from fragment
-    if ( tmp ) {
-    safe.removeChild( tmp );
-    }
</del><ins>+    opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === &quot;number&quot; ? opt.duration :
+        opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
</ins><span class="cx"> 
</span><del>-    // Reset defaultChecked for any radios and checkboxes
-    // about to be appended to the DOM in IE 6/7 (#8060)
-    if ( !jQuery.support.appendChecked ) {
-    jQuery.grep( getAll( nodes, &quot;input&quot; ), fixDefaultChecked );
</del><ins>+    // normalize opt.queue - true/undefined/null -&gt; &quot;fx&quot;
+    if ( opt.queue == null || opt.queue === true ) {
+        opt.queue = &quot;fx&quot;;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    i = 0;
-    while ( (elem = nodes[ i++ ]) ) {
</del><ins>+    // Queueing
+    opt.old = opt.complete;
</ins><span class="cx"> 
</span><del>-    // #4087 - If origin and destination elements are the same, and this is
-    // that element, do not do anything
-    if ( selection &amp;&amp; jQuery.inArray( elem, selection ) !== -1 ) {
-    continue;
-    }
</del><ins>+    opt.complete = function() {
+        if ( jQuery.isFunction( opt.old ) ) {
+            opt.old.call( this );
+        }
</ins><span class="cx"> 
</span><del>-    contains = jQuery.contains( elem.ownerDocument, elem );
</del><ins>+        if ( opt.queue ) {
+            jQuery.dequeue( this, opt.queue );
+        }
+    };
</ins><span class="cx"> 
</span><del>-    // Append to fragment
-    tmp = getAll( safe.appendChild( elem ), &quot;script&quot; );
</del><ins>+    return opt;
+};
</ins><span class="cx"> 
</span><del>-    // Preserve script evaluation history
-    if ( contains ) {
-    setGlobalEval( tmp );
-    }
</del><ins>+jQuery.fn.extend({
+    fadeTo: function( speed, to, easing, callback ) {
</ins><span class="cx"> 
</span><del>-    // Capture executables
-    if ( scripts ) {
-    j = 0;
-    while ( (elem = tmp[ j++ ]) ) {
-    if ( rscriptType.test( elem.type || &quot;&quot; ) ) {
-    scripts.push( elem );
-    }
-    }
-    }
-    }
</del><ins>+        // show any hidden elements after setting opacity to 0
+        return this.filter( isHidden ).css( &quot;opacity&quot;, 0 ).show()
</ins><span class="cx"> 
</span><del>-    tmp = null;
</del><ins>+            // animate to the value specified
+            .end().animate({ opacity: to }, speed, easing, callback );
+    },
+    animate: function( prop, speed, easing, callback ) {
+        var empty = jQuery.isEmptyObject( prop ),
+            optall = jQuery.speed( speed, easing, callback ),
+            doAnimation = function() {
+                // Operate on a copy of prop so per-property easing won't be lost
+                var anim = Animation( this, jQuery.extend( {}, prop ), optall );
</ins><span class="cx"> 
</span><del>-    return safe;
</del><ins>+                // Empty animations, or finishing resolves immediately
+                if ( empty || data_priv.get( this, &quot;finish&quot; ) ) {
+                    anim.stop( true );
+                }
+            };
+            doAnimation.finish = doAnimation;
+
+        return empty || optall.queue === false ?
+            this.each( doAnimation ) :
+            this.queue( optall.queue, doAnimation );
</ins><span class="cx">     },
</span><ins>+    stop: function( type, clearQueue, gotoEnd ) {
+        var stopQueue = function( hooks ) {
+            var stop = hooks.stop;
+            delete hooks.stop;
+            stop( gotoEnd );
+        };
</ins><span class="cx"> 
</span><del>-    cleanData: function( elems, /* internal */ acceptData ) {
-    var elem, type, id, data,
-    i = 0,
-    internalKey = jQuery.expando,
-    cache = jQuery.cache,
-    deleteExpando = jQuery.support.deleteExpando,
-    special = jQuery.event.special;
</del><ins>+        if ( typeof type !== &quot;string&quot; ) {
+            gotoEnd = clearQueue;
+            clearQueue = type;
+            type = undefined;
+        }
+        if ( clearQueue &amp;&amp; type !== false ) {
+            this.queue( type || &quot;fx&quot;, [] );
+        }
</ins><span class="cx"> 
</span><del>-    for ( ; (elem = elems[i]) != null; i++ ) {
</del><ins>+        return this.each(function() {
+            var dequeue = true,
+                index = type != null &amp;&amp; type + &quot;queueHooks&quot;,
+                timers = jQuery.timers,
+                data = data_priv.get( this );
</ins><span class="cx"> 
</span><del>-    if ( acceptData || jQuery.acceptData( elem ) ) {
</del><ins>+            if ( index ) {
+                if ( data[ index ] &amp;&amp; data[ index ].stop ) {
+                    stopQueue( data[ index ] );
+                }
+            } else {
+                for ( index in data ) {
+                    if ( data[ index ] &amp;&amp; data[ index ].stop &amp;&amp; rrun.test( index ) ) {
+                        stopQueue( data[ index ] );
+                    }
+                }
+            }
</ins><span class="cx"> 
</span><del>-    id = elem[ internalKey ];
-    data = id &amp;&amp; cache[ id ];
</del><ins>+            for ( index = timers.length; index--; ) {
+                if ( timers[ index ].elem === this &amp;&amp; (type == null || timers[ index ].queue === type) ) {
+                    timers[ index ].anim.stop( gotoEnd );
+                    dequeue = false;
+                    timers.splice( index, 1 );
+                }
+            }
</ins><span class="cx"> 
</span><del>-    if ( data ) {
-    if ( data.events ) {
-    for ( type in data.events ) {
-    if ( special[ type ] ) {
-    jQuery.event.remove( elem, type );
</del><ins>+            // start the next in the queue if the last step wasn't forced
+            // timers currently will call their complete callbacks, which will dequeue
+            // but only if they were gotoEnd
+            if ( dequeue || !gotoEnd ) {
+                jQuery.dequeue( this, type );
+            }
+        });
+    },
+    finish: function( type ) {
+        if ( type !== false ) {
+            type = type || &quot;fx&quot;;
+        }
+        return this.each(function() {
+            var index,
+                data = data_priv.get( this ),
+                queue = data[ type + &quot;queue&quot; ],
+                hooks = data[ type + &quot;queueHooks&quot; ],
+                timers = jQuery.timers,
+                length = queue ? queue.length : 0;
</ins><span class="cx"> 
</span><del>-    // This is a shortcut to avoid jQuery.event.remove's overhead
-    } else {
-    jQuery.removeEvent( elem, type, data.handle );
-    }
-    }
-    }
</del><ins>+            // enable finishing flag on private data
+            data.finish = true;
</ins><span class="cx"> 
</span><del>-    // Remove cache only if it was not already removed by jQuery.event.remove
-    if ( cache[ id ] ) {
</del><ins>+            // empty the queue first
+            jQuery.queue( this, type, [] );
</ins><span class="cx"> 
</span><del>-    delete cache[ id ];
</del><ins>+            if ( hooks &amp;&amp; hooks.stop ) {
+                hooks.stop.call( this, true );
+            }
</ins><span class="cx"> 
</span><del>-    // IE does not allow us to delete expando properties from nodes,
-    // nor does it have a removeAttribute function on Document nodes;
-    // we must handle all of these cases
-    if ( deleteExpando ) {
-    delete elem[ internalKey ];
</del><ins>+            // look for any active animations, and finish them
+            for ( index = timers.length; index--; ) {
+                if ( timers[ index ].elem === this &amp;&amp; timers[ index ].queue === type ) {
+                    timers[ index ].anim.stop( true );
+                    timers.splice( index, 1 );
+                }
+            }
</ins><span class="cx"> 
</span><del>-    } else if ( typeof elem.removeAttribute !== core_strundefined ) {
-    elem.removeAttribute( internalKey );
</del><ins>+            // look for any animations in the old queue and finish them
+            for ( index = 0; index &lt; length; index++ ) {
+                if ( queue[ index ] &amp;&amp; queue[ index ].finish ) {
+                    queue[ index ].finish.call( this );
+                }
+            }
</ins><span class="cx"> 
</span><del>-    } else {
-    elem[ internalKey ] = null;
</del><ins>+            // turn off finishing flag
+            delete data.finish;
+        });
</ins><span class="cx">     }
</span><ins>+});
</ins><span class="cx"> 
</span><del>-    core_deletedIds.push( id );
-    }
-    }
-    }
-    }
-    }
</del><ins>+jQuery.each([ &quot;toggle&quot;, &quot;show&quot;, &quot;hide&quot; ], function( i, name ) {
+    var cssFn = jQuery.fn[ name ];
+    jQuery.fn[ name ] = function( speed, easing, callback ) {
+        return speed == null || typeof speed === &quot;boolean&quot; ?
+            cssFn.apply( this, arguments ) :
+            this.animate( genFx( name, true ), speed, easing, callback );
+    };
</ins><span class="cx"> });
</span><del>-var iframe, getStyles, curCSS,
-    ralpha = /alpha\([^)]*\)/i,
-    ropacity = /opacity\s*=\s*([^)]*)/,
-    rposition = /^(top|right|bottom|left)$/,
-    // swappable if display is none or starts with table except &quot;table&quot;, &quot;table-cell&quot;, or &quot;table-caption&quot;
-    // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
-    rdisplayswap = /^(none|table(?!-c[ea]).+)/,
-    rmargin = /^margin/,
-    rnumsplit = new RegExp( &quot;^(&quot; + core_pnum + &quot;)(.*)$&quot;, &quot;i&quot; ),
-    rnumnonpx = new RegExp( &quot;^(&quot; + core_pnum + &quot;)(?!px)[a-z%]+$&quot;, &quot;i&quot; ),
-    rrelNum = new RegExp( &quot;^([+-])=(&quot; + core_pnum + &quot;)&quot;, &quot;i&quot; ),
-    elemdisplay = { BODY: &quot;block&quot; },
</del><span class="cx"> 
</span><del>-    cssShow = { position: &quot;absolute&quot;, visibility: &quot;hidden&quot;, display: &quot;block&quot; },
-    cssNormalTransform = {
-    letterSpacing: 0,
-    fontWeight: 400
-    },
</del><ins>+// Generate shortcuts for custom animations
+jQuery.each({
+    slideDown: genFx(&quot;show&quot;),
+    slideUp: genFx(&quot;hide&quot;),
+    slideToggle: genFx(&quot;toggle&quot;),
+    fadeIn: { opacity: &quot;show&quot; },
+    fadeOut: { opacity: &quot;hide&quot; },
+    fadeToggle: { opacity: &quot;toggle&quot; }
+}, function( name, props ) {
+    jQuery.fn[ name ] = function( speed, easing, callback ) {
+        return this.animate( props, speed, easing, callback );
+    };
+});
</ins><span class="cx"> 
</span><del>-    cssExpand = [ &quot;Top&quot;, &quot;Right&quot;, &quot;Bottom&quot;, &quot;Left&quot; ],
-    cssPrefixes = [ &quot;Webkit&quot;, &quot;O&quot;, &quot;Moz&quot;, &quot;ms&quot; ];
</del><ins>+jQuery.timers = [];
+jQuery.fx.tick = function() {
+    var timer,
+        i = 0,
+        timers = jQuery.timers;
</ins><span class="cx"> 
</span><del>-// return a css property mapped to a potentially vendor prefixed property
-function vendorPropName( style, name ) {
</del><ins>+    fxNow = jQuery.now();
</ins><span class="cx"> 
</span><del>-    // shortcut for names that are not vendor prefixed
-    if ( name in style ) {
-    return name;
</del><ins>+    for ( ; i &lt; timers.length; i++ ) {
+        timer = timers[ i ];
+        // Checks the timer has not already been removed
+        if ( !timer() &amp;&amp; timers[ i ] === timer ) {
+            timers.splice( i--, 1 );
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // check for vendor prefixed names
-    var capName = name.charAt(0).toUpperCase() + name.slice(1),
-    origName = name,
-    i = cssPrefixes.length;
</del><ins>+    if ( !timers.length ) {
+        jQuery.fx.stop();
+    }
+    fxNow = undefined;
+};
</ins><span class="cx"> 
</span><del>-    while ( i-- ) {
-    name = cssPrefixes[ i ] + capName;
-    if ( name in style ) {
-    return name;
</del><ins>+jQuery.fx.timer = function( timer ) {
+    jQuery.timers.push( timer );
+    if ( timer() ) {
+        jQuery.fx.start();
+    } else {
+        jQuery.timers.pop();
</ins><span class="cx">     }
</span><ins>+};
+
+jQuery.fx.interval = 13;
+
+jQuery.fx.start = function() {
+    if ( !timerId ) {
+        timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
</ins><span class="cx">     }
</span><ins>+};
</ins><span class="cx"> 
</span><del>-    return origName;
-}
</del><ins>+jQuery.fx.stop = function() {
+    clearInterval( timerId );
+    timerId = null;
+};
</ins><span class="cx"> 
</span><del>-function isHidden( elem, el ) {
-    // isHidden might be called from jQuery#filter function;
-    // in that case, element will be second argument
-    elem = el || elem;
-    return jQuery.css( elem, &quot;display&quot; ) === &quot;none&quot; || !jQuery.contains( elem.ownerDocument, elem );
-}
</del><ins>+jQuery.fx.speeds = {
+    slow: 600,
+    fast: 200,
+    // Default speed
+    _default: 400
+};
</ins><span class="cx"> 
</span><del>-function showHide( elements, show ) {
-    var display, elem, hidden,
-    values = [],
-    index = 0,
-    length = elements.length;
</del><span class="cx"> 
</span><del>-    for ( ; index &lt; length; index++ ) {
-    elem = elements[ index ];
-    if ( !elem.style ) {
-    continue;
-    }
</del><ins>+// Based off of the plugin by Clint Helfers, with permission.
+// http://blindsignals.com/index.php/2009/07/jquery-delay/
+jQuery.fn.delay = function( time, type ) {
+    time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
+    type = type || &quot;fx&quot;;
</ins><span class="cx"> 
</span><del>-    values[ index ] = jQuery._data( elem, &quot;olddisplay&quot; );
-    display = elem.style.display;
-    if ( show ) {
-    // Reset the inline display of this element to learn if it is
-    // being hidden by cascaded rules or not
-    if ( !values[ index ] &amp;&amp; display === &quot;none&quot; ) {
-    elem.style.display = &quot;&quot;;
-    }
</del><ins>+    return this.queue( type, function( next, hooks ) {
+        var timeout = setTimeout( next, time );
+        hooks.stop = function() {
+            clearTimeout( timeout );
+        };
+    });
+};
</ins><span class="cx"> 
</span><del>-    // Set elements which have been overridden with display: none
-    // in a stylesheet to whatever the default browser style is
-    // for such an element
-    if ( elem.style.display === &quot;&quot; &amp;&amp; isHidden( elem ) ) {
-    values[ index ] = jQuery._data( elem, &quot;olddisplay&quot;, css_defaultDisplay(elem.nodeName) );
-    }
-    } else {
</del><span class="cx"> 
</span><del>-    if ( !values[ index ] ) {
-    hidden = isHidden( elem );
</del><ins>+(function() {
+    var input = document.createElement( &quot;input&quot; ),
+        select = document.createElement( &quot;select&quot; ),
+        opt = select.appendChild( document.createElement( &quot;option&quot; ) );
</ins><span class="cx"> 
</span><del>-    if ( display &amp;&amp; display !== &quot;none&quot; || !hidden ) {
-    jQuery._data( elem, &quot;olddisplay&quot;, hidden ? display : jQuery.css( elem, &quot;display&quot; ) );
-    }
-    }
-    }
-    }
</del><ins>+    input.type = &quot;checkbox&quot;;
</ins><span class="cx"> 
</span><del>-    // Set the display of most of the elements in a second loop
-    // to avoid the constant reflow
-    for ( index = 0; index &lt; length; index++ ) {
-    elem = elements[ index ];
-    if ( !elem.style ) {
-    continue;
-    }
-    if ( !show || elem.style.display === &quot;none&quot; || elem.style.display === &quot;&quot; ) {
-    elem.style.display = show ? values[ index ] || &quot;&quot; : &quot;none&quot;;
-    }
-    }
</del><ins>+    // Support: iOS 5.1, Android 4.x, Android 2.3
+    // Check the default checkbox/radio value (&quot;&quot; on old WebKit; &quot;on&quot; elsewhere)
+    support.checkOn = input.value !== &quot;&quot;;
</ins><span class="cx"> 
</span><del>-    return elements;
-}
</del><ins>+    // Must access the parent to make an option select properly
+    // Support: IE9, IE10
+    support.optSelected = opt.selected;
</ins><span class="cx"> 
</span><del>-jQuery.fn.extend({
-    css: function( name, value ) {
-    return jQuery.access( this, function( elem, name, value ) {
-    var len, styles,
-    map = {},
-    i = 0;
</del><ins>+    // Make sure that the options inside disabled selects aren't marked as disabled
+    // (WebKit marks them as disabled)
+    select.disabled = true;
+    support.optDisabled = !opt.disabled;
</ins><span class="cx"> 
</span><del>-    if ( jQuery.isArray( name ) ) {
-    styles = getStyles( elem );
-    len = name.length;
</del><ins>+    // Check if an input maintains its value after becoming a radio
+    // Support: IE9, IE10
+    input = document.createElement( &quot;input&quot; );
+    input.value = &quot;t&quot;;
+    input.type = &quot;radio&quot;;
+    support.radioValue = input.value === &quot;t&quot;;
+})();
</ins><span class="cx"> 
</span><del>-    for ( ; i &lt; len; i++ ) {
-    map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
-    }
</del><span class="cx"> 
</span><del>-    return map;
-    }
</del><ins>+var nodeHook, boolHook,
+    attrHandle = jQuery.expr.attrHandle;
</ins><span class="cx"> 
</span><del>-    return value !== undefined ?
-    jQuery.style( elem, name, value ) :
-    jQuery.css( elem, name );
-    }, name, value, arguments.length &gt; 1 );
</del><ins>+jQuery.fn.extend({
+    attr: function( name, value ) {
+        return access( this, jQuery.attr, name, value, arguments.length &gt; 1 );
</ins><span class="cx">     },
</span><del>-    show: function() {
-    return showHide( this, true );
-    },
-    hide: function() {
-    return showHide( this );
-    },
-    toggle: function( state ) {
-    var bool = typeof state === &quot;boolean&quot;;
</del><span class="cx"> 
</span><del>-    return this.each(function() {
-    if ( bool ? state : isHidden( this ) ) {
-    jQuery( this ).show();
-    } else {
-    jQuery( this ).hide();
</del><ins>+    removeAttr: function( name ) {
+        return this.each(function() {
+            jQuery.removeAttr( this, name );
+        });
</ins><span class="cx">     }
</span><del>-    });
-    }
</del><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> jQuery.extend({
</span><del>-    // Add in style property hooks for overriding the default
-    // behavior of getting and setting a style property
-    cssHooks: {
-    opacity: {
-    get: function( elem, computed ) {
-    if ( computed ) {
-    // We should always get a number back from opacity
-    var ret = curCSS( elem, &quot;opacity&quot; );
-    return ret === &quot;&quot; ? &quot;1&quot; : ret;
-    }
-    }
-    }
-    },
</del><ins>+    attr: function( elem, name, value ) {
+        var hooks, ret,
+            nType = elem.nodeType;
</ins><span class="cx"> 
</span><del>-    // Exclude the following css properties to add px
-    cssNumber: {
-    &quot;columnCount&quot;: true,
-    &quot;fillOpacity&quot;: true,
-    &quot;fontWeight&quot;: true,
-    &quot;lineHeight&quot;: true,
-    &quot;opacity&quot;: true,
-    &quot;orphans&quot;: true,
-    &quot;widows&quot;: true,
-    &quot;zIndex&quot;: true,
-    &quot;zoom&quot;: true
-    },
</del><ins>+        // don't get/set attributes on text, comment and attribute nodes
+        if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+            return;
+        }
</ins><span class="cx"> 
</span><del>-    // Add in properties whose names you wish to fix before
-    // setting or getting the value
-    cssProps: {
-    // normalize float css property
-    &quot;float&quot;: jQuery.support.cssFloat ? &quot;cssFloat&quot; : &quot;styleFloat&quot;
-    },
</del><ins>+        // Fallback to prop when attributes are not supported
+        if ( typeof elem.getAttribute === strundefined ) {
+            return jQuery.prop( elem, name, value );
+        }
</ins><span class="cx"> 
</span><del>-    // Get and set the style property on a DOM Node
-    style: function( elem, name, value, extra ) {
-    // Don't set styles on text and comment nodes
-    if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
-    return;
-    }
</del><ins>+        // All attributes are lowercase
+        // Grab necessary hook if one is defined
+        if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
+            name = name.toLowerCase();
+            hooks = jQuery.attrHooks[ name ] ||
+                ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
+        }
</ins><span class="cx"> 
</span><del>-    // Make sure that we're working with the right name
-    var ret, type, hooks,
-    origName = jQuery.camelCase( name ),
-    style = elem.style;
</del><ins>+        if ( value !== undefined ) {
</ins><span class="cx"> 
</span><del>-    name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
</del><ins>+            if ( value === null ) {
+                jQuery.removeAttr( elem, name );
</ins><span class="cx"> 
</span><del>-    // gets hook for the prefixed version
-    // followed by the unprefixed version
-    hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
</del><ins>+            } else if ( hooks &amp;&amp; &quot;set&quot; in hooks &amp;&amp; (ret = hooks.set( elem, value, name )) !== undefined ) {
+                return ret;
</ins><span class="cx"> 
</span><del>-    // Check if we're setting a value
-    if ( value !== undefined ) {
-    type = typeof value;
</del><ins>+            } else {
+                elem.setAttribute( name, value + &quot;&quot; );
+                return value;
+            }
</ins><span class="cx"> 
</span><del>-    // convert relative number strings (+= or -=) to relative numbers. #7345
-    if ( type === &quot;string&quot; &amp;&amp; (ret = rrelNum.exec( value )) ) {
-    value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
-    // Fixes bug #9237
-    type = &quot;number&quot;;
-    }
</del><ins>+        } else if ( hooks &amp;&amp; &quot;get&quot; in hooks &amp;&amp; (ret = hooks.get( elem, name )) !== null ) {
+            return ret;
</ins><span class="cx"> 
</span><del>-    // Make sure that NaN and null values aren't set. See: #7116
-    if ( value == null || type === &quot;number&quot; &amp;&amp; isNaN( value ) ) {
-    return;
-    }
</del><ins>+        } else {
+            ret = jQuery.find.attr( elem, name );
</ins><span class="cx"> 
</span><del>-    // If a number was passed in, add 'px' to the (except for certain CSS properties)
-    if ( type === &quot;number&quot; &amp;&amp; !jQuery.cssNumber[ origName ] ) {
-    value += &quot;px&quot;;
-    }
</del><ins>+            // Non-existent attributes return null, we normalize to undefined
+            return ret == null ?
+                undefined :
+                ret;
+        }
+    },
</ins><span class="cx"> 
</span><del>-    // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
-    // but it would mean to define eight (for every problematic property) identical functions
-    if ( !jQuery.support.clearCloneStyle &amp;&amp; value === &quot;&quot; &amp;&amp; name.indexOf(&quot;background&quot;) === 0 ) {
-    style[ name ] = &quot;inherit&quot;;
-    }
</del><ins>+    removeAttr: function( elem, value ) {
+        var name, propName,
+            i = 0,
+            attrNames = value &amp;&amp; value.match( rnotwhite );
</ins><span class="cx"> 
</span><del>-    // If a hook was provided, use that value, otherwise just set the specified value
-    if ( !hooks || !(&quot;set&quot; in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
</del><ins>+        if ( attrNames &amp;&amp; elem.nodeType === 1 ) {
+            while ( (name = attrNames[i++]) ) {
+                propName = jQuery.propFix[ name ] || name;
</ins><span class="cx"> 
</span><del>-    // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
-    // Fixes bug #5509
-    try {
-    style[ name ] = value;
-    } catch(e) {}
-    }
</del><ins>+                // Boolean attributes get special treatment (#10870)
+                if ( jQuery.expr.match.bool.test( name ) ) {
+                    // Set corresponding property to false
+                    elem[ propName ] = false;
+                }
</ins><span class="cx"> 
</span><del>-    } else {
-    // If a hook was provided get the non-computed value from there
-    if ( hooks &amp;&amp; &quot;get&quot; in hooks &amp;&amp; (ret = hooks.get( elem, false, extra )) !== undefined ) {
-    return ret;
</del><ins>+                elem.removeAttribute( name );
+            }
+        }
+    },
+
+    attrHooks: {
+        type: {
+            set: function( elem, value ) {
+                if ( !support.radioValue &amp;&amp; value === &quot;radio&quot; &amp;&amp;
+                    jQuery.nodeName( elem, &quot;input&quot; ) ) {
+                    // Setting the type on a radio button after the value resets the value in IE6-9
+                    // Reset value to default in case type is set after value during creation
+                    var val = elem.value;
+                    elem.setAttribute( &quot;type&quot;, value );
+                    if ( val ) {
+                        elem.value = val;
+                    }
+                    return value;
+                }
+            }
+        }
</ins><span class="cx">     }
</span><ins>+});
</ins><span class="cx"> 
</span><del>-    // Otherwise just get the value from the style object
-    return style[ name ];
</del><ins>+// Hooks for boolean attributes
+boolHook = {
+    set: function( elem, value, name ) {
+        if ( value === false ) {
+            // Remove boolean attributes when set to false
+            jQuery.removeAttr( elem, name );
+        } else {
+            elem.setAttribute( name, name );
+        }
+        return name;
</ins><span class="cx">     }
</span><del>-    },
</del><ins>+};
+jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
+    var getter = attrHandle[ name ] || jQuery.find.attr;
</ins><span class="cx"> 
</span><del>-    css: function( elem, name, extra, styles ) {
-    var num, val, hooks,
-    origName = jQuery.camelCase( name );
</del><ins>+    attrHandle[ name ] = function( elem, name, isXML ) {
+        var ret, handle;
+        if ( !isXML ) {
+            // Avoid an infinite loop by temporarily removing this function from the getter
+            handle = attrHandle[ name ];
+            attrHandle[ name ] = ret;
+            ret = getter( elem, name, isXML ) != null ?
+                name.toLowerCase() :
+                null;
+            attrHandle[ name ] = handle;
+        }
+        return ret;
+    };
+});
</ins><span class="cx"> 
</span><del>-    // Make sure that we're working with the right name
-    name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
</del><span class="cx"> 
</span><del>-    // gets hook for the prefixed version
-    // followed by the unprefixed version
-    hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
</del><span class="cx"> 
</span><del>-    // If a hook was provided get the computed value from there
-    if ( hooks &amp;&amp; &quot;get&quot; in hooks ) {
-    val = hooks.get( elem, true, extra );
-    }
</del><span class="cx"> 
</span><del>-    // Otherwise, if a way to get the computed value exists, use that
-    if ( val === undefined ) {
-    val = curCSS( elem, name, styles );
-    }
</del><ins>+var rfocusable = /^(?:input|select|textarea|button)$/i;
</ins><span class="cx"> 
</span><del>-    //convert &quot;normal&quot; to computed value
-    if ( val === &quot;normal&quot; &amp;&amp; name in cssNormalTransform ) {
-    val = cssNormalTransform[ name ];
-    }
</del><ins>+jQuery.fn.extend({
+    prop: function( name, value ) {
+        return access( this, jQuery.prop, name, value, arguments.length &gt; 1 );
+    },
</ins><span class="cx"> 
</span><del>-    // Return, converting to number if forced or a qualifier was provided and val looks numeric
-    if ( extra === &quot;&quot; || extra ) {
-    num = parseFloat( val );
-    return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
</del><ins>+    removeProp: function( name ) {
+        return this.each(function() {
+            delete this[ jQuery.propFix[ name ] || name ];
+        });
</ins><span class="cx">     }
</span><del>-    return val;
</del><ins>+});
+
+jQuery.extend({
+    propFix: {
+        &quot;for&quot;: &quot;htmlFor&quot;,
+        &quot;class&quot;: &quot;className&quot;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    // A method for quickly swapping in/out CSS properties to get correct calculations
-    swap: function( elem, options, callback, args ) {
-    var ret, name,
-    old = {};
</del><ins>+    prop: function( elem, name, value ) {
+        var ret, hooks, notxml,
+            nType = elem.nodeType;
</ins><span class="cx"> 
</span><del>-    // Remember the old values, and insert the new ones
-    for ( name in options ) {
-    old[ name ] = elem.style[ name ];
-    elem.style[ name ] = options[ name ];
-    }
</del><ins>+        // don't get/set properties on text, comment and attribute nodes
+        if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+            return;
+        }
</ins><span class="cx"> 
</span><del>-    ret = callback.apply( elem, args || [] );
</del><ins>+        notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
</ins><span class="cx"> 
</span><del>-    // Revert the old values
-    for ( name in options ) {
-    elem.style[ name ] = old[ name ];
-    }
</del><ins>+        if ( notxml ) {
+            // Fix name and attach hooks
+            name = jQuery.propFix[ name ] || name;
+            hooks = jQuery.propHooks[ name ];
+        }
</ins><span class="cx"> 
</span><del>-    return ret;
</del><ins>+        if ( value !== undefined ) {
+            return hooks &amp;&amp; &quot;set&quot; in hooks &amp;&amp; (ret = hooks.set( elem, value, name )) !== undefined ?
+                ret :
+                ( elem[ name ] = value );
+
+        } else {
+            return hooks &amp;&amp; &quot;get&quot; in hooks &amp;&amp; (ret = hooks.get( elem, name )) !== null ?
+                ret :
+                elem[ name ];
+        }
+    },
+
+    propHooks: {
+        tabIndex: {
+            get: function( elem ) {
+                return elem.hasAttribute( &quot;tabindex&quot; ) || rfocusable.test( elem.nodeName ) || elem.href ?
+                    elem.tabIndex :
+                    -1;
+            }
+        }
</ins><span class="cx">     }
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-// NOTE: we've included the &quot;window&quot; in window.getComputedStyle
-// because jsdom on node.js will break without it.
-if ( window.getComputedStyle ) {
-    getStyles = function( elem ) {
-    return window.getComputedStyle( elem, null );
</del><ins>+// Support: IE9+
+// Selectedness for an option in an optgroup can be inaccurate
+if ( !support.optSelected ) {
+    jQuery.propHooks.selected = {
+        get: function( elem ) {
+            var parent = elem.parentNode;
+            if ( parent &amp;&amp; parent.parentNode ) {
+                parent.parentNode.selectedIndex;
+            }
+            return null;
+        }
</ins><span class="cx">     };
</span><ins>+}
</ins><span class="cx"> 
</span><del>-    curCSS = function( elem, name, _computed ) {
-    var width, minWidth, maxWidth,
-    computed = _computed || getStyles( elem ),
</del><ins>+jQuery.each([
+    &quot;tabIndex&quot;,
+    &quot;readOnly&quot;,
+    &quot;maxLength&quot;,
+    &quot;cellSpacing&quot;,
+    &quot;cellPadding&quot;,
+    &quot;rowSpan&quot;,
+    &quot;colSpan&quot;,
+    &quot;useMap&quot;,
+    &quot;frameBorder&quot;,
+    &quot;contentEditable&quot;
+], function() {
+    jQuery.propFix[ this.toLowerCase() ] = this;
+});
</ins><span class="cx"> 
</span><del>-    // getPropertyValue is only needed for .css('filter') in IE9, see #12537
-    ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
-    style = elem.style;
</del><span class="cx"> 
</span><del>-    if ( computed ) {
</del><span class="cx"> 
</span><del>-    if ( ret === &quot;&quot; &amp;&amp; !jQuery.contains( elem.ownerDocument, elem ) ) {
-    ret = jQuery.style( elem, name );
-    }
</del><span class="cx"> 
</span><del>-    // A tribute to the &quot;awesome hack by Dean Edwards&quot;
-    // Chrome &lt; 17 and Safari 5.0 uses &quot;computed value&quot; instead of &quot;used value&quot; for margin-right
-    // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
-    // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
-    if ( rnumnonpx.test( ret ) &amp;&amp; rmargin.test( name ) ) {
</del><ins>+var rclass = /[\t\r\n\f]/g;
</ins><span class="cx"> 
</span><del>-    // Remember the original values
-    width = style.width;
-    minWidth = style.minWidth;
-    maxWidth = style.maxWidth;
</del><ins>+jQuery.fn.extend({
+    addClass: function( value ) {
+        var classes, elem, cur, clazz, j, finalValue,
+            proceed = typeof value === &quot;string&quot; &amp;&amp; value,
+            i = 0,
+            len = this.length;
</ins><span class="cx"> 
</span><del>-    // Put in the new values to get a computed value out
-    style.minWidth = style.maxWidth = style.width = ret;
-    ret = computed.width;
</del><ins>+        if ( jQuery.isFunction( value ) ) {
+            return this.each(function( j ) {
+                jQuery( this ).addClass( value.call( this, j, this.className ) );
+            });
+        }
</ins><span class="cx"> 
</span><del>-    // Revert the changed values
-    style.width = width;
-    style.minWidth = minWidth;
-    style.maxWidth = maxWidth;
-    }
-    }
</del><ins>+        if ( proceed ) {
+            // The disjunction here is for better compressibility (see removeClass)
+            classes = ( value || &quot;&quot; ).match( rnotwhite ) || [];
</ins><span class="cx"> 
</span><del>-    return ret;
-    };
-} else if ( document.documentElement.currentStyle ) {
-    getStyles = function( elem ) {
-    return elem.currentStyle;
-    };
</del><ins>+            for ( ; i &lt; len; i++ ) {
+                elem = this[ i ];
+                cur = elem.nodeType === 1 &amp;&amp; ( elem.className ?
+                    ( &quot; &quot; + elem.className + &quot; &quot; ).replace( rclass, &quot; &quot; ) :
+                    &quot; &quot;
+                );
</ins><span class="cx"> 
</span><del>-    curCSS = function( elem, name, _computed ) {
-    var left, rs, rsLeft,
-    computed = _computed || getStyles( elem ),
-    ret = computed ? computed[ name ] : undefined,
-    style = elem.style;
</del><ins>+                if ( cur ) {
+                    j = 0;
+                    while ( (clazz = classes[j++]) ) {
+                        if ( cur.indexOf( &quot; &quot; + clazz + &quot; &quot; ) &lt; 0 ) {
+                            cur += clazz + &quot; &quot;;
+                        }
+                    }
</ins><span class="cx"> 
</span><del>-    // Avoid setting ret to empty string here
-    // so we don't default to auto
-    if ( ret == null &amp;&amp; style &amp;&amp; style[ name ] ) {
-    ret = style[ name ];
-    }
</del><ins>+                    // only assign if different to avoid unneeded rendering.
+                    finalValue = jQuery.trim( cur );
+                    if ( elem.className !== finalValue ) {
+                        elem.className = finalValue;
+                    }
+                }
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // From the awesome hack by Dean Edwards
-    // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
</del><ins>+        return this;
+    },
</ins><span class="cx"> 
</span><del>-    // If we're not dealing with a regular pixel number
-    // but a number that has a weird ending, we need to convert it to pixels
-    // but not position css attributes, as those are proportional to the parent element instead
-    // and we can't measure the parent instead because it might trigger a &quot;stacking dolls&quot; problem
-    if ( rnumnonpx.test( ret ) &amp;&amp; !rposition.test( name ) ) {
</del><ins>+    removeClass: function( value ) {
+        var classes, elem, cur, clazz, j, finalValue,
+            proceed = arguments.length === 0 || typeof value === &quot;string&quot; &amp;&amp; value,
+            i = 0,
+            len = this.length;
</ins><span class="cx"> 
</span><del>-    // Remember the original values
-    left = style.left;
-    rs = elem.runtimeStyle;
-    rsLeft = rs &amp;&amp; rs.left;
</del><ins>+        if ( jQuery.isFunction( value ) ) {
+            return this.each(function( j ) {
+                jQuery( this ).removeClass( value.call( this, j, this.className ) );
+            });
+        }
+        if ( proceed ) {
+            classes = ( value || &quot;&quot; ).match( rnotwhite ) || [];
</ins><span class="cx"> 
</span><del>-    // Put in the new values to get a computed value out
-    if ( rsLeft ) {
-    rs.left = elem.currentStyle.left;
-    }
-    style.left = name === &quot;fontSize&quot; ? &quot;1em&quot; : ret;
-    ret = style.pixelLeft + &quot;px&quot;;
</del><ins>+            for ( ; i &lt; len; i++ ) {
+                elem = this[ i ];
+                // This expression is here for better compressibility (see addClass)
+                cur = elem.nodeType === 1 &amp;&amp; ( elem.className ?
+                    ( &quot; &quot; + elem.className + &quot; &quot; ).replace( rclass, &quot; &quot; ) :
+                    &quot;&quot;
+                );
</ins><span class="cx"> 
</span><del>-    // Revert the changed values
-    style.left = left;
-    if ( rsLeft ) {
-    rs.left = rsLeft;
-    }
-    }
</del><ins>+                if ( cur ) {
+                    j = 0;
+                    while ( (clazz = classes[j++]) ) {
+                        // Remove *all* instances
+                        while ( cur.indexOf( &quot; &quot; + clazz + &quot; &quot; ) &gt;= 0 ) {
+                            cur = cur.replace( &quot; &quot; + clazz + &quot; &quot;, &quot; &quot; );
+                        }
+                    }
</ins><span class="cx"> 
</span><del>-    return ret === &quot;&quot; ? &quot;auto&quot; : ret;
-    };
-}
</del><ins>+                    // only assign if different to avoid unneeded rendering.
+                    finalValue = value ? jQuery.trim( cur ) : &quot;&quot;;
+                    if ( elem.className !== finalValue ) {
+                        elem.className = finalValue;
+                    }
+                }
+            }
+        }
</ins><span class="cx"> 
</span><del>-function setPositiveNumber( elem, value, subtract ) {
-    var matches = rnumsplit.exec( value );
-    return matches ?
-    // Guard against undefined &quot;subtract&quot;, e.g., when used as in cssHooks
-    Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || &quot;px&quot; ) :
-    value;
-}
</del><ins>+        return this;
+    },
</ins><span class="cx"> 
</span><del>-function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
-    var i = extra === ( isBorderBox ? &quot;border&quot; : &quot;content&quot; ) ?
-    // If we already have the right measurement, avoid augmentation
-    4 :
-    // Otherwise initialize for horizontal or vertical properties
-    name === &quot;width&quot; ? 1 : 0,
</del><ins>+    toggleClass: function( value, stateVal ) {
+        var type = typeof value;
</ins><span class="cx"> 
</span><del>-    val = 0;
</del><ins>+        if ( typeof stateVal === &quot;boolean&quot; &amp;&amp; type === &quot;string&quot; ) {
+            return stateVal ? this.addClass( value ) : this.removeClass( value );
+        }
</ins><span class="cx"> 
</span><del>-    for ( ; i &lt; 4; i += 2 ) {
-    // both box models exclude margin, so add it if we want it
-    if ( extra === &quot;margin&quot; ) {
-    val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
-    }
</del><ins>+        if ( jQuery.isFunction( value ) ) {
+            return this.each(function( i ) {
+                jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
+            });
+        }
</ins><span class="cx"> 
</span><del>-    if ( isBorderBox ) {
-    // border-box includes padding, so remove it if we want content
-    if ( extra === &quot;content&quot; ) {
-    val -= jQuery.css( elem, &quot;padding&quot; + cssExpand[ i ], true, styles );
-    }
</del><ins>+        return this.each(function() {
+            if ( type === &quot;string&quot; ) {
+                // toggle individual class names
+                var className,
+                    i = 0,
+                    self = jQuery( this ),
+                    classNames = value.match( rnotwhite ) || [];
</ins><span class="cx"> 
</span><del>-    // at this point, extra isn't border nor margin, so remove border
-    if ( extra !== &quot;margin&quot; ) {
-    val -= jQuery.css( elem, &quot;border&quot; + cssExpand[ i ] + &quot;Width&quot;, true, styles );
-    }
-    } else {
-    // at this point, extra isn't content, so add padding
-    val += jQuery.css( elem, &quot;padding&quot; + cssExpand[ i ], true, styles );
</del><ins>+                while ( (className = classNames[ i++ ]) ) {
+                    // check each className given, space separated list
+                    if ( self.hasClass( className ) ) {
+                        self.removeClass( className );
+                    } else {
+                        self.addClass( className );
+                    }
+                }
</ins><span class="cx"> 
</span><del>-    // at this point, extra isn't content nor padding, so add border
-    if ( extra !== &quot;padding&quot; ) {
-    val += jQuery.css( elem, &quot;border&quot; + cssExpand[ i ] + &quot;Width&quot;, true, styles );
</del><ins>+            // Toggle whole class name
+            } else if ( type === strundefined || type === &quot;boolean&quot; ) {
+                if ( this.className ) {
+                    // store className if set
+                    data_priv.set( this, &quot;__className__&quot;, this.className );
+                }
+
+                // If the element has a class name or if we're passed &quot;false&quot;,
+                // then remove the whole classname (if there was one, the above saved it).
+                // Otherwise bring back whatever was previously saved (if anything),
+                // falling back to the empty string if nothing was stored.
+                this.className = this.className || value === false ? &quot;&quot; : data_priv.get( this, &quot;__className__&quot; ) || &quot;&quot;;
+            }
+        });
+    },
+
+    hasClass: function( selector ) {
+        var className = &quot; &quot; + selector + &quot; &quot;,
+            i = 0,
+            l = this.length;
+        for ( ; i &lt; l; i++ ) {
+            if ( this[i].nodeType === 1 &amp;&amp; (&quot; &quot; + this[i].className + &quot; &quot;).replace(rclass, &quot; &quot;).indexOf( className ) &gt;= 0 ) {
+                return true;
+            }
+        }
+
+        return false;
</ins><span class="cx">     }
</span><del>-    }
-    }
</del><ins>+});
</ins><span class="cx"> 
</span><del>-    return val;
-}
</del><span class="cx"> 
</span><del>-function getWidthOrHeight( elem, name, extra ) {
</del><span class="cx"> 
</span><del>-    // Start with offset property, which is equivalent to the border-box value
-    var valueIsBorderBox = true,
-    val = name === &quot;width&quot; ? elem.offsetWidth : elem.offsetHeight,
-    styles = getStyles( elem ),
-    isBorderBox = jQuery.support.boxSizing &amp;&amp; jQuery.css( elem, &quot;boxSizing&quot;, false, styles ) === &quot;border-box&quot;;
</del><span class="cx"> 
</span><del>-    // some non-html elements return undefined for offsetWidth, so check for null/undefined
-    // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
-    // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
-    if ( val &lt;= 0 || val == null ) {
-    // Fall back to computed then uncomputed css if necessary
-    val = curCSS( elem, name, styles );
-    if ( val &lt; 0 || val == null ) {
-    val = elem.style[ name ];
-    }
</del><ins>+var rreturn = /\r/g;
</ins><span class="cx"> 
</span><del>-    // Computed unit is not pixels. Stop here and return.
-    if ( rnumnonpx.test(val) ) {
-    return val;
-    }
</del><ins>+jQuery.fn.extend({
+    val: function( value ) {
+        var hooks, ret, isFunction,
+            elem = this[0];
</ins><span class="cx"> 
</span><del>-    // we need the check for style in case a browser which returns unreliable values
-    // for getComputedStyle silently falls back to the reliable elem.style
-    valueIsBorderBox = isBorderBox &amp;&amp; ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
</del><ins>+        if ( !arguments.length ) {
+            if ( elem ) {
+                hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
</ins><span class="cx"> 
</span><del>-    // Normalize &quot;&quot;, auto, and prepare for extra
-    val = parseFloat( val ) || 0;
-    }
</del><ins>+                if ( hooks &amp;&amp; &quot;get&quot; in hooks &amp;&amp; (ret = hooks.get( elem, &quot;value&quot; )) !== undefined ) {
+                    return ret;
+                }
</ins><span class="cx"> 
</span><del>-    // use the active box-sizing model to add/subtract irrelevant styles
-    return ( val +
-    augmentWidthOrHeight(
-    elem,
-    name,
-    extra || ( isBorderBox ? &quot;border&quot; : &quot;content&quot; ),
-    valueIsBorderBox,
-    styles
-    )
-    ) + &quot;px&quot;;
-}
</del><ins>+                ret = elem.value;
</ins><span class="cx"> 
</span><del>-// Try to determine the default display value of an element
-function css_defaultDisplay( nodeName ) {
-    var doc = document,
-    display = elemdisplay[ nodeName ];
</del><ins>+                return typeof ret === &quot;string&quot; ?
+                    // handle most common string cases
+                    ret.replace(rreturn, &quot;&quot;) :
+                    // handle cases where value is null/undef or number
+                    ret == null ? &quot;&quot; : ret;
+            }
</ins><span class="cx"> 
</span><del>-    if ( !display ) {
-    display = actualDisplay( nodeName, doc );
</del><ins>+            return;
+        }
</ins><span class="cx"> 
</span><del>-    // If the simple way fails, read from inside an iframe
-    if ( display === &quot;none&quot; || !display ) {
-    // Use the already-created iframe if possible
-    iframe = ( iframe ||
-    jQuery(&quot;&lt;iframe frameborder='0' width='0' height='0'/&gt;&quot;)
-    .css( &quot;cssText&quot;, &quot;display:block !important&quot; )
-    ).appendTo( doc.documentElement );
</del><ins>+        isFunction = jQuery.isFunction( value );
</ins><span class="cx"> 
</span><del>-    // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
-    doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
-    doc.write(&quot;&lt;!doctype html&gt;&lt;html&gt;&lt;body&gt;&quot;);
-    doc.close();
</del><ins>+        return this.each(function( i ) {
+            var val;
</ins><span class="cx"> 
</span><del>-    display = actualDisplay( nodeName, doc );
-    iframe.detach();
-    }
</del><ins>+            if ( this.nodeType !== 1 ) {
+                return;
+            }
</ins><span class="cx"> 
</span><del>-    // Store the correct default display
-    elemdisplay[ nodeName ] = display;
-    }
</del><ins>+            if ( isFunction ) {
+                val = value.call( this, i, jQuery( this ).val() );
+            } else {
+                val = value;
+            }
</ins><span class="cx"> 
</span><del>-    return display;
-}
</del><ins>+            // Treat null/undefined as &quot;&quot;; convert numbers to string
+            if ( val == null ) {
+                val = &quot;&quot;;
</ins><span class="cx"> 
</span><del>-// Called ONLY from within css_defaultDisplay
-function actualDisplay( name, doc ) {
-    var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
-    display = jQuery.css( elem[0], &quot;display&quot; );
-    elem.remove();
-    return display;
-}
</del><ins>+            } else if ( typeof val === &quot;number&quot; ) {
+                val += &quot;&quot;;
</ins><span class="cx"> 
</span><del>-jQuery.each([ &quot;height&quot;, &quot;width&quot; ], function( i, name ) {
-    jQuery.cssHooks[ name ] = {
-    get: function( elem, computed, extra ) {
-    if ( computed ) {
-    // certain elements can have dimension info if we invisibly show them
-    // however, it must have a current display style that would benefit from this
-    return elem.offsetWidth === 0 &amp;&amp; rdisplayswap.test( jQuery.css( elem, &quot;display&quot; ) ) ?
-    jQuery.swap( elem, cssShow, function() {
-    return getWidthOrHeight( elem, name, extra );
-    }) :
-    getWidthOrHeight( elem, name, extra );
-    }
-    },
</del><ins>+            } else if ( jQuery.isArray( val ) ) {
+                val = jQuery.map( val, function( value ) {
+                    return value == null ? &quot;&quot; : value + &quot;&quot;;
+                });
+            }
</ins><span class="cx"> 
</span><del>-    set: function( elem, value, extra ) {
-    var styles = extra &amp;&amp; getStyles( elem );
-    return setPositiveNumber( elem, value, extra ?
-    augmentWidthOrHeight(
-    elem,
-    name,
-    extra,
-    jQuery.support.boxSizing &amp;&amp; jQuery.css( elem, &quot;boxSizing&quot;, false, styles ) === &quot;border-box&quot;,
-    styles
-    ) : 0
-    );
</del><ins>+            hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
+
+            // If set returns undefined, fall back to normal setting
+            if ( !hooks || !(&quot;set&quot; in hooks) || hooks.set( this, val, &quot;value&quot; ) === undefined ) {
+                this.value = val;
+            }
+        });
</ins><span class="cx">     }
</span><del>-    };
</del><span class="cx"> });
</span><span class="cx"> 
</span><del>-if ( !jQuery.support.opacity ) {
-    jQuery.cssHooks.opacity = {
-    get: function( elem, computed ) {
-    // IE uses filters for opacity
-    return ropacity.test( (computed &amp;&amp; elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || &quot;&quot; ) ?
-    ( 0.01 * parseFloat( RegExp.$1 ) ) + &quot;&quot; :
-    computed ? &quot;1&quot; : &quot;&quot;;
-    },
</del><ins>+jQuery.extend({
+    valHooks: {
+        select: {
+            get: function( elem ) {
+                var value, option,
+                    options = elem.options,
+                    index = elem.selectedIndex,
+                    one = elem.type === &quot;select-one&quot; || index &lt; 0,
+                    values = one ? null : [],
+                    max = one ? index + 1 : options.length,
+                    i = index &lt; 0 ?
+                        max :
+                        one ? index : 0;
</ins><span class="cx"> 
</span><del>-    set: function( elem, value ) {
-    var style = elem.style,
-    currentStyle = elem.currentStyle,
-    opacity = jQuery.isNumeric( value ) ? &quot;alpha(opacity=&quot; + value * 100 + &quot;)&quot; : &quot;&quot;,
-    filter = currentStyle &amp;&amp; currentStyle.filter || style.filter || &quot;&quot;;
</del><ins>+                // Loop through all the selected options
+                for ( ; i &lt; max; i++ ) {
+                    option = options[ i ];
</ins><span class="cx"> 
</span><del>-    // IE has trouble with opacity if it does not have layout
-    // Force it by setting the zoom level
-    style.zoom = 1;
</del><ins>+                    // IE6-9 doesn't update selected after form reset (#2551)
+                    if ( ( option.selected || i === index ) &amp;&amp;
+                            // Don't return options that are disabled or in a disabled optgroup
+                            ( support.optDisabled ? !option.disabled : option.getAttribute( &quot;disabled&quot; ) === null ) &amp;&amp;
+                            ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, &quot;optgroup&quot; ) ) ) {
</ins><span class="cx"> 
</span><del>-    // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
-    // if value === &quot;&quot;, then remove inline opacity #12685
-    if ( ( value &gt;= 1 || value === &quot;&quot; ) &amp;&amp;
-    jQuery.trim( filter.replace( ralpha, &quot;&quot; ) ) === &quot;&quot; &amp;&amp;
-    style.removeAttribute ) {
</del><ins>+                        // Get the specific value for the option
+                        value = jQuery( option ).val();
</ins><span class="cx"> 
</span><del>-    // Setting style.filter to null, &quot;&quot; &amp; &quot; &quot; still leave &quot;filter:&quot; in the cssText
-    // if &quot;filter:&quot; is present at all, clearType is disabled, we want to avoid this
-    // style.removeAttribute is IE Only, but so apparently is this code path...
-    style.removeAttribute( &quot;filter&quot; );
</del><ins>+                        // We don't need an array for one selects
+                        if ( one ) {
+                            return value;
+                        }
</ins><span class="cx"> 
</span><del>-    // if there is no filter style applied in a css rule or unset inline opacity, we are done
-    if ( value === &quot;&quot; || currentStyle &amp;&amp; !currentStyle.filter ) {
-    return;
-    }
-    }
</del><ins>+                        // Multi-Selects return an array
+                        values.push( value );
+                    }
+                }
</ins><span class="cx"> 
</span><del>-    // otherwise, set new filter values
-    style.filter = ralpha.test( filter ) ?
-    filter.replace( ralpha, opacity ) :
-    filter + &quot; &quot; + opacity;
-    }
-    };
-}
</del><ins>+                return values;
+            },
</ins><span class="cx"> 
</span><del>-// These hooks cannot be added until DOM ready because the support test
-// for it is not run until after DOM ready
-jQuery(function() {
-    if ( !jQuery.support.reliableMarginRight ) {
-    jQuery.cssHooks.marginRight = {
-    get: function( elem, computed ) {
-    if ( computed ) {
-    // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
-    // Work around by temporarily setting element display to inline-block
-    return jQuery.swap( elem, { &quot;display&quot;: &quot;inline-block&quot; },
-    curCSS, [ elem, &quot;marginRight&quot; ] );
-    }
-    }
-    };
-    }
</del><ins>+            set: function( elem, value ) {
+                var optionSet, option,
+                    options = elem.options,
+                    values = jQuery.makeArray( value ),
+                    i = options.length;
</ins><span class="cx"> 
</span><del>-    // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
-    // getComputedStyle returns percent when specified for top/left/bottom/right
-    // rather than make the css module depend on the offset module, we just check for it here
-    if ( !jQuery.support.pixelPosition &amp;&amp; jQuery.fn.position ) {
-    jQuery.each( [ &quot;top&quot;, &quot;left&quot; ], function( i, prop ) {
-    jQuery.cssHooks[ prop ] = {
-    get: function( elem, computed ) {
-    if ( computed ) {
-    computed = curCSS( elem, prop );
-    // if curCSS returns percentage, fallback to offset
-    return rnumnonpx.test( computed ) ?
-    jQuery( elem ).position()[ prop ] + &quot;px&quot; :
-    computed;
</del><ins>+                while ( i-- ) {
+                    option = options[ i ];
+                    if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) &gt;= 0) ) {
+                        optionSet = true;
+                    }
+                }
+
+                // force browsers to behave consistently when non-matching value is set
+                if ( !optionSet ) {
+                    elem.selectedIndex = -1;
+                }
+                return values;
+            }
+        }
</ins><span class="cx">     }
</span><del>-    }
</del><ins>+});
+
+// Radios and checkboxes getter/setter
+jQuery.each([ &quot;radio&quot;, &quot;checkbox&quot; ], function() {
+    jQuery.valHooks[ this ] = {
+        set: function( elem, value ) {
+            if ( jQuery.isArray( value ) ) {
+                return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) &gt;= 0 );
+            }
+        }
</ins><span class="cx">     };
</span><del>-    });
</del><ins>+    if ( !support.checkOn ) {
+        jQuery.valHooks[ this ].get = function( elem ) {
+            // Support: Webkit
+            // &quot;&quot; is returned instead of &quot;on&quot; if a value isn't specified
+            return elem.getAttribute(&quot;value&quot;) === null ? &quot;on&quot; : elem.value;
+        };
</ins><span class="cx">     }
</span><del>-
</del><span class="cx"> });
</span><span class="cx"> 
</span><del>-if ( jQuery.expr &amp;&amp; jQuery.expr.filters ) {
-    jQuery.expr.filters.hidden = function( elem ) {
-    // Support: Opera &lt;= 12.12
-    // Opera reports offsetWidths and offsetHeights less than zero on some elements
-    return elem.offsetWidth &lt;= 0 &amp;&amp; elem.offsetHeight &lt;= 0 ||
-    (!jQuery.support.reliableHiddenOffsets &amp;&amp; ((elem.style &amp;&amp; elem.style.display) || jQuery.css( elem, &quot;display&quot; )) === &quot;none&quot;);
-    };
</del><span class="cx"> 
</span><del>-    jQuery.expr.filters.visible = function( elem ) {
-    return !jQuery.expr.filters.hidden( elem );
-    };
-}
</del><span class="cx"> 
</span><del>-// These hooks are used by animate to expand properties
-jQuery.each({
-    margin: &quot;&quot;,
-    padding: &quot;&quot;,
-    border: &quot;Width&quot;
-}, function( prefix, suffix ) {
-    jQuery.cssHooks[ prefix + suffix ] = {
-    expand: function( value ) {
-    var i = 0,
-    expanded = {},
</del><span class="cx"> 
</span><del>-    // assumes a single number if not a string
-    parts = typeof value === &quot;string&quot; ? value.split(&quot; &quot;) : [ value ];
</del><ins>+// Return jQuery for attributes-only inclusion
</ins><span class="cx"> 
</span><del>-    for ( ; i &lt; 4; i++ ) {
-    expanded[ prefix + cssExpand[ i ] + suffix ] =
-    parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
-    }
</del><span class="cx"> 
</span><del>-    return expanded;
-    }
-    };
</del><ins>+jQuery.each( (&quot;blur focus focusin focusout load resize scroll unload click dblclick &quot; +
+    &quot;mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave &quot; +
+    &quot;change select submit keydown keypress keyup error contextmenu&quot;).split(&quot; &quot;), function( i, name ) {
</ins><span class="cx"> 
</span><del>-    if ( !rmargin.test( prefix ) ) {
-    jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
-    }
</del><ins>+    // Handle event binding
+    jQuery.fn[ name ] = function( data, fn ) {
+        return arguments.length &gt; 0 ?
+            this.on( name, null, data, fn ) :
+            this.trigger( name );
+    };
</ins><span class="cx"> });
</span><del>-var r20 = /%20/g,
-    rbracket = /\[\]$/,
-    rCRLF = /\r?\n/g,
-    rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
-    rsubmittable = /^(?:input|select|textarea|keygen)/i;
</del><span class="cx"> 
</span><span class="cx"> jQuery.fn.extend({
</span><del>-    serialize: function() {
-    return jQuery.param( this.serializeArray() );
</del><ins>+    hover: function( fnOver, fnOut ) {
+        return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
</ins><span class="cx">     },
</span><del>-    serializeArray: function() {
-    return this.map(function(){
-    // Can add propHook for &quot;elements&quot; to filter or add form elements
-    var elements = jQuery.prop( this, &quot;elements&quot; );
-    return elements ? jQuery.makeArray( elements ) : this;
-    })
-    .filter(function(){
-    var type = this.type;
-    // Use .is(&quot;:disabled&quot;) so that fieldset[disabled] works
-    return this.name &amp;&amp; !jQuery( this ).is( &quot;:disabled&quot; ) &amp;&amp;
-    rsubmittable.test( this.nodeName ) &amp;&amp; !rsubmitterTypes.test( type ) &amp;&amp;
-    ( this.checked || !manipulation_rcheckableType.test( type ) );
-    })
-    .map(function( i, elem ){
-    var val = jQuery( this ).val();
</del><span class="cx"> 
</span><del>-    return val == null ?
-    null :
-    jQuery.isArray( val ) ?
-    jQuery.map( val, function( val ){
-    return { name: elem.name, value: val.replace( rCRLF, &quot;\r\n&quot; ) };
-    }) :
-    { name: elem.name, value: val.replace( rCRLF, &quot;\r\n&quot; ) };
-    }).get();
</del><ins>+    bind: function( types, data, fn ) {
+        return this.on( types, null, data, fn );
+    },
+    unbind: function( types, fn ) {
+        return this.off( types, null, fn );
+    },
+
+    delegate: function( selector, types, data, fn ) {
+        return this.on( types, selector, data, fn );
+    },
+    undelegate: function( selector, types, fn ) {
+        // ( namespace ) or ( selector, types [, fn] )
+        return arguments.length === 1 ? this.off( selector, &quot;**&quot; ) : this.off( types, selector || &quot;**&quot;, fn );
</ins><span class="cx">     }
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-//Serialize an array of form elements or a set of
-//key/values into a query string
-jQuery.param = function( a, traditional ) {
-    var prefix,
-    s = [],
-    add = function( key, value ) {
-    // If value is a function, invoke it and return its value
-    value = jQuery.isFunction( value ) ? value() : ( value == null ? &quot;&quot; : value );
-    s[ s.length ] = encodeURIComponent( key ) + &quot;=&quot; + encodeURIComponent( value );
-    };
</del><span class="cx"> 
</span><del>-    // Set traditional to true for jQuery &lt;= 1.3.2 behavior.
-    if ( traditional === undefined ) {
-    traditional = jQuery.ajaxSettings &amp;&amp; jQuery.ajaxSettings.traditional;
-    }
</del><ins>+var nonce = jQuery.now();
</ins><span class="cx"> 
</span><del>-    // If an array was passed in, assume that it is an array of form elements.
-    if ( jQuery.isArray( a ) || ( a.jquery &amp;&amp; !jQuery.isPlainObject( a ) ) ) {
-    // Serialize the form elements
-    jQuery.each( a, function() {
-    add( this.name, this.value );
-    });
</del><ins>+var rquery = (/\?/);
</ins><span class="cx"> 
</span><del>-    } else {
-    // If traditional, encode the &quot;old&quot; way (the way 1.3.2 or older
-    // did it), otherwise encode params recursively.
-    for ( prefix in a ) {
-    buildParams( prefix, a[ prefix ], traditional, add );
-    }
-    }
</del><span class="cx"> 
</span><del>-    // Return the resulting serialization
-    return s.join( &quot;&amp;&quot; ).replace( r20, &quot;+&quot; );
</del><ins>+
+// Support: Android 2.3
+// Workaround failure to string-cast null input
+jQuery.parseJSON = function( data ) {
+    return JSON.parse( data + &quot;&quot; );
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-function buildParams( prefix, obj, traditional, add ) {
-    var name;
</del><span class="cx"> 
</span><del>-    if ( jQuery.isArray( obj ) ) {
-    // Serialize array item.
-    jQuery.each( obj, function( i, v ) {
-    if ( traditional || rbracket.test( prefix ) ) {
-    // Treat each array item as a scalar.
-    add( prefix, v );
-
-    } else {
-    // Item is non-scalar (array or object), encode its numeric index.
-    buildParams( prefix + &quot;[&quot; + ( typeof v === &quot;object&quot; ? i : &quot;&quot; ) + &quot;]&quot;, v, traditional, add );
</del><ins>+// Cross-browser xml parsing
+jQuery.parseXML = function( data ) {
+    var xml, tmp;
+    if ( !data || typeof data !== &quot;string&quot; ) {
+        return null;
</ins><span class="cx">     }
</span><del>-    });
</del><span class="cx"> 
</span><del>-    } else if ( !traditional &amp;&amp; jQuery.type( obj ) === &quot;object&quot; ) {
-    // Serialize object item.
-    for ( name in obj ) {
-    buildParams( prefix + &quot;[&quot; + name + &quot;]&quot;, obj[ name ], traditional, add );
</del><ins>+    // Support: IE9
+    try {
+        tmp = new DOMParser();
+        xml = tmp.parseFromString( data, &quot;text/xml&quot; );
+    } catch ( e ) {
+        xml = undefined;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    } else {
-    // Serialize scalar item.
-    add( prefix, obj );
</del><ins>+    if ( !xml || xml.getElementsByTagName( &quot;parsererror&quot; ).length ) {
+        jQuery.error( &quot;Invalid XML: &quot; + data );
</ins><span class="cx">     }
</span><del>-}
-jQuery.each( (&quot;blur focus focusin focusout load resize scroll unload click dblclick &quot; +
-    &quot;mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave &quot; +
-    &quot;change select submit keydown keypress keyup error contextmenu&quot;).split(&quot; &quot;), function( i, name ) {
</del><ins>+    return xml;
+};
</ins><span class="cx"> 
</span><del>-    // Handle event binding
-    jQuery.fn[ name ] = function( data, fn ) {
-    return arguments.length &gt; 0 ?
-    this.on( name, null, data, fn ) :
-    this.trigger( name );
-    };
-});
</del><span class="cx"> 
</span><del>-jQuery.fn.hover = function( fnOver, fnOut ) {
-    return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
-};
</del><span class="cx"> var
</span><span class="cx">     // Document location
</span><span class="cx">     ajaxLocParts,
</span><span class="cx">     ajaxLocation,
</span><del>-    ajax_nonce = jQuery.now(),
</del><span class="cx"> 
</span><del>-    ajax_rquery = /\?/,
</del><span class="cx">     rhash = /#.*$/,
</span><span class="cx">     rts = /([?&amp;])_=[^&amp;]*/,
</span><del>-    rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
</del><ins>+    rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
</ins><span class="cx">     // #7653, #8125, #8152: local protocol detection
</span><span class="cx">     rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
</span><span class="cx">     rnoContent = /^(?:GET|HEAD)$/,
</span><span class="cx">     rprotocol = /^\/\//,
</span><del>-    rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
</del><ins>+    rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
</ins><span class="cx"> 
</span><del>-    // Keep a copy of the old load method
-    _load = jQuery.fn.load,
-
</del><span class="cx">     /* Prefilters
</span><span class="cx">      * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
</span><span class="cx">      * 2) These are called:
</span><span class="lines">@@ -7468,29 +7507,29 @@
</span><span class="cx">     // dataTypeExpression is optional and defaults to &quot;*&quot;
</span><span class="cx">     return function( dataTypeExpression, func ) {
</span><span class="cx"> 
</span><del>-    if ( typeof dataTypeExpression !== &quot;string&quot; ) {
-    func = dataTypeExpression;
-    dataTypeExpression = &quot;*&quot;;
-    }
</del><ins>+        if ( typeof dataTypeExpression !== &quot;string&quot; ) {
+            func = dataTypeExpression;
+            dataTypeExpression = &quot;*&quot;;
+        }
</ins><span class="cx"> 
</span><del>-    var dataType,
-    i = 0,
-    dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || [];
</del><ins>+        var dataType,
+            i = 0,
+            dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
</ins><span class="cx"> 
</span><del>-    if ( jQuery.isFunction( func ) ) {
-    // For each dataType in the dataTypeExpression
-    while ( (dataType = dataTypes[i++]) ) {
-    // Prepend if requested
-    if ( dataType[0] === &quot;+&quot; ) {
-    dataType = dataType.slice( 1 ) || &quot;*&quot;;
-    (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
</del><ins>+        if ( jQuery.isFunction( func ) ) {
+            // For each dataType in the dataTypeExpression
+            while ( (dataType = dataTypes[i++]) ) {
+                // Prepend if requested
+                if ( dataType[0] === &quot;+&quot; ) {
+                    dataType = dataType.slice( 1 ) || &quot;*&quot;;
+                    (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
</ins><span class="cx"> 
</span><del>-    // Otherwise append
-    } else {
-    (structure[ dataType ] = structure[ dataType ] || []).push( func );
-    }
-    }
-    }
</del><ins>+                // Otherwise append
+                } else {
+                    (structure[ dataType ] = structure[ dataType ] || []).push( func );
+                }
+            }
+        }
</ins><span class="cx">     };
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -7498,23 +7537,23 @@
</span><span class="cx"> function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
</span><span class="cx"> 
</span><span class="cx">     var inspected = {},
</span><del>-    seekingTransport = ( structure === transports );
</del><ins>+        seekingTransport = ( structure === transports );
</ins><span class="cx"> 
</span><span class="cx">     function inspect( dataType ) {
</span><del>-    var selected;
-    inspected[ dataType ] = true;
-    jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
-    var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
-    if( typeof dataTypeOrTransport === &quot;string&quot; &amp;&amp; !seekingTransport &amp;&amp; !inspected[ dataTypeOrTransport ] ) {
-    options.dataTypes.unshift( dataTypeOrTransport );
-    inspect( dataTypeOrTransport );
-    return false;
-    } else if ( seekingTransport ) {
-    return !( selected = dataTypeOrTransport );
</del><ins>+        var selected;
+        inspected[ dataType ] = true;
+        jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
+            var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
+            if ( typeof dataTypeOrTransport === &quot;string&quot; &amp;&amp; !seekingTransport &amp;&amp; !inspected[ dataTypeOrTransport ] ) {
+                options.dataTypes.unshift( dataTypeOrTransport );
+                inspect( dataTypeOrTransport );
+                return false;
+            } else if ( seekingTransport ) {
+                return !( selected = dataTypeOrTransport );
+            }
+        });
+        return selected;
</ins><span class="cx">     }
</span><del>-    });
-    return selected;
-    }
</del><span class="cx"> 
</span><span class="cx">     return inspect( options.dataTypes[ 0 ] ) || !inspected[ &quot;*&quot; ] &amp;&amp; inspect( &quot;*&quot; );
</span><span class="cx"> }
</span><span class="lines">@@ -7523,103 +7562,171 @@
</span><span class="cx"> // that takes &quot;flat&quot; options (not to be deep extended)
</span><span class="cx"> // Fixes #9887
</span><span class="cx"> function ajaxExtend( target, src ) {
</span><del>-    var deep, key,
-    flatOptions = jQuery.ajaxSettings.flatOptions || {};
</del><ins>+    var key, deep,
+        flatOptions = jQuery.ajaxSettings.flatOptions || {};
</ins><span class="cx"> 
</span><span class="cx">     for ( key in src ) {
</span><del>-    if ( src[ key ] !== undefined ) {
-    ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
</del><ins>+        if ( src[ key ] !== undefined ) {
+            ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
+        }
</ins><span class="cx">     }
</span><del>-    }
</del><span class="cx">     if ( deep ) {
</span><del>-    jQuery.extend( true, target, deep );
</del><ins>+        jQuery.extend( true, target, deep );
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return target;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-jQuery.fn.load = function( url, params, callback ) {
-    if ( typeof url !== &quot;string&quot; &amp;&amp; _load ) {
-    return _load.apply( this, arguments );
</del><ins>+/* Handles responses to an ajax request:
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+
+    var ct, type, finalDataType, firstDataType,
+        contents = s.contents,
+        dataTypes = s.dataTypes;
+
+    // Remove auto dataType and get content-type in the process
+    while ( dataTypes[ 0 ] === &quot;*&quot; ) {
+        dataTypes.shift();
+        if ( ct === undefined ) {
+            ct = s.mimeType || jqXHR.getResponseHeader(&quot;Content-Type&quot;);
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    var selector, response, type,
-    self = this,
-    off = url.indexOf(&quot; &quot;);
</del><ins>+    // Check if we're dealing with a known content-type
+    if ( ct ) {
+        for ( type in contents ) {
+            if ( contents[ type ] &amp;&amp; contents[ type ].test( ct ) ) {
+                dataTypes.unshift( type );
+                break;
+            }
+        }
+    }
</ins><span class="cx"> 
</span><del>-    if ( off &gt;= 0 ) {
-    selector = url.slice( off, url.length );
-    url = url.slice( 0, off );
</del><ins>+    // Check to see if we have a response for the expected dataType
+    if ( dataTypes[ 0 ] in responses ) {
+        finalDataType = dataTypes[ 0 ];
+    } else {
+        // Try convertible dataTypes
+        for ( type in responses ) {
+            if ( !dataTypes[ 0 ] || s.converters[ type + &quot; &quot; + dataTypes[0] ] ) {
+                finalDataType = type;
+                break;
+            }
+            if ( !firstDataType ) {
+                firstDataType = type;
+            }
+        }
+        // Or just use first one
+        finalDataType = finalDataType || firstDataType;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // If it's a function
-    if ( jQuery.isFunction( params ) ) {
</del><ins>+    // If we found a dataType
+    // We add the dataType to the list if needed
+    // and return the corresponding response
+    if ( finalDataType ) {
+        if ( finalDataType !== dataTypes[ 0 ] ) {
+            dataTypes.unshift( finalDataType );
+        }
+        return responses[ finalDataType ];
+    }
+}
</ins><span class="cx"> 
</span><del>-    // We assume that it's the callback
-    callback = params;
-    params = undefined;
</del><ins>+/* Chain conversions given the request and the original response
+ * Also sets the responseXXX fields on the jqXHR instance
+ */
+function ajaxConvert( s, response, jqXHR, isSuccess ) {
+    var conv2, current, conv, tmp, prev,
+        converters = {},
+        // Work with a copy of dataTypes in case we need to modify it for conversion
+        dataTypes = s.dataTypes.slice();
</ins><span class="cx"> 
</span><del>-    // Otherwise, build a param string
-    } else if ( params &amp;&amp; typeof params === &quot;object&quot; ) {
-    type = &quot;POST&quot;;
</del><ins>+    // Create converters map with lowercased keys
+    if ( dataTypes[ 1 ] ) {
+        for ( conv in s.converters ) {
+            converters[ conv.toLowerCase() ] = s.converters[ conv ];
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // If we have elements to modify, make the request
-    if ( self.length &gt; 0 ) {
-    jQuery.ajax({
-    url: url,
</del><ins>+    current = dataTypes.shift();
</ins><span class="cx"> 
</span><del>-    // if &quot;type&quot; variable is undefined, then &quot;GET&quot; method will be used
-    type: type,
-    dataType: &quot;html&quot;,
-    data: params
-    }).done(function( responseText ) {
</del><ins>+    // Convert to each sequential dataType
+    while ( current ) {
</ins><span class="cx"> 
</span><del>-    // Save response for use in complete callback
-    response = arguments;
</del><ins>+        if ( s.responseFields[ current ] ) {
+            jqXHR[ s.responseFields[ current ] ] = response;
+        }
</ins><span class="cx"> 
</span><del>-    self.html( selector ?
</del><ins>+        // Apply the dataFilter if provided
+        if ( !prev &amp;&amp; isSuccess &amp;&amp; s.dataFilter ) {
+            response = s.dataFilter( response, s.dataType );
+        }
</ins><span class="cx"> 
</span><del>-    // If a selector was specified, locate the right elements in a dummy div
-    // Exclude scripts to avoid IE 'Permission Denied' errors
-    jQuery(&quot;&lt;div&gt;&quot;).append( jQuery.parseHTML( responseText ) ).find( selector ) :
</del><ins>+        prev = current;
+        current = dataTypes.shift();
</ins><span class="cx"> 
</span><del>-    // Otherwise use the full result
-    responseText );
</del><ins>+        if ( current ) {
</ins><span class="cx"> 
</span><del>-    }).complete( callback &amp;&amp; function( jqXHR, status ) {
-    self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
-    });
-    }
</del><ins>+        // There's only work to do if current dataType is non-auto
+            if ( current === &quot;*&quot; ) {
</ins><span class="cx"> 
</span><del>-    return this;
-};
</del><ins>+                current = prev;
</ins><span class="cx"> 
</span><del>-// Attach a bunch of functions for handling common AJAX events
-jQuery.each( [ &quot;ajaxStart&quot;, &quot;ajaxStop&quot;, &quot;ajaxComplete&quot;, &quot;ajaxError&quot;, &quot;ajaxSuccess&quot;, &quot;ajaxSend&quot; ], function( i, type ){
-    jQuery.fn[ type ] = function( fn ){
-    return this.on( type, fn );
-    };
-});
</del><ins>+            // Convert response if prev dataType is non-auto and differs from current
+            } else if ( prev !== &quot;*&quot; &amp;&amp; prev !== current ) {
</ins><span class="cx"> 
</span><del>-jQuery.each( [ &quot;get&quot;, &quot;post&quot; ], function( i, method ) {
-    jQuery[ method ] = function( url, data, callback, type ) {
-    // shift arguments if data argument was omitted
-    if ( jQuery.isFunction( data ) ) {
-    type = type || callback;
-    callback = data;
-    data = undefined;
</del><ins>+                // Seek a direct converter
+                conv = converters[ prev + &quot; &quot; + current ] || converters[ &quot;* &quot; + current ];
+
+                // If none found, seek a pair
+                if ( !conv ) {
+                    for ( conv2 in converters ) {
+
+                        // If conv2 outputs current
+                        tmp = conv2.split( &quot; &quot; );
+                        if ( tmp[ 1 ] === current ) {
+
+                            // If prev can be converted to accepted input
+                            conv = converters[ prev + &quot; &quot; + tmp[ 0 ] ] ||
+                                converters[ &quot;* &quot; + tmp[ 0 ] ];
+                            if ( conv ) {
+                                // Condense equivalence converters
+                                if ( conv === true ) {
+                                    conv = converters[ conv2 ];
+
+                                // Otherwise, insert the intermediate dataType
+                                } else if ( converters[ conv2 ] !== true ) {
+                                    current = tmp[ 0 ];
+                                    dataTypes.unshift( tmp[ 1 ] );
+                                }
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                // Apply converter (if not an equivalence)
+                if ( conv !== true ) {
+
+                    // Unless errors are allowed to bubble, catch and return them
+                    if ( conv &amp;&amp; s[ &quot;throws&quot; ] ) {
+                        response = conv( response );
+                    } else {
+                        try {
+                            response = conv( response );
+                        } catch ( e ) {
+                            return { state: &quot;parsererror&quot;, error: conv ? e : &quot;No conversion from &quot; + prev + &quot; to &quot; + current };
+                        }
+                    }
+                }
+            }
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return jQuery.ajax({
-    url: url,
-    type: method,
-    dataType: type,
-    data: data,
-    success: callback
-    });
-    };
-});
</del><ins>+    return { state: &quot;success&quot;, data: response };
+}
</ins><span class="cx"> 
</span><span class="cx"> jQuery.extend({
</span><span class="cx"> 
</span><span class="lines">@@ -7631,82 +7738,83 @@
</span><span class="cx">     etag: {},
</span><span class="cx"> 
</span><span class="cx">     ajaxSettings: {
</span><del>-    url: ajaxLocation,
-    type: &quot;GET&quot;,
-    isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
-    global: true,
-    processData: true,
-    async: true,
-    contentType: &quot;application/x-www-form-urlencoded; charset=UTF-8&quot;,
-    /*
-    timeout: 0,
-    data: null,
-    dataType: null,
-    username: null,
-    password: null,
-    cache: null,
-    throws: false,
-    traditional: false,
-    headers: {},
-    */
</del><ins>+        url: ajaxLocation,
+        type: &quot;GET&quot;,
+        isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+        global: true,
+        processData: true,
+        async: true,
+        contentType: &quot;application/x-www-form-urlencoded; charset=UTF-8&quot;,
+        /*
+        timeout: 0,
+        data: null,
+        dataType: null,
+        username: null,
+        password: null,
+        cache: null,
+        throws: false,
+        traditional: false,
+        headers: {},
+        */
</ins><span class="cx"> 
</span><del>-    accepts: {
-    &quot;*&quot;: allTypes,
-    text: &quot;text/plain&quot;,
-    html: &quot;text/html&quot;,
-    xml: &quot;application/xml, text/xml&quot;,
-    json: &quot;application/json, text/javascript&quot;
-    },
</del><ins>+        accepts: {
+            &quot;*&quot;: allTypes,
+            text: &quot;text/plain&quot;,
+            html: &quot;text/html&quot;,
+            xml: &quot;application/xml, text/xml&quot;,
+            json: &quot;application/json, text/javascript&quot;
+        },
</ins><span class="cx"> 
</span><del>-    contents: {
-    xml: /xml/,
-    html: /html/,
-    json: /json/
-    },
</del><ins>+        contents: {
+            xml: /xml/,
+            html: /html/,
+            json: /json/
+        },
</ins><span class="cx"> 
</span><del>-    responseFields: {
-    xml: &quot;responseXML&quot;,
-    text: &quot;responseText&quot;
-    },
</del><ins>+        responseFields: {
+            xml: &quot;responseXML&quot;,
+            text: &quot;responseText&quot;,
+            json: &quot;responseJSON&quot;
+        },
</ins><span class="cx"> 
</span><del>-    // Data converters
-    // Keys separate source (or catchall &quot;*&quot;) and destination types with a single space
-    converters: {
</del><ins>+        // Data converters
+        // Keys separate source (or catchall &quot;*&quot;) and destination types with a single space
+        converters: {
</ins><span class="cx"> 
</span><del>-    // Convert anything to text
-    &quot;* text&quot;: window.String,
</del><ins>+            // Convert anything to text
+            &quot;* text&quot;: String,
</ins><span class="cx"> 
</span><del>-    // Text to html (true = no transformation)
-    &quot;text html&quot;: true,
</del><ins>+            // Text to html (true = no transformation)
+            &quot;text html&quot;: true,
</ins><span class="cx"> 
</span><del>-    // Evaluate text as a json expression
-    &quot;text json&quot;: jQuery.parseJSON,
</del><ins>+            // Evaluate text as a json expression
+            &quot;text json&quot;: jQuery.parseJSON,
</ins><span class="cx"> 
</span><del>-    // Parse text as xml
-    &quot;text xml&quot;: jQuery.parseXML
-    },
</del><ins>+            // Parse text as xml
+            &quot;text xml&quot;: jQuery.parseXML
+        },
</ins><span class="cx"> 
</span><del>-    // For options that shouldn't be deep extended:
-    // you can add your own custom options here if
-    // and when you create one that shouldn't be
-    // deep extended (see ajaxExtend)
-    flatOptions: {
-    url: true,
-    context: true
-    }
</del><ins>+        // For options that shouldn't be deep extended:
+        // you can add your own custom options here if
+        // and when you create one that shouldn't be
+        // deep extended (see ajaxExtend)
+        flatOptions: {
+            url: true,
+            context: true
+        }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // Creates a full fledged settings object into target
</span><span class="cx">     // with both ajaxSettings and settings fields.
</span><span class="cx">     // If target is omitted, writes into ajaxSettings.
</span><span class="cx">     ajaxSetup: function( target, settings ) {
</span><del>-    return settings ?
</del><ins>+        return settings ?
</ins><span class="cx"> 
</span><del>-    // Building a settings object
-    ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
</del><ins>+            // Building a settings object
+            ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
</ins><span class="cx"> 
</span><del>-    // Extending ajaxSettings
-    ajaxExtend( jQuery.ajaxSettings, target );
</del><ins>+            // Extending ajaxSettings
+            ajaxExtend( jQuery.ajaxSettings, target );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
</span><span class="lines">@@ -7715,1883 +7823,1289 @@
</span><span class="cx">     // Main method
</span><span class="cx">     ajax: function( url, options ) {
</span><span class="cx"> 
</span><del>-    // If url is an object, simulate pre-1.5 signature
-    if ( typeof url === &quot;object&quot; ) {
-    options = url;
-    url = undefined;
-    }
</del><ins>+        // If url is an object, simulate pre-1.5 signature
+        if ( typeof url === &quot;object&quot; ) {
+            options = url;
+            url = undefined;
+        }
</ins><span class="cx"> 
</span><del>-    // Force options to be an object
-    options = options || {};
</del><ins>+        // Force options to be an object
+        options = options || {};
</ins><span class="cx"> 
</span><del>-    var // Cross-domain detection vars
-    parts,
-    // Loop variable
-    i,
-    // URL without anti-cache param
-    cacheURL,
-    // Response headers as string
-    responseHeadersString,
-    // timeout handle
-    timeoutTimer,
</del><ins>+        var transport,
+            // URL without anti-cache param
+            cacheURL,
+            // Response headers
+            responseHeadersString,
+            responseHeaders,
+            // timeout handle
+            timeoutTimer,
+            // Cross-domain detection vars
+            parts,
+            // To know if global events are to be dispatched
+            fireGlobals,
+            // Loop variable
+            i,
+            // Create the final options object
+            s = jQuery.ajaxSetup( {}, options ),
+            // Callbacks context
+            callbackContext = s.context || s,
+            // Context for global events is callbackContext if it is a DOM node or jQuery collection
+            globalEventContext = s.context &amp;&amp; ( callbackContext.nodeType || callbackContext.jquery ) ?
+                jQuery( callbackContext ) :
+                jQuery.event,
+            // Deferreds
+            deferred = jQuery.Deferred(),
+            completeDeferred = jQuery.Callbacks(&quot;once memory&quot;),
+            // Status-dependent callbacks
+            statusCode = s.statusCode || {},
+            // Headers (they are sent all at once)
+            requestHeaders = {},
+            requestHeadersNames = {},
+            // The jqXHR state
+            state = 0,
+            // Default abort message
+            strAbort = &quot;canceled&quot;,
+            // Fake xhr
+            jqXHR = {
+                readyState: 0,
</ins><span class="cx"> 
</span><del>-    // To know if global events are to be dispatched
-    fireGlobals,
</del><ins>+                // Builds headers hashtable if needed
+                getResponseHeader: function( key ) {
+                    var match;
+                    if ( state === 2 ) {
+                        if ( !responseHeaders ) {
+                            responseHeaders = {};
+                            while ( (match = rheaders.exec( responseHeadersString )) ) {
+                                responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+                            }
+                        }
+                        match = responseHeaders[ key.toLowerCase() ];
+                    }
+                    return match == null ? null : match;
+                },
</ins><span class="cx"> 
</span><del>-    transport,
-    // Response headers
-    responseHeaders,
-    // Create the final options object
-    s = jQuery.ajaxSetup( {}, options ),
-    // Callbacks context
-    callbackContext = s.context || s,
-    // Context for global events is callbackContext if it is a DOM node or jQuery collection
-    globalEventContext = s.context &amp;&amp; ( callbackContext.nodeType || callbackContext.jquery ) ?
-    jQuery( callbackContext ) :
-    jQuery.event,
-    // Deferreds
-    deferred = jQuery.Deferred(),
-    completeDeferred = jQuery.Callbacks(&quot;once memory&quot;),
-    // Status-dependent callbacks
-    statusCode = s.statusCode || {},
-    // Headers (they are sent all at once)
-    requestHeaders = {},
-    requestHeadersNames = {},
-    // The jqXHR state
-    state = 0,
-    // Default abort message
-    strAbort = &quot;canceled&quot;,
-    // Fake xhr
-    jqXHR = {
-    readyState: 0,
</del><ins>+                // Raw string
+                getAllResponseHeaders: function() {
+                    return state === 2 ? responseHeadersString : null;
+                },
</ins><span class="cx"> 
</span><del>-    // Builds headers hashtable if needed
-    getResponseHeader: function( key ) {
-    var match;
-    if ( state === 2 ) {
-    if ( !responseHeaders ) {
-    responseHeaders = {};
-    while ( (match = rheaders.exec( responseHeadersString )) ) {
-    responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
-    }
-    }
-    match = responseHeaders[ key.toLowerCase() ];
-    }
-    return match == null ? null : match;
-    },
</del><ins>+                // Caches the header
+                setRequestHeader: function( name, value ) {
+                    var lname = name.toLowerCase();
+                    if ( !state ) {
+                        name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+                        requestHeaders[ name ] = value;
+                    }
+                    return this;
+                },
</ins><span class="cx"> 
</span><del>-    // Raw string
-    getAllResponseHeaders: function() {
-    return state === 2 ? responseHeadersString : null;
-    },
</del><ins>+                // Overrides response content-type header
+                overrideMimeType: function( type ) {
+                    if ( !state ) {
+                        s.mimeType = type;
+                    }
+                    return this;
+                },
</ins><span class="cx"> 
</span><del>-    // Caches the header
-    setRequestHeader: function( name, value ) {
-    var lname = name.toLowerCase();
-    if ( !state ) {
-    name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
-    requestHeaders[ name ] = value;
-    }
-    return this;
-    },
</del><ins>+                // Status-dependent callbacks
+                statusCode: function( map ) {
+                    var code;
+                    if ( map ) {
+                        if ( state &lt; 2 ) {
+                            for ( code in map ) {
+                                // Lazy-add the new callback in a way that preserves old ones
+                                statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
+                            }
+                        } else {
+                            // Execute the appropriate callbacks
+                            jqXHR.always( map[ jqXHR.status ] );
+                        }
+                    }
+                    return this;
+                },
</ins><span class="cx"> 
</span><del>-    // Overrides response content-type header
-    overrideMimeType: function( type ) {
-    if ( !state ) {
-    s.mimeType = type;
-    }
-    return this;
-    },
</del><ins>+                // Cancel the request
+                abort: function( statusText ) {
+                    var finalText = statusText || strAbort;
+                    if ( transport ) {
+                        transport.abort( finalText );
+                    }
+                    done( 0, finalText );
+                    return this;
+                }
+            };
</ins><span class="cx"> 
</span><del>-    // Status-dependent callbacks
-    statusCode: function( map ) {
-    var code;
-    if ( map ) {
-    if ( state &lt; 2 ) {
-    for ( code in map ) {
-    // Lazy-add the new callback in a way that preserves old ones
-    statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
-    }
-    } else {
-    // Execute the appropriate callbacks
-    jqXHR.always( map[ jqXHR.status ] );
-    }
-    }
-    return this;
-    },
</del><ins>+        // Attach deferreds
+        deferred.promise( jqXHR ).complete = completeDeferred.add;
+        jqXHR.success = jqXHR.done;
+        jqXHR.error = jqXHR.fail;
</ins><span class="cx"> 
</span><del>-    // Cancel the request
-    abort: function( statusText ) {
-    var finalText = statusText || strAbort;
-    if ( transport ) {
-    transport.abort( finalText );
-    }
-    done( 0, finalText );
-    return this;
-    }
-    };
</del><ins>+        // Remove hash character (#7531: and string promotion)
+        // Add protocol if not provided (prefilters might expect it)
+        // Handle falsy url in the settings object (#10093: consistency with old signature)
+        // We also use the url parameter if available
+        s.url = ( ( url || s.url || ajaxLocation ) + &quot;&quot; ).replace( rhash, &quot;&quot; )
+            .replace( rprotocol, ajaxLocParts[ 1 ] + &quot;//&quot; );
</ins><span class="cx"> 
</span><del>-    // Attach deferreds
-    deferred.promise( jqXHR ).complete = completeDeferred.add;
-    jqXHR.success = jqXHR.done;
-    jqXHR.error = jqXHR.fail;
</del><ins>+        // Alias method option to type as per ticket #12004
+        s.type = options.method || options.type || s.method || s.type;
</ins><span class="cx"> 
</span><del>-    // Remove hash character (#7531: and string promotion)
-    // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
-    // Handle falsy url in the settings object (#10093: consistency with old signature)
-    // We also use the url parameter if available
-    s.url = ( ( url || s.url || ajaxLocation ) + &quot;&quot; ).replace( rhash, &quot;&quot; ).replace( rprotocol, ajaxLocParts[ 1 ] + &quot;//&quot; );
</del><ins>+        // Extract dataTypes list
+        s.dataTypes = jQuery.trim( s.dataType || &quot;*&quot; ).toLowerCase().match( rnotwhite ) || [ &quot;&quot; ];
</ins><span class="cx"> 
</span><del>-    // Alias method option to type as per ticket #12004
-    s.type = options.method || options.type || s.method || s.type;
</del><ins>+        // A cross-domain request is in order when we have a protocol:host:port mismatch
+        if ( s.crossDomain == null ) {
+            parts = rurl.exec( s.url.toLowerCase() );
+            s.crossDomain = !!( parts &amp;&amp;
+                ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
+                    ( parts[ 3 ] || ( parts[ 1 ] === &quot;http:&quot; ? &quot;80&quot; : &quot;443&quot; ) ) !==
+                        ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === &quot;http:&quot; ? &quot;80&quot; : &quot;443&quot; ) ) )
+            );
+        }
</ins><span class="cx"> 
</span><del>-    // Extract dataTypes list
-    s.dataTypes = jQuery.trim( s.dataType || &quot;*&quot; ).toLowerCase().match( core_rnotwhite ) || [&quot;&quot;];
</del><ins>+        // Convert data if not already a string
+        if ( s.data &amp;&amp; s.processData &amp;&amp; typeof s.data !== &quot;string&quot; ) {
+            s.data = jQuery.param( s.data, s.traditional );
+        }
</ins><span class="cx"> 
</span><del>-    // A cross-domain request is in order when we have a protocol:host:port mismatch
-    if ( s.crossDomain == null ) {
-    parts = rurl.exec( s.url.toLowerCase() );
-    s.crossDomain = !!( parts &amp;&amp;
-    ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
-    ( parts[ 3 ] || ( parts[ 1 ] === &quot;http:&quot; ? 80 : 443 ) ) !=
-    ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === &quot;http:&quot; ? 80 : 443 ) ) )
-    );
-    }
</del><ins>+        // Apply prefilters
+        inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
</ins><span class="cx"> 
</span><del>-    // Convert data if not already a string
-    if ( s.data &amp;&amp; s.processData &amp;&amp; typeof s.data !== &quot;string&quot; ) {
-    s.data = jQuery.param( s.data, s.traditional );
-    }
</del><ins>+        // If request was aborted inside a prefilter, stop there
+        if ( state === 2 ) {
+            return jqXHR;
+        }
</ins><span class="cx"> 
</span><del>-    // Apply prefilters
-    inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
</del><ins>+        // We can fire global events as of now if asked to
+        fireGlobals = s.global;
</ins><span class="cx"> 
</span><del>-    // If request was aborted inside a prefilter, stop there
-    if ( state === 2 ) {
-    return jqXHR;
-    }
</del><ins>+        // Watch for a new set of requests
+        if ( fireGlobals &amp;&amp; jQuery.active++ === 0 ) {
+            jQuery.event.trigger(&quot;ajaxStart&quot;);
+        }
</ins><span class="cx"> 
</span><del>-    // We can fire global events as of now if asked to
-    fireGlobals = s.global;
</del><ins>+        // Uppercase the type
+        s.type = s.type.toUpperCase();
</ins><span class="cx"> 
</span><del>-    // Watch for a new set of requests
-    if ( fireGlobals &amp;&amp; jQuery.active++ === 0 ) {
-    jQuery.event.trigger(&quot;ajaxStart&quot;);
-    }
</del><ins>+        // Determine if request has content
+        s.hasContent = !rnoContent.test( s.type );
</ins><span class="cx"> 
</span><del>-    // Uppercase the type
-    s.type = s.type.toUpperCase();
</del><ins>+        // Save the URL in case we're toying with the If-Modified-Since
+        // and/or If-None-Match header later on
+        cacheURL = s.url;
</ins><span class="cx"> 
</span><del>-    // Determine if request has content
-    s.hasContent = !rnoContent.test( s.type );
</del><ins>+        // More options handling for requests with no content
+        if ( !s.hasContent ) {
</ins><span class="cx"> 
</span><del>-    // Save the URL in case we're toying with the If-Modified-Since
-    // and/or If-None-Match header later on
-    cacheURL = s.url;
</del><ins>+            // If data is available, append data to url
+            if ( s.data ) {
+                cacheURL = ( s.url += ( rquery.test( cacheURL ) ? &quot;&amp;&quot; : &quot;?&quot; ) + s.data );
+                // #9682: remove data so that it's not used in an eventual retry
+                delete s.data;
+            }
</ins><span class="cx"> 
</span><del>-    // More options handling for requests with no content
-    if ( !s.hasContent ) {
</del><ins>+            // Add anti-cache in url if needed
+            if ( s.cache === false ) {
+                s.url = rts.test( cacheURL ) ?
</ins><span class="cx"> 
</span><del>-    // If data is available, append data to url
-    if ( s.data ) {
-    cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? &quot;&amp;&quot; : &quot;?&quot; ) + s.data );
-    // #9682: remove data so that it's not used in an eventual retry
-    delete s.data;
-    }
</del><ins>+                    // If there is already a '_' parameter, set its value
+                    cacheURL.replace( rts, &quot;$1_=&quot; + nonce++ ) :
</ins><span class="cx"> 
</span><del>-    // Add anti-cache in url if needed
-    if ( s.cache === false ) {
-    s.url = rts.test( cacheURL ) ?
</del><ins>+                    // Otherwise add one to the end
+                    cacheURL + ( rquery.test( cacheURL ) ? &quot;&amp;&quot; : &quot;?&quot; ) + &quot;_=&quot; + nonce++;
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // If there is already a '_' parameter, set its value
-    cacheURL.replace( rts, &quot;$1_=&quot; + ajax_nonce++ ) :
</del><ins>+        // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+        if ( s.ifModified ) {
+            if ( jQuery.lastModified[ cacheURL ] ) {
+                jqXHR.setRequestHeader( &quot;If-Modified-Since&quot;, jQuery.lastModified[ cacheURL ] );
+            }
+            if ( jQuery.etag[ cacheURL ] ) {
+                jqXHR.setRequestHeader( &quot;If-None-Match&quot;, jQuery.etag[ cacheURL ] );
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // Otherwise add one to the end
-    cacheURL + ( ajax_rquery.test( cacheURL ) ? &quot;&amp;&quot; : &quot;?&quot; ) + &quot;_=&quot; + ajax_nonce++;
-    }
-    }
</del><ins>+        // Set the correct header, if data is being sent
+        if ( s.data &amp;&amp; s.hasContent &amp;&amp; s.contentType !== false || options.contentType ) {
+            jqXHR.setRequestHeader( &quot;Content-Type&quot;, s.contentType );
+        }
</ins><span class="cx"> 
</span><del>-    // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
-    if ( s.ifModified ) {
-    if ( jQuery.lastModified[ cacheURL ] ) {
-    jqXHR.setRequestHeader( &quot;If-Modified-Since&quot;, jQuery.lastModified[ cacheURL ] );
-    }
-    if ( jQuery.etag[ cacheURL ] ) {
-    jqXHR.setRequestHeader( &quot;If-None-Match&quot;, jQuery.etag[ cacheURL ] );
-    }
-    }
</del><ins>+        // Set the Accepts header for the server, depending on the dataType
+        jqXHR.setRequestHeader(
+            &quot;Accept&quot;,
+            s.dataTypes[ 0 ] &amp;&amp; s.accepts[ s.dataTypes[0] ] ?
+                s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== &quot;*&quot; ? &quot;, &quot; + allTypes + &quot;; q=0.01&quot; : &quot;&quot; ) :
+                s.accepts[ &quot;*&quot; ]
+        );
</ins><span class="cx"> 
</span><del>-    // Set the correct header, if data is being sent
-    if ( s.data &amp;&amp; s.hasContent &amp;&amp; s.contentType !== false || options.contentType ) {
-    jqXHR.setRequestHeader( &quot;Content-Type&quot;, s.contentType );
-    }
</del><ins>+        // Check for headers option
+        for ( i in s.headers ) {
+            jqXHR.setRequestHeader( i, s.headers[ i ] );
+        }
</ins><span class="cx"> 
</span><del>-    // Set the Accepts header for the server, depending on the dataType
-    jqXHR.setRequestHeader(
-    &quot;Accept&quot;,
-    s.dataTypes[ 0 ] &amp;&amp; s.accepts[ s.dataTypes[0] ] ?
-    s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== &quot;*&quot; ? &quot;, &quot; + allTypes + &quot;; q=0.01&quot; : &quot;&quot; ) :
-    s.accepts[ &quot;*&quot; ]
-    );
</del><ins>+        // Allow custom headers/mimetypes and early abort
+        if ( s.beforeSend &amp;&amp; ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+            // Abort if not done already and return
+            return jqXHR.abort();
+        }
</ins><span class="cx"> 
</span><del>-    // Check for headers option
-    for ( i in s.headers ) {
-    jqXHR.setRequestHeader( i, s.headers[ i ] );
-    }
</del><ins>+        // aborting is no longer a cancellation
+        strAbort = &quot;abort&quot;;
</ins><span class="cx"> 
</span><del>-    // Allow custom headers/mimetypes and early abort
-    if ( s.beforeSend &amp;&amp; ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
-    // Abort if not done already and return
-    return jqXHR.abort();
-    }
</del><ins>+        // Install callbacks on deferreds
+        for ( i in { success: 1, error: 1, complete: 1 } ) {
+            jqXHR[ i ]( s[ i ] );
+        }
</ins><span class="cx"> 
</span><del>-    // aborting is no longer a cancellation
-    strAbort = &quot;abort&quot;;
</del><ins>+        // Get transport
+        transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
</ins><span class="cx"> 
</span><del>-    // Install callbacks on deferreds
-    for ( i in { success: 1, error: 1, complete: 1 } ) {
-    jqXHR[ i ]( s[ i ] );
-    }
</del><ins>+        // If no transport, we auto-abort
+        if ( !transport ) {
+            done( -1, &quot;No Transport&quot; );
+        } else {
+            jqXHR.readyState = 1;
</ins><span class="cx"> 
</span><del>-    // Get transport
-    transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
</del><ins>+            // Send global event
+            if ( fireGlobals ) {
+                globalEventContext.trigger( &quot;ajaxSend&quot;, [ jqXHR, s ] );
+            }
+            // Timeout
+            if ( s.async &amp;&amp; s.timeout &gt; 0 ) {
+                timeoutTimer = setTimeout(function() {
+                    jqXHR.abort(&quot;timeout&quot;);
+                }, s.timeout );
+            }
</ins><span class="cx"> 
</span><del>-    // If no transport, we auto-abort
-    if ( !transport ) {
-    done( -1, &quot;No Transport&quot; );
-    } else {
-    jqXHR.readyState = 1;
</del><ins>+            try {
+                state = 1;
+                transport.send( requestHeaders, done );
+            } catch ( e ) {
+                // Propagate exception as error if not done
+                if ( state &lt; 2 ) {
+                    done( -1, e );
+                // Simply rethrow otherwise
+                } else {
+                    throw e;
+                }
+            }
+        }
</ins><span class="cx"> 
</span><del>-    // Send global event
-    if ( fireGlobals ) {
-    globalEventContext.trigger( &quot;ajaxSend&quot;, [ jqXHR, s ] );
-    }
-    // Timeout
-    if ( s.async &amp;&amp; s.timeout &gt; 0 ) {
-    timeoutTimer = setTimeout(function() {
-    jqXHR.abort(&quot;timeout&quot;);
-    }, s.timeout );
-    }
</del><ins>+        // Callback for when everything is done
+        function done( status, nativeStatusText, responses, headers ) {
+            var isSuccess, success, error, response, modified,
+                statusText = nativeStatusText;
</ins><span class="cx"> 
</span><del>-    try {
-    state = 1;
-    transport.send( requestHeaders, done );
-    } catch ( e ) {
-    // Propagate exception as error if not done
-    if ( state &lt; 2 ) {
-    done( -1, e );
-    // Simply rethrow otherwise
-    } else {
-    throw e;
-    }
-    }
-    }
</del><ins>+            // Called once
+            if ( state === 2 ) {
+                return;
+            }
</ins><span class="cx"> 
</span><del>-    // Callback for when everything is done
-    function done( status, nativeStatusText, responses, headers ) {
-    var isSuccess, success, error, response, modified,
-    statusText = nativeStatusText;
</del><ins>+            // State is &quot;done&quot; now
+            state = 2;
</ins><span class="cx"> 
</span><del>-    // Called once
-    if ( state === 2 ) {
-    return;
-    }
</del><ins>+            // Clear timeout if it exists
+            if ( timeoutTimer ) {
+                clearTimeout( timeoutTimer );
+            }
</ins><span class="cx"> 
</span><del>-    // State is &quot;done&quot; now
-    state = 2;
</del><ins>+            // Dereference transport for early garbage collection
+            // (no matter how long the jqXHR object will be used)
+            transport = undefined;
</ins><span class="cx"> 
</span><del>-    // Clear timeout if it exists
-    if ( timeoutTimer ) {
-    clearTimeout( timeoutTimer );
-    }
</del><ins>+            // Cache response headers
+            responseHeadersString = headers || &quot;&quot;;
</ins><span class="cx"> 
</span><del>-    // Dereference transport for early garbage collection
-    // (no matter how long the jqXHR object will be used)
-    transport = undefined;
</del><ins>+            // Set readyState
+            jqXHR.readyState = status &gt; 0 ? 4 : 0;
</ins><span class="cx"> 
</span><del>-    // Cache response headers
-    responseHeadersString = headers || &quot;&quot;;
</del><ins>+            // Determine if successful
+            isSuccess = status &gt;= 200 &amp;&amp; status &lt; 300 || status === 304;
</ins><span class="cx"> 
</span><del>-    // Set readyState
-    jqXHR.readyState = status &gt; 0 ? 4 : 0;
</del><ins>+            // Get response data
+            if ( responses ) {
+                response = ajaxHandleResponses( s, jqXHR, responses );
+            }
</ins><span class="cx"> 
</span><del>-    // Get response data
-    if ( responses ) {
-    response = ajaxHandleResponses( s, jqXHR, responses );
-    }
</del><ins>+            // Convert no matter what (that way responseXXX fields are always set)
+            response = ajaxConvert( s, response, jqXHR, isSuccess );
</ins><span class="cx"> 
</span><del>-    // If successful, handle type chaining
-    if ( status &gt;= 200 &amp;&amp; status &lt; 300 || status === 304 ) {
</del><ins>+            // If successful, handle type chaining
+            if ( isSuccess ) {
</ins><span class="cx"> 
</span><del>-    // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
-    if ( s.ifModified ) {
-    modified = jqXHR.getResponseHeader(&quot;Last-Modified&quot;);
-    if ( modified ) {
-    jQuery.lastModified[ cacheURL ] = modified;
-    }
-    modified = jqXHR.getResponseHeader(&quot;etag&quot;);
-    if ( modified ) {
-    jQuery.etag[ cacheURL ] = modified;
-    }
-    }
</del><ins>+                // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+                if ( s.ifModified ) {
+                    modified = jqXHR.getResponseHeader(&quot;Last-Modified&quot;);
+                    if ( modified ) {
+                        jQuery.lastModified[ cacheURL ] = modified;
+                    }
+                    modified = jqXHR.getResponseHeader(&quot;etag&quot;);
+                    if ( modified ) {
+                        jQuery.etag[ cacheURL ] = modified;
+                    }
+                }
</ins><span class="cx"> 
</span><del>-    // if no content
-    if ( status === 204 ) {
-    isSuccess = true;
-    statusText = &quot;nocontent&quot;;
</del><ins>+                // if no content
+                if ( status === 204 || s.type === &quot;HEAD&quot; ) {
+                    statusText = &quot;nocontent&quot;;
</ins><span class="cx"> 
</span><del>-    // if not modified
-    } else if ( status === 304 ) {
-    isSuccess = true;
-    statusText = &quot;notmodified&quot;;
</del><ins>+                // if not modified
+                } else if ( status === 304 ) {
+                    statusText = &quot;notmodified&quot;;
</ins><span class="cx"> 
</span><del>-    // If we have data, let's convert it
-    } else {
-    isSuccess = ajaxConvert( s, response );
-    statusText = isSuccess.state;
-    success = isSuccess.data;
-    error = isSuccess.error;
-    isSuccess = !error;
-    }
-    } else {
-    // We extract error from statusText
-    // then normalize statusText and status for non-aborts
-    error = statusText;
-    if ( status || !statusText ) {
-    statusText = &quot;error&quot;;
-    if ( status &lt; 0 ) {
-    status = 0;
-    }
-    }
-    }
</del><ins>+                // If we have data, let's convert it
+                } else {
+                    statusText = response.state;
+                    success = response.data;
+                    error = response.error;
+                    isSuccess = !error;
+                }
+            } else {
+                // We extract error from statusText
+                // then normalize statusText and status for non-aborts
+                error = statusText;
+                if ( status || !statusText ) {
+                    statusText = &quot;error&quot;;
+                    if ( status &lt; 0 ) {
+                        status = 0;
+                    }
+                }
+            }
</ins><span class="cx"> 
</span><del>-    // Set data for the fake xhr object
-    jqXHR.status = status;
-    jqXHR.statusText = ( nativeStatusText || statusText ) + &quot;&quot;;
</del><ins>+            // Set data for the fake xhr object
+            jqXHR.status = status;
+            jqXHR.statusText = ( nativeStatusText || statusText ) + &quot;&quot;;
</ins><span class="cx"> 
</span><del>-    // Success/Error
-    if ( isSuccess ) {
-    deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
-    } else {
-    deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
-    }
</del><ins>+            // Success/Error
+            if ( isSuccess ) {
+                deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+            } else {
+                deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+            }
</ins><span class="cx"> 
</span><del>-    // Status-dependent callbacks
-    jqXHR.statusCode( statusCode );
-    statusCode = undefined;
</del><ins>+            // Status-dependent callbacks
+            jqXHR.statusCode( statusCode );
+            statusCode = undefined;
</ins><span class="cx"> 
</span><del>-    if ( fireGlobals ) {
-    globalEventContext.trigger( isSuccess ? &quot;ajaxSuccess&quot; : &quot;ajaxError&quot;,
-    [ jqXHR, s, isSuccess ? success : error ] );
-    }
</del><ins>+            if ( fireGlobals ) {
+                globalEventContext.trigger( isSuccess ? &quot;ajaxSuccess&quot; : &quot;ajaxError&quot;,
+                    [ jqXHR, s, isSuccess ? success : error ] );
+            }
</ins><span class="cx"> 
</span><del>-    // Complete
-    completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
</del><ins>+            // Complete
+            completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
</ins><span class="cx"> 
</span><del>-    if ( fireGlobals ) {
-    globalEventContext.trigger( &quot;ajaxComplete&quot;, [ jqXHR, s ] );
-    // Handle the global AJAX counter
-    if ( !( --jQuery.active ) ) {
-    jQuery.event.trigger(&quot;ajaxStop&quot;);
-    }
-    }
-    }
</del><ins>+            if ( fireGlobals ) {
+                globalEventContext.trigger( &quot;ajaxComplete&quot;, [ jqXHR, s ] );
+                // Handle the global AJAX counter
+                if ( !( --jQuery.active ) ) {
+                    jQuery.event.trigger(&quot;ajaxStop&quot;);
+                }
+            }
+        }
</ins><span class="cx"> 
</span><del>-    return jqXHR;
</del><ins>+        return jqXHR;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    getScript: function( url, callback ) {
-    return jQuery.get( url, undefined, callback, &quot;script&quot; );
</del><ins>+    getJSON: function( url, data, callback ) {
+        return jQuery.get( url, data, callback, &quot;json&quot; );
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    getJSON: function( url, data, callback ) {
-    return jQuery.get( url, data, callback, &quot;json&quot; );
</del><ins>+    getScript: function( url, callback ) {
+        return jQuery.get( url, undefined, callback, &quot;script&quot; );
</ins><span class="cx">     }
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-/* Handles responses to an ajax request:
- * - sets all responseXXX fields accordingly
- * - finds the right dataType (mediates between content-type and expected dataType)
- * - returns the corresponding response
- */
-function ajaxHandleResponses( s, jqXHR, responses ) {
-    var firstDataType, ct, finalDataType, type,
-    contents = s.contents,
-    dataTypes = s.dataTypes,
-    responseFields = s.responseFields;
</del><ins>+jQuery.each( [ &quot;get&quot;, &quot;post&quot; ], function( i, method ) {
+    jQuery[ method ] = function( url, data, callback, type ) {
+        // shift arguments if data argument was omitted
+        if ( jQuery.isFunction( data ) ) {
+            type = type || callback;
+            callback = data;
+            data = undefined;
+        }
</ins><span class="cx"> 
</span><del>-    // Fill responseXXX fields
-    for ( type in responseFields ) {
-    if ( type in responses ) {
-    jqXHR[ responseFields[type] ] = responses[ type ];
-    }
-    }
</del><ins>+        return jQuery.ajax({
+            url: url,
+            type: method,
+            dataType: type,
+            data: data,
+            success: callback
+        });
+    };
+});
</ins><span class="cx"> 
</span><del>-    // Remove auto dataType and get content-type in the process
-    while( dataTypes[ 0 ] === &quot;*&quot; ) {
-    dataTypes.shift();
-    if ( ct === undefined ) {
-    ct = s.mimeType || jqXHR.getResponseHeader(&quot;Content-Type&quot;);
-    }
-    }
</del><ins>+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( [ &quot;ajaxStart&quot;, &quot;ajaxStop&quot;, &quot;ajaxComplete&quot;, &quot;ajaxError&quot;, &quot;ajaxSuccess&quot;, &quot;ajaxSend&quot; ], function( i, type ) {
+    jQuery.fn[ type ] = function( fn ) {
+        return this.on( type, fn );
+    };
+});
</ins><span class="cx"> 
</span><del>-    // Check if we're dealing with a known content-type
-    if ( ct ) {
-    for ( type in contents ) {
-    if ( contents[ type ] &amp;&amp; contents[ type ].test( ct ) ) {
-    dataTypes.unshift( type );
-    break;
-    }
-    }
-    }
</del><span class="cx"> 
</span><del>-    // Check to see if we have a response for the expected dataType
-    if ( dataTypes[ 0 ] in responses ) {
-    finalDataType = dataTypes[ 0 ];
-    } else {
-    // Try convertible dataTypes
-    for ( type in responses ) {
-    if ( !dataTypes[ 0 ] || s.converters[ type + &quot; &quot; + dataTypes[0] ] ) {
-    finalDataType = type;
-    break;
-    }
-    if ( !firstDataType ) {
-    firstDataType = type;
-    }
-    }
-    // Or just use first one
-    finalDataType = finalDataType || firstDataType;
-    }
</del><ins>+jQuery._evalUrl = function( url ) {
+    return jQuery.ajax({
+        url: url,
+        type: &quot;GET&quot;,
+        dataType: &quot;script&quot;,
+        async: false,
+        global: false,
+        &quot;throws&quot;: true
+    });
+};
</ins><span class="cx"> 
</span><del>-    // If we found a dataType
-    // We add the dataType to the list if needed
-    // and return the corresponding response
-    if ( finalDataType ) {
-    if ( finalDataType !== dataTypes[ 0 ] ) {
-    dataTypes.unshift( finalDataType );
-    }
-    return responses[ finalDataType ];
-    }
-}
</del><span class="cx"> 
</span><del>-// Chain conversions given the request and the original response
-function ajaxConvert( s, response ) {
-    var conv2, current, conv, tmp,
-    converters = {},
-    i = 0,
-    // Work with a copy of dataTypes in case we need to modify it for conversion
-    dataTypes = s.dataTypes.slice(),
-    prev = dataTypes[ 0 ];
</del><ins>+jQuery.fn.extend({
+    wrapAll: function( html ) {
+        var wrap;
</ins><span class="cx"> 
</span><del>-    // Apply the dataFilter if provided
-    if ( s.dataFilter ) {
-    response = s.dataFilter( response, s.dataType );
-    }
</del><ins>+        if ( jQuery.isFunction( html ) ) {
+            return this.each(function( i ) {
+                jQuery( this ).wrapAll( html.call(this, i) );
+            });
+        }
</ins><span class="cx"> 
</span><del>-    // Create converters map with lowercased keys
-    if ( dataTypes[ 1 ] ) {
-    for ( conv in s.converters ) {
-    converters[ conv.toLowerCase() ] = s.converters[ conv ];
-    }
-    }
</del><ins>+        if ( this[ 0 ] ) {
</ins><span class="cx"> 
</span><del>-    // Convert to each sequential dataType, tolerating list modification
-    for ( ; (current = dataTypes[++i]); ) {
</del><ins>+            // The elements to wrap the target around
+            wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
</ins><span class="cx"> 
</span><del>-    // There's only work to do if current dataType is non-auto
-    if ( current !== &quot;*&quot; ) {
</del><ins>+            if ( this[ 0 ].parentNode ) {
+                wrap.insertBefore( this[ 0 ] );
+            }
</ins><span class="cx"> 
</span><del>-    // Convert response if prev dataType is non-auto and differs from current
-    if ( prev !== &quot;*&quot; &amp;&amp; prev !== current ) {
</del><ins>+            wrap.map(function() {
+                var elem = this;
</ins><span class="cx"> 
</span><del>-    // Seek a direct converter
-    conv = converters[ prev + &quot; &quot; + current ] || converters[ &quot;* &quot; + current ];
</del><ins>+                while ( elem.firstElementChild ) {
+                    elem = elem.firstElementChild;
+                }
</ins><span class="cx"> 
</span><del>-    // If none found, seek a pair
-    if ( !conv ) {
-    for ( conv2 in converters ) {
</del><ins>+                return elem;
+            }).append( this );
+        }
</ins><span class="cx"> 
</span><del>-    // If conv2 outputs current
-    tmp = conv2.split(&quot; &quot;);
-    if ( tmp[ 1 ] === current ) {
</del><ins>+        return this;
+    },
</ins><span class="cx"> 
</span><del>-    // If prev can be converted to accepted input
-    conv = converters[ prev + &quot; &quot; + tmp[ 0 ] ] ||
-    converters[ &quot;* &quot; + tmp[ 0 ] ];
-    if ( conv ) {
-    // Condense equivalence converters
-    if ( conv === true ) {
-    conv = converters[ conv2 ];
</del><ins>+    wrapInner: function( html ) {
+        if ( jQuery.isFunction( html ) ) {
+            return this.each(function( i ) {
+                jQuery( this ).wrapInner( html.call(this, i) );
+            });
+        }
</ins><span class="cx"> 
</span><del>-    // Otherwise, insert the intermediate dataType
-    } else if ( converters[ conv2 ] !== true ) {
-    current = tmp[ 0 ];
-    dataTypes.splice( i--, 0, current );
-    }
</del><ins>+        return this.each(function() {
+            var self = jQuery( this ),
+                contents = self.contents();
</ins><span class="cx"> 
</span><del>-    break;
-    }
-    }
-    }
-    }
</del><ins>+            if ( contents.length ) {
+                contents.wrapAll( html );
</ins><span class="cx"> 
</span><del>-    // Apply converter (if not an equivalence)
-    if ( conv !== true ) {
</del><ins>+            } else {
+                self.append( html );
+            }
+        });
+    },
</ins><span class="cx"> 
</span><del>-    // Unless errors are allowed to bubble, catch and return them
-    if ( conv &amp;&amp; s[&quot;throws&quot;] ) {
-    response = conv( response );
-    } else {
-    try {
-    response = conv( response );
-    } catch ( e ) {
-    return { state: &quot;parsererror&quot;, error: conv ? e : &quot;No conversion from &quot; + prev + &quot; to &quot; + current };
-    }
-    }
-    }
-    }
</del><ins>+    wrap: function( html ) {
+        var isFunction = jQuery.isFunction( html );
</ins><span class="cx"> 
</span><del>-    // Update prev for next iteration
-    prev = current;
-    }
-    }
-
-    return { state: &quot;success&quot;, data: response };
-}
-// Install script dataType
-jQuery.ajaxSetup({
-    accepts: {
-    script: &quot;text/javascript, application/javascript, application/ecmascript, application/x-ecmascript&quot;
</del><ins>+        return this.each(function( i ) {
+            jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
+        });
</ins><span class="cx">     },
</span><del>-    contents: {
-    script: /(?:java|ecma)script/
-    },
-    converters: {
-    &quot;text script&quot;: function( text ) {
-    jQuery.globalEval( text );
-    return text;
-    }
-    }
-});
</del><span class="cx"> 
</span><del>-// Handle cache's special case and global
-jQuery.ajaxPrefilter( &quot;script&quot;, function( s ) {
-    if ( s.cache === undefined ) {
-    s.cache = false;
</del><ins>+    unwrap: function() {
+        return this.parent().each(function() {
+            if ( !jQuery.nodeName( this, &quot;body&quot; ) ) {
+                jQuery( this ).replaceWith( this.childNodes );
+            }
+        }).end();
</ins><span class="cx">     }
</span><del>-    if ( s.crossDomain ) {
-    s.type = &quot;GET&quot;;
-    s.global = false;
-    }
</del><span class="cx"> });
</span><span class="cx"> 
</span><del>-// Bind script tag hack transport
-jQuery.ajaxTransport( &quot;script&quot;, function(s) {
</del><span class="cx"> 
</span><del>-    // This transport only deals with cross domain requests
-    if ( s.crossDomain ) {
</del><ins>+jQuery.expr.filters.hidden = function( elem ) {
+    // Support: Opera &lt;= 12.12
+    // Opera reports offsetWidths and offsetHeights less than zero on some elements
+    return elem.offsetWidth &lt;= 0 &amp;&amp; elem.offsetHeight &lt;= 0;
+};
+jQuery.expr.filters.visible = function( elem ) {
+    return !jQuery.expr.filters.hidden( elem );
+};
</ins><span class="cx"> 
</span><del>-    var script,
-    head = document.head || jQuery(&quot;head&quot;)[0] || document.documentElement;
</del><span class="cx"> 
</span><del>-    return {
</del><span class="cx"> 
</span><del>-    send: function( _, callback ) {
</del><span class="cx"> 
</span><del>-    script = document.createElement(&quot;script&quot;);
</del><ins>+var r20 = /%20/g,
+    rbracket = /\[\]$/,
+    rCRLF = /\r?\n/g,
+    rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+    rsubmittable = /^(?:input|select|textarea|keygen)/i;
</ins><span class="cx"> 
</span><del>-    script.async = true;
</del><ins>+function buildParams( prefix, obj, traditional, add ) {
+    var name;
</ins><span class="cx"> 
</span><del>-    if ( s.scriptCharset ) {
-    script.charset = s.scriptCharset;
-    }
</del><ins>+    if ( jQuery.isArray( obj ) ) {
+        // Serialize array item.
+        jQuery.each( obj, function( i, v ) {
+            if ( traditional || rbracket.test( prefix ) ) {
+                // Treat each array item as a scalar.
+                add( prefix, v );
</ins><span class="cx"> 
</span><del>-    script.src = s.url;
</del><ins>+            } else {
+                // Item is non-scalar (array or object), encode its numeric index.
+                buildParams( prefix + &quot;[&quot; + ( typeof v === &quot;object&quot; ? i : &quot;&quot; ) + &quot;]&quot;, v, traditional, add );
+            }
+        });
</ins><span class="cx"> 
</span><del>-    // Attach handlers for all browsers
-    script.onload = script.onreadystatechange = function( _, isAbort ) {
</del><ins>+    } else if ( !traditional &amp;&amp; jQuery.type( obj ) === &quot;object&quot; ) {
+        // Serialize object item.
+        for ( name in obj ) {
+            buildParams( prefix + &quot;[&quot; + name + &quot;]&quot;, obj[ name ], traditional, add );
+        }
</ins><span class="cx"> 
</span><del>-    if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
-
-    // Handle memory leak in IE
-    script.onload = script.onreadystatechange = null;
-
-    // Remove the script
-    if ( script.parentNode ) {
-    script.parentNode.removeChild( script );
</del><ins>+    } else {
+        // Serialize scalar item.
+        add( prefix, obj );
</ins><span class="cx">     }
</span><ins>+}
</ins><span class="cx"> 
</span><del>-    // Dereference the script
-    script = null;
</del><ins>+// Serialize an array of form elements or a set of
+// key/values into a query string
+jQuery.param = function( a, traditional ) {
+    var prefix,
+        s = [],
+        add = function( key, value ) {
+            // If value is a function, invoke it and return its value
+            value = jQuery.isFunction( value ) ? value() : ( value == null ? &quot;&quot; : value );
+            s[ s.length ] = encodeURIComponent( key ) + &quot;=&quot; + encodeURIComponent( value );
+        };
</ins><span class="cx"> 
</span><del>-    // Callback if not abort
-    if ( !isAbort ) {
-    callback( 200, &quot;success&quot; );
</del><ins>+    // Set traditional to true for jQuery &lt;= 1.3.2 behavior.
+    if ( traditional === undefined ) {
+        traditional = jQuery.ajaxSettings &amp;&amp; jQuery.ajaxSettings.traditional;
</ins><span class="cx">     }
</span><del>-    }
-    };
</del><span class="cx"> 
</span><del>-    // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
-    // Use native DOM manipulation to avoid our domManip AJAX trickery
-    head.insertBefore( script, head.firstChild );
-    },
</del><ins>+    // If an array was passed in, assume that it is an array of form elements.
+    if ( jQuery.isArray( a ) || ( a.jquery &amp;&amp; !jQuery.isPlainObject( a ) ) ) {
+        // Serialize the form elements
+        jQuery.each( a, function() {
+            add( this.name, this.value );
+        });
</ins><span class="cx"> 
</span><del>-    abort: function() {
-    if ( script ) {
-    script.onload( undefined, true );
</del><ins>+    } else {
+        // If traditional, encode the &quot;old&quot; way (the way 1.3.2 or older
+        // did it), otherwise encode params recursively.
+        for ( prefix in a ) {
+            buildParams( prefix, a[ prefix ], traditional, add );
+        }
</ins><span class="cx">     }
</span><del>-    }
-    };
-    }
-});
-var oldCallbacks = [],
-    rjsonp = /(=)\?(?=&amp;|$)|\?\?/;
</del><span class="cx"> 
</span><del>-// Default jsonp settings
-jQuery.ajaxSetup({
-    jsonp: &quot;callback&quot;,
-    jsonpCallback: function() {
-    var callback = oldCallbacks.pop() || ( jQuery.expando + &quot;_&quot; + ( ajax_nonce++ ) );
-    this[ callback ] = true;
-    return callback;
-    }
-});
</del><ins>+    // Return the resulting serialization
+    return s.join( &quot;&amp;&quot; ).replace( r20, &quot;+&quot; );
+};
</ins><span class="cx"> 
</span><del>-// Detect, normalize options and install callbacks for jsonp requests
-jQuery.ajaxPrefilter( &quot;json jsonp&quot;, function( s, originalSettings, jqXHR ) {
</del><ins>+jQuery.fn.extend({
+    serialize: function() {
+        return jQuery.param( this.serializeArray() );
+    },
+    serializeArray: function() {
+        return this.map(function() {
+            // Can add propHook for &quot;elements&quot; to filter or add form elements
+            var elements = jQuery.prop( this, &quot;elements&quot; );
+            return elements ? jQuery.makeArray( elements ) : this;
+        })
+        .filter(function() {
+            var type = this.type;
</ins><span class="cx"> 
</span><del>-    var callbackName, overwritten, responseContainer,
-    jsonProp = s.jsonp !== false &amp;&amp; ( rjsonp.test( s.url ) ?
-    &quot;url&quot; :
-    typeof s.data === &quot;string&quot; &amp;&amp; !( s.contentType || &quot;&quot; ).indexOf(&quot;application/x-www-form-urlencoded&quot;) &amp;&amp; rjsonp.test( s.data ) &amp;&amp; &quot;data&quot;
-    );
</del><ins>+            // Use .is( &quot;:disabled&quot; ) so that fieldset[disabled] works
+            return this.name &amp;&amp; !jQuery( this ).is( &quot;:disabled&quot; ) &amp;&amp;
+                rsubmittable.test( this.nodeName ) &amp;&amp; !rsubmitterTypes.test( type ) &amp;&amp;
+                ( this.checked || !rcheckableType.test( type ) );
+        })
+        .map(function( i, elem ) {
+            var val = jQuery( this ).val();
</ins><span class="cx"> 
</span><del>-    // Handle iff the expected data type is &quot;jsonp&quot; or we have a parameter to set
-    if ( jsonProp || s.dataTypes[ 0 ] === &quot;jsonp&quot; ) {
-
-    // Get callback name, remembering preexisting value associated with it
-    callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
-    s.jsonpCallback() :
-    s.jsonpCallback;
-
-    // Insert callback into url or form data
-    if ( jsonProp ) {
-    s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, &quot;$1&quot; + callbackName );
-    } else if ( s.jsonp !== false ) {
-    s.url += ( ajax_rquery.test( s.url ) ? &quot;&amp;&quot; : &quot;?&quot; ) + s.jsonp + &quot;=&quot; + callbackName;
</del><ins>+            return val == null ?
+                null :
+                jQuery.isArray( val ) ?
+                    jQuery.map( val, function( val ) {
+                        return { name: elem.name, value: val.replace( rCRLF, &quot;\r\n&quot; ) };
+                    }) :
+                    { name: elem.name, value: val.replace( rCRLF, &quot;\r\n&quot; ) };
+        }).get();
</ins><span class="cx">     }
</span><del>-
-    // Use data converter to retrieve json after script execution
-    s.converters[&quot;script json&quot;] = function() {
-    if ( !responseContainer ) {
-    jQuery.error( callbackName + &quot; was not called&quot; );
-    }
-    return responseContainer[ 0 ];
-    };
-
-    // force json dataType
-    s.dataTypes[ 0 ] = &quot;json&quot;;
-
-    // Install callback
-    overwritten = window[ callbackName ];
-    window[ callbackName ] = function() {
-    responseContainer = arguments;
-    };
-
-    // Clean-up function (fires after converters)
-    jqXHR.always(function() {
-    // Restore preexisting value
-    window[ callbackName ] = overwritten;
-
-    // Save back as free
-    if ( s[ callbackName ] ) {
-    // make sure that re-using the options doesn't screw things around
-    s.jsonpCallback = originalSettings.jsonpCallback;
-
-    // save the callback name for future use
-    oldCallbacks.push( callbackName );
-    }
-
-    // Call if it was a function and we have a response
-    if ( responseContainer &amp;&amp; jQuery.isFunction( overwritten ) ) {
-    overwritten( responseContainer[ 0 ] );
-    }
-
-    responseContainer = overwritten = undefined;
-    });
-
-    // Delegate to script
-    return &quot;script&quot;;
-    }
</del><span class="cx"> });
</span><del>-var xhrCallbacks, xhrSupported,
-    xhrId = 0,
-    // #5280: Internet Explorer will keep connections alive if we don't abort on unload
-    xhrOnUnloadAbort = window.ActiveXObject &amp;&amp; function() {
-    // Abort all pending requests
-    var key;
-    for ( key in xhrCallbacks ) {
-    xhrCallbacks[ key ]( undefined, true );
-    }
-    };
</del><span class="cx"> 
</span><del>-// Functions to create xhrs
-function createStandardXHR() {
-    try {
-    return new window.XMLHttpRequest();
-    } catch( e ) {}
-}
</del><span class="cx"> 
</span><del>-function createActiveXHR() {
</del><ins>+jQuery.ajaxSettings.xhr = function() {
</ins><span class="cx">     try {
</span><del>-    return new window.ActiveXObject(&quot;Microsoft.XMLHTTP&quot;);
</del><ins>+        return new XMLHttpRequest();
</ins><span class="cx">     } catch( e ) {}
</span><del>-}
</del><ins>+};
</ins><span class="cx"> 
</span><del>-// Create the request object
-// (This is still attached to ajaxSettings for backward compatibility)
-jQuery.ajaxSettings.xhr = window.ActiveXObject ?
-    /* Microsoft failed to properly
-     * implement the XMLHttpRequest in IE7 (can't request local files),
-     * so we use the ActiveXObject when it is available
-     * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
-     * we need a fallback.
-     */
-    function() {
-    return !this.isLocal &amp;&amp; createStandardXHR() || createActiveXHR();
-    } :
-    // For all other browsers, use the standard XMLHttpRequest object
-    createStandardXHR;
</del><ins>+var xhrId = 0,
+    xhrCallbacks = {},
+    xhrSuccessStatus = {
+        // file protocol always yields status code 0, assume 200
+        0: 200,
+        // Support: IE9
+        // #1450: sometimes IE returns 1223 when it should be 204
+        1223: 204
+    },
+    xhrSupported = jQuery.ajaxSettings.xhr();
</ins><span class="cx"> 
</span><del>-// Determine support properties
-xhrSupported = jQuery.ajaxSettings.xhr();
-jQuery.support.cors = !!xhrSupported &amp;&amp; ( &quot;withCredentials&quot; in xhrSupported );
-xhrSupported = jQuery.support.ajax = !!xhrSupported;
</del><ins>+// Support: IE9
+// Open requests must be manually aborted on unload (#5280)
+if ( window.ActiveXObject ) {
+    jQuery( window ).on( &quot;unload&quot;, function() {
+        for ( var key in xhrCallbacks ) {
+            xhrCallbacks[ key ]();
+        }
+    });
+}
</ins><span class="cx"> 
</span><del>-// Create transport if the browser can provide an xhr
-if ( xhrSupported ) {
</del><ins>+support.cors = !!xhrSupported &amp;&amp; ( &quot;withCredentials&quot; in xhrSupported );
+support.ajax = xhrSupported = !!xhrSupported;
</ins><span class="cx"> 
</span><del>-    jQuery.ajaxTransport(function( s ) {
-    // Cross domain only allowed if supported through XMLHttpRequest
-    if ( !s.crossDomain || jQuery.support.cors ) {
-
</del><ins>+jQuery.ajaxTransport(function( options ) {
</ins><span class="cx">     var callback;
</span><span class="cx"> 
</span><del>-    return {
-    send: function( headers, complete ) {
</del><ins>+    // Cross domain only allowed if supported through XMLHttpRequest
+    if ( support.cors || xhrSupported &amp;&amp; !options.crossDomain ) {
+        return {
+            send: function( headers, complete ) {
+                var i,
+                    xhr = options.xhr(),
+                    id = ++xhrId;
</ins><span class="cx"> 
</span><del>-    // Get a new xhr
-    var handle, i,
-    xhr = s.xhr();
</del><ins>+                xhr.open( options.type, options.url, options.async, options.username, options.password );
</ins><span class="cx"> 
</span><del>-    // Open the socket
-    // Passing null username, generates a login popup on Opera (#2865)
-    if ( s.username ) {
-    xhr.open( s.type, s.url, s.async, s.username, s.password );
-    } else {
-    xhr.open( s.type, s.url, s.async );
-    }
</del><ins>+                // Apply custom fields if provided
+                if ( options.xhrFields ) {
+                    for ( i in options.xhrFields ) {
+                        xhr[ i ] = options.xhrFields[ i ];
+                    }
+                }
</ins><span class="cx"> 
</span><del>-    // Apply custom fields if provided
-    if ( s.xhrFields ) {
-    for ( i in s.xhrFields ) {
-    xhr[ i ] = s.xhrFields[ i ];
-    }
-    }
</del><ins>+                // Override mime type if needed
+                if ( options.mimeType &amp;&amp; xhr.overrideMimeType ) {
+                    xhr.overrideMimeType( options.mimeType );
+                }
</ins><span class="cx"> 
</span><del>-    // Override mime type if needed
-    if ( s.mimeType &amp;&amp; xhr.overrideMimeType ) {
-    xhr.overrideMimeType( s.mimeType );
-    }
</del><ins>+                // X-Requested-With header
+                // For cross-domain requests, seeing as conditions for a preflight are
+                // akin to a jigsaw puzzle, we simply never set it to be sure.
+                // (it can always be set on a per-request basis or even using ajaxSetup)
+                // For same-domain requests, won't change header if already provided.
+                if ( !options.crossDomain &amp;&amp; !headers[&quot;X-Requested-With&quot;] ) {
+                    headers[&quot;X-Requested-With&quot;] = &quot;XMLHttpRequest&quot;;
+                }
</ins><span class="cx"> 
</span><del>-    // X-Requested-With header
-    // For cross-domain requests, seeing as conditions for a preflight are
-    // akin to a jigsaw puzzle, we simply never set it to be sure.
-    // (it can always be set on a per-request basis or even using ajaxSetup)
-    // For same-domain requests, won't change header if already provided.
-    if ( !s.crossDomain &amp;&amp; !headers[&quot;X-Requested-With&quot;] ) {
-    headers[&quot;X-Requested-With&quot;] = &quot;XMLHttpRequest&quot;;
-    }
</del><ins>+                // Set headers
+                for ( i in headers ) {
+                    xhr.setRequestHeader( i, headers[ i ] );
+                }
</ins><span class="cx"> 
</span><del>-    // Need an extra try/catch for cross domain requests in Firefox 3
-    try {
-    for ( i in headers ) {
-    xhr.setRequestHeader( i, headers[ i ] );
-    }
-    } catch( err ) {}
</del><ins>+                // Callback
+                callback = function( type ) {
+                    return function() {
+                        if ( callback ) {
+                            delete xhrCallbacks[ id ];
+                            callback = xhr.onload = xhr.onerror = null;
</ins><span class="cx"> 
</span><del>-    // Do send the request
-    // This may raise an exception which is actually
-    // handled in jQuery.ajax (so no try/catch here)
-    xhr.send( ( s.hasContent &amp;&amp; s.data ) || null );
</del><ins>+                            if ( type === &quot;abort&quot; ) {
+                                xhr.abort();
+                            } else if ( type === &quot;error&quot; ) {
+                                complete(
+                                    // file: protocol always yields status 0; see #8605, #14207
+                                    xhr.status,
+                                    xhr.statusText
+                                );
+                            } else {
+                                complete(
+                                    xhrSuccessStatus[ xhr.status ] || xhr.status,
+                                    xhr.statusText,
+                                    // Support: IE9
+                                    // Accessing binary-data responseText throws an exception
+                                    // (#11426)
+                                    typeof xhr.responseText === &quot;string&quot; ? {
+                                        text: xhr.responseText
+                                    } : undefined,
+                                    xhr.getAllResponseHeaders()
+                                );
+                            }
+                        }
+                    };
+                };
</ins><span class="cx"> 
</span><del>-    // Listener
-    callback = function( _, isAbort ) {
-    var status, responseHeaders, statusText, responses;
</del><ins>+                // Listen to events
+                xhr.onload = callback();
+                xhr.onerror = callback(&quot;error&quot;);
</ins><span class="cx"> 
</span><del>-    // Firefox throws exceptions when accessing properties
-    // of an xhr when a network error occurred
-    // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
-    try {
</del><ins>+                // Create the abort callback
+                callback = xhrCallbacks[ id ] = callback(&quot;abort&quot;);
</ins><span class="cx"> 
</span><del>-    // Was never called and is aborted or complete
-    if ( callback &amp;&amp; ( isAbort || xhr.readyState === 4 ) ) {
</del><ins>+                // Do send the request
+                // This may raise an exception which is actually
+                // handled in jQuery.ajax (so no try/catch here)
+                xhr.send( options.hasContent &amp;&amp; options.data || null );
+            },
</ins><span class="cx"> 
</span><del>-    // Only called once
-    callback = undefined;
-
-    // Do not keep as active anymore
-    if ( handle ) {
-    xhr.onreadystatechange = jQuery.noop;
-    if ( xhrOnUnloadAbort ) {
-    delete xhrCallbacks[ handle ];
</del><ins>+            abort: function() {
+                if ( callback ) {
+                    callback();
+                }
+            }
+        };
</ins><span class="cx">     }
</span><del>-    }
</del><ins>+});
</ins><span class="cx"> 
</span><del>-    // If it's an abort
-    if ( isAbort ) {
-    // Abort it manually if needed
-    if ( xhr.readyState !== 4 ) {
-    xhr.abort();
-    }
-    } else {
-    responses = {};
-    status = xhr.status;
-    responseHeaders = xhr.getAllResponseHeaders();
</del><span class="cx"> 
</span><del>-    // When requesting binary data, IE6-9 will throw an exception
-    // on any attempt to access responseText (#11426)
-    if ( typeof xhr.responseText === &quot;string&quot; ) {
-    responses.text = xhr.responseText;
-    }
</del><span class="cx"> 
</span><del>-    // Firefox throws an exception when accessing
-    // statusText for faulty cross-domain requests
-    try {
-    statusText = xhr.statusText;
-    } catch( e ) {
-    // We normalize with Webkit giving an empty statusText
-    statusText = &quot;&quot;;
-    }
</del><span class="cx"> 
</span><del>-    // Filter status for non standard behaviors
-
-    // If the request is local and we have data: assume a success
-    // (success with no data won't get notified, that's the best we
-    // can do given current implementations)
-    if ( !status &amp;&amp; s.isLocal &amp;&amp; !s.crossDomain ) {
-    status = responses.text ? 200 : 404;
-    // IE - #1450: sometimes returns 1223 when it should be 204
-    } else if ( status === 1223 ) {
-    status = 204;
</del><ins>+// Install script dataType
+jQuery.ajaxSetup({
+    accepts: {
+        script: &quot;text/javascript, application/javascript, application/ecmascript, application/x-ecmascript&quot;
+    },
+    contents: {
+        script: /(?:java|ecma)script/
+    },
+    converters: {
+        &quot;text script&quot;: function( text ) {
+            jQuery.globalEval( text );
+            return text;
+        }
</ins><span class="cx">     }
</span><del>-    }
-    }
-    } catch( firefoxAccessException ) {
-    if ( !isAbort ) {
-    complete( -1, firefoxAccessException );
-    }
-    }
</del><ins>+});
</ins><span class="cx"> 
</span><del>-    // Call complete if needed
-    if ( responses ) {
-    complete( status, statusText, responses, responseHeaders );
</del><ins>+// Handle cache's special case and crossDomain
+jQuery.ajaxPrefilter( &quot;script&quot;, function( s ) {
+    if ( s.cache === undefined ) {
+        s.cache = false;
</ins><span class="cx">     }
</span><del>-    };
-
-    if ( !s.async ) {
-    // if we're in sync mode we fire the callback
-    callback();
-    } else if ( xhr.readyState === 4 ) {
-    // (IE6 &amp; IE7) if it's in cache and has been
-    // retrieved directly we need to fire the callback
-    setTimeout( callback );
-    } else {
-    handle = ++xhrId;
-    if ( xhrOnUnloadAbort ) {
-    // Create the active xhrs callbacks list if needed
-    // and attach the unload handler
-    if ( !xhrCallbacks ) {
-    xhrCallbacks = {};
-    jQuery( window ).unload( xhrOnUnloadAbort );
</del><ins>+    if ( s.crossDomain ) {
+        s.type = &quot;GET&quot;;
</ins><span class="cx">     }
</span><del>-    // Add to list of active xhrs callbacks
-    xhrCallbacks[ handle ] = callback;
-    }
-    xhr.onreadystatechange = callback;
-    }
-    },
</del><ins>+});
</ins><span class="cx"> 
</span><del>-    abort: function() {
-    if ( callback ) {
-    callback( undefined, true );
</del><ins>+// Bind script tag hack transport
+jQuery.ajaxTransport( &quot;script&quot;, function( s ) {
+    // This transport only deals with cross domain requests
+    if ( s.crossDomain ) {
+        var script, callback;
+        return {
+            send: function( _, complete ) {
+                script = jQuery(&quot;&lt;script&gt;&quot;).prop({
+                    async: true,
+                    charset: s.scriptCharset,
+                    src: s.url
+                }).on(
+                    &quot;load error&quot;,
+                    callback = function( evt ) {
+                        script.remove();
+                        callback = null;
+                        if ( evt ) {
+                            complete( evt.type === &quot;error&quot; ? 404 : 200, evt.type );
+                        }
+                    }
+                );
+                document.head.appendChild( script[ 0 ] );
+            },
+            abort: function() {
+                if ( callback ) {
+                    callback();
+                }
+            }
+        };
</ins><span class="cx">     }
</span><del>-    }
-    };
-    }
-    });
-}
-var fxNow, timerId,
-    rfxtypes = /^(?:toggle|show|hide)$/,
-    rfxnum = new RegExp( &quot;^(?:([+-])=|)(&quot; + core_pnum + &quot;)([a-z%]*)$&quot;, &quot;i&quot; ),
-    rrun = /queueHooks$/,
-    animationPrefilters = [ defaultPrefilter ],
-    tweeners = {
-    &quot;*&quot;: [function( prop, value ) {
-    var end, unit,
-    tween = this.createTween( prop, value ),
-    parts = rfxnum.exec( value ),
-    target = tween.cur(),
-    start = +target || 0,
-    scale = 1,
-    maxIterations = 20;
</del><ins>+});
</ins><span class="cx"> 
</span><del>-    if ( parts ) {
-    end = +parts[2];
-    unit = parts[3] || ( jQuery.cssNumber[ prop ] ? &quot;&quot; : &quot;px&quot; );
</del><span class="cx"> 
</span><del>-    // We need to compute starting value
-    if ( unit !== &quot;px&quot; &amp;&amp; start ) {
-    // Iteratively approximate from a nonzero starting point
-    // Prefer the current property, because this process will be trivial if it uses the same units
-    // Fallback to end or a simple constant
-    start = jQuery.css( tween.elem, prop, true ) || end || 1;
</del><span class="cx"> 
</span><del>-    do {
-    // If previous iteration zeroed out, double until we get *something*
-    // Use a string for doubling factor so we don't accidentally see scale as unchanged below
-    scale = scale || &quot;.5&quot;;
</del><span class="cx"> 
</span><del>-    // Adjust and apply
-    start = start / scale;
-    jQuery.style( tween.elem, prop, start + unit );
</del><ins>+var oldCallbacks = [],
+    rjsonp = /(=)\?(?=&amp;|$)|\?\?/;
</ins><span class="cx"> 
</span><del>-    // Update scale, tolerating zero or NaN from tween.cur()
-    // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
-    } while ( scale !== (scale = tween.cur() / target) &amp;&amp; scale !== 1 &amp;&amp; --maxIterations );
</del><ins>+// Default jsonp settings
+jQuery.ajaxSetup({
+    jsonp: &quot;callback&quot;,
+    jsonpCallback: function() {
+        var callback = oldCallbacks.pop() || ( jQuery.expando + &quot;_&quot; + ( nonce++ ) );
+        this[ callback ] = true;
+        return callback;
</ins><span class="cx">     }
</span><ins>+});
</ins><span class="cx"> 
</span><del>-    tween.unit = unit;
-    tween.start = start;
-    // If a +=/-= token was provided, we're doing a relative animation
-    tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;
-    }
-    return tween;
-    }]
-    };
</del><ins>+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( &quot;json jsonp&quot;, function( s, originalSettings, jqXHR ) {
</ins><span class="cx"> 
</span><del>-// Animations created synchronously will run synchronously
-function createFxNow() {
-    setTimeout(function() {
-    fxNow = undefined;
-    });
-    return ( fxNow = jQuery.now() );
-}
</del><ins>+    var callbackName, overwritten, responseContainer,
+        jsonProp = s.jsonp !== false &amp;&amp; ( rjsonp.test( s.url ) ?
+            &quot;url&quot; :
+            typeof s.data === &quot;string&quot; &amp;&amp; !( s.contentType || &quot;&quot; ).indexOf(&quot;application/x-www-form-urlencoded&quot;) &amp;&amp; rjsonp.test( s.data ) &amp;&amp; &quot;data&quot;
+        );
</ins><span class="cx"> 
</span><del>-function createTweens( animation, props ) {
-    jQuery.each( props, function( prop, value ) {
-    var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ &quot;*&quot; ] ),
-    index = 0,
-    length = collection.length;
-    for ( ; index &lt; length; index++ ) {
-    if ( collection[ index ].call( animation, prop, value ) ) {
</del><ins>+    // Handle iff the expected data type is &quot;jsonp&quot; or we have a parameter to set
+    if ( jsonProp || s.dataTypes[ 0 ] === &quot;jsonp&quot; ) {
</ins><span class="cx"> 
</span><del>-    // we're done with this property
-    return;
-    }
-    }
-    });
-}
</del><ins>+        // Get callback name, remembering preexisting value associated with it
+        callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
+            s.jsonpCallback() :
+            s.jsonpCallback;
</ins><span class="cx"> 
</span><del>-function Animation( elem, properties, options ) {
-    var result,
-    stopped,
-    index = 0,
-    length = animationPrefilters.length,
-    deferred = jQuery.Deferred().always( function() {
-    // don't match elem in the :animated selector
-    delete tick.elem;
-    }),
-    tick = function() {
-    if ( stopped ) {
-    return false;
-    }
-    var currentTime = fxNow || createFxNow(),
-    remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
-    // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
-    temp = remaining / animation.duration || 0,
-    percent = 1 - temp,
-    index = 0,
-    length = animation.tweens.length;
</del><ins>+        // Insert callback into url or form data
+        if ( jsonProp ) {
+            s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, &quot;$1&quot; + callbackName );
+        } else if ( s.jsonp !== false ) {
+            s.url += ( rquery.test( s.url ) ? &quot;&amp;&quot; : &quot;?&quot; ) + s.jsonp + &quot;=&quot; + callbackName;
+        }
</ins><span class="cx"> 
</span><del>-    for ( ; index &lt; length ; index++ ) {
-    animation.tweens[ index ].run( percent );
-    }
</del><ins>+        // Use data converter to retrieve json after script execution
+        s.converters[&quot;script json&quot;] = function() {
+            if ( !responseContainer ) {
+                jQuery.error( callbackName + &quot; was not called&quot; );
+            }
+            return responseContainer[ 0 ];
+        };
</ins><span class="cx"> 
</span><del>-    deferred.notifyWith( elem, [ animation, percent, remaining ]);
</del><ins>+        // force json dataType
+        s.dataTypes[ 0 ] = &quot;json&quot;;
</ins><span class="cx"> 
</span><del>-    if ( percent &lt; 1 &amp;&amp; length ) {
-    return remaining;
-    } else {
-    deferred.resolveWith( elem, [ animation ] );
-    return false;
-    }
-    },
-    animation = deferred.promise({
-    elem: elem,
-    props: jQuery.extend( {}, properties ),
-    opts: jQuery.extend( true, { specialEasing: {} }, options ),
-    originalProperties: properties,
-    originalOptions: options,
-    startTime: fxNow || createFxNow(),
-    duration: options.duration,
-    tweens: [],
-    createTween: function( prop, end ) {
-    var tween = jQuery.Tween( elem, animation.opts, prop, end,
-    animation.opts.specialEasing[ prop ] || animation.opts.easing );
-    animation.tweens.push( tween );
-    return tween;
-    },
-    stop: function( gotoEnd ) {
-    var index = 0,
-    // if we are going to the end, we want to run all the tweens
-    // otherwise we skip this part
-    length = gotoEnd ? animation.tweens.length : 0;
-    if ( stopped ) {
-    return this;
-    }
-    stopped = true;
-    for ( ; index &lt; length ; index++ ) {
-    animation.tweens[ index ].run( 1 );
-    }
</del><ins>+        // Install callback
+        overwritten = window[ callbackName ];
+        window[ callbackName ] = function() {
+            responseContainer = arguments;
+        };
</ins><span class="cx"> 
</span><del>-    // resolve when we played the last frame
-    // otherwise, reject
-    if ( gotoEnd ) {
-    deferred.resolveWith( elem, [ animation, gotoEnd ] );
-    } else {
-    deferred.rejectWith( elem, [ animation, gotoEnd ] );
-    }
-    return this;
-    }
-    }),
-    props = animation.props;
</del><ins>+        // Clean-up function (fires after converters)
+        jqXHR.always(function() {
+            // Restore preexisting value
+            window[ callbackName ] = overwritten;
</ins><span class="cx"> 
</span><del>-    propFilter( props, animation.opts.specialEasing );
</del><ins>+            // Save back as free
+            if ( s[ callbackName ] ) {
+                // make sure that re-using the options doesn't screw things around
+                s.jsonpCallback = originalSettings.jsonpCallback;
</ins><span class="cx"> 
</span><del>-    for ( ; index &lt; length ; index++ ) {
-    result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
-    if ( result ) {
-    return result;
-    }
-    }
</del><ins>+                // save the callback name for future use
+                oldCallbacks.push( callbackName );
+            }
</ins><span class="cx"> 
</span><del>-    createTweens( animation, props );
</del><ins>+            // Call if it was a function and we have a response
+            if ( responseContainer &amp;&amp; jQuery.isFunction( overwritten ) ) {
+                overwritten( responseContainer[ 0 ] );
+            }
</ins><span class="cx"> 
</span><del>-    if ( jQuery.isFunction( animation.opts.start ) ) {
-    animation.opts.start.call( elem, animation );
</del><ins>+            responseContainer = overwritten = undefined;
+        });
+
+        // Delegate to script
+        return &quot;script&quot;;
</ins><span class="cx">     }
</span><ins>+});
</ins><span class="cx"> 
</span><del>-    jQuery.fx.timer(
-    jQuery.extend( tick, {
-    elem: elem,
-    anim: animation,
-    queue: animation.opts.queue
-    })
-    );
</del><span class="cx"> 
</span><del>-    // attach callbacks from options
-    return animation.progress( animation.opts.progress )
-    .done( animation.opts.done, animation.opts.complete )
-    .fail( animation.opts.fail )
-    .always( animation.opts.always );
-}
</del><span class="cx"> 
</span><del>-function propFilter( props, specialEasing ) {
-    var value, name, index, easing, hooks;
</del><span class="cx"> 
</span><del>-    // camelCase, specialEasing and expand cssHook pass
-    for ( index in props ) {
-    name = jQuery.camelCase( index );
-    easing = specialEasing[ name ];
-    value = props[ index ];
-    if ( jQuery.isArray( value ) ) {
-    easing = value[ 1 ];
-    value = props[ index ] = value[ 0 ];
</del><ins>+// data: string of html
+// context (optional): If specified, the fragment will be created in this context, defaults to document
+// keepScripts (optional): If true, will include scripts passed in the html string
+jQuery.parseHTML = function( data, context, keepScripts ) {
+    if ( !data || typeof data !== &quot;string&quot; ) {
+        return null;
</ins><span class="cx">     }
</span><del>-
-    if ( index !== name ) {
-    props[ name ] = value;
-    delete props[ index ];
</del><ins>+    if ( typeof context === &quot;boolean&quot; ) {
+        keepScripts = context;
+        context = false;
</ins><span class="cx">     }
</span><ins>+    context = context || document;
</ins><span class="cx"> 
</span><del>-    hooks = jQuery.cssHooks[ name ];
-    if ( hooks &amp;&amp; &quot;expand&quot; in hooks ) {
-    value = hooks.expand( value );
-    delete props[ name ];
</del><ins>+    var parsed = rsingleTag.exec( data ),
+        scripts = !keepScripts &amp;&amp; [];
</ins><span class="cx"> 
</span><del>-    // not quite $.extend, this wont overwrite keys already present.
-    // also - reusing 'index' from above because we have the correct &quot;name&quot;
-    for ( index in value ) {
-    if ( !( index in props ) ) {
-    props[ index ] = value[ index ];
-    specialEasing[ index ] = easing;
</del><ins>+    // Single tag
+    if ( parsed ) {
+        return [ context.createElement( parsed[1] ) ];
</ins><span class="cx">     }
</span><del>-    }
-    } else {
-    specialEasing[ name ] = easing;
-    }
-    }
-}
</del><span class="cx"> 
</span><del>-jQuery.Animation = jQuery.extend( Animation, {
</del><ins>+    parsed = jQuery.buildFragment( [ data ], context, scripts );
</ins><span class="cx"> 
</span><del>-    tweener: function( props, callback ) {
-    if ( jQuery.isFunction( props ) ) {
-    callback = props;
-    props = [ &quot;*&quot; ];
-    } else {
-    props = props.split(&quot; &quot;);
</del><ins>+    if ( scripts &amp;&amp; scripts.length ) {
+        jQuery( scripts ).remove();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    var prop,
-    index = 0,
-    length = props.length;
</del><ins>+    return jQuery.merge( [], parsed.childNodes );
+};
</ins><span class="cx"> 
</span><del>-    for ( ; index &lt; length ; index++ ) {
-    prop = props[ index ];
-    tweeners[ prop ] = tweeners[ prop ] || [];
-    tweeners[ prop ].unshift( callback );
-    }
-    },
</del><span class="cx"> 
</span><del>-    prefilter: function( callback, prepend ) {
-    if ( prepend ) {
-    animationPrefilters.unshift( callback );
-    } else {
-    animationPrefilters.push( callback );
-    }
-    }
-});
</del><ins>+// Keep a copy of the old load method
+var _load = jQuery.fn.load;
</ins><span class="cx"> 
</span><del>-function defaultPrefilter( elem, props, opts ) {
-    /*jshint validthis:true */
-    var prop, index, length,
-    value, dataShow, toggle,
-    tween, hooks, oldfire,
-    anim = this,
-    style = elem.style,
-    orig = {},
-    handled = [],
-    hidden = elem.nodeType &amp;&amp; isHidden( elem );
-
-    // handle queue: false promises
-    if ( !opts.queue ) {
-    hooks = jQuery._queueHooks( elem, &quot;fx&quot; );
-    if ( hooks.unqueued == null ) {
-    hooks.unqueued = 0;
-    oldfire = hooks.empty.fire;
-    hooks.empty.fire = function() {
-    if ( !hooks.unqueued ) {
-    oldfire();
</del><ins>+/**
+ * Load a url into a page
+ */
+jQuery.fn.load = function( url, params, callback ) {
+    if ( typeof url !== &quot;string&quot; &amp;&amp; _load ) {
+        return _load.apply( this, arguments );
</ins><span class="cx">     }
</span><del>-    };
-    }
-    hooks.unqueued++;
</del><span class="cx"> 
</span><del>-    anim.always(function() {
-    // doing this makes sure that the complete handler will be called
-    // before this completes
-    anim.always(function() {
-    hooks.unqueued--;
-    if ( !jQuery.queue( elem, &quot;fx&quot; ).length ) {
-    hooks.empty.fire();
-    }
-    });
-    });
-    }
</del><ins>+    var selector, type, response,
+        self = this,
+        off = url.indexOf(&quot; &quot;);
</ins><span class="cx"> 
</span><del>-    // height/width overflow pass
-    if ( elem.nodeType === 1 &amp;&amp; ( &quot;height&quot; in props || &quot;width&quot; in props ) ) {
-    // Make sure that nothing sneaks out
-    // Record all 3 overflow attributes because IE does not
-    // change the overflow attribute when overflowX and
-    // overflowY are set to the same value
-    opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
-
-    // Set display property to inline-block for height/width
-    // animations on inline elements that are having width/height animated
-    if ( jQuery.css( elem, &quot;display&quot; ) === &quot;inline&quot; &amp;&amp;
-    jQuery.css( elem, &quot;float&quot; ) === &quot;none&quot; ) {
-
-    // inline-level elements accept inline-block;
-    // block-level elements need to be inline with layout
-    if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === &quot;inline&quot; ) {
-    style.display = &quot;inline-block&quot;;
-
-    } else {
-    style.zoom = 1;
</del><ins>+    if ( off &gt;= 0 ) {
+        selector = url.slice( off );
+        url = url.slice( 0, off );
</ins><span class="cx">     }
</span><del>-    }
-    }
</del><span class="cx"> 
</span><del>-    if ( opts.overflow ) {
-    style.overflow = &quot;hidden&quot;;
-    if ( !jQuery.support.shrinkWrapBlocks ) {
-    anim.always(function() {
-    style.overflow = opts.overflow[ 0 ];
-    style.overflowX = opts.overflow[ 1 ];
-    style.overflowY = opts.overflow[ 2 ];
-    });
-    }
-    }
</del><ins>+    // If it's a function
+    if ( jQuery.isFunction( params ) ) {
</ins><span class="cx"> 
</span><ins>+        // We assume that it's the callback
+        callback = params;
+        params = undefined;
</ins><span class="cx"> 
</span><del>-    // show/hide pass
-    for ( index in props ) {
-    value = props[ index ];
-    if ( rfxtypes.exec( value ) ) {
-    delete props[ index ];
-    toggle = toggle || value === &quot;toggle&quot;;
-    if ( value === ( hidden ? &quot;hide&quot; : &quot;show&quot; ) ) {
-    continue;
</del><ins>+    // Otherwise, build a param string
+    } else if ( params &amp;&amp; typeof params === &quot;object&quot; ) {
+        type = &quot;POST&quot;;
</ins><span class="cx">     }
</span><del>-    handled.push( index );
-    }
-    }
</del><span class="cx"> 
</span><del>-    length = handled.length;
-    if ( length ) {
-    dataShow = jQuery._data( elem, &quot;fxshow&quot; ) || jQuery._data( elem, &quot;fxshow&quot;, {} );
-    if ( &quot;hidden&quot; in dataShow ) {
-    hidden = dataShow.hidden;
-    }
</del><ins>+    // If we have elements to modify, make the request
+    if ( self.length &gt; 0 ) {
+        jQuery.ajax({
+            url: url,
</ins><span class="cx"> 
</span><del>-    // store state if its toggle - enables .stop().toggle() to &quot;reverse&quot;
-    if ( toggle ) {
-    dataShow.hidden = !hidden;
-    }
-    if ( hidden ) {
-    jQuery( elem ).show();
-    } else {
-    anim.done(function() {
-    jQuery( elem ).hide();
-    });
-    }
-    anim.done(function() {
-    var prop;
-    jQuery._removeData( elem, &quot;fxshow&quot; );
-    for ( prop in orig ) {
-    jQuery.style( elem, prop, orig[ prop ] );
-    }
-    });
-    for ( index = 0 ; index &lt; length ; index++ ) {
-    prop = handled[ index ];
-    tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 );
-    orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop );
</del><ins>+            // if &quot;type&quot; variable is undefined, then &quot;GET&quot; method will be used
+            type: type,
+            dataType: &quot;html&quot;,
+            data: params
+        }).done(function( responseText ) {
</ins><span class="cx"> 
</span><del>-    if ( !( prop in dataShow ) ) {
-    dataShow[ prop ] = tween.start;
-    if ( hidden ) {
-    tween.end = tween.start;
-    tween.start = prop === &quot;width&quot; || prop === &quot;height&quot; ? 1 : 0;
-    }
-    }
-    }
-    }
-}
</del><ins>+            // Save response for use in complete callback
+            response = arguments;
</ins><span class="cx"> 
</span><del>-function Tween( elem, options, prop, end, easing ) {
-    return new Tween.prototype.init( elem, options, prop, end, easing );
-}
-jQuery.Tween = Tween;
</del><ins>+            self.html( selector ?
</ins><span class="cx"> 
</span><del>-Tween.prototype = {
-    constructor: Tween,
-    init: function( elem, options, prop, end, easing, unit ) {
-    this.elem = elem;
-    this.prop = prop;
-    this.easing = easing || &quot;swing&quot;;
-    this.options = options;
-    this.start = this.now = this.cur();
-    this.end = end;
-    this.unit = unit || ( jQuery.cssNumber[ prop ] ? &quot;&quot; : &quot;px&quot; );
-    },
-    cur: function() {
-    var hooks = Tween.propHooks[ this.prop ];
</del><ins>+                // If a selector was specified, locate the right elements in a dummy div
+                // Exclude scripts to avoid IE 'Permission Denied' errors
+                jQuery(&quot;&lt;div&gt;&quot;).append( jQuery.parseHTML( responseText ) ).find( selector ) :
</ins><span class="cx"> 
</span><del>-    return hooks &amp;&amp; hooks.get ?
-    hooks.get( this ) :
-    Tween.propHooks._default.get( this );
-    },
-    run: function( percent ) {
-    var eased,
-    hooks = Tween.propHooks[ this.prop ];
</del><ins>+                // Otherwise use the full result
+                responseText );
</ins><span class="cx"> 
</span><del>-    if ( this.options.duration ) {
-    this.pos = eased = jQuery.easing[ this.easing ](
-    percent, this.options.duration * percent, 0, 1, this.options.duration
-    );
-    } else {
-    this.pos = eased = percent;
</del><ins>+        }).complete( callback &amp;&amp; function( jqXHR, status ) {
+            self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
+        });
</ins><span class="cx">     }
</span><del>-    this.now = ( this.end - this.start ) * eased + this.start;
</del><span class="cx"> 
</span><del>-    if ( this.options.step ) {
-    this.options.step.call( this.elem, this.now, this );
-    }
-
-    if ( hooks &amp;&amp; hooks.set ) {
-    hooks.set( this );
-    } else {
-    Tween.propHooks._default.set( this );
-    }
</del><span class="cx">     return this;
</span><del>-    }
</del><span class="cx"> };
</span><span class="cx"> 
</span><del>-Tween.prototype.init.prototype = Tween.prototype;
</del><span class="cx"> 
</span><del>-Tween.propHooks = {
-    _default: {
-    get: function( tween ) {
-    var result;
</del><span class="cx"> 
</span><del>-    if ( tween.elem[ tween.prop ] != null &amp;&amp;
-    (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
-    return tween.elem[ tween.prop ];
-    }
</del><span class="cx"> 
</span><del>-    // passing an empty string as a 3rd parameter to .css will automatically
-    // attempt a parseFloat and fallback to a string if the parse fails
-    // so, simple values such as &quot;10px&quot; are parsed to Float.
-    // complex values such as &quot;rotate(1rad)&quot; are returned as is.
-    result = jQuery.css( tween.elem, tween.prop, &quot;&quot; );
-    // Empty strings, null, undefined and &quot;auto&quot; are converted to 0.
-    return !result || result === &quot;auto&quot; ? 0 : result;
-    },
-    set: function( tween ) {
-    // use step hook for back compat - use cssHook if its there - use .style if its
-    // available and use plain properties where available
-    if ( jQuery.fx.step[ tween.prop ] ) {
-    jQuery.fx.step[ tween.prop ]( tween );
-    } else if ( tween.elem.style &amp;&amp; ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
-    jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
-    } else {
-    tween.elem[ tween.prop ] = tween.now;
-    }
-    }
-    }
</del><ins>+jQuery.expr.filters.animated = function( elem ) {
+    return jQuery.grep(jQuery.timers, function( fn ) {
+        return elem === fn.elem;
+    }).length;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-// Remove in 2.0 - this supports IE8's panic based approach
-// to setting things on disconnected nodes
</del><span class="cx"> 
</span><del>-Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
-    set: function( tween ) {
-    if ( tween.elem.nodeType &amp;&amp; tween.elem.parentNode ) {
-    tween.elem[ tween.prop ] = tween.now;
-    }
-    }
-};
</del><span class="cx"> 
</span><del>-jQuery.each([ &quot;toggle&quot;, &quot;show&quot;, &quot;hide&quot; ], function( i, name ) {
-    var cssFn = jQuery.fn[ name ];
-    jQuery.fn[ name ] = function( speed, easing, callback ) {
-    return speed == null || typeof speed === &quot;boolean&quot; ?
-    cssFn.apply( this, arguments ) :
-    this.animate( genFx( name, true ), speed, easing, callback );
-    };
-});
</del><span class="cx"> 
</span><del>-jQuery.fn.extend({
-    fadeTo: function( speed, to, easing, callback ) {
</del><ins>+var docElem = window.document.documentElement;
</ins><span class="cx"> 
</span><del>-    // show any hidden elements after setting opacity to 0
-    return this.filter( isHidden ).css( &quot;opacity&quot;, 0 ).show()
</del><ins>+/**
+ * Gets a window from an element
+ */
+function getWindow( elem ) {
+    return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 &amp;&amp; elem.defaultView;
+}
</ins><span class="cx"> 
</span><del>-    // animate to the value specified
-    .end().animate({ opacity: to }, speed, easing, callback );
-    },
-    animate: function( prop, speed, easing, callback ) {
-    var empty = jQuery.isEmptyObject( prop ),
-    optall = jQuery.speed( speed, easing, callback ),
-    doAnimation = function() {
-    // Operate on a copy of prop so per-property easing won't be lost
-    var anim = Animation( this, jQuery.extend( {}, prop ), optall );
-    doAnimation.finish = function() {
-    anim.stop( true );
-    };
-    // Empty animations, or finishing resolves immediately
-    if ( empty || jQuery._data( this, &quot;finish&quot; ) ) {
-    anim.stop( true );
-    }
-    };
-    doAnimation.finish = doAnimation;
</del><ins>+jQuery.offset = {
+    setOffset: function( elem, options, i ) {
+        var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
+            position = jQuery.css( elem, &quot;position&quot; ),
+            curElem = jQuery( elem ),
+            props = {};
</ins><span class="cx"> 
</span><del>-    return empty || optall.queue === false ?
-    this.each( doAnimation ) :
-    this.queue( optall.queue, doAnimation );
-    },
-    stop: function( type, clearQueue, gotoEnd ) {
-    var stopQueue = function( hooks ) {
-    var stop = hooks.stop;
-    delete hooks.stop;
-    stop( gotoEnd );
-    };
</del><ins>+        // Set position first, in-case top/left are set even on static elem
+        if ( position === &quot;static&quot; ) {
+            elem.style.position = &quot;relative&quot;;
+        }
</ins><span class="cx"> 
</span><del>-    if ( typeof type !== &quot;string&quot; ) {
-    gotoEnd = clearQueue;
-    clearQueue = type;
-    type = undefined;
-    }
-    if ( clearQueue &amp;&amp; type !== false ) {
-    this.queue( type || &quot;fx&quot;, [] );
-    }
</del><ins>+        curOffset = curElem.offset();
+        curCSSTop = jQuery.css( elem, &quot;top&quot; );
+        curCSSLeft = jQuery.css( elem, &quot;left&quot; );
+        calculatePosition = ( position === &quot;absolute&quot; || position === &quot;fixed&quot; ) &amp;&amp;
+            ( curCSSTop + curCSSLeft ).indexOf(&quot;auto&quot;) &gt; -1;
</ins><span class="cx"> 
</span><del>-    return this.each(function() {
-    var dequeue = true,
-    index = type != null &amp;&amp; type + &quot;queueHooks&quot;,
-    timers = jQuery.timers,
-    data = jQuery._data( this );
</del><ins>+        // Need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+        if ( calculatePosition ) {
+            curPosition = curElem.position();
+            curTop = curPosition.top;
+            curLeft = curPosition.left;
</ins><span class="cx"> 
</span><del>-    if ( index ) {
-    if ( data[ index ] &amp;&amp; data[ index ].stop ) {
-    stopQueue( data[ index ] );
-    }
-    } else {
-    for ( index in data ) {
-    if ( data[ index ] &amp;&amp; data[ index ].stop &amp;&amp; rrun.test( index ) ) {
-    stopQueue( data[ index ] );
-    }
-    }
-    }
</del><ins>+        } else {
+            curTop = parseFloat( curCSSTop ) || 0;
+            curLeft = parseFloat( curCSSLeft ) || 0;
+        }
</ins><span class="cx"> 
</span><del>-    for ( index = timers.length; index--; ) {
-    if ( timers[ index ].elem === this &amp;&amp; (type == null || timers[ index ].queue === type) ) {
-    timers[ index ].anim.stop( gotoEnd );
-    dequeue = false;
-    timers.splice( index, 1 );
-    }
-    }
</del><ins>+        if ( jQuery.isFunction( options ) ) {
+            options = options.call( elem, i, curOffset );
+        }
</ins><span class="cx"> 
</span><del>-    // start the next in the queue if the last step wasn't forced
-    // timers currently will call their complete callbacks, which will dequeue
-    // but only if they were gotoEnd
-    if ( dequeue || !gotoEnd ) {
-    jQuery.dequeue( this, type );
-    }
-    });
-    },
-    finish: function( type ) {
-    if ( type !== false ) {
-    type = type || &quot;fx&quot;;
-    }
-    return this.each(function() {
-    var index,
-    data = jQuery._data( this ),
-    queue = data[ type + &quot;queue&quot; ],
-    hooks = data[ type + &quot;queueHooks&quot; ],
-    timers = jQuery.timers,
-    length = queue ? queue.length : 0;
</del><ins>+        if ( options.top != null ) {
+            props.top = ( options.top - curOffset.top ) + curTop;
+        }
+        if ( options.left != null ) {
+            props.left = ( options.left - curOffset.left ) + curLeft;
+        }
</ins><span class="cx"> 
</span><del>-    // enable finishing flag on private data
-    data.finish = true;
</del><ins>+        if ( &quot;using&quot; in options ) {
+            options.using.call( elem, props );
</ins><span class="cx"> 
</span><del>-    // empty the queue first
-    jQuery.queue( this, type, [] );
-
-    if ( hooks &amp;&amp; hooks.cur &amp;&amp; hooks.cur.finish ) {
-    hooks.cur.finish.call( this );
</del><ins>+        } else {
+            curElem.css( props );
+        }
</ins><span class="cx">     }
</span><ins>+};
</ins><span class="cx"> 
</span><del>-    // look for any active animations, and finish them
-    for ( index = timers.length; index--; ) {
-    if ( timers[ index ].elem === this &amp;&amp; timers[ index ].queue === type ) {
-    timers[ index ].anim.stop( true );
-    timers.splice( index, 1 );
-    }
-    }
</del><ins>+jQuery.fn.extend({
+    offset: function( options ) {
+        if ( arguments.length ) {
+            return options === undefined ?
+                this :
+                this.each(function( i ) {
+                    jQuery.offset.setOffset( this, options, i );
+                });
+        }
</ins><span class="cx"> 
</span><del>-    // look for any animations in the old queue and finish them
-    for ( index = 0; index &lt; length; index++ ) {
-    if ( queue[ index ] &amp;&amp; queue[ index ].finish ) {
-    queue[ index ].finish.call( this );
-    }
-    }
</del><ins>+        var docElem, win,
+            elem = this[ 0 ],
+            box = { top: 0, left: 0 },
+            doc = elem &amp;&amp; elem.ownerDocument;
</ins><span class="cx"> 
</span><del>-    // turn off finishing flag
-    delete data.finish;
-    });
-    }
-});
</del><ins>+        if ( !doc ) {
+            return;
+        }
</ins><span class="cx"> 
</span><del>-// Generate parameters to create a standard animation
-function genFx( type, includeWidth ) {
-    var which,
-    attrs = { height: type },
-    i = 0;
</del><ins>+        docElem = doc.documentElement;
</ins><span class="cx"> 
</span><del>-    // if we include width, step value is 1 to do all cssExpand values,
-    // if we don't include width, step value is 2 to skip over Left and Right
-    includeWidth = includeWidth? 1 : 0;
-    for( ; i &lt; 4 ; i += 2 - includeWidth ) {
-    which = cssExpand[ i ];
-    attrs[ &quot;margin&quot; + which ] = attrs[ &quot;padding&quot; + which ] = type;
-    }
</del><ins>+        // Make sure it's not a disconnected DOM node
+        if ( !jQuery.contains( docElem, elem ) ) {
+            return box;
+        }
</ins><span class="cx"> 
</span><del>-    if ( includeWidth ) {
-    attrs.opacity = attrs.width = type;
-    }
</del><ins>+        // If we don't have gBCR, just use 0,0 rather than error
+        // BlackBerry 5, iOS 3 (original iPhone)
+        if ( typeof elem.getBoundingClientRect !== strundefined ) {
+            box = elem.getBoundingClientRect();
+        }
+        win = getWindow( doc );
+        return {
+            top: box.top + win.pageYOffset - docElem.clientTop,
+            left: box.left + win.pageXOffset - docElem.clientLeft
+        };
+    },
</ins><span class="cx"> 
</span><del>-    return attrs;
-}
</del><ins>+    position: function() {
+        if ( !this[ 0 ] ) {
+            return;
+        }
</ins><span class="cx"> 
</span><del>-// Generate shortcuts for custom animations
-jQuery.each({
-    slideDown: genFx(&quot;show&quot;),
-    slideUp: genFx(&quot;hide&quot;),
-    slideToggle: genFx(&quot;toggle&quot;),
-    fadeIn: { opacity: &quot;show&quot; },
-    fadeOut: { opacity: &quot;hide&quot; },
-    fadeToggle: { opacity: &quot;toggle&quot; }
-}, function( name, props ) {
-    jQuery.fn[ name ] = function( speed, easing, callback ) {
-    return this.animate( props, speed, easing, callback );
-    };
-});
</del><ins>+        var offsetParent, offset,
+            elem = this[ 0 ],
+            parentOffset = { top: 0, left: 0 };
</ins><span class="cx"> 
</span><del>-jQuery.speed = function( speed, easing, fn ) {
-    var opt = speed &amp;&amp; typeof speed === &quot;object&quot; ? jQuery.extend( {}, speed ) : {
-    complete: fn || !fn &amp;&amp; easing ||
-    jQuery.isFunction( speed ) &amp;&amp; speed,
-    duration: speed,
-    easing: fn &amp;&amp; easing || easing &amp;&amp; !jQuery.isFunction( easing ) &amp;&amp; easing
-    };
</del><ins>+        // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
+        if ( jQuery.css( elem, &quot;position&quot; ) === &quot;fixed&quot; ) {
+            // We assume that getBoundingClientRect is available when computed position is fixed
+            offset = elem.getBoundingClientRect();
</ins><span class="cx"> 
</span><del>-    opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === &quot;number&quot; ? opt.duration :
-    opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
</del><ins>+        } else {
+            // Get *real* offsetParent
+            offsetParent = this.offsetParent();
</ins><span class="cx"> 
</span><del>-    // normalize opt.queue - true/undefined/null -&gt; &quot;fx&quot;
-    if ( opt.queue == null || opt.queue === true ) {
-    opt.queue = &quot;fx&quot;;
-    }
</del><ins>+            // Get correct offsets
+            offset = this.offset();
+            if ( !jQuery.nodeName( offsetParent[ 0 ], &quot;html&quot; ) ) {
+                parentOffset = offsetParent.offset();
+            }
</ins><span class="cx"> 
</span><del>-    // Queueing
-    opt.old = opt.complete;
</del><ins>+            // Add offsetParent borders
+            parentOffset.top += jQuery.css( offsetParent[ 0 ], &quot;borderTopWidth&quot;, true );
+            parentOffset.left += jQuery.css( offsetParent[ 0 ], &quot;borderLeftWidth&quot;, true );
+        }
</ins><span class="cx"> 
</span><del>-    opt.complete = function() {
-    if ( jQuery.isFunction( opt.old ) ) {
-    opt.old.call( this );
-    }
-
-    if ( opt.queue ) {
-    jQuery.dequeue( this, opt.queue );
-    }
-    };
-
-    return opt;
-};
-
-jQuery.easing = {
-    linear: function( p ) {
-    return p;
</del><ins>+        // Subtract parent offsets and element margins
+        return {
+            top: offset.top - parentOffset.top - jQuery.css( elem, &quot;marginTop&quot;, true ),
+            left: offset.left - parentOffset.left - jQuery.css( elem, &quot;marginLeft&quot;, true )
+        };
</ins><span class="cx">     },
</span><del>-    swing: function( p ) {
-    return 0.5 - Math.cos( p*Math.PI ) / 2;
-    }
-};
</del><span class="cx"> 
</span><del>-jQuery.timers = [];
-jQuery.fx = Tween.prototype.init;
-jQuery.fx.tick = function() {
-    var timer,
-    timers = jQuery.timers,
-    i = 0;
</del><ins>+    offsetParent: function() {
+        return this.map(function() {
+            var offsetParent = this.offsetParent || docElem;
</ins><span class="cx"> 
</span><del>-    fxNow = jQuery.now();
</del><ins>+            while ( offsetParent &amp;&amp; ( !jQuery.nodeName( offsetParent, &quot;html&quot; ) &amp;&amp; jQuery.css( offsetParent, &quot;position&quot; ) === &quot;static&quot; ) ) {
+                offsetParent = offsetParent.offsetParent;
+            }
</ins><span class="cx"> 
</span><del>-    for ( ; i &lt; timers.length; i++ ) {
-    timer = timers[ i ];
-    // Checks the timer has not already been removed
-    if ( !timer() &amp;&amp; timers[ i ] === timer ) {
-    timers.splice( i--, 1 );
</del><ins>+            return offsetParent || docElem;
+        });
</ins><span class="cx">     }
</span><del>-    }
</del><ins>+});
</ins><span class="cx"> 
</span><del>-    if ( !timers.length ) {
-    jQuery.fx.stop();
-    }
-    fxNow = undefined;
-};
</del><ins>+// Create scrollLeft and scrollTop methods
+jQuery.each( { scrollLeft: &quot;pageXOffset&quot;, scrollTop: &quot;pageYOffset&quot; }, function( method, prop ) {
+    var top = &quot;pageYOffset&quot; === prop;
</ins><span class="cx"> 
</span><del>-jQuery.fx.timer = function( timer ) {
-    if ( timer() &amp;&amp; jQuery.timers.push( timer ) ) {
-    jQuery.fx.start();
-    }
-};
</del><ins>+    jQuery.fn[ method ] = function( val ) {
+        return access( this, function( elem, method, val ) {
+            var win = getWindow( elem );
</ins><span class="cx"> 
</span><del>-jQuery.fx.interval = 13;
</del><ins>+            if ( val === undefined ) {
+                return win ? win[ prop ] : elem[ method ];
+            }
</ins><span class="cx"> 
</span><del>-jQuery.fx.start = function() {
-    if ( !timerId ) {
-    timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
-    }
-};
</del><ins>+            if ( win ) {
+                win.scrollTo(
+                    !top ? val : window.pageXOffset,
+                    top ? val : window.pageYOffset
+                );
</ins><span class="cx"> 
</span><del>-jQuery.fx.stop = function() {
-    clearInterval( timerId );
-    timerId = null;
-};
-
-jQuery.fx.speeds = {
-    slow: 600,
-    fast: 200,
-    // Default speed
-    _default: 400
-};
-
-// Back Compat &lt;1.8 extension point
-jQuery.fx.step = {};
-
-if ( jQuery.expr &amp;&amp; jQuery.expr.filters ) {
-    jQuery.expr.filters.animated = function( elem ) {
-    return jQuery.grep(jQuery.timers, function( fn ) {
-    return elem === fn.elem;
-    }).length;
</del><ins>+            } else {
+                elem[ method ] = val;
+            }
+        }, method, val, arguments.length, null );
</ins><span class="cx">     };
</span><del>-}
-jQuery.fn.offset = function( options ) {
-    if ( arguments.length ) {
-    return options === undefined ?
-    this :
-    this.each(function( i ) {
-    jQuery.offset.setOffset( this, options, i );
-    });
-    }
</del><ins>+});
</ins><span class="cx"> 
</span><del>-    var docElem, win,
-    box = { top: 0, left: 0 },
-    elem = this[ 0 ],
-    doc = elem &amp;&amp; elem.ownerDocument;
</del><ins>+// Add the top/left cssHooks using jQuery.fn.position
+// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+// getComputedStyle returns percent when specified for top/left/bottom/right
+// rather than make the css module depend on the offset module, we just check for it here
+jQuery.each( [ &quot;top&quot;, &quot;left&quot; ], function( i, prop ) {
+    jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
+        function( elem, computed ) {
+            if ( computed ) {
+                computed = curCSS( elem, prop );
+                // if curCSS returns percentage, fallback to offset
+                return rnumnonpx.test( computed ) ?
+                    jQuery( elem ).position()[ prop ] + &quot;px&quot; :
+                    computed;
+            }
+        }
+    );
+});
</ins><span class="cx"> 
</span><del>-    if ( !doc ) {
-    return;
-    }
</del><span class="cx"> 
</span><del>-    docElem = doc.documentElement;
</del><ins>+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
+jQuery.each( { Height: &quot;height&quot;, Width: &quot;width&quot; }, function( name, type ) {
+    jQuery.each( { padding: &quot;inner&quot; + name, content: type, &quot;&quot;: &quot;outer&quot; + name }, function( defaultExtra, funcName ) {
+        // margin is only for outerHeight, outerWidth
+        jQuery.fn[ funcName ] = function( margin, value ) {
+            var chainable = arguments.length &amp;&amp; ( defaultExtra || typeof margin !== &quot;boolean&quot; ),
+                extra = defaultExtra || ( margin === true || value === true ? &quot;margin&quot; : &quot;border&quot; );
</ins><span class="cx"> 
</span><del>-    // Make sure it's not a disconnected DOM node
-    if ( !jQuery.contains( docElem, elem ) ) {
-    return box;
-    }
</del><ins>+            return access( this, function( elem, type, value ) {
+                var doc;
</ins><span class="cx"> 
</span><del>-    // If we don't have gBCR, just use 0,0 rather than error
-    // BlackBerry 5, iOS 3 (original iPhone)
-    if ( typeof elem.getBoundingClientRect !== core_strundefined ) {
-    box = elem.getBoundingClientRect();
-    }
-    win = getWindow( doc );
-    return {
-    top: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),
-    left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
-    };
-};
</del><ins>+                if ( jQuery.isWindow( elem ) ) {
+                    // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
+                    // isn't a whole lot we can do. See pull request at this URL for discussion:
+                    // https://github.com/jquery/jquery/pull/764
+                    return elem.document.documentElement[ &quot;client&quot; + name ];
+                }
</ins><span class="cx"> 
</span><del>-jQuery.offset = {
</del><ins>+                // Get document width or height
+                if ( elem.nodeType === 9 ) {
+                    doc = elem.documentElement;
</ins><span class="cx"> 
</span><del>-    setOffset: function( elem, options, i ) {
-    var position = jQuery.css( elem, &quot;position&quot; );
</del><ins>+                    // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
+                    // whichever is greatest
+                    return Math.max(
+                        elem.body[ &quot;scroll&quot; + name ], doc[ &quot;scroll&quot; + name ],
+                        elem.body[ &quot;offset&quot; + name ], doc[ &quot;offset&quot; + name ],
+                        doc[ &quot;client&quot; + name ]
+                    );
+                }
</ins><span class="cx"> 
</span><del>-    // set position first, in-case top/left are set even on static elem
-    if ( position === &quot;static&quot; ) {
-    elem.style.position = &quot;relative&quot;;
-    }
</del><ins>+                return value === undefined ?
+                    // Get width or height on the element, requesting but not forcing parseFloat
+                    jQuery.css( elem, type, extra ) :
</ins><span class="cx"> 
</span><del>-    var curElem = jQuery( elem ),
-    curOffset = curElem.offset(),
-    curCSSTop = jQuery.css( elem, &quot;top&quot; ),
-    curCSSLeft = jQuery.css( elem, &quot;left&quot; ),
-    calculatePosition = ( position === &quot;absolute&quot; || position === &quot;fixed&quot; ) &amp;&amp; jQuery.inArray(&quot;auto&quot;, [curCSSTop, curCSSLeft]) &gt; -1,
-    props = {}, curPosition = {}, curTop, curLeft;
</del><ins>+                    // Set width or height on the element
+                    jQuery.style( elem, type, value, extra );
+            }, type, chainable ? margin : undefined, chainable, null );
+        };
+    });
+});
</ins><span class="cx"> 
</span><del>-    // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
-    if ( calculatePosition ) {
-    curPosition = curElem.position();
-    curTop = curPosition.top;
-    curLeft = curPosition.left;
-    } else {
-    curTop = parseFloat( curCSSTop ) || 0;
-    curLeft = parseFloat( curCSSLeft ) || 0;
-    }
</del><span class="cx"> 
</span><del>-    if ( jQuery.isFunction( options ) ) {
-    options = options.call( elem, i, curOffset );
-    }
-
-    if ( options.top != null ) {
-    props.top = ( options.top - curOffset.top ) + curTop;
-    }
-    if ( options.left != null ) {
-    props.left = ( options.left - curOffset.left ) + curLeft;
-    }
-
-    if ( &quot;using&quot; in options ) {
-    options.using.call( elem, props );
-    } else {
-    curElem.css( props );
-    }
-    }
</del><ins>+// The number of elements contained in the matched element set
+jQuery.fn.size = function() {
+    return this.length;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><ins>+jQuery.fn.andSelf = jQuery.fn.addBack;
</ins><span class="cx"> 
</span><del>-jQuery.fn.extend({
</del><span class="cx"> 
</span><del>-    position: function() {
-    if ( !this[ 0 ] ) {
-    return;
-    }
</del><span class="cx"> 
</span><del>-    var offsetParent, offset,
-    parentOffset = { top: 0, left: 0 },
-    elem = this[ 0 ];
</del><span class="cx"> 
</span><del>-    // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
-    if ( jQuery.css( elem, &quot;position&quot; ) === &quot;fixed&quot; ) {
-    // we assume that getBoundingClientRect is available when computed position is fixed
-    offset = elem.getBoundingClientRect();
-    } else {
-    // Get *real* offsetParent
-    offsetParent = this.offsetParent();
-
-    // Get correct offsets
-    offset = this.offset();
-    if ( !jQuery.nodeName( offsetParent[ 0 ], &quot;html&quot; ) ) {
-    parentOffset = offsetParent.offset();
-    }
-
-    // Add offsetParent borders
-    parentOffset.top  += jQuery.css( offsetParent[ 0 ], &quot;borderTopWidth&quot;, true );
-    parentOffset.left += jQuery.css( offsetParent[ 0 ], &quot;borderLeftWidth&quot;, true );
-    }
-
-    // Subtract parent offsets and element margins
-    // note: when an element has margin: auto the offsetLeft and marginLeft
-    // are the same in Safari causing offset.left to incorrectly be 0
-    return {
-    top:  offset.top  - parentOffset.top - jQuery.css( elem, &quot;marginTop&quot;, true ),
-    left: offset.left - parentOffset.left - jQuery.css( elem, &quot;marginLeft&quot;, true)
-    };
-    },
-
-    offsetParent: function() {
-    return this.map(function() {
-    var offsetParent = this.offsetParent || document.documentElement;
-    while ( offsetParent &amp;&amp; ( !jQuery.nodeName( offsetParent, &quot;html&quot; ) &amp;&amp; jQuery.css( offsetParent, &quot;position&quot;) === &quot;static&quot; ) ) {
-    offsetParent = offsetParent.offsetParent;
-    }
-    return offsetParent || document.documentElement;
</del><ins>+// Register as a named AMD module, since jQuery can be concatenated with other
+// files that may use define, but not via a proper concatenation script that
+// understands anonymous AMD modules. A named AMD is safest and most robust
+// way to register. Lowercase jquery is used because AMD module names are
+// derived from file names, and jQuery is normally delivered in a lowercase
+// file name. Do this after creating the global so that if an AMD module wants
+// to call noConflict to hide this version of jQuery, it will work.
+if ( typeof define === &quot;function&quot; &amp;&amp; define.amd ) {
+    define( &quot;jquery&quot;, [], function() {
+        return jQuery;
</ins><span class="cx">     });
</span><del>-    }
-});
</del><ins>+}
</ins><span class="cx"> 
</span><span class="cx"> 
</span><del>-// Create scrollLeft and scrollTop methods
-jQuery.each( {scrollLeft: &quot;pageXOffset&quot;, scrollTop: &quot;pageYOffset&quot;}, function( method, prop ) {
-    var top = /Y/.test( prop );
</del><span class="cx"> 
</span><del>-    jQuery.fn[ method ] = function( val ) {
-    return jQuery.access( this, function( elem, method, val ) {
-    var win = getWindow( elem );
</del><span class="cx"> 
</span><del>-    if ( val === undefined ) {
-    return win ? (prop in win) ? win[ prop ] :
-    win.document.documentElement[ method ] :
-    elem[ method ];
-    }
</del><ins>+var
+    // Map over jQuery in case of overwrite
+    _jQuery = window.jQuery,
</ins><span class="cx"> 
</span><del>-    if ( win ) {
-    win.scrollTo(
-    !top ? val : jQuery( win ).scrollLeft(),
-    top ? val : jQuery( win ).scrollTop()
-    );
</del><ins>+    // Map over the $ in case of overwrite
+    _$ = window.$;
</ins><span class="cx"> 
</span><del>-    } else {
-    elem[ method ] = val;
</del><ins>+jQuery.noConflict = function( deep ) {
+    if ( window.$ === jQuery ) {
+        window.$ = _$;
</ins><span class="cx">     }
</span><del>-    }, method, val, arguments.length, null );
-    };
-});
</del><span class="cx"> 
</span><del>-function getWindow( elem ) {
-    return jQuery.isWindow( elem ) ?
-    elem :
-    elem.nodeType === 9 ?
-    elem.defaultView || elem.parentWindow :
-    false;
-}
-// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
-jQuery.each( { Height: &quot;height&quot;, Width: &quot;width&quot; }, function( name, type ) {
-    jQuery.each( { padding: &quot;inner&quot; + name, content: type, &quot;&quot;: &quot;outer&quot; + name }, function( defaultExtra, funcName ) {
-    // margin is only for outerHeight, outerWidth
-    jQuery.fn[ funcName ] = function( margin, value ) {
-    var chainable = arguments.length &amp;&amp; ( defaultExtra || typeof margin !== &quot;boolean&quot; ),
-    extra = defaultExtra || ( margin === true || value === true ? &quot;margin&quot; : &quot;border&quot; );
-
-    return jQuery.access( this, function( elem, type, value ) {
-    var doc;
-
-    if ( jQuery.isWindow( elem ) ) {
-    // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
-    // isn't a whole lot we can do. See pull request at this URL for discussion:
-    // https://github.com/jquery/jquery/pull/764
-    return elem.document.documentElement[ &quot;client&quot; + name ];
</del><ins>+    if ( deep &amp;&amp; window.jQuery === jQuery ) {
+        window.jQuery = _jQuery;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Get document width or height
-    if ( elem.nodeType === 9 ) {
-    doc = elem.documentElement;
</del><ins>+    return jQuery;
+};
</ins><span class="cx"> 
</span><del>-    // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
-    // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
-    return Math.max(
-    elem.body[ &quot;scroll&quot; + name ], doc[ &quot;scroll&quot; + name ],
-    elem.body[ &quot;offset&quot; + name ], doc[ &quot;offset&quot; + name ],
-    doc[ &quot;client&quot; + name ]
-    );
-    }
</del><ins>+// Expose jQuery and $ identifiers, even in
+// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
+// and CommonJS for browser emulators (#13566)
+if ( typeof noGlobal === strundefined ) {
+    window.jQuery = window.$ = jQuery;
+}
</ins><span class="cx"> 
</span><del>-    return value === undefined ?
-    // Get width or height on the element, requesting but not forcing parseFloat
-    jQuery.css( elem, type, extra ) :
</del><span class="cx"> 
</span><del>-    // Set width or height on the element
-    jQuery.style( elem, type, value, extra );
-    }, type, chainable ? margin : undefined, chainable, null );
-    };
-    });
-});
-// Limit scope pollution from any deprecated API
-// (function() {
</del><span class="cx"> 
</span><del>-// })();
-// Expose jQuery to the global object
-window.jQuery = window.$ = jQuery;
</del><span class="cx"> 
</span><del>-// Expose jQuery as an AMD module, but only for AMD loaders that
-// understand the issues with loading multiple versions of jQuery
-// in a page that all might call define(). The loader will indicate
-// they have special allowances for multiple jQuery versions by
-// specifying define.amd.jQuery = true. Register as a named module,
-// since jQuery can be concatenated with other files that may use define,
-// but not use a proper concatenation script that understands anonymous
-// AMD modules. A named AMD is safest and most robust way to register.
-// Lowercase jquery is used because AMD module names are derived from
-// file names, and jQuery is normally delivered in a lowercase file name.
-// Do this after creating the global so that if an AMD module wants to call
-// noConflict to hide this version of jQuery, it will work.
-if ( typeof define === &quot;function&quot; &amp;&amp; define.amd &amp;&amp; define.amd.jQuery ) {
-    define( &quot;jquery&quot;, [], function () { return jQuery; } );
-}
</del><ins>+return jQuery;
</ins><span class="cx"> 
</span><del>-})( window );
</del><span class="cx">\ No newline at end of file
</span><ins>+}));
</ins></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbower_componentstodomvccommonbasecss"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/todomvc-common/base.css (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/todomvc-common/base.css        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/todomvc-common/base.css        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -14,7 +14,6 @@
</span><span class="cx">     font-family: inherit;
</span><span class="cx">     color: inherit;
</span><span class="cx">     -webkit-appearance: none;
</span><del>-    /*-moz-appearance: none;*/
</del><span class="cx">     -ms-appearance: none;
</span><span class="cx">     -o-appearance: none;
</span><span class="cx">     appearance: none;
</span><span class="lines">@@ -34,6 +33,11 @@
</span><span class="cx">     font-smoothing: antialiased;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+button,
+input[type=&quot;checkbox&quot;] {
+  outline: none;
+}
+
</ins><span class="cx"> #todoapp {
</span><span class="cx">     background: #fff;
</span><span class="cx">     background: rgba(255, 255, 255, 0.9);
</span><span class="lines">@@ -43,7 +47,7 @@
</span><span class="cx">     border-top-left-radius: 2px;
</span><span class="cx">     border-top-right-radius: 2px;
</span><span class="cx">     box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
</span><del>-    0 25px 50px 0 rgba(0, 0, 0, 0.15);
</del><ins>+                0 25px 50px 0 rgba(0, 0, 0, 0.15);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #todoapp:before {
</span><span class="lines">@@ -100,9 +104,6 @@
</span><span class="cx">     background: #8d7d77;
</span><span class="cx">     background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
</span><span class="cx">     background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
</span><del>-    background: -moz-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-    background: -o-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-    background: -ms-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
</del><span class="cx">     background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
</span><span class="cx">     filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
</span><span class="cx">     border-top-left-radius: 1px;
</span><span class="lines">@@ -123,7 +124,6 @@
</span><span class="cx">     padding: 6px;
</span><span class="cx">     border: 1px solid #999;
</span><span class="cx">     box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
</span><del>-    -webkit-box-sizing: border-box;
</del><span class="cx">     -moz-box-sizing: border-box;
</span><span class="cx">     -ms-box-sizing: border-box;
</span><span class="cx">     -o-box-sizing: border-box;
</span><span class="lines">@@ -159,7 +159,8 @@
</span><span class="cx">     left: -4px;
</span><span class="cx">     width: 40px;
</span><span class="cx">     text-align: center;
</span><del>-    border: none; /* Mobile Safari */
</del><ins>+    /* Mobile Safari */
+    border: none;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #toggle-all:before {
</span><span class="lines">@@ -214,9 +215,9 @@
</span><span class="cx">     top: 0;
</span><span class="cx">     bottom: 0;
</span><span class="cx">     margin: auto 0;
</span><del>-    border: none; /* Mobile Safari */
</del><ins>+    /* Mobile Safari */
+    border: none;
</ins><span class="cx">     -webkit-appearance: none;
</span><del>-    /*-moz-appearance: none;*/
</del><span class="cx">     -ms-appearance: none;
</span><span class="cx">     -o-appearance: none;
</span><span class="cx">     appearance: none;
</span><span class="lines">@@ -224,7 +225,8 @@
</span><span class="cx"> 
</span><span class="cx"> #todo-list li .toggle:after {
</span><span class="cx">     content: '✔';
</span><del>-    line-height: 43px; /* 40 + a couple of pixels visual adjustment */
</del><ins>+    /* 40 + a couple of pixels visual adjustment */
+    line-height: 43px;
</ins><span class="cx">     font-size: 20px;
</span><span class="cx">     color: #d9d9d9;
</span><span class="cx">     text-shadow: 0 -1px 0 #bfbfbf;
</span><span class="lines">@@ -238,15 +240,13 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #todo-list li label {
</span><ins>+    white-space: pre;
</ins><span class="cx">     word-break: break-word;
</span><del>-    padding: 15px;
</del><ins>+    padding: 15px 60px 15px 15px;
</ins><span class="cx">     margin-left: 45px;
</span><span class="cx">     display: block;
</span><span class="cx">     line-height: 1.2;
</span><span class="cx">     -webkit-transition: color 0.4s;
</span><del>-    -moz-transition: color 0.4s;
-    -ms-transition: color 0.4s;
-    -o-transition: color 0.4s;
</del><span class="cx">     transition: color 0.4s;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -267,19 +267,14 @@
</span><span class="cx">     font-size: 22px;
</span><span class="cx">     color: #a88a8a;
</span><span class="cx">     -webkit-transition: all 0.2s;
</span><del>-    -moz-transition: all 0.2s;
-    -ms-transition: all 0.2s;
-    -o-transition: all 0.2s;
</del><span class="cx">     transition: all 0.2s;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #todo-list li .destroy:hover {
</span><span class="cx">     text-shadow: 0 0 1px #000,
</span><del>-     0 0 10px rgba(199, 107, 107, 0.8);
</del><ins>+                 0 0 10px rgba(199, 107, 107, 0.8);
</ins><span class="cx">     -webkit-transform: scale(1.3);
</span><del>-    -moz-transform: scale(1.3);
</del><span class="cx">     -ms-transform: scale(1.3);
</span><del>-    -o-transform: scale(1.3);
</del><span class="cx">     transform: scale(1.3);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -320,10 +315,10 @@
</span><span class="cx">     height: 50px;
</span><span class="cx">     z-index: -1;
</span><span class="cx">     box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
</span><del>-    0 6px 0 -3px rgba(255, 255, 255, 0.8),
-    0 7px 1px -3px rgba(0, 0, 0, 0.3),
-    0 43px 0 -6px rgba(255, 255, 255, 0.8),
-    0 44px 2px -6px rgba(0, 0, 0, 0.2);
</del><ins>+                0 6px 0 -3px rgba(255, 255, 255, 0.8),
+                0 7px 1px -3px rgba(0, 0, 0, 0.3),
+                0 43px 0 -6px rgba(255, 255, 255, 0.8),
+                0 44px 2px -6px rgba(0, 0, 0, 0.2);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #todo-count {
</span><span class="lines">@@ -387,30 +382,32 @@
</span><span class="cx">     Hack to remove background from Mobile Safari.
</span><span class="cx">     Can't use it globally since it destroys checkboxes in Firefox and Opera
</span><span class="cx"> */
</span><ins>+
</ins><span class="cx"> @media screen and (-webkit-min-device-pixel-ratio:0) {
</span><span class="cx">     #toggle-all,
</span><span class="cx">     #todo-list li .toggle {
</span><del>-    background: none;
</del><ins>+        background: none;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     #todo-list li .toggle {
</span><del>-    height: 40px;
</del><ins>+        height: 40px;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     #toggle-all {
</span><del>-    top: -56px;
-    left: -15px;
-    width: 65px;
-    height: 41px;
-    -webkit-transform: rotate(90deg);
-    transform: rotate(90deg);
-    -webkit-appearance: none;
-    appearance: none;
</del><ins>+        top: -56px;
+        left: -15px;
+        width: 65px;
+        height: 41px;
+        -webkit-transform: rotate(90deg);
+        -ms-transform: rotate(90deg);
+        transform: rotate(90deg);
+        -webkit-appearance: none;
+        appearance: none;
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-.hidden{
-    display:none;
</del><ins>+.hidden {
+    display: none;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> hr {
</span><span class="lines">@@ -528,7 +525,7 @@
</span><span class="cx">     border-top-color: rgba(0, 0, 0, .04);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-/**body*/.learn-bar &gt; .learn {
</del><ins>+.learn-bar &gt; .learn {
</ins><span class="cx">     position: absolute;
</span><span class="cx">     width: 272px;
</span><span class="cx">     top: 8px;
</span><span class="lines">@@ -536,20 +533,24 @@
</span><span class="cx">     padding: 10px;
</span><span class="cx">     border-radius: 5px;
</span><span class="cx">     background-color: rgba(255, 255, 255, .6);
</span><ins>+    -webkit-transition-property: left;
</ins><span class="cx">     transition-property: left;
</span><ins>+    -webkit-transition-duration: 500ms;
</ins><span class="cx">     transition-duration: 500ms;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> @media (min-width: 899px) {
</span><del>-    /**body*/.learn-bar {
-    width: auto;
-    margin: 0 0 0 300px;
</del><ins>+    .learn-bar {
+        width: auto;
+        margin: 0 0 0 300px;
</ins><span class="cx">     }
</span><del>-    /**body*/.learn-bar &gt; .learn {
-    left: 8px;
</del><ins>+
+    .learn-bar &gt; .learn {
+        left: 8px;
</ins><span class="cx">     }
</span><del>-    /**body*/.learn-bar #todoapp {
-    width: 550px;
-    margin: 130px auto 40px auto;
</del><ins>+
+    .learn-bar #todoapp {
+        width: 550px;
+        margin: 130px auto 40px auto;
</ins><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsbower_componentstodomvccommonbasejs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/todomvc-common/base.js (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/todomvc-common/base.js        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/bower_components/todomvc-common/base.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -4,204 +4,204 @@
</span><span class="cx">     // Underscore's Template Module
</span><span class="cx">     // Courtesy of underscorejs.org
</span><span class="cx">     var _ = (function (_) {
</span><del>-    _.defaults = function (object) {
-    if (!object) {
-    return object;
-    }
-    for (var argsIndex = 1, argsLength = arguments.length; argsIndex &lt; argsLength; argsIndex++) {
-    var iterable = arguments[argsIndex];
-    if (iterable) {
-    for (var key in iterable) {
-    if (object[key] == null) {
-    object[key] = iterable[key];
-    }
-    }
-    }
-    }
-    return object;
-    }
</del><ins>+        _.defaults = function (object) {
+            if (!object) {
+                return object;
+            }
+            for (var argsIndex = 1, argsLength = arguments.length; argsIndex &lt; argsLength; argsIndex++) {
+                var iterable = arguments[argsIndex];
+                if (iterable) {
+                    for (var key in iterable) {
+                        if (object[key] == null) {
+                            object[key] = iterable[key];
+                        }
+                    }
+                }
+            }
+            return object;
+        }
</ins><span class="cx"> 
</span><del>-    // By default, Underscore uses ERB-style template delimiters, change the
-    // following template settings to use alternative delimiters.
-    _.templateSettings = {
-    evaluate    : /&lt;%([\s\S]+?)%&gt;/g,
-    interpolate : /&lt;%=([\s\S]+?)%&gt;/g,
-    escape      : /&lt;%-([\s\S]+?)%&gt;/g
-    };
</del><ins>+        // By default, Underscore uses ERB-style template delimiters, change the
+        // following template settings to use alternative delimiters.
+        _.templateSettings = {
+            evaluate    : /&lt;%([\s\S]+?)%&gt;/g,
+            interpolate : /&lt;%=([\s\S]+?)%&gt;/g,
+            escape      : /&lt;%-([\s\S]+?)%&gt;/g
+        };
</ins><span class="cx"> 
</span><del>-    // When customizing `templateSettings`, if you don't want to define an
-    // interpolation, evaluation or escaping regex, we need one that is
-    // guaranteed not to match.
-    var noMatch = /(.)^/;
</del><ins>+        // When customizing `templateSettings`, if you don't want to define an
+        // interpolation, evaluation or escaping regex, we need one that is
+        // guaranteed not to match.
+        var noMatch = /(.)^/;
</ins><span class="cx"> 
</span><del>-    // Certain characters need to be escaped so that they can be put into a
-    // string literal.
-    var escapes = {
-    &quot;'&quot;:      &quot;'&quot;,
-    '\\':     '\\',
-    '\r':     'r',
-    '\n':     'n',
-    '\t':     't',
-    '\u2028': 'u2028',
-    '\u2029': 'u2029'
-    };
</del><ins>+        // Certain characters need to be escaped so that they can be put into a
+        // string literal.
+        var escapes = {
+            &quot;'&quot;:      &quot;'&quot;,
+            '\\':     '\\',
+            '\r':     'r',
+            '\n':     'n',
+            '\t':     't',
+            '\u2028': 'u2028',
+            '\u2029': 'u2029'
+        };
</ins><span class="cx"> 
</span><del>-    var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
</del><ins>+        var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
</ins><span class="cx"> 
</span><del>-    // JavaScript micro-templating, similar to John Resig's implementation.
-    // Underscore templating handles arbitrary delimiters, preserves whitespace,
-    // and correctly escapes quotes within interpolated code.
-    _.template = function(text, data, settings) {
-    var render;
-    settings = _.defaults({}, settings, _.templateSettings);
</del><ins>+        // JavaScript micro-templating, similar to John Resig's implementation.
+        // Underscore templating handles arbitrary delimiters, preserves whitespace,
+        // and correctly escapes quotes within interpolated code.
+        _.template = function(text, data, settings) {
+            var render;
+            settings = _.defaults({}, settings, _.templateSettings);
</ins><span class="cx"> 
</span><del>-    // Combine delimiters into one regular expression via alternation.
-    var matcher = new RegExp([
-    (settings.escape || noMatch).source,
-    (settings.interpolate || noMatch).source,
-    (settings.evaluate || noMatch).source
-    ].join('|') + '|$', 'g');
</del><ins>+            // Combine delimiters into one regular expression via alternation.
+            var matcher = new RegExp([
+                (settings.escape || noMatch).source,
+                (settings.interpolate || noMatch).source,
+                (settings.evaluate || noMatch).source
+            ].join('|') + '|$', 'g');
</ins><span class="cx"> 
</span><del>-    // Compile the template source, escaping string literals appropriately.
-    var index = 0;
-    var source = &quot;__p+='&quot;;
-    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
-    source += text.slice(index, offset)
-    .replace(escaper, function(match) { return '\\' + escapes[match]; });
</del><ins>+            // Compile the template source, escaping string literals appropriately.
+            var index = 0;
+            var source = &quot;__p+='&quot;;
+            text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
+                source += text.slice(index, offset)
+                    .replace(escaper, function(match) { return '\\' + escapes[match]; });
</ins><span class="cx"> 
</span><del>-    if (escape) {
-    source += &quot;'+\n((__t=(&quot; + escape + &quot;))==null?'':_.escape(__t))+\n'&quot;;
-    }
-    if (interpolate) {
-    source += &quot;'+\n((__t=(&quot; + interpolate + &quot;))==null?'':__t)+\n'&quot;;
-    }
-    if (evaluate) {
-    source += &quot;';\n&quot; + evaluate + &quot;\n__p+='&quot;;
-    }
-    index = offset + match.length;
-    return match;
-    });
-    source += &quot;';\n&quot;;
</del><ins>+                if (escape) {
+                    source += &quot;'+\n((__t=(&quot; + escape + &quot;))==null?'':_.escape(__t))+\n'&quot;;
+                }
+                if (interpolate) {
+                    source += &quot;'+\n((__t=(&quot; + interpolate + &quot;))==null?'':__t)+\n'&quot;;
+                }
+                if (evaluate) {
+                    source += &quot;';\n&quot; + evaluate + &quot;\n__p+='&quot;;
+                }
+                index = offset + match.length;
+                return match;
+            });
+            source += &quot;';\n&quot;;
</ins><span class="cx"> 
</span><del>-    // If a variable is not specified, place data values in local scope.
-    if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
</del><ins>+            // If a variable is not specified, place data values in local scope.
+            if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
</ins><span class="cx"> 
</span><del>-    source = &quot;var __t,__p='',__j=Array.prototype.join,&quot; +
-    &quot;print=function(){__p+=__j.call(arguments,'');};\n&quot; +
-    source + &quot;return __p;\n&quot;;
</del><ins>+            source = &quot;var __t,__p='',__j=Array.prototype.join,&quot; +
+                &quot;print=function(){__p+=__j.call(arguments,'');};\n&quot; +
+                source + &quot;return __p;\n&quot;;
</ins><span class="cx"> 
</span><del>-    try {
-    render = new Function(settings.variable || 'obj', '_', source);
-    } catch (e) {
-    e.source = source;
-    throw e;
-    }
</del><ins>+            try {
+                render = new Function(settings.variable || 'obj', '_', source);
+            } catch (e) {
+                e.source = source;
+                throw e;
+            }
</ins><span class="cx"> 
</span><del>-    if (data) return render(data, _);
-    var template = function(data) {
-    return render.call(this, data, _);
-    };
</del><ins>+            if (data) return render(data, _);
+            var template = function(data) {
+                return render.call(this, data, _);
+            };
</ins><span class="cx"> 
</span><del>-    // Provide the compiled function source as a convenience for precompilation.
-    template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
</del><ins>+            // Provide the compiled function source as a convenience for precompilation.
+            template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
</ins><span class="cx"> 
</span><del>-    return template;
-    };
</del><ins>+            return template;
+        };
</ins><span class="cx"> 
</span><del>-    return _;
</del><ins>+        return _;
</ins><span class="cx">     })({});
</span><span class="cx"> 
</span><span class="cx">     if (location.hostname === 'todomvc.com') {
</span><del>-    window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
</del><ins>+        window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     function redirect() {
</span><del>-    if (location.hostname === 'tastejs.github.io') {
-    location.href = location.href.replace('tastejs.github.io/todomvc', 'todomvc.com');
</del><ins>+        if (location.hostname === 'tastejs.github.io') {
+            location.href = location.href.replace('tastejs.github.io/todomvc', 'todomvc.com');
+        }
</ins><span class="cx">     }
</span><del>-    }
</del><span class="cx"> 
</span><span class="cx">     function findRoot() {
</span><del>-    var base;
</del><ins>+        var base;
</ins><span class="cx"> 
</span><del>-    [/labs/, /\w*-examples/].forEach(function (href) {
-    var match = location.href.match(href);
</del><ins>+        [/labs/, /\w*-examples/].forEach(function (href) {
+            var match = location.href.match(href);
</ins><span class="cx"> 
</span><del>-    if (!base &amp;&amp; match) {
-    base = location.href.indexOf(match);
-    }
-    });
</del><ins>+            if (!base &amp;&amp; match) {
+                base = location.href.indexOf(match);
+            }
+        });
</ins><span class="cx"> 
</span><del>-    return location.href.substr(0, base);
</del><ins>+        return location.href.substr(0, base);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     function getFile(file, callback) {
</span><del>-    if (!location.host) {
-    return console.info('Miss the info bar? Run TodoMVC from a server to avoid a cross-origin error.');
-    }
</del><ins>+        if (!location.host) {
+            return console.info('Miss the info bar? Run TodoMVC from a server to avoid a cross-origin error.');
+        }
</ins><span class="cx"> 
</span><del>-    var xhr = new XMLHttpRequest();
</del><ins>+        var xhr = new XMLHttpRequest();
</ins><span class="cx"> 
</span><del>-    xhr.open('GET', findRoot() + file, true);
-    xhr.send();
</del><ins>+        xhr.open('GET', findRoot() + file, true);
+        xhr.send();
</ins><span class="cx"> 
</span><del>-    xhr.onload = function () {
-    if (xhr.status === 200 &amp;&amp; callback) {
-    callback(xhr.responseText);
</del><ins>+        xhr.onload = function () {
+            if (xhr.status === 200 &amp;&amp; callback) {
+                callback(xhr.responseText);
+            }
+        };
</ins><span class="cx">     }
</span><del>-    };
-    }
</del><span class="cx"> 
</span><span class="cx">     function Learn(learnJSON, config) {
</span><del>-    if (!(this instanceof Learn)) {
-    return new Learn(learnJSON, config);
-    }
</del><ins>+        if (!(this instanceof Learn)) {
+            return new Learn(learnJSON, config);
+        }
</ins><span class="cx"> 
</span><del>-    var template, framework;
</del><ins>+        var template, framework;
</ins><span class="cx"> 
</span><del>-    if (typeof learnJSON !== 'object') {
-    try {
-    learnJSON = JSON.parse(learnJSON);
-    } catch (e) {
-    return;
-    }
-    }
</del><ins>+        if (typeof learnJSON !== 'object') {
+            try {
+                learnJSON = JSON.parse(learnJSON);
+            } catch (e) {
+                return;
+            }
+        }
</ins><span class="cx"> 
</span><del>-    if (config) {
-    template = config.template;
-    framework = config.framework;
-    }
</del><ins>+        if (config) {
+            template = config.template;
+            framework = config.framework;
+        }
</ins><span class="cx"> 
</span><del>-    if (!template &amp;&amp; learnJSON.templates) {
-    template = learnJSON.templates.todomvc;
-    }
</del><ins>+        if (!template &amp;&amp; learnJSON.templates) {
+            template = learnJSON.templates.todomvc;
+        }
</ins><span class="cx"> 
</span><del>-    if (!framework &amp;&amp; document.querySelector('[data-framework]')) {
-    framework = document.querySelector('[data-framework]').getAttribute('data-framework');
-    }
</del><ins>+        if (!framework &amp;&amp; document.querySelector('[data-framework]')) {
+            framework = document.querySelector('[data-framework]').getAttribute('data-framework');
+        }
</ins><span class="cx"> 
</span><span class="cx"> 
</span><del>-    if (template &amp;&amp; learnJSON[framework]) {
-    this.frameworkJSON = learnJSON[framework];
-    this.template = template;
</del><ins>+        if (template &amp;&amp; learnJSON[framework]) {
+            this.frameworkJSON = learnJSON[framework];
+            this.template = template;
</ins><span class="cx"> 
</span><del>-    this.append();
</del><ins>+            this.append();
+        }
</ins><span class="cx">     }
</span><del>-    }
</del><span class="cx"> 
</span><span class="cx">     Learn.prototype.append = function () {
</span><del>-    var aside = document.createElement('aside');
-    aside.innerHTML = _.template(this.template, this.frameworkJSON);
-    aside.className = 'learn';
</del><ins>+        var aside = document.createElement('aside');
+        aside.innerHTML = _.template(this.template, this.frameworkJSON);
+        aside.className = 'learn';
</ins><span class="cx"> 
</span><del>-    // Localize demo links
-    var demoLinks = aside.querySelectorAll('.demo-link');
-    Array.prototype.forEach.call(demoLinks, function (demoLink) {
-    demoLink.setAttribute('href', findRoot() + demoLink.getAttribute('href'));
-    });
</del><ins>+        // Localize demo links
+        var demoLinks = aside.querySelectorAll('.demo-link');
+        Array.prototype.forEach.call(demoLinks, function (demoLink) {
+            demoLink.setAttribute('href', findRoot() + demoLink.getAttribute('href'));
+        });
</ins><span class="cx"> 
</span><del>-    document.body.className = (document.body.className + ' learn-bar').trim();
-    document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
</del><ins>+        document.body.className = (document.body.className + ' learn-bar').trim();
+        document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     redirect();
</span></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsindexhtml"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/index.html (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/index.html        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/index.html        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -1,80 +1,78 @@
</span><span class="cx"> &lt;!doctype html&gt;
</span><span class="cx"> &lt;html lang=&quot;en&quot; data-framework=&quot;emberjs&quot;&gt;
</span><span class="cx">     &lt;head&gt;
</span><del>-    &lt;meta charset=&quot;utf-8&quot;&gt;
-    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
-    &lt;title&gt;ember.js • TodoMVC&lt;/title&gt;
-    &lt;link rel=&quot;stylesheet&quot; href=&quot;bower_components/todomvc-common/base.css&quot;&gt;
</del><ins>+        &lt;meta charset=&quot;utf-8&quot;&gt;
+        &lt;title&gt;ember.js • TodoMVC&lt;/title&gt;
+        &lt;link rel=&quot;stylesheet&quot; href=&quot;bower_components/todomvc-common/base.css&quot;&gt;
</ins><span class="cx">     &lt;/head&gt;
</span><span class="cx">     &lt;body&gt;
</span><del>-    &lt;script type=&quot;text/x-handlebars&quot; data-template-name=&quot;todos&quot;&gt;
-    &lt;section id=&quot;todoapp&quot;&gt;
-    &lt;header id=&quot;header&quot;&gt;
-    &lt;h1&gt;todos&lt;/h1&gt;
-    {{view Ember.TextField id=&quot;new-todo&quot; placeholder=&quot;What needs to be done?&quot;
-     valueBinding=&quot;newTitle&quot; action=&quot;createTodo&quot;}}
-    &lt;/header&gt;
-    {{#if length}}
-    &lt;section id=&quot;main&quot;&gt;
-    &lt;ul id=&quot;todo-list&quot;&gt;
-    {{#each filteredTodos itemController=&quot;todo&quot;}}
-    &lt;li {{bindAttr class=&quot;isCompleted:completed isEditing:editing&quot;}}&gt;
-    {{#if isEditing}}
-    {{view Todos.EditTodoView todoBinding=&quot;this&quot;}}
-    {{else}}
-    {{view Ember.Checkbox checkedBinding=&quot;isCompleted&quot; class=&quot;toggle&quot;}}
-    &lt;label {{action &quot;editTodo&quot; on=&quot;doubleClick&quot;}}&gt;{{title}}&lt;/label&gt;
-    &lt;button {{action &quot;removeTodo&quot;}} class=&quot;destroy&quot;&gt;&lt;/button&gt;
-    {{/if}}
-    &lt;/li&gt;
-    {{/each}}
-    &lt;/ul&gt;
-    {{view Ember.Checkbox id=&quot;toggle-all&quot; checkedBinding=&quot;allAreDone&quot;}}
-    &lt;/section&gt;
-    &lt;footer id=&quot;footer&quot;&gt;
-    &lt;span id=&quot;todo-count&quot;&gt;{{{remainingFormatted}}}&lt;/span&gt;
-    &lt;ul id=&quot;filters&quot;&gt;
-    &lt;li&gt;
-    {{#linkTo todos.index activeClass=&quot;selected&quot;}}All{{/linkTo}}
-    &lt;/li&gt;
-    &lt;li&gt;
-    {{#linkTo todos.active activeClass=&quot;selected&quot;}}Active{{/linkTo}}
-    &lt;/li&gt;
-    &lt;li&gt;
-    {{#linkTo todos.completed activeClass=&quot;selected&quot;}}Completed{{/linkTo}}
-    &lt;/li&gt;
-    &lt;/ul&gt;
-    {{#if hasCompleted}}
-    &lt;button id=&quot;clear-completed&quot; {{action &quot;clearCompleted&quot;}} {{bindAttr class=&quot;buttonClass:hidden&quot;}}&gt;
-    Clear completed ({{completed}})
-    &lt;/button&gt;
-    {{/if}}
-    &lt;/footer&gt;
-    {{/if}}
-    &lt;/section&gt;
-    &lt;footer id=&quot;info&quot;&gt;
-    &lt;p&gt;Double-click to edit a todo&lt;/p&gt;
-    &lt;p&gt;
-    Created by
-    &lt;a href=&quot;http://github.com/tomdale&quot;&gt;Tom Dale&lt;/a&gt;,
-    &lt;a href=&quot;http://github.com/addyosmani&quot;&gt;Addy Osmani&lt;/a&gt;
-    &lt;/p&gt;
-    &lt;p&gt;Part of &lt;a href=&quot;http://todomvc.com&quot;&gt;TodoMVC&lt;/a&gt;&lt;/p&gt;
-    &lt;/footer&gt;
-    &lt;/script&gt;
-    &lt;script src=&quot;bower_components/todomvc-common/base.js&quot;&gt;&lt;/script&gt;
-    &lt;script src=&quot;bower_components/jquery/jquery.js&quot;&gt;&lt;/script&gt;
-    &lt;script src=&quot;bower_components/handlebars/handlebars.js&quot;&gt;&lt;/script&gt;
-    &lt;script src=&quot;bower_components/ember/ember.js&quot;&gt;&lt;/script&gt;
-    &lt;!-- TODO: change out with a component when a built one is available on Bower --&gt;
-    &lt;script src=&quot;js/libs/ember-data.js&quot;&gt;&lt;/script&gt;
-    &lt;script src=&quot;bower_components/ember-localstorage-adapter/localstorage_adapter.js&quot;&gt;&lt;/script&gt;
-    &lt;script src=&quot;js/app.js&quot;&gt;&lt;/script&gt;
-    &lt;script src=&quot;js/router.js&quot;&gt;&lt;/script&gt;
-    &lt;script src=&quot;js/models/todo.js&quot;&gt;&lt;/script&gt;
-    &lt;script src=&quot;js/models/store.js&quot;&gt;&lt;/script&gt;
-    &lt;script src=&quot;js/controllers/todos_controller.js&quot;&gt;&lt;/script&gt;
-    &lt;script src=&quot;js/controllers/todo_controller.js&quot;&gt;&lt;/script&gt;
-    &lt;script src=&quot;js/views/edit_todo_view.js&quot;&gt;&lt;/script&gt;
</del><ins>+        &lt;script type=&quot;text/x-handlebars&quot; data-template-name=&quot;todos&quot;&gt;
+            &lt;section id=&quot;todoapp&quot;&gt;
+                &lt;header id=&quot;header&quot;&gt;
+                    &lt;h1&gt;todos&lt;/h1&gt;
+                    {{input id=&quot;new-todo&quot; type=&quot;text&quot; value=newTitle action=&quot;createTodo&quot; placeholder=&quot;What needs to be done?&quot;}}
+                &lt;/header&gt;
+                {{#if length}}
+                    &lt;section id=&quot;main&quot;&gt;
+                        &lt;ul id=&quot;todo-list&quot;&gt;
+                            {{#each filteredTodos itemController=&quot;todo&quot;}}
+                                &lt;li {{bind-attr class=&quot;isCompleted:completed isEditing:editing&quot;}}&gt;
+                                    {{#if isEditing}}
+                                        {{edit-todo class=&quot;edit&quot; value=bufferedTitle focus-out=&quot;doneEditing&quot; insert-newline=&quot;doneEditing&quot; escape-press=&quot;cancelEditing&quot;}}
+                                    {{else}}
+                                        {{input type=&quot;checkbox&quot; class=&quot;toggle&quot; checked=isCompleted}}
+                                        &lt;label {{action &quot;editTodo&quot; on=&quot;doubleClick&quot;}}&gt;{{title}}&lt;/label&gt;
+                                        &lt;button {{action &quot;removeTodo&quot;}} class=&quot;destroy&quot;&gt;&lt;/button&gt;
+                                    {{/if}}
+                                    &lt;/li&gt;
+                            {{/each}}
+                        &lt;/ul&gt;
+                        {{input type=&quot;checkbox&quot; id=&quot;toggle-all&quot; checked=allAreDone}}
+                    &lt;/section&gt;
+                    &lt;footer id=&quot;footer&quot;&gt;
+                        &lt;span id=&quot;todo-count&quot;&gt;&lt;strong&gt;{{remaining.length}}&lt;/strong&gt; {{pluralize 'item' remaining.length}} left&lt;/span&gt;
+                        &lt;ul id=&quot;filters&quot;&gt;
+                            &lt;li&gt;
+                                {{#link-to &quot;todos.index&quot; activeClass=&quot;selected&quot;}}All{{/link-to}}
+                            &lt;/li&gt;
+                            &lt;li&gt;
+                                {{#link-to &quot;todos.active&quot; activeClass=&quot;selected&quot;}}Active{{/link-to}}
+                            &lt;/li&gt;
+                            &lt;li&gt;
+                                {{#link-to &quot;todos.completed&quot; activeClass=&quot;selected&quot;}}Completed{{/link-to}}
+                            &lt;/li&gt;
+                        &lt;/ul&gt;
+                        {{#if completed.length}}
+                            &lt;button id=&quot;clear-completed&quot; {{action &quot;clearCompleted&quot;}}&gt;
+                                Clear completed ({{completed.length}})
+                            &lt;/button&gt;
+                        {{/if}}
+                    &lt;/footer&gt;
+                {{/if}}
+            &lt;/section&gt;
+            &lt;footer id=&quot;info&quot;&gt;
+                &lt;p&gt;Double-click to edit a todo&lt;/p&gt;
+                &lt;p&gt;
+                    Created by
+                    &lt;a href=&quot;http://github.com/tomdale&quot;&gt;Tom Dale&lt;/a&gt;,
+                    &lt;a href=&quot;http://github.com/addyosmani&quot;&gt;Addy Osmani&lt;/a&gt;
+                &lt;/p&gt;
+                &lt;p&gt;Part of &lt;a href=&quot;http://todomvc.com&quot;&gt;TodoMVC&lt;/a&gt;&lt;/p&gt;
+            &lt;/footer&gt;
+        &lt;/script&gt;
+        &lt;script src=&quot;bower_components/todomvc-common/base.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;bower_components/jquery/jquery.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;bower_components/handlebars/handlebars.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;bower_components/ember/ember.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;bower_components/ember-data/ember-data.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;bower_components/ember-localstorage-adapter/localstorage_adapter.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;js/app.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;js/router.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;js/models/todo.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;js/controllers/todos_controller.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;js/controllers/todo_controller.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;js/views/edit_todo_view.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;js/views/todos_view.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;js/helpers/pluralize.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;/body&gt;
</span><span class="cx"> &lt;/html&gt;
</span></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjsappjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/app.js (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/app.js        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/app.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -1,2 +1,6 @@
</span><del>-/*global Ember */
</del><ins>+/*global Ember, DS, Todos:true */
</ins><span class="cx"> window.Todos = Ember.Application.create();
</span><ins>+
+Todos.ApplicationAdapter = DS.LSAdapter.extend({
+    namespace: 'todos-emberjs'
+});
</ins></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjscontrollerstodo_controllerjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/controllers/todo_controller.js (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/controllers/todo_controller.js        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/controllers/todo_controller.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -1,17 +1,58 @@
</span><del>-/*global Todos Ember */
</del><ins>+/*global Todos, Ember */
</ins><span class="cx"> 'use strict';
</span><span class="cx"> 
</span><span class="cx"> Todos.TodoController = Ember.ObjectController.extend({
</span><span class="cx">     isEditing: false,
</span><span class="cx"> 
</span><del>-    editTodo: function () {
-    this.set('isEditing', true);
</del><ins>+    // We use the bufferedTitle to store the original value of
+    // the model's title so that we can roll it back later in the
+    // `cancelEditing` action.
+    bufferedTitle: Ember.computed.oneWay('title'),
+
+    actions: {
+        editTodo: function () {
+            this.set('isEditing', true);
+        },
+
+        doneEditing: function () {
+            var bufferedTitle = this.get('bufferedTitle').trim();
+
+            if (Ember.isEmpty(bufferedTitle)) {
+                // The `doneEditing` action gets sent twice when the user hits
+                // enter (once via 'insert-newline' and once via 'focus-out').
+                //
+                // We debounce our call to 'removeTodo' so that it only gets
+                // made once.
+                Ember.run.debounce(this, 'removeTodo', 0);
+            } else {
+                var todo = this.get('model');
+                todo.set('title', bufferedTitle);
+                todo.save();
+            }
+
+            // Re-set our newly edited title to persist its trimmed version
+            this.set('bufferedTitle', bufferedTitle);
+            this.set('isEditing', false);
+        },
+
+        cancelEditing: function () {
+            this.set('bufferedTitle', this.get('title'));
+            this.set('isEditing', false);
+        },
+
+        removeTodo: function () {
+            this.removeTodo();
+        }
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     removeTodo: function () {
</span><del>-    var todo = this.get('model');
</del><ins>+        var todo = this.get('model');
</ins><span class="cx"> 
</span><del>-    todo.deleteRecord();
-    todo.get('store').commit();
-    }
</del><ins>+        todo.deleteRecord();
+        todo.save();
+    },
+
+    saveWhenCompleted: function () {
+        this.get('model').save();
+    }.observes('isCompleted')
</ins><span class="cx"> });
</span></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjscontrollerstodos_controllerjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/controllers/todos_controller.js (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/controllers/todos_controller.js        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/controllers/todos_controller.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -1,59 +1,49 @@
</span><del>-/*global Todos Ember */
</del><ins>+/*global Todos, Ember */
</ins><span class="cx"> 'use strict';
</span><span class="cx"> 
</span><span class="cx"> Todos.TodosController = Ember.ArrayController.extend({
</span><del>-    createTodo: function () {
-    // Get the todo title set by the &quot;New Todo&quot; text field
-    var title = this.get('newTitle');
-    if (!title.trim()) {
-    return;
-    }
</del><ins>+    actions: {
+        createTodo: function () {
+            var title, todo;
</ins><span class="cx"> 
</span><del>-    // Create the new Todo model
-    Todos.Todo.createRecord({
-    title: title,
-    isCompleted: false
-    });
</del><ins>+            // Get the todo title set by the &quot;New Todo&quot; text field
+            title = this.get('newTitle').trim();
+            if (!title) {
+                return;
+            }
</ins><span class="cx"> 
</span><del>-    // Clear the &quot;New Todo&quot; text field
-    this.set('newTitle', '');
</del><ins>+            // Create the new Todo model
+            todo = this.store.createRecord('todo', {
+                title: title,
+                isCompleted: false
+            });
+            todo.save();
</ins><span class="cx"> 
</span><del>-    // Save the new model
-    this.get('store').commit();
-    },
</del><ins>+            // Clear the &quot;New Todo&quot; text field
+            this.set('newTitle', '');
+        },
</ins><span class="cx"> 
</span><del>-    clearCompleted: function () {
-    var completed = this.filterProperty('isCompleted', true);
-    completed.invoke('deleteRecord');
-
-    this.get('store').commit();
</del><ins>+        clearCompleted: function () {
+            var completed = this.get('completed');
+            completed.invoke('deleteRecord');
+            completed.invoke('save');
+        },
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    remaining: function () {
-    return this.filterProperty('isCompleted', false).get('length');
-    }.property('@each.isCompleted'),
</del><ins>+    /* properties */
</ins><span class="cx"> 
</span><del>-    remainingFormatted: function () {
-    var remaining = this.get('remaining');
-    var plural = remaining === 1 ? 'item' : 'items';
-    return '&lt;strong&gt;%@&lt;/strong&gt; %@ left'.fmt(remaining, plural);
-    }.property('remaining'),
</del><ins>+    remaining: Ember.computed.filterBy('content', 'isCompleted', false),
+    completed: Ember.computed.filterBy('content', 'isCompleted', true),
</ins><span class="cx"> 
</span><del>-    completed: function () {
-    return this.filterProperty('isCompleted', true).get('length');
-    }.property('@each.isCompleted'),
-
-    hasCompleted: function () {
-    return this.get('completed') &gt; 0;
-    }.property('completed'),
-
</del><span class="cx">     allAreDone: function (key, value) {
</span><del>-    if (value !== undefined) {
-    this.setEach('isCompleted', value);
-    return value;
-    } else {
-    return !!this.get('length') &amp;&amp;
-    this.everyProperty('isCompleted', true);
-    }
-    }.property('@each.isCompleted')
</del><ins>+        if (value !== undefined) {
+            this.setEach('isCompleted', value);
+            return value;
+        } else {
+            var length = this.get('length');
+            var completedLength = this.get('completed.length');
+
+            return length &gt; 0 &amp;&amp; length === completedLength;
+        }
+    }.property('length', 'completed.length')
</ins><span class="cx"> });
</span></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjshelperspluralizejs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/helpers/pluralize.js (0 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/helpers/pluralize.js                                (rev 0)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/helpers/pluralize.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+/*global Todos, Ember */
+'use strict';
+
+Ember.Handlebars.helper('pluralize', function (singular, count) {
+    /* From Ember-Data */
+    var inflector = new Ember.Inflector(Ember.Inflector.defaultRules);
+
+    return count === 1 ? singular : inflector.pluralize(singular);
+});
</ins></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjsmodelsstorejs"></a>
<div class="delfile"><h4>Deleted: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/models/store.js (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/models/store.js        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/models/store.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -1,11 +0,0 @@
</span><del>-/*global Todos DS */
-'use strict';
-
-Todos.Store = DS.Store.extend({
-    revision: 12,
-    adapter: 'Todos.LSAdapter'
-});
-
-Todos.LSAdapter = DS.LSAdapter.extend({
-    namespace: 'todos-emberjs'
-});
</del></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjsmodelstodojs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/models/todo.js (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/models/todo.js        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/models/todo.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -1,13 +1,7 @@
</span><del>-/*global Todos DS Ember */
</del><ins>+/*global Todos, DS */
</ins><span class="cx"> 'use strict';
</span><span class="cx"> 
</span><span class="cx"> Todos.Todo = DS.Model.extend({
</span><span class="cx">     title: DS.attr('string'),
</span><del>-    isCompleted: DS.attr('boolean'),
-
-    todoDidChange: function () {
-    Ember.run.once(this, function () {
-    this.get('store').commit();
-    });
-    }.observes('isCompleted', 'title')
</del><ins>+    isCompleted: DS.attr('boolean')
</ins><span class="cx"> });
</span></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjsrouterjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/router.js (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/router.js        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/router.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -1,46 +1,41 @@
</span><del>-/*global Todos Ember */
</del><ins>+/*global Ember, Todos */
</ins><span class="cx"> 'use strict';
</span><span class="cx"> 
</span><span class="cx"> Todos.Router.map(function () {
</span><span class="cx">     this.resource('todos', { path: '/' }, function () {
</span><del>-    this.route('active');
-    this.route('completed');
</del><ins>+        this.route('active');
+        this.route('completed');
</ins><span class="cx">     });
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> Todos.TodosRoute = Ember.Route.extend({
</span><span class="cx">     model: function () {
</span><del>-    return Todos.Todo.find();
</del><ins>+        return this.store.find('todo');
</ins><span class="cx">     }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> Todos.TodosIndexRoute = Ember.Route.extend({
</span><span class="cx">     setupController: function () {
</span><del>-    var todos = Todos.Todo.find();
-    this.controllerFor('todos').set('filteredTodos', todos);
</del><ins>+        this.controllerFor('todos').set('filteredTodos', this.modelFor('todos'));
</ins><span class="cx">     }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> Todos.TodosActiveRoute = Ember.Route.extend({
</span><span class="cx">     setupController: function () {
</span><del>-    var todos = Todos.Todo.filter(function (todo) {
-    if (!todo.get('isCompleted')) {
-    return true;
-    }
-    });
</del><ins>+        var todos = this.store.filter('todo', function (todo) {
+            return !todo.get('isCompleted');
+        });
</ins><span class="cx"> 
</span><del>-    this.controllerFor('todos').set('filteredTodos', todos);
</del><ins>+        this.controllerFor('todos').set('filteredTodos', todos);
</ins><span class="cx">     }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> Todos.TodosCompletedRoute = Ember.Route.extend({
</span><span class="cx">     setupController: function () {
</span><del>-    var todos = Todos.Todo.filter(function (todo) {
-    if (todo.get('isCompleted')) {
-    return true;
-    }
-    });
</del><ins>+        var todos = this.store.filter('todo', function (todo) {
+            return todo.get('isCompleted');
+        });
</ins><span class="cx"> 
</span><del>-    this.controllerFor('todos').set('filteredTodos', todos);
</del><ins>+        this.controllerFor('todos').set('filteredTodos', todos);
</ins><span class="cx">     }
</span><span class="cx"> });
</span></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjsviewsedit_todo_viewjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/views/edit_todo_view.js (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/views/edit_todo_view.js        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/views/edit_todo_view.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -1,28 +1,12 @@
</span><del>-/*global Todos Ember */
</del><ins>+/*global Todos, Ember */
</ins><span class="cx"> 'use strict';
</span><span class="cx"> 
</span><span class="cx"> Todos.EditTodoView = Ember.TextField.extend({
</span><del>-    classNames: ['edit'],
-
-    valueBinding: 'todo.title',
-
-    change: function () {
-    var value = this.get('value');
-
-    if (Ember.isEmpty(value)) {
-    this.get('controller').removeTodo();
-    }
-    },
-
-    focusOut: function () {
-    this.set('controller.isEditing', false);
-    },
-
-    insertNewline: function () {
-    this.set('controller.isEditing', false);
-    },
-
-    didInsertElement: function () {
-    this.$().focus();
-    }
</del><ins>+    focusOnInsert: function () {
+        // Re-set input value to get rid of a reduntant text selection
+        this.$().val(this.$().val());
+        this.$().focus();
+    }.on('didInsertElement')
</ins><span class="cx"> });
</span><ins>+
+Ember.Handlebars.helper('edit-todo', Todos.EditTodoView);
</ins></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsjsviewstodos_viewjs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/views/todos_view.js (0 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/views/todos_view.js                                (rev 0)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/js/views/todos_view.js        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+/*global Todos, Ember */
+'use strict';
+
+Todos.TodosView = Ember.View.extend({
+    focusInput: function () {
+        this.$('#new-todo').focus();
+    }.on('didInsertElement')
+});
</ins></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjsreadmemd"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/readme.md (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/readme.md        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/readme.md        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -21,6 +21,7 @@
</span><span class="cx"> 
</span><span class="cx"> * [Getting Into Ember.js](http://net.tutsplus.com/tutorials/javascript-ajax/getting-into-ember-js)
</span><span class="cx"> * [EmberWatch](http://emberwatch.com)
</span><ins>+* [CodeSchool course Warming Up With Ember.js](https://www.codeschool.com/courses/warming-up-with-emberjs)
</ins><span class="cx"> 
</span><span class="cx"> Get help from other Ember.js users:
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkPerformanceTestsDoYouEvenBenchresourcestodomvcarchitectureexamplesemberjstesthtml"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/test.html (163428 => 163429)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/test.html        2014-02-05 05:32:21 UTC (rev 163428)
+++ trunk/PerformanceTests/DoYouEvenBench/resources/todomvc/architecture-examples/emberjs/test.html        2014-02-05 05:36:04 UTC (rev 163429)
</span><span class="lines">@@ -9,49 +9,49 @@
</span><span class="cx">     title: 'SimpleEmberJS',
</span><span class="cx">     url: 'index.html',
</span><span class="cx">     prepare: function (contentWindow, contentDocument) {
</span><del>-    contentWindow.Todos.Store = contentWindow.DS.Store.extend({
-    revision: 12,
-    adapter: 'Todos.LSAdapter',
-    commit: function () { }
-    });
</del><ins>+        contentWindow.Todos.Store = contentWindow.DS.Store.extend({
+            revision: 12,
+            adapter: 'Todos.LSAdapter',
+            commit: function () { }
+        });
</ins><span class="cx"> 
</span><del>-    var promise = new SimplePromise;
</del><ins>+        var promise = new SimplePromise;
</ins><span class="cx"> 
</span><del>-    function resolveIfReady() {
-    if (contentDocument.querySelector('#new-todo'))
-    return promise.resolve();
-    setTimeout(resolveIfReady, 10);
-    }
-    resolveIfReady();
</del><ins>+        function resolveIfReady() {
+            if (contentDocument.querySelector('#new-todo'))
+                return promise.resolve();
+            setTimeout(resolveIfReady, 10);
+        }
+        resolveIfReady();
</ins><span class="cx"> 
</span><del>-    return promise;
</del><ins>+        return promise;
</ins><span class="cx">     },
</span><span class="cx">     testSteps: function (contentWindow, contentDocument) {
</span><del>-    contentDocument.querySelector('#new-todo').focus();
-    var views = contentWindow.Ember.View.views;
-    var emberRun = contentWindow.Ember.run;
-    var numberOfItemsToAdd = 100;
-    return [
-    ['Adding' + numberOfItemsToAdd + 'Items', function () {
-    for (var i = 0; i &lt; numberOfItemsToAdd; i++) {
-    emberRun(function () { views[&quot;new-todo&quot;].set('value', 'Something to do'); });
-    emberRun(function () { views[&quot;new-todo&quot;].insertNewline(document.createEvent('Event')); });
</del><ins>+        contentDocument.querySelector('#new-todo').focus();
+        var views = contentWindow.Ember.View.views;
+        var emberRun = contentWindow.Ember.run;
+        var numberOfItemsToAdd = 100;
+        return [
+            ['Adding' + numberOfItemsToAdd + 'Items', function () {
+                for (var i = 0; i &lt; numberOfItemsToAdd; i++) {
+                    emberRun(function () { views[&quot;new-todo&quot;].set('value', 'Something to do'); });
+                    emberRun(function () { views[&quot;new-todo&quot;].insertNewline(document.createEvent('Event')); });
+                }
+            }],
+            ['CompletingAllItems', function () {
+                var checkboxes = contentDocument.querySelectorAll('.ember-checkbox');
+                for (var i = 0; i &lt; checkboxes.length; i++) {
+                    var view = views[checkboxes[i].id];
+                    emberRun(function () { view.set('checked', true); });
+                }
+            }],
+            ['DeletingItems', function () {
+                var deleteButtons = contentDocument.querySelectorAll('.destroy');
+                for (var i = 0; i &lt; deleteButtons.length; i++)
+                    emberRun(function () { deleteButtons[i].click(); });
+            }],
+        ];
</ins><span class="cx">     }
</span><del>-    }],
-    ['CompletingAllItems', function () {
-    var checkboxes = contentDocument.querySelectorAll('.ember-checkbox');
-    for (var i = 0; i &lt; checkboxes.length; i++) {
-    var view = views[checkboxes[i].id];
-    emberRun(function () { view.set('checked', true); });
-    }
-    }],
-    ['DeletingItems', function () {
-    var deleteButtons = contentDocument.querySelectorAll('.destroy');
-    for (var i = 0; i &lt; deleteButtons.length; i++)
-    emberRun(function () { deleteButtons[i].click(); });
-    }],
-    ];
-    }
</del><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> &lt;/script&gt;
</span></span></pre>
</div>
</div>

</body>
</html>