Make the analysis page more useful
[WebKit-https.git] / Websites / perf.webkit.org / public / v2 / js / ember-data.js
1 /*!
2  * @overview  Ember Data
3  * @copyright Copyright 2011-2014 Tilde Inc. and contributors.
4  *            Portions Copyright 2011 LivingSocial Inc.
5  * @license   Licensed under MIT license (see license.js)
6  * @version   1.0.0-beta.8.2a68c63a
7  */
8 (function(global) {
9 var define, requireModule, require, requirejs;
10
11 (function() {
12   var registry = {}, seen = {};
13
14   define = function(name, deps, callback) {
15     registry[name] = { deps: deps, callback: callback };
16   };
17
18   requirejs = require = requireModule = function(name) {
19   requirejs._eak_seen = registry;
20
21     if (seen[name]) { return seen[name]; }
22     seen[name] = {};
23
24     if (!registry[name]) {
25       throw new Error("Could not find module " + name);
26     }
27
28     var mod = registry[name],
29         deps = mod.deps,
30         callback = mod.callback,
31         reified = [],
32         exports;
33
34     for (var i=0, l=deps.length; i<l; i++) {
35       if (deps[i] === 'exports') {
36         reified.push(exports = {});
37       } else {
38         reified.push(requireModule(resolve(deps[i])));
39       }
40     }
41
42     var value = callback.apply(this, reified);
43     return seen[name] = exports || value;
44
45     function resolve(child) {
46       if (child.charAt(0) !== '.') { return child; }
47       var parts = child.split("/");
48       var parentBase = name.split("/").slice(0, -1);
49
50       for (var i=0, l=parts.length; i<l; i++) {
51         var part = parts[i];
52
53         if (part === '..') { parentBase.pop(); }
54         else if (part === '.') { continue; }
55         else { parentBase.push(part); }
56       }
57
58       return parentBase.join("/");
59     }
60   };
61 })();
62
63 define("activemodel-adapter/lib/main", 
64   ["./system","exports"],
65   function(__dependency1__, __exports__) {
66     "use strict";
67     var ActiveModelAdapter = __dependency1__.ActiveModelAdapter;
68     var ActiveModelSerializer = __dependency1__.ActiveModelSerializer;
69     var EmbeddedRecordsMixin = __dependency1__.EmbeddedRecordsMixin;
70
71     __exports__.ActiveModelAdapter = ActiveModelAdapter;
72     __exports__.ActiveModelSerializer = ActiveModelSerializer;
73     __exports__.EmbeddedRecordsMixin = EmbeddedRecordsMixin;
74   });
75 define("activemodel-adapter/lib/setup-container", 
76   ["../../ember-data/lib/system/container_proxy","./system/active_model_serializer","./system/active_model_adapter","exports"],
77   function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
78     "use strict";
79     var ContainerProxy = __dependency1__["default"];
80     var ActiveModelSerializer = __dependency2__["default"];
81     var ActiveModelAdapter = __dependency3__["default"];
82
83     __exports__["default"] = function setupActiveModelAdapter(container, application){
84       var proxy = new ContainerProxy(container);
85       proxy.registerDeprecations([
86         {deprecated: 'serializer:_ams',  valid: 'serializer:-active-model'},
87         {deprecated: 'adapter:_ams',     valid: 'adapter:-active-model'}
88       ]);
89
90       container.register('serializer:-active-model', ActiveModelSerializer);
91       container.register('adapter:-active-model', ActiveModelAdapter);
92     };
93   });
94 define("activemodel-adapter/lib/system", 
95   ["./system/embedded_records_mixin","./system/active_model_adapter","./system/active_model_serializer","exports"],
96   function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
97     "use strict";
98     var EmbeddedRecordsMixin = __dependency1__["default"];
99     var ActiveModelAdapter = __dependency2__["default"];
100     var ActiveModelSerializer = __dependency3__["default"];
101
102     __exports__.EmbeddedRecordsMixin = EmbeddedRecordsMixin;
103     __exports__.ActiveModelAdapter = ActiveModelAdapter;
104     __exports__.ActiveModelSerializer = ActiveModelSerializer;
105   });
106 define("activemodel-adapter/lib/system/active_model_adapter", 
107   ["../../../ember-data/lib/adapters","../../../ember-data/lib/system/adapter","../../../ember-inflector/lib/main","./active_model_serializer","./embedded_records_mixin","exports"],
108   function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
109     "use strict";
110     var RESTAdapter = __dependency1__.RESTAdapter;
111     var InvalidError = __dependency2__.InvalidError;
112     var pluralize = __dependency3__.pluralize;
113     var ActiveModelSerializer = __dependency4__["default"];
114     var EmbeddedRecordsMixin = __dependency5__["default"];
115
116     /**
117       @module ember-data
118     */
119
120     var forEach = Ember.EnumerableUtils.forEach;
121     var decamelize = Ember.String.decamelize,
122         underscore = Ember.String.underscore;
123
124     /**
125       The ActiveModelAdapter is a subclass of the RESTAdapter designed to integrate
126       with a JSON API that uses an underscored naming convention instead of camelCasing.
127       It has been designed to work out of the box with the
128       [active_model_serializers](http://github.com/rails-api/active_model_serializers)
129       Ruby gem. This Adapter expects specific settings using ActiveModel::Serializers,
130       `embed :ids, include: true` which sideloads the records.
131
132       This adapter extends the DS.RESTAdapter by making consistent use of the camelization,
133       decamelization and pluralization methods to normalize the serialized JSON into a
134       format that is compatible with a conventional Rails backend and Ember Data.
135
136       ## JSON Structure
137
138       The ActiveModelAdapter expects the JSON returned from your server to follow
139       the REST adapter conventions substituting underscored keys for camelcased ones.
140
141       ### Conventional Names
142
143       Attribute names in your JSON payload should be the underscored versions of
144       the attributes in your Ember.js models.
145
146       For example, if you have a `Person` model:
147
148       ```js
149       App.FamousPerson = DS.Model.extend({
150         firstName: DS.attr('string'),
151         lastName: DS.attr('string'),
152         occupation: DS.attr('string')
153       });
154       ```
155
156       The JSON returned should look like this:
157
158       ```js
159       {
160         "famous_person": {
161           "first_name": "Barack",
162           "last_name": "Obama",
163           "occupation": "President"
164         }
165       }
166       ```
167
168       @class ActiveModelAdapter
169       @constructor
170       @namespace DS
171       @extends DS.RESTAdapter
172     **/
173
174     var ActiveModelAdapter = RESTAdapter.extend({
175       defaultSerializer: '-active-model',
176       /**
177         The ActiveModelAdapter overrides the `pathForType` method to build
178         underscored URLs by decamelizing and pluralizing the object type name.
179
180         ```js
181           this.pathForType("famousPerson");
182           //=> "famous_people"
183         ```
184
185         @method pathForType
186         @param {String} type
187         @return String
188       */
189       pathForType: function(type) {
190         var decamelized = decamelize(type);
191         var underscored = underscore(decamelized);
192         return pluralize(underscored);
193       },
194
195       /**
196         The ActiveModelAdapter overrides the `ajaxError` method
197         to return a DS.InvalidError for all 422 Unprocessable Entity
198         responses.
199
200         A 422 HTTP response from the server generally implies that the request
201         was well formed but the API was unable to process it because the
202         content was not semantically correct or meaningful per the API.
203
204         For more information on 422 HTTP Error code see 11.2 WebDAV RFC 4918
205         https://tools.ietf.org/html/rfc4918#section-11.2
206
207         @method ajaxError
208         @param jqXHR
209         @return error
210       */
211       ajaxError: function(jqXHR) {
212         var error = this._super(jqXHR);
213
214         if (jqXHR && jqXHR.status === 422) {
215           var response = Ember.$.parseJSON(jqXHR.responseText),
216               errors = {};
217
218           if (response.errors !== undefined) {
219             var jsonErrors = response.errors;
220
221             forEach(Ember.keys(jsonErrors), function(key) {
222               errors[Ember.String.camelize(key)] = jsonErrors[key];
223             });
224           }
225
226           return new InvalidError(errors);
227         } else {
228           return error;
229         }
230       }
231     });
232
233     __exports__["default"] = ActiveModelAdapter;
234   });
235 define("activemodel-adapter/lib/system/active_model_serializer", 
236   ["../../../ember-inflector/lib/main","../../../ember-data/lib/serializers/rest_serializer","exports"],
237   function(__dependency1__, __dependency2__, __exports__) {
238     "use strict";
239     var singularize = __dependency1__.singularize;
240     var RESTSerializer = __dependency2__["default"];
241     /**
242       @module ember-data
243     */
244
245     var get = Ember.get,
246         forEach = Ember.EnumerableUtils.forEach,
247         camelize =   Ember.String.camelize,
248         capitalize = Ember.String.capitalize,
249         decamelize = Ember.String.decamelize,
250         underscore = Ember.String.underscore;
251     /**
252       The ActiveModelSerializer is a subclass of the RESTSerializer designed to integrate
253       with a JSON API that uses an underscored naming convention instead of camelCasing.
254       It has been designed to work out of the box with the
255       [active_model_serializers](http://github.com/rails-api/active_model_serializers)
256       Ruby gem. This Serializer expects specific settings using ActiveModel::Serializers,
257       `embed :ids, include: true` which sideloads the records.
258
259       This serializer extends the DS.RESTSerializer by making consistent
260       use of the camelization, decamelization and pluralization methods to
261       normalize the serialized JSON into a format that is compatible with
262       a conventional Rails backend and Ember Data.
263
264       ## JSON Structure
265
266       The ActiveModelSerializer expects the JSON returned from your server
267       to follow the REST adapter conventions substituting underscored keys
268       for camelcased ones.
269
270       ### Conventional Names
271
272       Attribute names in your JSON payload should be the underscored versions of
273       the attributes in your Ember.js models.
274
275       For example, if you have a `Person` model:
276
277       ```js
278       App.FamousPerson = DS.Model.extend({
279         firstName: DS.attr('string'),
280         lastName: DS.attr('string'),
281         occupation: DS.attr('string')
282       });
283       ```
284
285       The JSON returned should look like this:
286
287       ```js
288       {
289         "famous_person": {
290           "first_name": "Barack",
291           "last_name": "Obama",
292           "occupation": "President"
293         }
294       }
295       ```
296
297       @class ActiveModelSerializer
298       @namespace DS
299       @extends DS.RESTSerializer
300     */
301     var ActiveModelSerializer = RESTSerializer.extend({
302       // SERIALIZE
303
304       /**
305         Converts camelCased attributes to underscored when serializing.
306
307         @method keyForAttribute
308         @param {String} attribute
309         @return String
310       */
311       keyForAttribute: function(attr) {
312         return decamelize(attr);
313       },
314
315       /**
316         Underscores relationship names and appends "_id" or "_ids" when serializing
317         relationship keys.
318
319         @method keyForRelationship
320         @param {String} key
321         @param {String} kind
322         @return String
323       */
324       keyForRelationship: function(key, kind) {
325         key = decamelize(key);
326         if (kind === "belongsTo") {
327           return key + "_id";
328         } else if (kind === "hasMany") {
329           return singularize(key) + "_ids";
330         } else {
331           return key;
332         }
333       },
334
335       /*
336         Does not serialize hasMany relationships by default.
337       */
338       serializeHasMany: Ember.K,
339
340       /**
341         Underscores the JSON root keys when serializing.
342
343         @method serializeIntoHash
344         @param {Object} hash
345         @param {subclass of DS.Model} type
346         @param {DS.Model} record
347         @param {Object} options
348       */
349       serializeIntoHash: function(data, type, record, options) {
350         var root = underscore(decamelize(type.typeKey));
351         data[root] = this.serialize(record, options);
352       },
353
354       /**
355         Serializes a polymorphic type as a fully capitalized model name.
356
357         @method serializePolymorphicType
358         @param {DS.Model} record
359         @param {Object} json
360         @param relationship
361       */
362       serializePolymorphicType: function(record, json, relationship) {
363         var key = relationship.key,
364             belongsTo = get(record, key);
365
366         if (belongsTo) {
367           key = this.keyForAttribute(key);
368           json[key + "_type"] = capitalize(belongsTo.constructor.typeKey);
369         }
370       },
371
372       // EXTRACT
373
374       /**
375         Add extra step to `DS.RESTSerializer.normalize` so links are normalized.
376
377         If your payload looks like:
378
379         ```js
380         {
381           "post": {
382             "id": 1,
383             "title": "Rails is omakase",
384             "links": { "flagged_comments": "api/comments/flagged" }
385           }
386         }
387         ```
388
389         The normalized version would look like this
390
391         ```js
392         {
393           "post": {
394             "id": 1,
395             "title": "Rails is omakase",
396             "links": { "flaggedComments": "api/comments/flagged" }
397           }
398         }
399         ```
400
401         @method normalize
402         @param {subclass of DS.Model} type
403         @param {Object} hash
404         @param {String} prop
405         @return Object
406       */
407
408       normalize: function(type, hash, prop) {
409         this.normalizeLinks(hash);
410
411         return this._super(type, hash, prop);
412       },
413
414       /**
415         Convert `snake_cased` links  to `camelCase`
416
417         @method normalizeLinks
418         @param {Object} data
419       */
420
421       normalizeLinks: function(data){
422         if (data.links) {
423           var links = data.links;
424
425           for (var link in links) {
426             var camelizedLink = camelize(link);
427
428             if (camelizedLink !== link) {
429               links[camelizedLink] = links[link];
430               delete links[link];
431             }
432           }
433         }
434       },
435
436       /**
437         Normalize the polymorphic type from the JSON.
438
439         Normalize:
440         ```js
441           {
442             id: "1"
443             minion: { type: "evil_minion", id: "12"}
444           }
445         ```
446
447         To:
448         ```js
449           {
450             id: "1"
451             minion: { type: "evilMinion", id: "12"}
452           }
453         ```
454
455         @method normalizeRelationships
456         @private
457       */
458       normalizeRelationships: function(type, hash) {
459         var payloadKey, payload;
460
461         if (this.keyForRelationship) {
462           type.eachRelationship(function(key, relationship) {
463             if (relationship.options.polymorphic) {
464               payloadKey = this.keyForAttribute(key);
465               payload = hash[payloadKey];
466               if (payload && payload.type) {
467                 payload.type = this.typeForRoot(payload.type);
468               } else if (payload && relationship.kind === "hasMany") {
469                 var self = this;
470                 forEach(payload, function(single) {
471                   single.type = self.typeForRoot(single.type);
472                 });
473               }
474             } else {
475               payloadKey = this.keyForRelationship(key, relationship.kind);
476               payload = hash[payloadKey];
477             }
478
479             hash[key] = payload;
480
481             if (key !== payloadKey) {
482               delete hash[payloadKey];
483             }
484           }, this);
485         }
486       }
487     });
488
489     __exports__["default"] = ActiveModelSerializer;
490   });
491 define("activemodel-adapter/lib/system/embedded_records_mixin", 
492   ["../../../ember-inflector/lib/main","exports"],
493   function(__dependency1__, __exports__) {
494     "use strict";
495     var get = Ember.get;
496     var forEach = Ember.EnumerableUtils.forEach;
497     var camelize = Ember.String.camelize;
498
499     var pluralize = __dependency1__.pluralize;
500
501     /**
502       ## Using Embedded Records
503
504       `DS.EmbeddedRecordsMixin` supports serializing embedded records.
505
506       To set up embedded records, include the mixin when extending a serializer
507       then define and configure embedded (model) relationships.
508
509       Below is an example of a per-type serializer ('post' type).
510
511       ```js
512       App.PostSerializer = DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {
513         attrs: {
514           author: {embedded: 'always'},
515           comments: {serialize: 'ids'}
516         }
517       })
518       ```
519
520       The `attrs` option for a resource `{embedded: 'always'}` is shorthand for:
521
522       ```js
523       {serialize: 'records', deserialize: 'records'}
524       ```
525
526       ### Configuring Attrs
527
528       A resource's `attrs` option may be set to use `ids`, `records` or `no` for the
529       `serialize`  and `deserialize` settings.
530
531       The `attrs` property can be set on the ApplicationSerializer or a per-type
532       serializer.
533
534       In the case where embedded JSON is expected while extracting a payoad (reading)
535       the setting is `deserialize: 'records'`, there is no need to use `ids` when
536       extracting as that is the default behavior without this mixin if you are using
537       the vanilla ActiveModelAdapter. Likewise, to embed JSON in the payload while
538       serializing `serialize: 'records'` is the setting to use. There is an option of
539       not embedding JSON in the serialized payload by using `serialize: 'ids'`. If you
540       do not want the relationship sent at all, you can use `serialize: 'no'`.
541
542
543       ### ActiveModelSerializer defaults
544       If you do not overwrite `attrs` for a specific relationship, the `ActiveModelSerializer`
545       will behave in the following way:
546
547       BelongsTo: `{serialize:'id', deserialize:'id'}`
548       HasMany:   `{serialize:no,  deserialize:'ids'}`
549
550       ### Model Relationships
551
552       Embedded records must have a model defined to be extracted and serialized.
553
554       To successfully extract and serialize embedded records the model relationships
555       must be setup correcty See the
556       [defining relationships](/guides/models/defining-models/#toc_defining-relationships)
557       section of the **Defining Models** guide page.
558
559       Records without an `id` property are not considered embedded records, model
560       instances must have an `id` property to be used with Ember Data.
561
562       ### Example JSON payloads, Models and Serializers
563
564       **When customizing a serializer it is imporant to grok what the cusomizations
565       are, please read the docs for the methods this mixin provides, in case you need
566       to modify to fit your specific needs.**
567
568       For example review the docs for each method of this mixin:
569
570       * [extractArray](/api/data/classes/DS.EmbeddedRecordsMixin.html#method_extractArray)
571       * [extractSingle](/api/data/classes/DS.EmbeddedRecordsMixin.html#method_extractSingle)
572       * [serializeBelongsTo](/api/data/classes/DS.EmbeddedRecordsMixin.html#method_serializeBelongsTo)
573       * [serializeHasMany](/api/data/classes/DS.EmbeddedRecordsMixin.html#method_serializeHasMany)
574
575       @class EmbeddedRecordsMixin
576       @namespace DS
577     */
578     var EmbeddedRecordsMixin = Ember.Mixin.create({
579
580       /**
581         Serialize `belongsTo` relationship when it is configured as an embedded object.
582
583         This example of an author model belongs to a post model:
584
585         ```js
586         Post = DS.Model.extend({
587           title:    DS.attr('string'),
588           body:     DS.attr('string'),
589           author:   DS.belongsTo('author')
590         });
591
592         Author = DS.Model.extend({
593           name:     DS.attr('string'),
594           post:     DS.belongsTo('post')
595         });
596         ```
597
598         Use a custom (type) serializer for the post model to configure embedded author
599
600         ```js
601         App.PostSerializer = DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
602           attrs: {
603             author: {embedded: 'always'}
604           }
605         })
606         ```
607
608         A payload with an attribute configured for embedded records can serialize
609         the records together under the root attribute's payload:
610
611         ```js
612         {
613           "post": {
614             "id": "1"
615             "title": "Rails is omakase",
616             "author": {
617               "id": "2"
618               "name": "dhh"
619             }
620           }
621         }
622         ```
623
624         @method serializeBelongsTo
625         @param {DS.Model} record
626         @param {Object} json
627         @param {Object} relationship
628       */
629       serializeBelongsTo: function(record, json, relationship) {
630         var attr = relationship.key;
631         var attrs = this.get('attrs');
632         if (noSerializeOptionSpecified(attrs, attr)) {
633           this._super(record, json, relationship);
634           return;
635         }
636         var includeIds = hasSerializeIdsOption(attrs, attr);
637         var includeRecords = hasSerializeRecordsOption(attrs, attr);
638         var embeddedRecord = record.get(attr);
639         if (includeIds) {
640           key = this.keyForRelationship(attr, relationship.kind);
641           if (!embeddedRecord) {
642             json[key] = null;
643           } else {
644             json[key] = get(embeddedRecord, 'id');
645           }
646         } else if (includeRecords) {
647           var key = this.keyForRelationship(attr);
648           if (!embeddedRecord) {
649             json[key] = null;
650           } else {
651             json[key] = embeddedRecord.serialize({includeId: true});
652             this.removeEmbeddedForeignKey(record, embeddedRecord, relationship, json[key]);
653           }
654         }
655       },
656
657       /**
658         Serialize `hasMany` relationship when it is configured as embedded objects.
659
660         This example of a post model has many comments:
661
662         ```js
663         Post = DS.Model.extend({
664           title:    DS.attr('string'),
665           body:     DS.attr('string'),
666           comments: DS.hasMany('comment')
667         });
668
669         Comment = DS.Model.extend({
670           body:     DS.attr('string'),
671           post:     DS.belongsTo('post')
672         });
673         ```
674
675         Use a custom (type) serializer for the post model to configure embedded comments
676
677         ```js
678         App.PostSerializer = DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
679           attrs: {
680             comments: {embedded: 'always'}
681           }
682         })
683         ```
684
685         A payload with an attribute configured for embedded records can serialize
686         the records together under the root attribute's payload:
687
688         ```js
689         {
690           "post": {
691             "id": "1"
692             "title": "Rails is omakase",
693             "body": "I want this for my ORM, I want that for my template language..."
694             "comments": [{
695               "id": "1",
696               "body": "Rails is unagi"
697             }, {
698               "id": "2",
699               "body": "Omakase O_o"
700             }]
701           }
702         }
703         ```
704
705         The attrs options object can use more specific instruction for extracting and
706         serializing. When serializing, an option to embed `ids` or `records` can be set.
707         When extracting the only option is `records`.
708
709         So `{embedded: 'always'}` is shorthand for:
710         `{serialize: 'records', deserialize: 'records'}`
711
712         To embed the `ids` for a related object (using a hasMany relationship):
713
714         ```js
715         App.PostSerializer = DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
716           attrs: {
717             comments: {serialize: 'ids', deserialize: 'records'}
718           }
719         })
720         ```
721
722         ```js
723         {
724           "post": {
725             "id": "1"
726             "title": "Rails is omakase",
727             "body": "I want this for my ORM, I want that for my template language..."
728             "comments": ["1", "2"]
729           }
730         }
731         ```
732
733         @method serializeHasMany
734         @param {DS.Model} record
735         @param {Object} json
736         @param {Object} relationship
737       */
738       serializeHasMany: function(record, json, relationship) {
739         var attr = relationship.key;
740         var attrs = this.get('attrs');
741         if (noSerializeOptionSpecified(attrs, attr)) {
742           this._super(record, json, relationship);
743           return;
744         }
745         var includeIds = hasSerializeIdsOption(attrs, attr);
746         var includeRecords = hasSerializeRecordsOption(attrs, attr);
747         var key;
748         if (includeIds) {
749           key = this.keyForRelationship(attr, relationship.kind);
750           json[key] = get(record, attr).mapBy('id');
751         } else if (includeRecords) {
752           key = this.keyForAttribute(attr);
753           json[key] = get(record, attr).map(function(embeddedRecord) {
754             var serializedEmbeddedRecord = embeddedRecord.serialize({includeId: true});
755             this.removeEmbeddedForeignKey(record, embeddedRecord, relationship, serializedEmbeddedRecord);
756             return serializedEmbeddedRecord;
757           }, this);
758         }
759       },
760
761       /**
762         When serializing an embedded record, modify the property (in the json payload)
763         that refers to the parent record (foreign key for relationship).
764
765         Serializing a `belongsTo` relationship removes the property that refers to the
766         parent record
767
768         Serializing a `hasMany` relationship does not remove the property that refers to
769         the parent record.
770
771         @method removeEmbeddedForeignKey
772         @param {DS.Model} record
773         @param {DS.Model} embeddedRecord
774         @param {Object} relationship
775         @param {Object} json
776       */
777       removeEmbeddedForeignKey: function (record, embeddedRecord, relationship, json) {
778         if (relationship.kind === 'hasMany') {
779           return;
780         } else if (relationship.kind === 'belongsTo') {
781           var parentRecord = record.constructor.inverseFor(relationship.key);
782           if (parentRecord) {
783             var name = parentRecord.name;
784             var embeddedSerializer = this.store.serializerFor(embeddedRecord.constructor);
785             var parentKey = embeddedSerializer.keyForRelationship(name, parentRecord.kind);
786             if (parentKey) {
787               delete json[parentKey];
788             }
789           }
790         }
791       },
792
793       /**
794         Extract an embedded object from the payload for a single object
795         and add the object in the compound document (side-loaded) format instead.
796
797         A payload with an attribute configured for embedded records needs to be extracted:
798
799         ```js
800         {
801           "post": {
802             "id": 1
803             "title": "Rails is omakase",
804             "author": {
805               "id": 2
806               "name": "dhh"
807             }
808             "comments": []
809           }
810         }
811         ```
812
813         Ember Data is expecting a payload with a compound document (side-loaded) like:
814
815         ```js
816         {
817           "post": {
818             "id": "1"
819             "title": "Rails is omakase",
820             "author": "2"
821             "comments": []
822           },
823           "authors": [{
824             "id": "2"
825             "post": "1"
826             "name": "dhh"
827           }]
828           "comments": []
829         }
830         ```
831
832         The payload's `author` attribute represents an object with a `belongsTo` relationship.
833         The `post` attribute under `author` is the foreign key with the id for the post
834
835         @method extractSingle
836         @param {DS.Store} store
837         @param {subclass of DS.Model} primaryType
838         @param {Object} payload
839         @param {String} recordId
840         @return Object the primary response to the original request
841       */
842       extractSingle: function(store, primaryType, payload, recordId) {
843         var root = this.keyForAttribute(primaryType.typeKey),
844             partial = payload[root];
845
846         updatePayloadWithEmbedded(this, store, primaryType, payload, partial);
847
848         return this._super(store, primaryType, payload, recordId);
849       },
850
851       /**
852         Extract embedded objects in an array when an attr is configured for embedded,
853         and add them as side-loaded objects instead.
854
855         A payload with an attr configured for embedded records needs to be extracted:
856
857         ```js
858         {
859           "post": {
860             "id": "1"
861             "title": "Rails is omakase",
862             "comments": [{
863               "id": "1",
864               "body": "Rails is unagi"
865             }, {
866               "id": "2",
867               "body": "Omakase O_o"
868             }]
869           }
870         }
871         ```
872
873         Ember Data is expecting a payload with compound document (side-loaded) like:
874
875         ```js
876         {
877           "post": {
878             "id": "1"
879             "title": "Rails is omakase",
880             "comments": ["1", "2"]
881           },
882           "comments": [{
883             "id": "1",
884             "body": "Rails is unagi"
885           }, {
886             "id": "2",
887             "body": "Omakase O_o"
888           }]
889         }
890         ```
891
892         The payload's `comments` attribute represents records in a `hasMany` relationship
893
894         @method extractArray
895         @param {DS.Store} store
896         @param {subclass of DS.Model} primaryType
897         @param {Object} payload
898         @return {Array<Object>} The primary array that was returned in response
899           to the original query.
900       */
901       extractArray: function(store, primaryType, payload) {
902         var root = this.keyForAttribute(primaryType.typeKey),
903             partials = payload[pluralize(root)];
904
905         forEach(partials, function(partial) {
906           updatePayloadWithEmbedded(this, store, primaryType, payload, partial);
907         }, this);
908
909         return this._super(store, primaryType, payload);
910       }
911     });
912
913     // checks config for attrs option to embedded (always) - serialize and deserialize
914     function hasEmbeddedAlwaysOption(attrs, attr) {
915       var option = attrsOption(attrs, attr);
916       return option && option.embedded === 'always';
917     }
918
919     // checks config for attrs option to serialize ids
920     function hasSerializeRecordsOption(attrs, attr) {
921       var alwaysEmbed = hasEmbeddedAlwaysOption(attrs, attr);
922       var option = attrsOption(attrs, attr);
923       return alwaysEmbed || (option && (option.serialize === 'records'));
924     }
925
926     // checks config for attrs option to serialize records
927     function hasSerializeIdsOption(attrs, attr) {
928       var option = attrsOption(attrs, attr);
929       return option && (option.serialize === 'ids' || option.serialize === 'id');
930     }
931
932     // checks config for attrs option to serialize records
933     function noSerializeOptionSpecified(attrs, attr) {
934       var option = attrsOption(attrs, attr);
935       var serializeRecords = hasSerializeRecordsOption(attrs, attr);
936       var serializeIds = hasSerializeIdsOption(attrs, attr);
937       return !(option && (option.serialize || option.embedded));
938     }
939
940     // checks config for attrs option to deserialize records
941     // a defined option object for a resource is treated the same as
942     // `deserialize: 'records'`
943     function hasDeserializeRecordsOption(attrs, attr) {
944       var alwaysEmbed = hasEmbeddedAlwaysOption(attrs, attr);
945       var option = attrsOption(attrs, attr);
946       var hasSerializingOption = option && (option.deserialize || option.serialize);
947       return alwaysEmbed || hasSerializingOption /* option.deserialize === 'records' */;
948     }
949
950     function attrsOption(attrs, attr) {
951       return attrs && (attrs[Ember.String.camelize(attr)] || attrs[attr]);
952     }
953
954     // chooses a relationship kind to branch which function is used to update payload
955     // does not change payload if attr is not embedded
956     function updatePayloadWithEmbedded(serializer, store, type, payload, partial) {
957       var attrs = get(serializer, 'attrs');
958
959       if (!attrs) {
960         return;
961       }
962       type.eachRelationship(function(key, relationship) {
963         if (hasDeserializeRecordsOption(attrs, key)) {
964           if (relationship.kind === "hasMany") {
965             updatePayloadWithEmbeddedHasMany(serializer, store, key, relationship, payload, partial);
966           }
967           if (relationship.kind === "belongsTo") {
968             updatePayloadWithEmbeddedBelongsTo(serializer, store, key, relationship, payload, partial);
969           }
970         }
971       });
972     }
973
974     // handles embedding for `hasMany` relationship
975     function updatePayloadWithEmbeddedHasMany(serializer, store, primaryType, relationship, payload, partial) {
976       var embeddedSerializer = store.serializerFor(relationship.type.typeKey);
977       var primaryKey = get(serializer, 'primaryKey');
978       var attr = relationship.type.typeKey;
979       // underscore forces the embedded records to be side loaded.
980       // it is needed when main type === relationship.type
981       var embeddedTypeKey = '_' + serializer.typeForRoot(relationship.type.typeKey);
982       var expandedKey = serializer.keyForRelationship(primaryType, relationship.kind);
983       var attribute  = serializer.keyForAttribute(primaryType);
984       var ids = [];
985
986       if (!partial[attribute]) {
987         return;
988       }
989
990       payload[embeddedTypeKey] = payload[embeddedTypeKey] || [];
991
992       forEach(partial[attribute], function(data) {
993         var embeddedType = store.modelFor(attr);
994         updatePayloadWithEmbedded(embeddedSerializer, store, embeddedType, payload, data);
995         ids.push(data[primaryKey]);
996         payload[embeddedTypeKey].push(data);
997       });
998
999       partial[expandedKey] = ids;
1000       delete partial[attribute];
1001     }
1002
1003     // handles embedding for `belongsTo` relationship
1004     function updatePayloadWithEmbeddedBelongsTo(serializer, store, primaryType, relationship, payload, partial) {
1005       var attrs = serializer.get('attrs');
1006
1007       if (!attrs ||
1008         !(hasDeserializeRecordsOption(attrs, Ember.String.camelize(primaryType)) ||
1009           hasDeserializeRecordsOption(attrs, primaryType))) {
1010         return;
1011       }
1012       var attr = relationship.type.typeKey;
1013       var _serializer = store.serializerFor(relationship.type.typeKey);
1014       var primaryKey = get(_serializer, 'primaryKey');
1015       var embeddedTypeKey = Ember.String.pluralize(attr); // TODO don't use pluralize
1016       var expandedKey = _serializer.keyForRelationship(primaryType, relationship.kind);
1017       var attribute = _serializer.keyForAttribute(primaryType);
1018
1019       if (!partial[attribute]) {
1020         return;
1021       }
1022       payload[embeddedTypeKey] = payload[embeddedTypeKey] || [];
1023       var embeddedType = store.modelFor(relationship.type.typeKey);
1024       // Recursive call for nested record
1025       updatePayloadWithEmbedded(_serializer, store, embeddedType, payload, partial[attribute]);
1026       partial[expandedKey] = partial[attribute].id;
1027       // Need to move an embedded `belongsTo` object into a pluralized collection
1028       payload[embeddedTypeKey].push(partial[attribute]);
1029       // Need a reference to the parent so relationship works between both `belongsTo` records
1030       partial[attribute][relationship.parentType.typeKey + '_id'] = partial.id;
1031       delete partial[attribute];
1032     }
1033
1034     __exports__["default"] = EmbeddedRecordsMixin;
1035   });
1036 define("ember-data/lib/adapters", 
1037   ["./adapters/fixture_adapter","./adapters/rest_adapter","exports"],
1038   function(__dependency1__, __dependency2__, __exports__) {
1039     "use strict";
1040     /**
1041       @module ember-data
1042     */
1043
1044     var FixtureAdapter = __dependency1__["default"];
1045     var RESTAdapter = __dependency2__["default"];
1046
1047     __exports__.RESTAdapter = RESTAdapter;
1048     __exports__.FixtureAdapter = FixtureAdapter;
1049   });
1050 define("ember-data/lib/adapters/fixture_adapter", 
1051   ["../system/adapter","exports"],
1052   function(__dependency1__, __exports__) {
1053     "use strict";
1054     /**
1055       @module ember-data
1056     */
1057
1058     var get = Ember.get, fmt = Ember.String.fmt,
1059         indexOf = Ember.EnumerableUtils.indexOf;
1060
1061     var counter = 0;
1062
1063     var Adapter = __dependency1__["default"];
1064
1065     /**
1066       `DS.FixtureAdapter` is an adapter that loads records from memory.
1067       It's primarily used for development and testing. You can also use
1068       `DS.FixtureAdapter` while working on the API but are not ready to
1069       integrate yet. It is a fully functioning adapter. All CRUD methods
1070       are implemented. You can also implement query logic that a remote
1071       system would do. It's possible to develop your entire application
1072       with `DS.FixtureAdapter`.
1073
1074       For information on how to use the `FixtureAdapter` in your
1075       application please see the [FixtureAdapter
1076       guide](/guides/models/the-fixture-adapter/).
1077
1078       @class FixtureAdapter
1079       @namespace DS
1080       @extends DS.Adapter
1081     */
1082     var FixtureAdapter = Adapter.extend({
1083       // by default, fixtures are already in normalized form
1084       serializer: null,
1085
1086       /**
1087         If `simulateRemoteResponse` is `true` the `FixtureAdapter` will
1088         wait a number of milliseconds before resolving promises with the
1089         fixture values. The wait time can be configured via the `latency`
1090         property.
1091
1092         @property simulateRemoteResponse
1093         @type {Boolean}
1094         @default true
1095       */
1096       simulateRemoteResponse: true,
1097
1098       /**
1099         By default the `FixtureAdapter` will simulate a wait of the
1100         `latency` milliseconds before resolving promises with the fixture
1101         values. This behavior can be turned off via the
1102         `simulateRemoteResponse` property.
1103
1104         @property latency
1105         @type {Number}
1106         @default 50
1107       */
1108       latency: 50,
1109
1110       /**
1111         Implement this method in order to provide data associated with a type
1112
1113         @method fixturesForType
1114         @param {Subclass of DS.Model} type
1115         @return {Array}
1116       */
1117       fixturesForType: function(type) {
1118         if (type.FIXTURES) {
1119           var fixtures = Ember.A(type.FIXTURES);
1120           return fixtures.map(function(fixture){
1121             var fixtureIdType = typeof fixture.id;
1122             if(fixtureIdType !== "number" && fixtureIdType !== "string"){
1123               throw new Error(fmt('the id property must be defined as a number or string for fixture %@', [fixture]));
1124             }
1125             fixture.id = fixture.id + '';
1126             return fixture;
1127           });
1128         }
1129         return null;
1130       },
1131
1132       /**
1133         Implement this method in order to query fixtures data
1134
1135         @method queryFixtures
1136         @param {Array} fixture
1137         @param {Object} query
1138         @param {Subclass of DS.Model} type
1139         @return {Promise|Array}
1140       */
1141       queryFixtures: function(fixtures, query, type) {
1142         Ember.assert('Not implemented: You must override the DS.FixtureAdapter::queryFixtures method to support querying the fixture store.');
1143       },
1144
1145       /**
1146         @method updateFixtures
1147         @param {Subclass of DS.Model} type
1148         @param {Array} fixture
1149       */
1150       updateFixtures: function(type, fixture) {
1151         if(!type.FIXTURES) {
1152           type.FIXTURES = [];
1153         }
1154
1155         var fixtures = type.FIXTURES;
1156
1157         this.deleteLoadedFixture(type, fixture);
1158
1159         fixtures.push(fixture);
1160       },
1161
1162       /**
1163         Implement this method in order to provide json for CRUD methods
1164
1165         @method mockJSON
1166         @param {Subclass of DS.Model} type
1167         @param {DS.Model} record
1168       */
1169       mockJSON: function(store, type, record) {
1170         return store.serializerFor(type).serialize(record, { includeId: true });
1171       },
1172
1173       /**
1174         @method generateIdForRecord
1175         @param {DS.Store} store
1176         @param {DS.Model} record
1177         @return {String} id
1178       */
1179       generateIdForRecord: function(store) {
1180         return "fixture-" + counter++;
1181       },
1182
1183       /**
1184         @method find
1185         @param {DS.Store} store
1186         @param {subclass of DS.Model} type
1187         @param {String} id
1188         @return {Promise} promise
1189       */
1190       find: function(store, type, id) {
1191         var fixtures = this.fixturesForType(type),
1192             fixture;
1193
1194         Ember.assert("Unable to find fixtures for model type "+type.toString(), fixtures);
1195
1196         if (fixtures) {
1197           fixture = Ember.A(fixtures).findProperty('id', id);
1198         }
1199
1200         if (fixture) {
1201           return this.simulateRemoteCall(function() {
1202             return fixture;
1203           }, this);
1204         }
1205       },
1206
1207       /**
1208         @method findMany
1209         @param {DS.Store} store
1210         @param {subclass of DS.Model} type
1211         @param {Array} ids
1212         @return {Promise} promise
1213       */
1214       findMany: function(store, type, ids) {
1215         var fixtures = this.fixturesForType(type);
1216
1217         Ember.assert("Unable to find fixtures for model type "+type.toString(), fixtures);
1218
1219         if (fixtures) {
1220           fixtures = fixtures.filter(function(item) {
1221             return indexOf(ids, item.id) !== -1;
1222           });
1223         }
1224
1225         if (fixtures) {
1226           return this.simulateRemoteCall(function() {
1227             return fixtures;
1228           }, this);
1229         }
1230       },
1231
1232       /**
1233         @private
1234         @method findAll
1235         @param {DS.Store} store
1236         @param {subclass of DS.Model} type
1237         @param {String} sinceToken
1238         @return {Promise} promise
1239       */
1240       findAll: function(store, type) {
1241         var fixtures = this.fixturesForType(type);
1242
1243         Ember.assert("Unable to find fixtures for model type "+type.toString(), fixtures);
1244
1245         return this.simulateRemoteCall(function() {
1246           return fixtures;
1247         }, this);
1248       },
1249
1250       /**
1251         @private
1252         @method findQuery
1253         @param {DS.Store} store
1254         @param {subclass of DS.Model} type
1255         @param {Object} query
1256         @param {DS.AdapterPopulatedRecordArray} recordArray
1257         @return {Promise} promise
1258       */
1259       findQuery: function(store, type, query, array) {
1260         var fixtures = this.fixturesForType(type);
1261
1262         Ember.assert("Unable to find fixtures for model type " + type.toString(), fixtures);
1263
1264         fixtures = this.queryFixtures(fixtures, query, type);
1265
1266         if (fixtures) {
1267           return this.simulateRemoteCall(function() {
1268             return fixtures;
1269           }, this);
1270         }
1271       },
1272
1273       /**
1274         @method createRecord
1275         @param {DS.Store} store
1276         @param {subclass of DS.Model} type
1277         @param {DS.Model} record
1278         @return {Promise} promise
1279       */
1280       createRecord: function(store, type, record) {
1281         var fixture = this.mockJSON(store, type, record);
1282
1283         this.updateFixtures(type, fixture);
1284
1285         return this.simulateRemoteCall(function() {
1286           return fixture;
1287         }, this);
1288       },
1289
1290       /**
1291         @method updateRecord
1292         @param {DS.Store} store
1293         @param {subclass of DS.Model} type
1294         @param {DS.Model} record
1295         @return {Promise} promise
1296       */
1297       updateRecord: function(store, type, record) {
1298         var fixture = this.mockJSON(store, type, record);
1299
1300         this.updateFixtures(type, fixture);
1301
1302         return this.simulateRemoteCall(function() {
1303           return fixture;
1304         }, this);
1305       },
1306
1307       /**
1308         @method deleteRecord
1309         @param {DS.Store} store
1310         @param {subclass of DS.Model} type
1311         @param {DS.Model} record
1312         @return {Promise} promise
1313       */
1314       deleteRecord: function(store, type, record) {
1315         var fixture = this.mockJSON(store, type, record);
1316
1317         this.deleteLoadedFixture(type, fixture);
1318
1319         return this.simulateRemoteCall(function() {
1320           // no payload in a deletion
1321           return null;
1322         });
1323       },
1324
1325       /*
1326         @method deleteLoadedFixture
1327         @private
1328         @param type
1329         @param record
1330       */
1331       deleteLoadedFixture: function(type, record) {
1332         var existingFixture = this.findExistingFixture(type, record);
1333
1334         if(existingFixture) {
1335           var index = indexOf(type.FIXTURES, existingFixture);
1336           type.FIXTURES.splice(index, 1);
1337           return true;
1338         }
1339       },
1340
1341       /*
1342         @method findExistingFixture
1343         @private
1344         @param type
1345         @param record
1346       */
1347       findExistingFixture: function(type, record) {
1348         var fixtures = this.fixturesForType(type);
1349         var id = get(record, 'id');
1350
1351         return this.findFixtureById(fixtures, id);
1352       },
1353
1354       /*
1355         @method findFixtureById
1356         @private
1357         @param fixtures
1358         @param id
1359       */
1360       findFixtureById: function(fixtures, id) {
1361         return Ember.A(fixtures).find(function(r) {
1362           if(''+get(r, 'id') === ''+id) {
1363             return true;
1364           } else {
1365             return false;
1366           }
1367         });
1368       },
1369
1370       /*
1371         @method simulateRemoteCall
1372         @private
1373         @param callback
1374         @param context
1375       */
1376       simulateRemoteCall: function(callback, context) {
1377         var adapter = this;
1378
1379         return new Ember.RSVP.Promise(function(resolve) {
1380           if (get(adapter, 'simulateRemoteResponse')) {
1381             // Schedule with setTimeout
1382             Ember.run.later(function() {
1383               resolve(callback.call(context));
1384             }, get(adapter, 'latency'));
1385           } else {
1386             // Asynchronous, but at the of the runloop with zero latency
1387             Ember.run.schedule('actions', null, function() {
1388               resolve(callback.call(context));
1389             });
1390           }
1391         }, "DS: FixtureAdapter#simulateRemoteCall");
1392       }
1393     });
1394
1395     __exports__["default"] = FixtureAdapter;
1396   });
1397 define("ember-data/lib/adapters/rest_adapter", 
1398   ["../system/adapter","exports"],
1399   function(__dependency1__, __exports__) {
1400     "use strict";
1401     /**
1402       @module ember-data
1403     */
1404
1405     var Adapter = __dependency1__["default"];
1406     var get = Ember.get, set = Ember.set;
1407     var forEach = Ember.ArrayPolyfills.forEach;
1408
1409     /**
1410       The REST adapter allows your store to communicate with an HTTP server by
1411       transmitting JSON via XHR. Most Ember.js apps that consume a JSON API
1412       should use the REST adapter.
1413
1414       This adapter is designed around the idea that the JSON exchanged with
1415       the server should be conventional.
1416
1417       ## JSON Structure
1418
1419       The REST adapter expects the JSON returned from your server to follow
1420       these conventions.
1421
1422       ### Object Root
1423
1424       The JSON payload should be an object that contains the record inside a
1425       root property. For example, in response to a `GET` request for
1426       `/posts/1`, the JSON should look like this:
1427
1428       ```js
1429       {
1430         "post": {
1431           "title": "I'm Running to Reform the W3C's Tag",
1432           "author": "Yehuda Katz"
1433         }
1434       }
1435       ```
1436
1437       ### Conventional Names
1438
1439       Attribute names in your JSON payload should be the camelCased versions of
1440       the attributes in your Ember.js models.
1441
1442       For example, if you have a `Person` model:
1443
1444       ```js
1445       App.Person = DS.Model.extend({
1446         firstName: DS.attr('string'),
1447         lastName: DS.attr('string'),
1448         occupation: DS.attr('string')
1449       });
1450       ```
1451
1452       The JSON returned should look like this:
1453
1454       ```js
1455       {
1456         "person": {
1457           "firstName": "Barack",
1458           "lastName": "Obama",
1459           "occupation": "President"
1460         }
1461       }
1462       ```
1463
1464       ## Customization
1465
1466       ### Endpoint path customization
1467
1468       Endpoint paths can be prefixed with a `namespace` by setting the namespace
1469       property on the adapter:
1470
1471       ```js
1472       DS.RESTAdapter.reopen({
1473         namespace: 'api/1'
1474       });
1475       ```
1476       Requests for `App.Person` would now target `/api/1/people/1`.
1477
1478       ### Host customization
1479
1480       An adapter can target other hosts by setting the `host` property.
1481
1482       ```js
1483       DS.RESTAdapter.reopen({
1484         host: 'https://api.example.com'
1485       });
1486       ```
1487
1488       ### Headers customization
1489
1490       Some APIs require HTTP headers, e.g. to provide an API key. Arbitrary
1491       headers can be set as key/value pairs on the `RESTAdapter`'s `headers`
1492       object and Ember Data will send them along with each ajax request.
1493
1494
1495       ```js
1496       App.ApplicationAdapter = DS.RESTAdapter.extend({
1497         headers: {
1498           "API_KEY": "secret key",
1499           "ANOTHER_HEADER": "Some header value"
1500         }
1501       });
1502       ```
1503
1504       `headers` can also be used as a computed property to support dynamic
1505       headers. In the example below, the `session` object has been
1506       injected into an adapter by Ember's container.
1507
1508       ```js
1509       App.ApplicationAdapter = DS.RESTAdapter.extend({
1510         headers: function() {
1511           return {
1512             "API_KEY": this.get("session.authToken"),
1513             "ANOTHER_HEADER": "Some header value"
1514           };
1515         }.property("session.authToken")
1516       });
1517       ```
1518
1519       In some cases, your dynamic headers may require data from some
1520       object outside of Ember's observer system (for example
1521       `document.cookie`). You can use the
1522       [volatile](/api/classes/Ember.ComputedProperty.html#method_volatile)
1523       function to set the property into a non-chached mode causing the headers to
1524       be recomputed with every request.
1525
1526       ```js
1527       App.ApplicationAdapter = DS.RESTAdapter.extend({
1528         headers: function() {
1529           return {
1530             "API_KEY": Ember.get(document.cookie.match(/apiKey\=([^;]*)/), "1"),
1531             "ANOTHER_HEADER": "Some header value"
1532           };
1533         }.property().volatile();
1534       });
1535       ```
1536
1537       @class RESTAdapter
1538       @constructor
1539       @namespace DS
1540       @extends DS.Adapter
1541     */
1542     var RESTAdapter = Adapter.extend({
1543       defaultSerializer: '-rest',
1544       /**
1545         Endpoint paths can be prefixed with a `namespace` by setting the namespace
1546         property on the adapter:
1547
1548         ```javascript
1549         DS.RESTAdapter.reopen({
1550           namespace: 'api/1'
1551         });
1552         ```
1553
1554         Requests for `App.Post` would now target `/api/1/post/`.
1555
1556         @property namespace
1557         @type {String}
1558       */
1559
1560       /**
1561         An adapter can target other hosts by setting the `host` property.
1562
1563         ```javascript
1564         DS.RESTAdapter.reopen({
1565           host: 'https://api.example.com'
1566         });
1567         ```
1568
1569         Requests for `App.Post` would now target `https://api.example.com/post/`.
1570
1571         @property host
1572         @type {String}
1573       */
1574
1575       /**
1576         Some APIs require HTTP headers, e.g. to provide an API
1577         key. Arbitrary headers can be set as key/value pairs on the
1578         `RESTAdapter`'s `headers` object and Ember Data will send them
1579         along with each ajax request. For dynamic headers see [headers
1580         customization](/api/data/classes/DS.RESTAdapter.html#toc_headers-customization).
1581
1582         ```javascript
1583         App.ApplicationAdapter = DS.RESTAdapter.extend({
1584           headers: {
1585             "API_KEY": "secret key",
1586             "ANOTHER_HEADER": "Some header value"
1587           }
1588         });
1589         ```
1590
1591         @property headers
1592         @type {Object}
1593       */
1594
1595       /**
1596         Called by the store in order to fetch the JSON for a given
1597         type and ID.
1598
1599         The `find` method makes an Ajax request to a URL computed by `buildURL`, and returns a
1600         promise for the resulting payload.
1601
1602         This method performs an HTTP `GET` request with the id provided as part of the query string.
1603
1604         @method find
1605         @param {DS.Store} store
1606         @param {subclass of DS.Model} type
1607         @param {String} id
1608         @return {Promise} promise
1609       */
1610       find: function(store, type, id) {
1611         return this.ajax(this.buildURL(type.typeKey, id), 'GET');
1612       },
1613
1614       /**
1615         Called by the store in order to fetch a JSON array for all
1616         of the records for a given type.
1617
1618         The `findAll` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
1619         promise for the resulting payload.
1620
1621         @private
1622         @method findAll
1623         @param {DS.Store} store
1624         @param {subclass of DS.Model} type
1625         @param {String} sinceToken
1626         @return {Promise} promise
1627       */
1628       findAll: function(store, type, sinceToken) {
1629         var query;
1630
1631         if (sinceToken) {
1632           query = { since: sinceToken };
1633         }
1634
1635         return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query });
1636       },
1637
1638       /**
1639         Called by the store in order to fetch a JSON array for
1640         the records that match a particular query.
1641
1642         The `findQuery` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
1643         promise for the resulting payload.
1644
1645         The `query` argument is a simple JavaScript object that will be passed directly
1646         to the server as parameters.
1647
1648         @private
1649         @method findQuery
1650         @param {DS.Store} store
1651         @param {subclass of DS.Model} type
1652         @param {Object} query
1653         @return {Promise} promise
1654       */
1655       findQuery: function(store, type, query) {
1656         return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query });
1657       },
1658
1659       /**
1660         Called by the store in order to fetch a JSON array for
1661         the unloaded records in a has-many relationship that were originally
1662         specified as IDs.
1663
1664         For example, if the original payload looks like:
1665
1666         ```js
1667         {
1668           "id": 1,
1669           "title": "Rails is omakase",
1670           "comments": [ 1, 2, 3 ]
1671         }
1672         ```
1673
1674         The IDs will be passed as a URL-encoded Array of IDs, in this form:
1675
1676         ```
1677         ids[]=1&ids[]=2&ids[]=3
1678         ```
1679
1680         Many servers, such as Rails and PHP, will automatically convert this URL-encoded array
1681         into an Array for you on the server-side. If you want to encode the
1682         IDs, differently, just override this (one-line) method.
1683
1684         The `findMany` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
1685         promise for the resulting payload.
1686
1687         @method findMany
1688         @param {DS.Store} store
1689         @param {subclass of DS.Model} type
1690         @param {Array} ids
1691         @return {Promise} promise
1692       */
1693       findMany: function(store, type, ids) {
1694         return this.ajax(this.buildURL(type.typeKey), 'GET', { data: { ids: ids } });
1695       },
1696
1697       /**
1698         Called by the store in order to fetch a JSON array for
1699         the unloaded records in a has-many relationship that were originally
1700         specified as a URL (inside of `links`).
1701
1702         For example, if your original payload looks like this:
1703
1704         ```js
1705         {
1706           "post": {
1707             "id": 1,
1708             "title": "Rails is omakase",
1709             "links": { "comments": "/posts/1/comments" }
1710           }
1711         }
1712         ```
1713
1714         This method will be called with the parent record and `/posts/1/comments`.
1715
1716         The `findHasMany` method will make an Ajax (HTTP GET) request to the originally specified URL.
1717         If the URL is host-relative (starting with a single slash), the
1718         request will use the host specified on the adapter (if any).
1719
1720         @method findHasMany
1721         @param {DS.Store} store
1722         @param {DS.Model} record
1723         @param {String} url
1724         @return {Promise} promise
1725       */
1726       findHasMany: function(store, record, url) {
1727         var host = get(this, 'host'),
1728             id   = get(record, 'id'),
1729             type = record.constructor.typeKey;
1730
1731         if (host && url.charAt(0) === '/' && url.charAt(1) !== '/') {
1732           url = host + url;
1733         }
1734
1735         return this.ajax(this.urlPrefix(url, this.buildURL(type, id)), 'GET');
1736       },
1737
1738       /**
1739         Called by the store in order to fetch a JSON array for
1740         the unloaded records in a belongs-to relationship that were originally
1741         specified as a URL (inside of `links`).
1742
1743         For example, if your original payload looks like this:
1744
1745         ```js
1746         {
1747           "person": {
1748             "id": 1,
1749             "name": "Tom Dale",
1750             "links": { "group": "/people/1/group" }
1751           }
1752         }
1753         ```
1754
1755         This method will be called with the parent record and `/people/1/group`.
1756
1757         The `findBelongsTo` method will make an Ajax (HTTP GET) request to the originally specified URL.
1758
1759         @method findBelongsTo
1760         @param {DS.Store} store
1761         @param {DS.Model} record
1762         @param {String} url
1763         @return {Promise} promise
1764       */
1765       findBelongsTo: function(store, record, url) {
1766         var id   = get(record, 'id'),
1767             type = record.constructor.typeKey;
1768
1769         return this.ajax(this.urlPrefix(url, this.buildURL(type, id)), 'GET');
1770       },
1771
1772       /**
1773         Called by the store when a newly created record is
1774         saved via the `save` method on a model record instance.
1775
1776         The `createRecord` method serializes the record and makes an Ajax (HTTP POST) request
1777         to a URL computed by `buildURL`.
1778
1779         See `serialize` for information on how to customize the serialized form
1780         of a record.
1781
1782         @method createRecord
1783         @param {DS.Store} store
1784         @param {subclass of DS.Model} type
1785         @param {DS.Model} record
1786         @return {Promise} promise
1787       */
1788       createRecord: function(store, type, record) {
1789         var data = {};
1790         var serializer = store.serializerFor(type.typeKey);
1791
1792         serializer.serializeIntoHash(data, type, record, { includeId: true });
1793
1794         return this.ajax(this.buildURL(type.typeKey), "POST", { data: data });
1795       },
1796
1797       /**
1798         Called by the store when an existing record is saved
1799         via the `save` method on a model record instance.
1800
1801         The `updateRecord` method serializes the record and makes an Ajax (HTTP PUT) request
1802         to a URL computed by `buildURL`.
1803
1804         See `serialize` for information on how to customize the serialized form
1805         of a record.
1806
1807         @method updateRecord
1808         @param {DS.Store} store
1809         @param {subclass of DS.Model} type
1810         @param {DS.Model} record
1811         @return {Promise} promise
1812       */
1813       updateRecord: function(store, type, record) {
1814         var data = {};
1815         var serializer = store.serializerFor(type.typeKey);
1816
1817         serializer.serializeIntoHash(data, type, record);
1818
1819         var id = get(record, 'id');
1820
1821         return this.ajax(this.buildURL(type.typeKey, id), "PUT", { data: data });
1822       },
1823
1824       /**
1825         Called by the store when a record is deleted.
1826
1827         The `deleteRecord` method  makes an Ajax (HTTP DELETE) request to a URL computed by `buildURL`.
1828
1829         @method deleteRecord
1830         @param {DS.Store} store
1831         @param {subclass of DS.Model} type
1832         @param {DS.Model} record
1833         @return {Promise} promise
1834       */
1835       deleteRecord: function(store, type, record) {
1836         var id = get(record, 'id');
1837
1838         return this.ajax(this.buildURL(type.typeKey, id), "DELETE");
1839       },
1840
1841       /**
1842         Builds a URL for a given type and optional ID.
1843
1844         By default, it pluralizes the type's name (for example, 'post'
1845         becomes 'posts' and 'person' becomes 'people'). To override the
1846         pluralization see [pathForType](#method_pathForType).
1847
1848         If an ID is specified, it adds the ID to the path generated
1849         for the type, separated by a `/`.
1850
1851         @method buildURL
1852         @param {String} type
1853         @param {String} id
1854         @return {String} url
1855       */
1856       buildURL: function(type, id) {
1857         var url = [],
1858             host = get(this, 'host'),
1859             prefix = this.urlPrefix();
1860
1861         if (type) { url.push(this.pathForType(type)); }
1862         if (id) { url.push(id); }
1863
1864         if (prefix) { url.unshift(prefix); }
1865
1866         url = url.join('/');
1867         if (!host && url) { url = '/' + url; }
1868
1869         return url;
1870       },
1871
1872       /**
1873         @method urlPrefix
1874         @private
1875         @param {String} path
1876         @param {String} parentUrl
1877         @return {String} urlPrefix
1878       */
1879       urlPrefix: function(path, parentURL) {
1880         var host = get(this, 'host'),
1881             namespace = get(this, 'namespace'),
1882             url = [];
1883
1884         if (path) {
1885           // Absolute path
1886           if (path.charAt(0) === '/') {
1887             if (host) {
1888               path = path.slice(1);
1889               url.push(host);
1890             }
1891           // Relative path
1892           } else if (!/^http(s)?:\/\//.test(path)) {
1893             url.push(parentURL);
1894           }
1895         } else {
1896           if (host) { url.push(host); }
1897           if (namespace) { url.push(namespace); }
1898         }
1899
1900         if (path) {
1901           url.push(path);
1902         }
1903
1904         return url.join('/');
1905       },
1906
1907       /**
1908         Determines the pathname for a given type.
1909
1910         By default, it pluralizes the type's name (for example,
1911         'post' becomes 'posts' and 'person' becomes 'people').
1912
1913         ### Pathname customization
1914
1915         For example if you have an object LineItem with an
1916         endpoint of "/line_items/".
1917
1918         ```js
1919         App.ApplicationAdapter = DS.RESTAdapter.extend({
1920           pathForType: function(type) {
1921             var decamelized = Ember.String.decamelize(type);
1922             return Ember.String.pluralize(decamelized);
1923           }
1924         });
1925         ```
1926
1927         @method pathForType
1928         @param {String} type
1929         @return {String} path
1930       **/
1931       pathForType: function(type) {
1932         var camelized = Ember.String.camelize(type);
1933         return Ember.String.pluralize(camelized);
1934       },
1935
1936       /**
1937         Takes an ajax response, and returns a relevant error.
1938
1939         Returning a `DS.InvalidError` from this method will cause the
1940         record to transition into the `invalid` state and make the
1941         `errors` object available on the record.
1942
1943         ```javascript
1944         App.ApplicationAdapter = DS.RESTAdapter.extend({
1945           ajaxError: function(jqXHR) {
1946             var error = this._super(jqXHR);
1947
1948             if (jqXHR && jqXHR.status === 422) {
1949               var jsonErrors = Ember.$.parseJSON(jqXHR.responseText)["errors"];
1950
1951               return new DS.InvalidError(jsonErrors);
1952             } else {
1953               return error;
1954             }
1955           }
1956         });
1957         ```
1958
1959         Note: As a correctness optimization, the default implementation of
1960         the `ajaxError` method strips out the `then` method from jquery's
1961         ajax response (jqXHR). This is important because the jqXHR's
1962         `then` method fulfills the promise with itself resulting in a
1963         circular "thenable" chain which may cause problems for some
1964         promise libraries.
1965
1966         @method ajaxError
1967         @param  {Object} jqXHR
1968         @return {Object} jqXHR
1969       */
1970       ajaxError: function(jqXHR) {
1971         if (jqXHR && typeof jqXHR === 'object') {
1972           jqXHR.then = null;
1973         }
1974
1975         return jqXHR;
1976       },
1977
1978       /**
1979         Takes a URL, an HTTP method and a hash of data, and makes an
1980         HTTP request.
1981
1982         When the server responds with a payload, Ember Data will call into `extractSingle`
1983         or `extractArray` (depending on whether the original query was for one record or
1984         many records).
1985
1986         By default, `ajax` method has the following behavior:
1987
1988         * It sets the response `dataType` to `"json"`
1989         * If the HTTP method is not `"GET"`, it sets the `Content-Type` to be
1990           `application/json; charset=utf-8`
1991         * If the HTTP method is not `"GET"`, it stringifies the data passed in. The
1992           data is the serialized record in the case of a save.
1993         * Registers success and failure handlers.
1994
1995         @method ajax
1996         @private
1997         @param {String} url
1998         @param {String} type The request type GET, POST, PUT, DELETE etc.
1999         @param {Object} hash
2000         @return {Promise} promise
2001       */
2002       ajax: function(url, type, hash) {
2003         var adapter = this;
2004
2005         return new Ember.RSVP.Promise(function(resolve, reject) {
2006           hash = adapter.ajaxOptions(url, type, hash);
2007
2008           hash.success = function(json) {
2009             Ember.run(null, resolve, json);
2010           };
2011
2012           hash.error = function(jqXHR, textStatus, errorThrown) {
2013             Ember.run(null, reject, adapter.ajaxError(jqXHR));
2014           };
2015
2016           Ember.$.ajax(hash);
2017         }, "DS: RestAdapter#ajax " + type + " to " + url);
2018       },
2019
2020       /**
2021         @method ajaxOptions
2022         @private
2023         @param {String} url
2024         @param {String} type The request type GET, POST, PUT, DELETE etc.
2025         @param {Object} hash
2026         @return {Object} hash
2027       */
2028       ajaxOptions: function(url, type, hash) {
2029         hash = hash || {};
2030         hash.url = url;
2031         hash.type = type;
2032         hash.dataType = 'json';
2033         hash.context = this;
2034
2035         if (hash.data && type !== 'GET') {
2036           hash.contentType = 'application/json; charset=utf-8';
2037           hash.data = JSON.stringify(hash.data);
2038         }
2039
2040         var headers = get(this, 'headers');
2041         if (headers !== undefined) {
2042           hash.beforeSend = function (xhr) {
2043             forEach.call(Ember.keys(headers), function(key) {
2044               xhr.setRequestHeader(key, headers[key]);
2045             });
2046           };
2047         }
2048
2049
2050         return hash;
2051       }
2052
2053     });
2054
2055     __exports__["default"] = RESTAdapter;
2056   });
2057 define("ember-data/lib/core", 
2058   ["exports"],
2059   function(__exports__) {
2060     "use strict";
2061     /**
2062       @module ember-data
2063     */
2064
2065     /**
2066       All Ember Data methods and functions are defined inside of this namespace.
2067
2068       @class DS
2069       @static
2070     */
2071     var DS;
2072     if ('undefined' === typeof DS) {
2073       /**
2074         @property VERSION
2075         @type String
2076         @default '1.0.0-beta.8.2a68c63a'
2077         @static
2078       */
2079       DS = Ember.Namespace.create({
2080         VERSION: '1.0.0-beta.8.2a68c63a'
2081       });
2082
2083       if (Ember.libraries) {
2084         Ember.libraries.registerCoreLibrary('Ember Data', DS.VERSION);
2085       }
2086     }
2087
2088     __exports__["default"] = DS;
2089   });
2090 define("ember-data/lib/ember-initializer", 
2091   ["./setup-container"],
2092   function(__dependency1__) {
2093     "use strict";
2094     var setupContainer = __dependency1__["default"];
2095
2096     var K = Ember.K;
2097
2098     /**
2099       @module ember-data
2100     */
2101
2102     /**
2103
2104       This code initializes Ember-Data onto an Ember application.
2105
2106       If an Ember.js developer defines a subclass of DS.Store on their application,
2107       as `App.ApplicationStore` (or via a module system that resolves to `store:application`)
2108       this code will automatically instantiate it and make it available on the
2109       router.
2110
2111       Additionally, after an application's controllers have been injected, they will
2112       each have the store made available to them.
2113
2114       For example, imagine an Ember.js application with the following classes:
2115
2116       App.ApplicationStore = DS.Store.extend({
2117         adapter: 'custom'
2118       });
2119
2120       App.PostsController = Ember.ArrayController.extend({
2121         // ...
2122       });
2123
2124       When the application is initialized, `App.ApplicationStore` will automatically be
2125       instantiated, and the instance of `App.PostsController` will have its `store`
2126       property set to that instance.
2127
2128       Note that this code will only be run if the `ember-application` package is
2129       loaded. If Ember Data is being used in an environment other than a
2130       typical application (e.g., node.js where only `ember-runtime` is available),
2131       this code will be ignored.
2132     */
2133
2134     Ember.onLoad('Ember.Application', function(Application) {
2135
2136       Application.initializer({
2137         name:       "ember-data",
2138         initialize: setupContainer
2139       });
2140
2141       // Deprecated initializers to satisfy old code that depended on them
2142
2143       Application.initializer({
2144         name:       "store",
2145         after:      "ember-data",
2146         initialize: K
2147       });
2148
2149       Application.initializer({
2150         name:       "activeModelAdapter",
2151         before:     "store",
2152         initialize: K
2153       });
2154
2155       Application.initializer({
2156         name:       "transforms",
2157         before:     "store",
2158         initialize: K
2159       });
2160
2161       Application.initializer({
2162         name:       "data-adapter",
2163         before:     "store",
2164         initialize: K
2165       });
2166
2167       Application.initializer({
2168         name:       "injectStore",
2169         before:     "store",
2170         initialize: K
2171       });
2172     });
2173   });
2174 define("ember-data/lib/ext/date", 
2175   [],
2176   function() {
2177     "use strict";
2178     /**
2179       @module ember-data
2180     */
2181
2182     /**
2183       Date.parse with progressive enhancement for ISO 8601 <https://github.com/csnover/js-iso8601>
2184
2185       © 2011 Colin Snover <http://zetafleet.com>
2186
2187       Released under MIT license.
2188
2189       @class Date
2190       @namespace Ember
2191       @static
2192     */
2193     Ember.Date = Ember.Date || {};
2194
2195     var origParse = Date.parse, numericKeys = [ 1, 4, 5, 6, 7, 10, 11 ];
2196
2197     /**
2198       @method parse
2199       @param date
2200     */
2201     Ember.Date.parse = function (date) {
2202         var timestamp, struct, minutesOffset = 0;
2203
2204         // ES5 §15.9.4.2 states that the string should attempt to be parsed as a Date Time String Format string
2205         // before falling back to any implementation-specific date parsing, so that’s what we do, even if native
2206         // implementations could be faster
2207         //              1 YYYY                2 MM       3 DD           4 HH    5 mm       6 ss        7 msec        8 Z 9 ±    10 tzHH    11 tzmm
2208         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))) {
2209             // avoid NaN timestamps caused by “undefined” values being passed to Date.UTC
2210             for (var i = 0, k; (k = numericKeys[i]); ++i) {
2211                 struct[k] = +struct[k] || 0;
2212             }
2213
2214             // allow undefined days and months
2215             struct[2] = (+struct[2] || 1) - 1;
2216             struct[3] = +struct[3] || 1;
2217
2218             if (struct[8] !== 'Z' && struct[9] !== undefined) {
2219                 minutesOffset = struct[10] * 60 + struct[11];
2220
2221                 if (struct[9] === '+') {
2222                     minutesOffset = 0 - minutesOffset;
2223                 }
2224             }
2225
2226             timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
2227         }
2228         else {
2229             timestamp = origParse ? origParse(date) : NaN;
2230         }
2231
2232         return timestamp;
2233     };
2234
2235     if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Date) {
2236       Date.parse = Ember.Date.parse;
2237     }
2238   });
2239 define("ember-data/lib/initializers/data_adapter", 
2240   ["../system/debug/debug_adapter","exports"],
2241   function(__dependency1__, __exports__) {
2242     "use strict";
2243     var DebugAdapter = __dependency1__["default"];
2244
2245     /**
2246       Configures a container with injections on Ember applications
2247       for the Ember-Data store. Accepts an optional namespace argument.
2248
2249       @method initializeStoreInjections
2250       @param {Ember.Container} container
2251     */
2252     __exports__["default"] = function initializeDebugAdapter(container){
2253       container.register('data-adapter:main', DebugAdapter);
2254     };
2255   });
2256 define("ember-data/lib/initializers/store", 
2257   ["../serializers","../adapters","../system/container_proxy","../system/store","exports"],
2258   function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
2259     "use strict";
2260     var JSONSerializer = __dependency1__.JSONSerializer;
2261     var RESTSerializer = __dependency1__.RESTSerializer;
2262     var RESTAdapter = __dependency2__.RESTAdapter;
2263     var ContainerProxy = __dependency3__["default"];
2264     var Store = __dependency4__["default"];
2265
2266     /**
2267       Configures a container for use with an Ember-Data
2268       store. Accepts an optional namespace argument.
2269
2270       @method initializeStore
2271       @param {Ember.Container} container
2272       @param {Object} [application] an application namespace
2273     */
2274     __exports__["default"] = function initializeStore(container, application){
2275       Ember.deprecate('Specifying a custom Store for Ember Data on your global namespace as `App.Store` ' +
2276                       'has been deprecated. Please use `App.ApplicationStore` instead.', !(application && application.Store));
2277
2278       container.register('store:main', container.lookupFactory('store:application') || (application && application.Store) || Store);
2279
2280       // allow older names to be looked up
2281
2282       var proxy = new ContainerProxy(container);
2283       proxy.registerDeprecations([
2284         {deprecated: 'serializer:_default',  valid: 'serializer:-default'},
2285         {deprecated: 'serializer:_rest',     valid: 'serializer:-rest'},
2286         {deprecated: 'adapter:_rest',        valid: 'adapter:-rest'}
2287       ]);
2288
2289       // new go forward paths
2290       container.register('serializer:-default', JSONSerializer);
2291       container.register('serializer:-rest', RESTSerializer);
2292       container.register('adapter:-rest', RESTAdapter);
2293
2294       // Eagerly generate the store so defaultStore is populated.
2295       // TODO: Do this in a finisher hook
2296       container.lookup('store:main');
2297     };
2298   });
2299 define("ember-data/lib/initializers/store_injections", 
2300   ["exports"],
2301   function(__exports__) {
2302     "use strict";
2303     /**
2304       Configures a container with injections on Ember applications
2305       for the Ember-Data store. Accepts an optional namespace argument.
2306
2307       @method initializeStoreInjections
2308       @param {Ember.Container} container
2309     */
2310     __exports__["default"] = function initializeStoreInjections(container){
2311       container.injection('controller',   'store', 'store:main');
2312       container.injection('route',        'store', 'store:main');
2313       container.injection('serializer',   'store', 'store:main');
2314       container.injection('data-adapter', 'store', 'store:main');
2315     };
2316   });
2317 define("ember-data/lib/initializers/transforms", 
2318   ["../transforms","exports"],
2319   function(__dependency1__, __exports__) {
2320     "use strict";
2321     var BooleanTransform = __dependency1__.BooleanTransform;
2322     var DateTransform = __dependency1__.DateTransform;
2323     var StringTransform = __dependency1__.StringTransform;
2324     var NumberTransform = __dependency1__.NumberTransform;
2325
2326     /**
2327       Configures a container for use with Ember-Data
2328       transforms.
2329
2330       @method initializeTransforms
2331       @param {Ember.Container} container
2332     */
2333     __exports__["default"] = function initializeTransforms(container){
2334       container.register('transform:boolean', BooleanTransform);
2335       container.register('transform:date',    DateTransform);
2336       container.register('transform:number',  NumberTransform);
2337       container.register('transform:string',  StringTransform);
2338     };
2339   });
2340 define("ember-data/lib/main", 
2341   ["./core","./ext/date","./system/store","./system/model","./system/changes","./system/adapter","./system/debug","./system/record_arrays","./system/record_array_manager","./adapters","./serializers/json_serializer","./serializers/rest_serializer","../../ember-inflector/lib/main","../../activemodel-adapter/lib/main","./transforms","./system/relationships","./ember-initializer","./setup-container","./system/container_proxy","exports"],
2342   function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __exports__) {
2343     "use strict";
2344     /**
2345       Ember Data
2346
2347       @module ember-data
2348       @main ember-data
2349     */
2350
2351     // support RSVP 2.x via resolve,  but prefer RSVP 3.x's Promise.cast
2352     Ember.RSVP.Promise.cast = Ember.RSVP.Promise.cast || Ember.RSVP.resolve;
2353
2354     var DS = __dependency1__["default"];
2355
2356     var Store = __dependency3__.Store;
2357     var PromiseArray = __dependency3__.PromiseArray;
2358     var PromiseObject = __dependency3__.PromiseObject;
2359     var Model = __dependency4__.Model;
2360     var Errors = __dependency4__.Errors;
2361     var RootState = __dependency4__.RootState;
2362     var attr = __dependency4__.attr;
2363     var AttributeChange = __dependency5__.AttributeChange;
2364     var RelationshipChange = __dependency5__.RelationshipChange;
2365     var RelationshipChangeAdd = __dependency5__.RelationshipChangeAdd;
2366     var RelationshipChangeRemove = __dependency5__.RelationshipChangeRemove;
2367     var OneToManyChange = __dependency5__.OneToManyChange;
2368     var ManyToNoneChange = __dependency5__.ManyToNoneChange;
2369     var OneToOneChange = __dependency5__.OneToOneChange;
2370     var ManyToManyChange = __dependency5__.ManyToManyChange;
2371     var InvalidError = __dependency6__.InvalidError;
2372     var Adapter = __dependency6__.Adapter;
2373     var DebugAdapter = __dependency7__["default"];
2374     var RecordArray = __dependency8__.RecordArray;
2375     var FilteredRecordArray = __dependency8__.FilteredRecordArray;
2376     var AdapterPopulatedRecordArray = __dependency8__.AdapterPopulatedRecordArray;
2377     var ManyArray = __dependency8__.ManyArray;
2378     var RecordArrayManager = __dependency9__["default"];
2379     var RESTAdapter = __dependency10__.RESTAdapter;
2380     var FixtureAdapter = __dependency10__.FixtureAdapter;
2381     var JSONSerializer = __dependency11__["default"];
2382     var RESTSerializer = __dependency12__["default"];
2383     var ActiveModelAdapter = __dependency14__.ActiveModelAdapter;
2384     var ActiveModelSerializer = __dependency14__.ActiveModelSerializer;
2385     var EmbeddedRecordsMixin = __dependency14__.EmbeddedRecordsMixin;
2386
2387     var Transform = __dependency15__.Transform;
2388     var DateTransform = __dependency15__.DateTransform;
2389     var NumberTransform = __dependency15__.NumberTransform;
2390     var StringTransform = __dependency15__.StringTransform;
2391     var BooleanTransform = __dependency15__.BooleanTransform;
2392
2393     var hasMany = __dependency16__.hasMany;
2394     var belongsTo = __dependency16__.belongsTo;
2395     var setupContainer = __dependency18__["default"];
2396
2397     var ContainerProxy = __dependency19__["default"];
2398
2399     DS.Store         = Store;
2400     DS.PromiseArray  = PromiseArray;
2401     DS.PromiseObject = PromiseObject;
2402
2403     DS.Model     = Model;
2404     DS.RootState = RootState;
2405     DS.attr      = attr;
2406     DS.Errors    = Errors;
2407
2408     DS.AttributeChange       = AttributeChange;
2409     DS.RelationshipChange    = RelationshipChange;
2410     DS.RelationshipChangeAdd = RelationshipChangeAdd;
2411     DS.OneToManyChange       = OneToManyChange;
2412     DS.ManyToNoneChange      = OneToManyChange;
2413     DS.OneToOneChange        = OneToOneChange;
2414     DS.ManyToManyChange      = ManyToManyChange;
2415
2416     DS.Adapter      = Adapter;
2417     DS.InvalidError = InvalidError;
2418
2419     DS.DebugAdapter = DebugAdapter;
2420
2421     DS.RecordArray                 = RecordArray;
2422     DS.FilteredRecordArray         = FilteredRecordArray;
2423     DS.AdapterPopulatedRecordArray = AdapterPopulatedRecordArray;
2424     DS.ManyArray                   = ManyArray;
2425
2426     DS.RecordArrayManager = RecordArrayManager;
2427
2428     DS.RESTAdapter    = RESTAdapter;
2429     DS.FixtureAdapter = FixtureAdapter;
2430
2431     DS.RESTSerializer = RESTSerializer;
2432     DS.JSONSerializer = JSONSerializer;
2433
2434     DS.Transform       = Transform;
2435     DS.DateTransform   = DateTransform;
2436     DS.StringTransform = StringTransform;
2437     DS.NumberTransform = NumberTransform;
2438     DS.BooleanTransform = BooleanTransform;
2439
2440     DS.ActiveModelAdapter    = ActiveModelAdapter;
2441     DS.ActiveModelSerializer = ActiveModelSerializer;
2442     DS.EmbeddedRecordsMixin  = EmbeddedRecordsMixin;
2443
2444     DS.belongsTo = belongsTo;
2445     DS.hasMany   = hasMany;
2446
2447     DS.ContainerProxy = ContainerProxy;
2448
2449     DS._setupContainer = setupContainer;
2450
2451     Ember.lookup.DS = DS;
2452
2453     __exports__["default"] = DS;
2454   });
2455 define("ember-data/lib/serializers", 
2456   ["./serializers/json_serializer","./serializers/rest_serializer","exports"],
2457   function(__dependency1__, __dependency2__, __exports__) {
2458     "use strict";
2459     var JSONSerializer = __dependency1__["default"];
2460     var RESTSerializer = __dependency2__["default"];
2461
2462     __exports__.JSONSerializer = JSONSerializer;
2463     __exports__.RESTSerializer = RESTSerializer;
2464   });
2465 define("ember-data/lib/serializers/json_serializer", 
2466   ["../system/changes","exports"],
2467   function(__dependency1__, __exports__) {
2468     "use strict";
2469     var RelationshipChange = __dependency1__.RelationshipChange;
2470     var get = Ember.get, set = Ember.set, isNone = Ember.isNone,
2471         map = Ember.ArrayPolyfills.map;
2472
2473     /**
2474       In Ember Data a Serializer is used to serialize and deserialize
2475       records when they are transferred in and out of an external source.
2476       This process involves normalizing property names, transforming
2477       attribute values and serializing relationships.
2478
2479       For maximum performance Ember Data recommends you use the
2480       [RESTSerializer](DS.RESTSerializer.html) or one of its subclasses.
2481
2482       `JSONSerializer` is useful for simpler or legacy backends that may
2483       not support the http://jsonapi.org/ spec.
2484
2485       @class JSONSerializer
2486       @namespace DS
2487     */
2488     var JSONSerializer = Ember.Object.extend({
2489       /**
2490         The primaryKey is used when serializing and deserializing
2491         data. Ember Data always uses the `id` property to store the id of
2492         the record. The external source may not always follow this
2493         convention. In these cases it is useful to override the
2494         primaryKey property to match the primaryKey of your external
2495         store.
2496
2497         Example
2498
2499         ```javascript
2500         App.ApplicationSerializer = DS.JSONSerializer.extend({
2501           primaryKey: '_id'
2502         });
2503         ```
2504
2505         @property primaryKey
2506         @type {String}
2507         @default 'id'
2508       */
2509       primaryKey: 'id',
2510
2511       /**
2512         The `attrs` object can be used to declare a simple mapping between
2513         property names on `DS.Model` records and payload keys in the
2514         serialized JSON object representing the record. An object with the
2515         propery `key` can also be used to designate the attribute's key on
2516         the response payload.
2517
2518         Example
2519
2520         ```javascript
2521         App.Person = DS.Model.extend({
2522           firstName: DS.attr('string'),
2523           lastName: DS.attr('string'),
2524           occupation: DS.attr('string'),
2525           admin: DS.attr('boolean')
2526         });
2527
2528         App.PersonSerializer = DS.JSONSerializer.extend({
2529           attrs: {
2530             admin: 'is_admin',
2531             occupation: {key: 'career'}
2532           }
2533         });
2534         ```
2535
2536         @property attrs
2537         @type {Object}
2538       */
2539
2540       /**
2541        Given a subclass of `DS.Model` and a JSON object this method will
2542        iterate through each attribute of the `DS.Model` and invoke the
2543        `DS.Transform#deserialize` method on the matching property of the
2544        JSON object.  This method is typically called after the
2545        serializer's `normalize` method.
2546
2547        @method applyTransforms
2548        @private
2549        @param {subclass of DS.Model} type
2550        @param {Object} data The data to transform
2551        @return {Object} data The transformed data object
2552       */
2553       applyTransforms: function(type, data) {
2554         type.eachTransformedAttribute(function(key, type) {
2555           var transform = this.transformFor(type);
2556           data[key] = transform.deserialize(data[key]);
2557         }, this);
2558
2559         return data;
2560       },
2561
2562       /**
2563         Normalizes a part of the JSON payload returned by
2564         the server. You should override this method, munge the hash
2565         and call super if you have generic normalization to do.
2566
2567         It takes the type of the record that is being normalized
2568         (as a DS.Model class), the property where the hash was
2569         originally found, and the hash to normalize.
2570
2571         You can use this method, for example, to normalize underscored keys to camelized
2572         or other general-purpose normalizations.
2573
2574         Example
2575
2576         ```javascript
2577         App.ApplicationSerializer = DS.JSONSerializer.extend({
2578           normalize: function(type, hash) {
2579             var fields = Ember.get(type, 'fields');
2580             fields.forEach(function(field) {
2581               var payloadField = Ember.String.underscore(field);
2582               if (field === payloadField) { return; }
2583
2584               hash[field] = hash[payloadField];
2585               delete hash[payloadField];
2586             });
2587             return this._super.apply(this, arguments);
2588           }
2589         });
2590         ```
2591
2592         @method normalize
2593         @param {subclass of DS.Model} type
2594         @param {Object} hash
2595         @return {Object}
2596       */
2597       normalize: function(type, hash) {
2598         if (!hash) { return hash; }
2599
2600         this.normalizeId(hash);
2601         this.normalizeUsingDeclaredMapping(type, hash);
2602         this.applyTransforms(type, hash);
2603         return hash;
2604       },
2605
2606       /**
2607         @method normalizeUsingDeclaredMapping
2608         @private
2609       */
2610       normalizeUsingDeclaredMapping: function(type, hash) {
2611         var attrs = get(this, 'attrs'), payloadKey, key;
2612
2613         if (attrs) {
2614           for (key in attrs) {
2615             payloadKey = attrs[key];
2616             if (payloadKey && payloadKey.key) {
2617               payloadKey = payloadKey.key;
2618             }
2619             if (typeof payloadKey === 'string') {
2620               hash[key] = hash[payloadKey];
2621               delete hash[payloadKey];
2622             }
2623           }
2624         }
2625       },
2626       /**
2627         @method normalizeId
2628         @private
2629       */
2630       normalizeId: function(hash) {
2631         var primaryKey = get(this, 'primaryKey');
2632
2633         if (primaryKey === 'id') { return; }
2634
2635         hash.id = hash[primaryKey];
2636         delete hash[primaryKey];
2637       },
2638
2639       // SERIALIZE
2640       /**
2641         Called when a record is saved in order to convert the
2642         record into JSON.
2643
2644         By default, it creates a JSON object with a key for
2645         each attribute and belongsTo relationship.
2646
2647         For example, consider this model:
2648
2649         ```javascript
2650         App.Comment = DS.Model.extend({
2651           title: DS.attr(),
2652           body: DS.attr(),
2653
2654           author: DS.belongsTo('user')
2655         });
2656         ```
2657
2658         The default serialization would create a JSON object like:
2659
2660         ```javascript
2661         {
2662           "title": "Rails is unagi",
2663           "body": "Rails? Omakase? O_O",
2664           "author": 12
2665         }
2666         ```
2667
2668         By default, attributes are passed through as-is, unless
2669         you specified an attribute type (`DS.attr('date')`). If
2670         you specify a transform, the JavaScript value will be
2671         serialized when inserted into the JSON hash.
2672
2673         By default, belongs-to relationships are converted into
2674         IDs when inserted into the JSON hash.
2675
2676         ## IDs
2677
2678         `serialize` takes an options hash with a single option:
2679         `includeId`. If this option is `true`, `serialize` will,
2680         by default include the ID in the JSON object it builds.
2681
2682         The adapter passes in `includeId: true` when serializing
2683         a record for `createRecord`, but not for `updateRecord`.
2684
2685         ## Customization
2686
2687         Your server may expect a different JSON format than the
2688         built-in serialization format.
2689
2690         In that case, you can implement `serialize` yourself and
2691         return a JSON hash of your choosing.
2692
2693         ```javascript
2694         App.PostSerializer = DS.JSONSerializer.extend({
2695           serialize: function(post, options) {
2696             var json = {
2697               POST_TTL: post.get('title'),
2698               POST_BDY: post.get('body'),
2699               POST_CMS: post.get('comments').mapProperty('id')
2700             }
2701
2702             if (options.includeId) {
2703               json.POST_ID_ = post.get('id');
2704             }
2705
2706             return json;
2707           }
2708         });
2709         ```
2710
2711         ## Customizing an App-Wide Serializer
2712
2713         If you want to define a serializer for your entire
2714         application, you'll probably want to use `eachAttribute`
2715         and `eachRelationship` on the record.
2716
2717         ```javascript
2718         App.ApplicationSerializer = DS.JSONSerializer.extend({
2719           serialize: function(record, options) {
2720             var json = {};
2721
2722             record.eachAttribute(function(name) {
2723               json[serverAttributeName(name)] = record.get(name);
2724             })
2725
2726             record.eachRelationship(function(name, relationship) {
2727               if (relationship.kind === 'hasMany') {
2728                 json[serverHasManyName(name)] = record.get(name).mapBy('id');
2729               }
2730             });
2731
2732             if (options.includeId) {
2733               json.ID_ = record.get('id');
2734             }
2735
2736             return json;
2737           }
2738         });
2739
2740         function serverAttributeName(attribute) {
2741           return attribute.underscore().toUpperCase();
2742         }
2743
2744         function serverHasManyName(name) {
2745           return serverAttributeName(name.singularize()) + "_IDS";
2746         }
2747         ```
2748
2749         This serializer will generate JSON that looks like this:
2750
2751         ```javascript
2752         {
2753           "TITLE": "Rails is omakase",
2754           "BODY": "Yep. Omakase.",
2755           "COMMENT_IDS": [ 1, 2, 3 ]
2756         }
2757         ```
2758
2759         ## Tweaking the Default JSON
2760
2761         If you just want to do some small tweaks on the default JSON,
2762         you can call super first and make the tweaks on the returned
2763         JSON.
2764
2765         ```javascript
2766         App.PostSerializer = DS.JSONSerializer.extend({
2767           serialize: function(record, options) {
2768             var json = this._super.apply(this, arguments);
2769
2770             json.subject = json.title;
2771             delete json.title;
2772
2773             return json;
2774           }
2775         });
2776         ```
2777
2778         @method serialize
2779         @param {subclass of DS.Model} record
2780         @param {Object} options
2781         @return {Object} json
2782       */
2783       serialize: function(record, options) {
2784         var json = {};
2785
2786         if (options && options.includeId) {
2787           var id = get(record, 'id');
2788
2789           if (id) {
2790             json[get(this, 'primaryKey')] = id;
2791           }
2792         }
2793
2794         record.eachAttribute(function(key, attribute) {
2795           this.serializeAttribute(record, json, key, attribute);
2796         }, this);
2797
2798         record.eachRelationship(function(key, relationship) {
2799           if (relationship.kind === 'belongsTo') {
2800             this.serializeBelongsTo(record, json, relationship);
2801           } else if (relationship.kind === 'hasMany') {
2802             this.serializeHasMany(record, json, relationship);
2803           }
2804         }, this);
2805
2806         return json;
2807       },
2808
2809       /**
2810        `serializeAttribute` can be used to customize how `DS.attr`
2811        properties are serialized
2812
2813        For example if you wanted to ensure all your attributes were always
2814        serialized as properties on an `attributes` object you could
2815        write:
2816
2817        ```javascript
2818        App.ApplicationSerializer = DS.JSONSerializer.extend({
2819          serializeAttribute: function(record, json, key, attributes) {
2820            json.attributes = json.attributes || {};
2821            this._super(record, json.attributes, key, attributes);
2822          }
2823        });
2824        ```
2825
2826        @method serializeAttribute
2827        @param {DS.Model} record
2828        @param {Object} json
2829        @param {String} key
2830        @param {Object} attribute
2831       */
2832       serializeAttribute: function(record, json, key, attribute) {
2833         var attrs = get(this, 'attrs');
2834         var value = get(record, key), type = attribute.type;
2835
2836         if (type) {
2837           var transform = this.transformFor(type);
2838           value = transform.serialize(value);
2839         }
2840
2841         // if provided, use the mapping provided by `attrs` in
2842         // the serializer
2843         key = attrs && attrs[key] || (this.keyForAttribute ? this.keyForAttribute(key) : key);
2844
2845         json[key] = value;
2846       },
2847
2848       /**
2849        `serializeBelongsTo` can be used to customize how `DS.belongsTo`
2850        properties are serialized.
2851
2852        Example
2853
2854        ```javascript
2855        App.PostSerializer = DS.JSONSerializer.extend({
2856          serializeBelongsTo: function(record, json, relationship) {
2857            var key = relationship.key;
2858
2859            var belongsTo = get(record, key);
2860
2861            key = this.keyForRelationship ? this.keyForRelationship(key, "belongsTo") : key;
2862
2863            json[key] = Ember.isNone(belongsTo) ? belongsTo : belongsTo.toJSON();
2864          }
2865        });
2866        ```
2867
2868        @method serializeBelongsTo
2869        @param {DS.Model} record
2870        @param {Object} json
2871        @param {Object} relationship
2872       */
2873       serializeBelongsTo: function(record, json, relationship) {
2874         var key = relationship.key;
2875
2876         var belongsTo = get(record, key);
2877
2878         key = this.keyForRelationship ? this.keyForRelationship(key, "belongsTo") : key;
2879
2880         if (isNone(belongsTo)) {
2881           json[key] = belongsTo;
2882         } else {
2883           json[key] = get(belongsTo, 'id');
2884         }
2885
2886         if (relationship.options.polymorphic) {
2887           this.serializePolymorphicType(record, json, relationship);
2888         }
2889       },
2890
2891       /**
2892        `serializeHasMany` can be used to customize how `DS.hasMany`
2893        properties are serialized.
2894
2895        Example
2896
2897        ```javascript
2898        App.PostSerializer = DS.JSONSerializer.extend({
2899          serializeHasMany: function(record, json, relationship) {
2900            var key = relationship.key;
2901            if (key === 'comments') {
2902              return;
2903            } else {
2904              this._super.apply(this, arguments);
2905            }
2906          }
2907        });
2908        ```
2909
2910        @method serializeHasMany
2911        @param {DS.Model} record
2912        @param {Object} json
2913        @param {Object} relationship
2914       */
2915       serializeHasMany: function(record, json, relationship) {
2916         var key = relationship.key;
2917         var payloadKey = this.keyForRelationship ? this.keyForRelationship(key, "hasMany") : key;
2918         var relationshipType = RelationshipChange.determineRelationshipType(record.constructor, relationship);
2919
2920         if (relationshipType === 'manyToNone' || relationshipType === 'manyToMany') {
2921           json[payloadKey] = get(record, key).mapBy('id');
2922           // TODO support for polymorphic manyToNone and manyToMany relationships
2923         }
2924       },
2925
2926       /**
2927         You can use this method to customize how polymorphic objects are
2928         serialized. Objects are considered to be polymorphic if
2929         `{polymorphic: true}` is pass as the second argument to the
2930         `DS.belongsTo` function.
2931
2932         Example
2933
2934         ```javascript
2935         App.CommentSerializer = DS.JSONSerializer.extend({
2936           serializePolymorphicType: function(record, json, relationship) {
2937             var key = relationship.key,
2938                 belongsTo = get(record, key);
2939             key = this.keyForAttribute ? this.keyForAttribute(key) : key;
2940             json[key + "_type"] = belongsTo.constructor.typeKey;
2941           }
2942         });
2943        ```
2944
2945         @method serializePolymorphicType
2946         @param {DS.Model} record
2947         @param {Object} json
2948         @param {Object} relationship
2949       */
2950       serializePolymorphicType: Ember.K,
2951
2952       // EXTRACT
2953
2954       /**
2955         The `extract` method is used to deserialize payload data from the
2956         server. By default the `JSONSerializer` does not push the records
2957         into the store. However records that subclass `JSONSerializer`
2958         such as the `RESTSerializer` may push records into the store as
2959         part of the extract call.
2960
2961         This method delegates to a more specific extract method based on
2962         the `requestType`.
2963
2964         Example
2965
2966         ```javascript
2967         var get = Ember.get;
2968         socket.on('message', function(message) {
2969           var modelName = message.model;
2970           var data = message.data;
2971           var type = store.modelFor(modelName);
2972           var serializer = store.serializerFor(type.typeKey);
2973           var record = serializer.extract(store, type, data, get(data, 'id'), 'single');
2974           store.push(modelName, record);
2975         });
2976         ```
2977
2978         @method extract
2979         @param {DS.Store} store
2980         @param {subclass of DS.Model} type
2981         @param {Object} payload
2982         @param {String or Number} id
2983         @param {String} requestType
2984         @return {Object} json The deserialized payload
2985       */
2986       extract: function(store, type, payload, id, requestType) {
2987         this.extractMeta(store, type, payload);
2988
2989         var specificExtract = "extract" + requestType.charAt(0).toUpperCase() + requestType.substr(1);
2990         return this[specificExtract](store, type, payload, id, requestType);
2991       },
2992
2993       /**
2994         `extractFindAll` is a hook into the extract method used when a
2995         call is made to `DS.Store#findAll`. By default this method is an
2996         alias for [extractArray](#method_extractArray).
2997
2998         @method extractFindAll
2999         @param {DS.Store} store
3000         @param {subclass of DS.Model} type
3001         @param {Object} payload
3002         @return {Array} array An array of deserialized objects
3003       */
3004       extractFindAll: function(store, type, payload){
3005         return this.extractArray(store, type, payload);
3006       },
3007       /**
3008         `extractFindQuery` is a hook into the extract method used when a
3009         call is made to `DS.Store#findQuery`. By default this method is an
3010         alias for [extractArray](#method_extractArray).
3011
3012         @method extractFindQuery
3013         @param {DS.Store} store
3014         @param {subclass of DS.Model} type
3015         @param {Object} payload
3016         @return {Array} array An array of deserialized objects
3017       */
3018       extractFindQuery: function(store, type, payload){
3019         return this.extractArray(store, type, payload);
3020       },
3021       /**
3022         `extractFindMany` is a hook into the extract method used when a
3023         call is made to `DS.Store#findMany`. By default this method is
3024         alias for [extractArray](#method_extractArray).
3025
3026         @method extractFindMany
3027         @param {DS.Store} store
3028         @param {subclass of DS.Model} type
3029         @param {Object} payload
3030         @return {Array} array An array of deserialized objects
3031       */
3032       extractFindMany: function(store, type, payload){
3033         return this.extractArray(store, type, payload);
3034       },
3035       /**
3036         `extractFindHasMany` is a hook into the extract method used when a
3037         call is made to `DS.Store#findHasMany`. By default this method is
3038         alias for [extractArray](#method_extractArray).
3039
3040         @method extractFindHasMany
3041         @param {DS.Store} store
3042         @param {subclass of DS.Model} type
3043         @param {Object} payload
3044         @return {Array} array An array of deserialized objects
3045       */
3046       extractFindHasMany: function(store, type, payload){
3047         return this.extractArray(store, type, payload);
3048       },
3049
3050       /**
3051         `extractCreateRecord` is a hook into the extract method used when a
3052         call is made to `DS.Store#createRecord`. By default this method is
3053         alias for [extractSave](#method_extractSave).
3054
3055         @method extractCreateRecord
3056         @param {DS.Store} store
3057         @param {subclass of DS.Model} type
3058         @param {Object} payload
3059         @return {Object} json The deserialized payload
3060       */
3061       extractCreateRecord: function(store, type, payload) {
3062         return this.extractSave(store, type, payload);
3063       },
3064       /**
3065         `extractUpdateRecord` is a hook into the extract method used when
3066         a call is made to `DS.Store#update`. By default this method is alias
3067         for [extractSave](#method_extractSave).
3068
3069         @method extractUpdateRecord
3070         @param {DS.Store} store
3071         @param {subclass of DS.Model} type
3072         @param {Object} payload
3073         @return {Object} json The deserialized payload
3074       */
3075       extractUpdateRecord: function(store, type, payload) {
3076         return this.extractSave(store, type, payload);
3077       },
3078       /**
3079         `extractDeleteRecord` is a hook into the extract method used when
3080         a call is made to `DS.Store#deleteRecord`. By default this method is
3081         alias for [extractSave](#method_extractSave).
3082
3083         @method extractDeleteRecord
3084         @param {DS.Store} store
3085         @param {subclass of DS.Model} type
3086         @param {Object} payload
3087         @return {Object} json The deserialized payload
3088       */
3089       extractDeleteRecord: function(store, type, payload) {
3090         return this.extractSave(store, type, payload);
3091       },
3092
3093       /**
3094         `extractFind` is a hook into the extract method used when
3095         a call is made to `DS.Store#find`. By default this method is
3096         alias for [extractSingle](#method_extractSingle).
3097
3098         @method extractFind
3099         @param {DS.Store} store
3100         @param {subclass of DS.Model} type
3101         @param {Object} payload
3102         @return {Object} json The deserialized payload
3103       */
3104       extractFind: function(store, type, payload) {
3105         return this.extractSingle(store, type, payload);
3106       },
3107       /**
3108         `extractFindBelongsTo` is a hook into the extract method used when
3109         a call is made to `DS.Store#findBelongsTo`. By default this method is
3110         alias for [extractSingle](#method_extractSingle).
3111
3112         @method extractFindBelongsTo
3113         @param {DS.Store} store
3114         @param {subclass of DS.Model} type
3115         @param {Object} payload
3116         @return {Object} json The deserialized payload
3117       */
3118       extractFindBelongsTo: function(store, type, payload) {
3119         return this.extractSingle(store, type, payload);
3120       },
3121       /**
3122         `extractSave` is a hook into the extract method used when a call
3123         is made to `DS.Model#save`. By default this method is alias
3124         for [extractSingle](#method_extractSingle).
3125
3126         @method extractSave
3127         @param {DS.Store} store
3128         @param {subclass of DS.Model} type
3129         @param {Object} payload
3130         @return {Object} json The deserialized payload
3131       */
3132       extractSave: function(store, type, payload) {
3133         return this.extractSingle(store, type, payload);
3134       },
3135
3136       /**
3137         `extractSingle` is used to deserialize a single record returned
3138         from the adapter.
3139
3140         Example
3141
3142         ```javascript
3143         App.PostSerializer = DS.JSONSerializer.extend({
3144           extractSingle: function(store, type, payload) {
3145             payload.comments = payload._embedded.comment;
3146             delete payload._embedded;
3147
3148             return this._super(store, type, payload);
3149           },
3150         });
3151         ```
3152
3153         @method extractSingle
3154         @param {DS.Store} store
3155         @param {subclass of DS.Model} type
3156         @param {Object} payload
3157         @return {Object} json The deserialized payload
3158       */
3159       extractSingle: function(store, type, payload) {
3160         return this.normalize(type, payload);
3161       },
3162
3163       /**
3164         `extractArray` is used to deserialize an array of records
3165         returned from the adapter.
3166
3167         Example
3168
3169         ```javascript
3170         App.PostSerializer = DS.JSONSerializer.extend({
3171           extractArray: function(store, type, payload) {
3172             return payload.map(function(json) {
3173               return this.extractSingle(store, type, json);
3174             }, this);
3175           }
3176         });
3177         ```
3178
3179         @method extractArray
3180         @param {DS.Store} store
3181         @param {subclass of DS.Model} type
3182         @param {Object} payload
3183         @return {Array} array An array of deserialized objects
3184       */
3185       extractArray: function(store, type, arrayPayload) {
3186         var serializer = this;
3187         return map.call(arrayPayload, function(singlePayload) {
3188           return serializer.normalize(type, singlePayload);
3189         });
3190       },
3191
3192       /**
3193         `extractMeta` is used to deserialize any meta information in the
3194         adapter payload. By default Ember Data expects meta information to
3195         be located on the `meta` property of the payload object.
3196
3197         Example
3198
3199         ```javascript
3200         App.PostSerializer = DS.JSONSerializer.extend({
3201           extractMeta: function(store, type, payload) {
3202             if (payload && payload._pagination) {
3203               store.metaForType(type, payload._pagination);
3204               delete payload._pagination;
3205             }
3206           }
3207         });
3208         ```
3209
3210         @method extractMeta
3211         @param {DS.Store} store
3212         @param {subclass of DS.Model} type
3213         @param {Object} payload
3214       */
3215       extractMeta: function(store, type, payload) {
3216         if (payload && payload.meta) {
3217           store.metaForType(type, payload.meta);
3218           delete payload.meta;
3219         }
3220       },
3221
3222       /**
3223        `keyForAttribute` can be used to define rules for how to convert an
3224        attribute name in your model to a key in your JSON.
3225
3226        Example
3227
3228        ```javascript
3229        App.ApplicationSerializer = DS.RESTSerializer.extend({
3230          keyForAttribute: function(attr) {
3231            return Ember.String.underscore(attr).toUpperCase();
3232          }
3233        });
3234        ```
3235
3236        @method keyForAttribute
3237        @param {String} key
3238        @return {String} normalized key
3239       */
3240
3241
3242       /**
3243        `keyForRelationship` can be used to define a custom key when
3244        serializing relationship properties. By default `JSONSerializer`
3245        does not provide an implementation of this method.
3246
3247        Example
3248
3249         ```javascript
3250         App.PostSerializer = DS.JSONSerializer.extend({
3251           keyForRelationship: function(key, relationship) {
3252              return 'rel_' + Ember.String.underscore(key);
3253           }
3254         });
3255         ```
3256
3257        @method keyForRelationship
3258        @param {String} key
3259        @param {String} relationship type
3260        @return {String} normalized key
3261       */
3262
3263       // HELPERS
3264
3265       /**
3266        @method transformFor
3267        @private
3268        @param {String} attributeType
3269        @param {Boolean} skipAssertion
3270        @return {DS.Transform} transform
3271       */
3272       transformFor: function(attributeType, skipAssertion) {
3273         var transform = this.container.lookup('transform:' + attributeType);
3274         Ember.assert("Unable to find transform for '" + attributeType + "'", skipAssertion || !!transform);
3275         return transform;
3276       }
3277     });
3278
3279     __exports__["default"] = JSONSerializer;