epf-source 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. data/dist/epf.js +3474 -0
  2. data/lib/epf/source.rb +7 -0
  3. metadata +47 -0
data/dist/epf.js ADDED
@@ -0,0 +1,3474 @@
1
+ (function (global) {
2
+ function require(file, parentModule) {
3
+ if ({}.hasOwnProperty.call(require.cache, file))
4
+ return require.cache[file];
5
+ var resolved = require.resolve(file);
6
+ if (!resolved)
7
+ throw new Error('Failed to resolve module ' + file);
8
+ var module$ = {
9
+ id: file,
10
+ require: require,
11
+ filename: file,
12
+ exports: {},
13
+ loaded: false,
14
+ parent: parentModule,
15
+ children: []
16
+ };
17
+ if (parentModule)
18
+ parentModule.children.push(module$);
19
+ var dirname = file.slice(0, file.lastIndexOf('/') + 1);
20
+ require.cache[file] = module$.exports;
21
+ resolved.call(module$.exports, module$, module$.exports, dirname, file);
22
+ module$.loaded = true;
23
+ return require.cache[file] = module$.exports;
24
+ }
25
+ require.modules = {};
26
+ require.cache = {};
27
+ require.resolve = function (file) {
28
+ return {}.hasOwnProperty.call(require.modules, file) ? require.modules[file] : void 0;
29
+ };
30
+ require.define = function (file, fn) {
31
+ require.modules[file] = fn;
32
+ };
33
+ var process = function () {
34
+ var cwd = '/';
35
+ return {
36
+ title: 'browser',
37
+ version: 'v0.8.9',
38
+ browser: true,
39
+ env: {},
40
+ argv: [],
41
+ nextTick: global.setImmediate || function (fn) {
42
+ setTimeout(fn, 0);
43
+ },
44
+ cwd: function () {
45
+ return cwd;
46
+ },
47
+ chdir: function (dir) {
48
+ cwd = dir;
49
+ }
50
+ };
51
+ }();
52
+ require.define('/lib/index.js', function (module, exports, __dirname, __filename) {
53
+ global.Ep = Ember.Namespace.create();
54
+ require('/lib/initializer.js', module);
55
+ require('/lib/model/index.js', module);
56
+ require('/lib/session/index.js', module);
57
+ require('/lib/serializer/index.js', module);
58
+ require('/lib/session/index.js', module);
59
+ require('/lib/local/index.js', module);
60
+ require('/lib/rest/index.js', module);
61
+ });
62
+ require.define('/lib/rest/index.js', function (module, exports, __dirname, __filename) {
63
+ require('/lib/rest/rest_adapter.js', module);
64
+ require('/lib/rest/rest_serializer.js', module);
65
+ });
66
+ require.define('/lib/rest/rest_serializer.js', function (module, exports, __dirname, __filename) {
67
+ require('/lib/serializer/index.js', module);
68
+ var get = Ember.get;
69
+ Ep.RestSerializer = Ep.JsonSerializer.extend({
70
+ keyForAttributeName: function (type, name) {
71
+ return Ember.String.decamelize(name);
72
+ },
73
+ keyForBelongsTo: function (type, name) {
74
+ var key = this.keyForAttributeName(type, name);
75
+ if (this.embeddedType(type, name)) {
76
+ return key;
77
+ }
78
+ return key + '_id';
79
+ },
80
+ keyForHasMany: function (type, name) {
81
+ var key = this.keyForAttributeName(type, name);
82
+ if (this.embeddedType(type, name)) {
83
+ return key;
84
+ }
85
+ return this.singularize(key) + '_ids';
86
+ },
87
+ keyForPolymorphicId: function (key) {
88
+ return key;
89
+ },
90
+ keyForPolymorphicType: function (key) {
91
+ return key.replace(/_id$/, '_type');
92
+ },
93
+ extractValidationErrors: function (type, json) {
94
+ var errors = {};
95
+ get(type, 'attributes').forEach(function (name) {
96
+ var key = this._keyForAttributeName(type, name);
97
+ if (json['errors'].hasOwnProperty(key)) {
98
+ errors[name] = json['errors'][key];
99
+ }
100
+ }, this);
101
+ return errors;
102
+ }
103
+ });
104
+ });
105
+ require.define('/lib/serializer/index.js', function (module, exports, __dirname, __filename) {
106
+ require('/lib/serializer/serializer.js', module);
107
+ require('/lib/serializer/json_serializer.js', module);
108
+ });
109
+ require.define('/lib/serializer/json_serializer.js', function (module, exports, __dirname, __filename) {
110
+ require('/lib/serializer/serializer.js', module);
111
+ require('/lib/transforms/json_transforms.js', module);
112
+ var get = Ember.get, set = Ember.set;
113
+ Ep.JsonSerializer = Ep.Serializer.extend({
114
+ init: function () {
115
+ this._super.apply(this, arguments);
116
+ if (!get(this, 'transforms')) {
117
+ this.set('transforms', Ep.JsonTransforms);
118
+ }
119
+ this.sideloadMapping = Ember.Map.create();
120
+ this.metadataMapping = Ember.Map.create();
121
+ this.configure({
122
+ meta: 'meta',
123
+ since: 'since'
124
+ });
125
+ },
126
+ configure: function (type, configuration) {
127
+ var key;
128
+ if (type && !configuration) {
129
+ for (key in type) {
130
+ this.metadataMapping.set(get(type, key), key);
131
+ }
132
+ return this._super(type);
133
+ }
134
+ var sideloadAs = configuration.sideloadAs, sideloadMapping;
135
+ if (sideloadAs) {
136
+ sideloadMapping = this.aliases.sideloadMapping || Ember.Map.create();
137
+ sideloadMapping.set(sideloadAs, type);
138
+ this.aliases.sideloadMapping = sideloadMapping;
139
+ delete configuration.sideloadAs;
140
+ }
141
+ this._super.apply(this, arguments);
142
+ },
143
+ addId: function (data, key, id) {
144
+ data[key] = id;
145
+ },
146
+ addAttribute: function (hash, key, value) {
147
+ hash[key] = value;
148
+ },
149
+ extractAttribute: function (type, hash, attributeName) {
150
+ var key = this._keyForAttributeName(type, attributeName);
151
+ return hash[key];
152
+ },
153
+ extractId: function (type, hash) {
154
+ var primaryKey = this._primaryKey(type);
155
+ if (hash.hasOwnProperty(primaryKey)) {
156
+ return hash[primaryKey] + '';
157
+ } else {
158
+ return null;
159
+ }
160
+ },
161
+ extractClientId: function (type, hash) {
162
+ var clientKey = this._clientKey(type);
163
+ if (hash.hasOwnProperty(clientKey) && hash[clientKey] !== null) {
164
+ return hash[clientKey] + '';
165
+ } else {
166
+ return null;
167
+ }
168
+ },
169
+ extractHasMany: function (type, hash, key) {
170
+ return hash[key];
171
+ },
172
+ extractBelongsTo: function (type, hash, key) {
173
+ return hash[key];
174
+ },
175
+ extractBelongsToPolymorphic: function (type, hash, key) {
176
+ var keyForId = this.keyForPolymorphicId(key), keyForType, id = hash[keyForId];
177
+ if (id) {
178
+ keyForType = this.keyForPolymorphicType(key);
179
+ return {
180
+ id: id,
181
+ type: hash[keyForType]
182
+ };
183
+ }
184
+ return null;
185
+ },
186
+ addBelongsTo: function (hash, record, key, relationship) {
187
+ var type = record.constructor, name = relationship.key, value = null, includeType = relationship.options && relationship.options.polymorphic, embeddedChild, child, id;
188
+ if (this.embeddedType(type, name)) {
189
+ if (embeddedChild = get(record, name)) {
190
+ value = this.serialize(embeddedChild, {
191
+ includeId: true,
192
+ includeType: includeType
193
+ });
194
+ }
195
+ hash[key] = value;
196
+ } else {
197
+ child = get(record, relationship.key);
198
+ id = get(child, 'id');
199
+ if (relationship.options && relationship.options.polymorphic && !Ember.isNone(id)) {
200
+ type = get(child, 'type');
201
+ this.addBelongsToPolymorphic(hash, key, id, type);
202
+ } else {
203
+ hash[key] = id === undefined ? null : this.serializeId(id);
204
+ }
205
+ }
206
+ },
207
+ addBelongsToPolymorphic: function (hash, key, id, type) {
208
+ var keyForId = this.keyForPolymorphicId(key), keyForType = this.keyForPolymorphicType(key);
209
+ hash[keyForId] = id;
210
+ hash[keyForType] = this.rootForType(type);
211
+ },
212
+ addHasMany: function (hash, record, key, relationship) {
213
+ var type = record.constructor, name = relationship.key, serializedHasMany = [], includeType = relationship.options && relationship.options.polymorphic, manyArray, embeddedType;
214
+ embeddedType = this.embeddedType(type, name);
215
+ if (embeddedType !== 'always') {
216
+ return;
217
+ }
218
+ manyArray = get(record, name);
219
+ manyArray.forEach(function (record) {
220
+ serializedHasMany.push(this.serialize(record, {
221
+ includeId: true,
222
+ includeType: includeType
223
+ }));
224
+ }, this);
225
+ hash[key] = serializedHasMany;
226
+ },
227
+ addType: function (hash, type) {
228
+ var keyForType = this.keyForEmbeddedType();
229
+ hash[keyForType] = this.rootForType(type);
230
+ },
231
+ deserialize: function (data) {
232
+ var result = [];
233
+ for (var prop in data) {
234
+ if (!data.hasOwnProperty(prop) || !!this.metadataMapping.get(prop)) {
235
+ continue;
236
+ }
237
+ var type = this.typeFromAlias(prop);
238
+ Ember.assert('Your server returned a hash with the key ' + prop + ' but you have no mapping for it', !!type);
239
+ var value = data[prop];
240
+ if (value instanceof Array) {
241
+ for (var i = 0; i < value.length; i++) {
242
+ result.push(this.deserializeModel(type, value[i]));
243
+ }
244
+ } else {
245
+ result.push(this.deserializeModel(type, value));
246
+ }
247
+ }
248
+ return result;
249
+ },
250
+ extractMeta: function (type, json) {
251
+ var meta = this.configOption(type, 'meta'), data = json, value;
252
+ if (meta && json[meta]) {
253
+ data = json[meta];
254
+ }
255
+ var result = {};
256
+ this.metadataMapping.forEach(function (property, key) {
257
+ if (value = data[property]) {
258
+ result[key] = value;
259
+ }
260
+ });
261
+ return result;
262
+ },
263
+ extractEmbeddedType: function (relationship, data) {
264
+ var foundType = relationship.type;
265
+ if (relationship.options && relationship.options.polymorphic) {
266
+ var key = this.keyFor(relationship), keyForEmbeddedType = this.keyForEmbeddedType(key);
267
+ foundType = this.typeFromAlias(data[keyForEmbeddedType]);
268
+ delete data[keyForEmbeddedType];
269
+ }
270
+ return foundType;
271
+ },
272
+ configureSideloadMappingForType: function (type, configured) {
273
+ if (!configured) {
274
+ configured = Ember.A([]);
275
+ }
276
+ configured.pushObject(type);
277
+ type.eachRelatedType(function (relatedType) {
278
+ if (!configured.contains(relatedType)) {
279
+ var root = this.defaultSideloadRootForType(relatedType);
280
+ this.aliases.set(root, relatedType);
281
+ this.configureSideloadMappingForType(relatedType, configured);
282
+ }
283
+ }, this);
284
+ },
285
+ keyForPolymorphicId: Ember.K,
286
+ keyForPolymorphicType: Ember.K,
287
+ keyForEmbeddedType: function () {
288
+ return 'type';
289
+ },
290
+ rootForType: function (type) {
291
+ var typeString = type.toString();
292
+ Ember.assert('Your model must not be anonymous. It was ' + type, typeString.charAt(0) !== '(');
293
+ var parts = typeString.split('.');
294
+ var name = parts[parts.length - 1];
295
+ return name.replace(/([A-Z])/g, '_$1').toLowerCase().slice(1);
296
+ },
297
+ defaultSideloadRootForType: function (type) {
298
+ return this.pluralize(this.rootForType(type));
299
+ }
300
+ });
301
+ });
302
+ require.define('/lib/transforms/json_transforms.js', function (module, exports, __dirname, __filename) {
303
+ var none = Ember.isNone, empty = Ember.isEmpty;
304
+ require('/lib/ext/date.js', module);
305
+ Ep.JsonTransforms = {
306
+ string: {
307
+ deserialize: function (serialized) {
308
+ return none(serialized) ? null : String(serialized);
309
+ },
310
+ serialize: function (deserialized) {
311
+ return none(deserialized) ? null : String(deserialized);
312
+ }
313
+ },
314
+ number: {
315
+ deserialize: function (serialized) {
316
+ return empty(serialized) ? null : Number(serialized);
317
+ },
318
+ serialize: function (deserialized) {
319
+ return empty(deserialized) ? null : Number(deserialized);
320
+ }
321
+ },
322
+ 'boolean': {
323
+ deserialize: function (serialized) {
324
+ var type = typeof serialized;
325
+ if (type === 'boolean') {
326
+ return serialized;
327
+ } else if (type === 'string') {
328
+ return serialized.match(/^true$|^t$|^1$/i) !== null;
329
+ } else if (type === 'number') {
330
+ return serialized === 1;
331
+ } else {
332
+ return false;
333
+ }
334
+ },
335
+ serialize: function (deserialized) {
336
+ return Boolean(deserialized);
337
+ }
338
+ },
339
+ date: {
340
+ deserialize: function (serialized) {
341
+ var type = typeof serialized;
342
+ if (type === 'string') {
343
+ return new Date(Ember.Date.parse(serialized));
344
+ } else if (type === 'number') {
345
+ return new Date(serialized);
346
+ } else if (serialized === null || serialized === undefined) {
347
+ return serialized;
348
+ } else {
349
+ return null;
350
+ }
351
+ },
352
+ serialize: function (date) {
353
+ if (date instanceof Date) {
354
+ var days = [
355
+ 'Sun',
356
+ 'Mon',
357
+ 'Tue',
358
+ 'Wed',
359
+ 'Thu',
360
+ 'Fri',
361
+ 'Sat'
362
+ ];
363
+ var months = [
364
+ 'Jan',
365
+ 'Feb',
366
+ 'Mar',
367
+ 'Apr',
368
+ 'May',
369
+ 'Jun',
370
+ 'Jul',
371
+ 'Aug',
372
+ 'Sep',
373
+ 'Oct',
374
+ 'Nov',
375
+ 'Dec'
376
+ ];
377
+ var pad = function (num) {
378
+ return num < 10 ? '0' + num : '' + num;
379
+ };
380
+ var utcYear = date.getUTCFullYear(), utcMonth = date.getUTCMonth(), utcDayOfMonth = date.getUTCDate(), utcDay = date.getUTCDay(), utcHours = date.getUTCHours(), utcMinutes = date.getUTCMinutes(), utcSeconds = date.getUTCSeconds();
381
+ var dayOfWeek = days[utcDay];
382
+ var dayOfMonth = pad(utcDayOfMonth);
383
+ var month = months[utcMonth];
384
+ return dayOfWeek + ', ' + dayOfMonth + ' ' + month + ' ' + utcYear + ' ' + pad(utcHours) + ':' + pad(utcMinutes) + ':' + pad(utcSeconds) + ' GMT';
385
+ } else {
386
+ return null;
387
+ }
388
+ }
389
+ }
390
+ };
391
+ });
392
+ require.define('/lib/ext/date.js', function (module, exports, __dirname, __filename) {
393
+ Ember.Date = Ember.Date || {};
394
+ var origParse = Date.parse, numericKeys = [
395
+ 1,
396
+ 4,
397
+ 5,
398
+ 6,
399
+ 7,
400
+ 10,
401
+ 11
402
+ ];
403
+ Ember.Date.parse = function (date) {
404
+ var timestamp, struct, minutesOffset = 0;
405
+ 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)) {
406
+ for (var i = 0, k; k = numericKeys[i]; ++i) {
407
+ struct[k] = +struct[k] || 0;
408
+ }
409
+ struct[2] = (+struct[2] || 1) - 1;
410
+ struct[3] = +struct[3] || 1;
411
+ if (struct[8] !== 'Z' && struct[9] !== undefined) {
412
+ minutesOffset = struct[10] * 60 + struct[11];
413
+ if (struct[9] === '+') {
414
+ minutesOffset = 0 - minutesOffset;
415
+ }
416
+ }
417
+ timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
418
+ } else {
419
+ timestamp = origParse ? origParse(date) : NaN;
420
+ }
421
+ return timestamp;
422
+ };
423
+ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Date) {
424
+ Date.parse = Ember.Date.parse;
425
+ }
426
+ });
427
+ require.define('/lib/serializer/serializer.js', function (module, exports, __dirname, __filename) {
428
+ require('/lib/model/index.js', module);
429
+ var get = Ember.get, set = Ember.set, map = Ember.ArrayPolyfills.map, isNone = Ember.isNone;
430
+ function mustImplement(name) {
431
+ return function () {
432
+ throw new Ember.Error('Your serializer ' + this.toString() + ' does not implement the required method ' + name);
433
+ };
434
+ }
435
+ Ep.Serializer = Ember.Object.extend({
436
+ init: function () {
437
+ this.mappings = Ember.Map.create();
438
+ this.aliases = Ember.Map.create();
439
+ this.configurations = Ember.Map.create();
440
+ this.globalConfigurations = {};
441
+ },
442
+ deserialize: mustImplement('deserialize'),
443
+ extractId: mustImplement('extractId'),
444
+ extractClientId: mustImplement('extractClientId'),
445
+ extractAttribute: mustImplement('extractAttribute'),
446
+ extractHasMany: mustImplement('extractHasMany'),
447
+ extractBelongsTo: mustImplement('extractBelongsTo'),
448
+ deserializeModel: function (type, hash) {
449
+ var model = this.createModel(type);
450
+ set(model, 'id', this.extractId(type, hash));
451
+ set(model, 'clientId', this.extractClientId(type, hash));
452
+ this.deserializeAttributes(model, hash);
453
+ this.deserializeRelationships(model, hash);
454
+ return model;
455
+ },
456
+ createModel: function (type) {
457
+ return type.create();
458
+ },
459
+ deserializeValue: function (value, attributeType) {
460
+ var transform = this.transforms ? this.transforms[attributeType] : null;
461
+ Ember.assert('You tried to use a attribute type (' + attributeType + ') that has not been registered', transform);
462
+ return transform.deserialize(value);
463
+ },
464
+ deserializeAttributes: function (model, data) {
465
+ model.eachAttribute(function (name, attribute) {
466
+ set(model, name, this.deserializeAttribute(model, data, name, attribute.type));
467
+ }, this);
468
+ },
469
+ deserializeAttribute: function (record, data, attributeName, attributeType) {
470
+ var value = this.extractAttribute(record.constructor, data, attributeName);
471
+ return this.deserializeValue(value, attributeType);
472
+ },
473
+ deserializeRelationships: function (model, hash) {
474
+ model.eachRelationship(function (name, relationship) {
475
+ if (relationship.kind === 'hasMany') {
476
+ this.deserializeHasMany(name, model, hash, relationship);
477
+ } else if (relationship.kind === 'belongsTo') {
478
+ this.deserializeBelongsTo(name, model, hash, relationship);
479
+ }
480
+ }, this);
481
+ },
482
+ deserializeHasMany: function (name, model, data, relationship) {
483
+ var type = get(model, 'type'), key = this._keyForHasMany(type, relationship.key), embeddedType = this.embeddedType(type, name), value = this.extractHasMany(type, data, key);
484
+ if (embeddedType) {
485
+ this.deserializeEmbeddedHasMany(name, model, value, relationship);
486
+ } else {
487
+ this.deserializeLazyHasMany(name, model, value, relationship);
488
+ }
489
+ },
490
+ deserializeEmbeddedHasMany: function (name, model, values, relationship) {
491
+ get(model, name).addObjects(values.map(function (data) {
492
+ var type = this.extractEmbeddedType(relationship, data);
493
+ return this.deserializeModel(type, data);
494
+ }, this));
495
+ },
496
+ deserializeLazyHasMany: function (name, model, values, relationship) {
497
+ if (!values) {
498
+ return;
499
+ }
500
+ get(model, name).addObjects(values.map(function (value) {
501
+ return Ep.LazyModel.create({
502
+ id: value && value.toString(),
503
+ type: relationship.type
504
+ });
505
+ }, this));
506
+ },
507
+ deserializeBelongsTo: function (name, model, hash, relationship) {
508
+ var type = get(model, 'type'), key = this._keyForBelongsTo(type, relationship.key), embeddedType = this.embeddedType(type, name), value;
509
+ if (embeddedType) {
510
+ if (relationship.options && relationship.options.polymorphic) {
511
+ value = this.extractBelongsToPolymorphic(type, hash, key);
512
+ } else {
513
+ value = this.extractBelongsTo(type, hash, key);
514
+ }
515
+ this.deserializeEmbeddedBelongsTo(name, model, value, relationship);
516
+ } else {
517
+ value = this.extractBelongsTo(type, hash, key);
518
+ this.deserializeLazyBelongsTo(name, model, value, relationship);
519
+ }
520
+ },
521
+ deserializeEmbeddedBelongsTo: function (name, model, value, relationship) {
522
+ if (!value) {
523
+ return;
524
+ }
525
+ var type = this.extractEmbeddedType(relationship, value);
526
+ var child = this.deserializeModel(type, value);
527
+ set(model, name, child);
528
+ },
529
+ deserializeLazyBelongsTo: function (name, model, value, relationship) {
530
+ if (!value) {
531
+ return;
532
+ }
533
+ set(model, name, Ep.LazyModel.create({
534
+ id: value && value.toString(),
535
+ type: relationship.type
536
+ }));
537
+ },
538
+ extractEmbeddedType: function (relationship, data) {
539
+ return relationship.type;
540
+ },
541
+ _convertPrematerializedHasMany: function (type, prematerializedHasMany) {
542
+ var tuplesOrReferencesOrOpaque;
543
+ if (typeof prematerializedHasMany === 'string') {
544
+ tuplesOrReferencesOrOpaque = prematerializedHasMany;
545
+ } else {
546
+ tuplesOrReferencesOrOpaque = this._convertTuples(type, prematerializedHasMany);
547
+ }
548
+ return tuplesOrReferencesOrOpaque;
549
+ },
550
+ _convertTuples: function (type, idsOrTuples) {
551
+ return map.call(idsOrTuples, function (idOrTuple) {
552
+ return this._convertTuple(type, idOrTuple);
553
+ }, this);
554
+ },
555
+ _convertTuple: function (type, idOrTuple) {
556
+ var foundType;
557
+ if (typeof idOrTuple === 'object') {
558
+ if (Ep.Model.detect(idOrTuple.type)) {
559
+ return idOrTuple;
560
+ } else {
561
+ foundType = this.typeFromAlias(idOrTuple.type);
562
+ Ember.assert('Unable to resolve type ' + idOrTuple.type + '. You may need to configure your serializer aliases.', !!foundType);
563
+ return {
564
+ id: idOrTuple.id,
565
+ type: foundType
566
+ };
567
+ }
568
+ }
569
+ return {
570
+ id: idOrTuple,
571
+ type: type
572
+ };
573
+ },
574
+ serialize: function (record, options) {
575
+ options = options || {};
576
+ var serialized = this.createSerializedForm(), id;
577
+ if (options.includeId) {
578
+ if (id = get(record, 'id')) {
579
+ this._addId(serialized, record.constructor, id);
580
+ }
581
+ this._addClientId(serialized, record.constructor, get(record, 'clientId'));
582
+ }
583
+ if (options.includeType) {
584
+ this.addType(serialized, record.constructor);
585
+ }
586
+ this.addAttributes(serialized, record);
587
+ this.addRelationships(serialized, record);
588
+ return serialized;
589
+ },
590
+ serializeValue: function (value, attributeType) {
591
+ var transform = this.transforms ? this.transforms[attributeType] : null;
592
+ Ember.assert('You tried to use an attribute type (' + attributeType + ') that has not been registered', transform);
593
+ return transform.serialize(value);
594
+ },
595
+ serializeId: function (id) {
596
+ if (isNaN(id)) {
597
+ return id;
598
+ }
599
+ return +id;
600
+ },
601
+ serializeClientId: function (clientId) {
602
+ return clientId;
603
+ },
604
+ addAttributes: function (data, record) {
605
+ record.eachAttribute(function (name, attribute) {
606
+ this._addAttribute(data, record, name, attribute.type);
607
+ }, this);
608
+ },
609
+ addAttribute: mustImplement('addAttribute'),
610
+ addId: mustImplement('addId'),
611
+ addType: Ember.K,
612
+ createSerializedForm: function () {
613
+ return {};
614
+ },
615
+ addRelationships: function (data, record) {
616
+ record.eachRelationship(function (name, relationship) {
617
+ if (relationship.kind === 'belongsTo') {
618
+ this._addBelongsTo(data, record, name, relationship);
619
+ } else if (relationship.kind === 'hasMany') {
620
+ this._addHasMany(data, record, name, relationship);
621
+ }
622
+ }, this);
623
+ },
624
+ addBelongsTo: mustImplement('addBelongsTo'),
625
+ addHasMany: mustImplement('addHasMany'),
626
+ keyForAttributeName: function (type, name) {
627
+ return name;
628
+ },
629
+ primaryKey: function (type) {
630
+ return 'id';
631
+ },
632
+ clientKey: function (type) {
633
+ return 'client_id';
634
+ },
635
+ keyForBelongsTo: function (type, name) {
636
+ return this.keyForAttributeName(type, name);
637
+ },
638
+ keyForHasMany: function (type, name) {
639
+ return this.keyForAttributeName(type, name);
640
+ },
641
+ _primaryKey: function (type) {
642
+ var config = this.configurationForType(type), primaryKey = config && config.primaryKey;
643
+ if (primaryKey) {
644
+ return primaryKey;
645
+ } else {
646
+ return this.primaryKey(type);
647
+ }
648
+ },
649
+ _clientKey: function (type) {
650
+ var config = this.configurationForType(type), clientKey = config && config.clientKey;
651
+ if (clientKey) {
652
+ return clientKey;
653
+ } else {
654
+ return this.clientKey(type);
655
+ }
656
+ },
657
+ _addAttribute: function (data, record, attributeName, attributeType) {
658
+ var key = this._keyForAttributeName(record.constructor, attributeName);
659
+ var value = get(record, attributeName);
660
+ this.addAttribute(data, key, this.serializeValue(value, attributeType));
661
+ },
662
+ _addId: function (hash, type, id) {
663
+ var primaryKey = this._primaryKey(type);
664
+ this.addId(hash, primaryKey, this.serializeId(id));
665
+ },
666
+ _addClientId: function (hash, type, id) {
667
+ var clientKey = this._clientKey(type);
668
+ this.addId(hash, clientKey, this.serializeClientId(id));
669
+ },
670
+ _keyForAttributeName: function (type, name) {
671
+ return this._keyFromMappingOrHook('keyForAttributeName', type, name);
672
+ },
673
+ _keyForBelongsTo: function (type, name) {
674
+ return this._keyFromMappingOrHook('keyForBelongsTo', type, name);
675
+ },
676
+ keyFor: function (description) {
677
+ var type = description.parentType, name = description.key;
678
+ switch (description.kind) {
679
+ case 'belongsTo':
680
+ return this._keyForBelongsTo(type, name);
681
+ case 'hasMany':
682
+ return this._keyForHasMany(type, name);
683
+ }
684
+ },
685
+ _keyForHasMany: function (type, name) {
686
+ return this._keyFromMappingOrHook('keyForHasMany', type, name);
687
+ },
688
+ _addBelongsTo: function (data, record, name, relationship) {
689
+ var key = this._keyForBelongsTo(record.constructor, name);
690
+ this.addBelongsTo(data, record, key, relationship);
691
+ },
692
+ _addHasMany: function (data, record, name, relationship) {
693
+ var key = this._keyForHasMany(record.constructor, name);
694
+ this.addHasMany(data, record, key, relationship);
695
+ },
696
+ _keyFromMappingOrHook: function (publicMethod, type, name) {
697
+ var key = this.mappingOption(type, name, 'key');
698
+ if (key) {
699
+ return key;
700
+ } else {
701
+ return this[publicMethod](type, name);
702
+ }
703
+ },
704
+ registerTransform: function (type, transform) {
705
+ this.transforms[type] = transform;
706
+ },
707
+ registerEnumTransform: function (type, objects) {
708
+ var transform = {
709
+ deserialize: function (serialized) {
710
+ return Ember.A(objects).objectAt(serialized);
711
+ },
712
+ serialize: function (deserialized) {
713
+ return Ember.EnumerableUtils.indexOf(objects, deserialized);
714
+ },
715
+ values: objects
716
+ };
717
+ this.registerTransform(type, transform);
718
+ },
719
+ map: function (type, mappings) {
720
+ this.mappings.set(type, mappings);
721
+ },
722
+ configure: function (type, configuration) {
723
+ if (type && !configuration) {
724
+ Ember.merge(this.globalConfigurations, type);
725
+ return;
726
+ }
727
+ var config, alias;
728
+ if (configuration.alias) {
729
+ alias = configuration.alias;
730
+ this.aliases.set(alias, type);
731
+ delete configuration.alias;
732
+ }
733
+ config = Ember.create(this.globalConfigurations);
734
+ Ember.merge(config, configuration);
735
+ this.configurations.set(type, config);
736
+ },
737
+ typeFromAlias: function (alias) {
738
+ this._completeAliases();
739
+ var singular = this.singularize(alias);
740
+ return this.container.lookup('model:' + singular);
741
+ },
742
+ mappingForType: function (type) {
743
+ this._reifyMappings();
744
+ return this.mappings.get(type) || {};
745
+ },
746
+ configurationForType: function (type) {
747
+ this._reifyConfigurations();
748
+ return this.configurations.get(type) || this.globalConfigurations;
749
+ },
750
+ _completeAliases: function () {
751
+ this._pluralizeAliases();
752
+ this._reifyAliases();
753
+ },
754
+ _pluralizeAliases: function () {
755
+ if (this._didPluralizeAliases) {
756
+ return;
757
+ }
758
+ var aliases = this.aliases, sideloadMapping = this.aliases.sideloadMapping, plural, self = this;
759
+ aliases.forEach(function (key, type) {
760
+ plural = self.pluralize(key);
761
+ Ember.assert('The \'' + key + '\' alias has already been defined', !aliases.get(plural));
762
+ aliases.set(plural, type);
763
+ });
764
+ if (sideloadMapping) {
765
+ sideloadMapping.forEach(function (key, type) {
766
+ Ember.assert('The \'' + key + '\' alias has already been defined', !aliases.get(key) || aliases.get(key) === type);
767
+ aliases.set(key, type);
768
+ });
769
+ delete this.aliases.sideloadMapping;
770
+ }
771
+ this._didPluralizeAliases = true;
772
+ },
773
+ _reifyAliases: function () {
774
+ if (this._didReifyAliases) {
775
+ return;
776
+ }
777
+ var aliases = this.aliases, reifiedAliases = Ember.Map.create(), foundType;
778
+ aliases.forEach(function (key, type) {
779
+ if (typeof type === 'string') {
780
+ foundType = Ember.get(Ember.lookup, type);
781
+ Ember.assert('Could not find model at path ' + key, type);
782
+ reifiedAliases.set(key, foundType);
783
+ } else {
784
+ reifiedAliases.set(key, type);
785
+ }
786
+ });
787
+ this.aliases = reifiedAliases;
788
+ this._didReifyAliases = true;
789
+ },
790
+ _reifyMappings: function () {
791
+ if (this._didReifyMappings) {
792
+ return;
793
+ }
794
+ var mappings = this.mappings, reifiedMappings = Ember.Map.create();
795
+ mappings.forEach(function (key, mapping) {
796
+ if (typeof key === 'string') {
797
+ var type = Ember.get(Ember.lookup, key);
798
+ Ember.assert('Could not find model at path ' + key, type);
799
+ reifiedMappings.set(type, mapping);
800
+ } else {
801
+ reifiedMappings.set(key, mapping);
802
+ }
803
+ });
804
+ this.mappings = reifiedMappings;
805
+ this._didReifyMappings = true;
806
+ },
807
+ _reifyConfigurations: function () {
808
+ if (this._didReifyConfigurations) {
809
+ return;
810
+ }
811
+ var configurations = this.configurations, reifiedConfigurations = Ember.Map.create();
812
+ configurations.forEach(function (key, mapping) {
813
+ if (typeof key === 'string' && key !== 'plurals') {
814
+ var type = Ember.get(Ember.lookup, key);
815
+ Ember.assert('Could not find model at path ' + key, type);
816
+ reifiedConfigurations.set(type, mapping);
817
+ } else {
818
+ reifiedConfigurations.set(key, mapping);
819
+ }
820
+ });
821
+ this.configurations = reifiedConfigurations;
822
+ this._didReifyConfigurations = true;
823
+ },
824
+ mappingOption: function (type, name, option) {
825
+ var mapping = this.mappingForType(type)[name];
826
+ return mapping && mapping[option];
827
+ },
828
+ configOption: function (type, option) {
829
+ var config = this.configurationForType(type);
830
+ return config[option];
831
+ },
832
+ embeddedType: function (type, name) {
833
+ return this.mappingOption(type, name, 'embedded');
834
+ },
835
+ eachEmbeddedRecord: function (record, callback, binding) {
836
+ this.eachEmbeddedBelongsToRecord(record, callback, binding);
837
+ this.eachEmbeddedHasManyRecord(record, callback, binding);
838
+ },
839
+ eachEmbeddedBelongsToRecord: function (record, callback, binding) {
840
+ this.eachEmbeddedBelongsTo(record.constructor, function (name, relationship, embeddedType) {
841
+ var embeddedRecord = get(record, name);
842
+ if (embeddedRecord) {
843
+ callback.call(binding, embeddedRecord, embeddedType);
844
+ }
845
+ });
846
+ },
847
+ eachEmbeddedHasManyRecord: function (record, callback, binding) {
848
+ this.eachEmbeddedHasMany(record.constructor, function (name, relationship, embeddedType) {
849
+ var array = get(record, name);
850
+ for (var i = 0, l = get(array, 'length'); i < l; i++) {
851
+ callback.call(binding, array.objectAt(i), embeddedType);
852
+ }
853
+ });
854
+ },
855
+ eachEmbeddedHasMany: function (type, callback, binding) {
856
+ this.eachEmbeddedRelationship(type, 'hasMany', callback, binding);
857
+ },
858
+ eachEmbeddedBelongsTo: function (type, callback, binding) {
859
+ this.eachEmbeddedRelationship(type, 'belongsTo', callback, binding);
860
+ },
861
+ eachEmbeddedRelationship: function (type, kind, callback, binding) {
862
+ type.eachRelationship(function (name, relationship) {
863
+ var embeddedType = this.embeddedType(type, name);
864
+ if (embeddedType) {
865
+ if (relationship.kind === kind) {
866
+ callback.call(binding, name, relationship, embeddedType);
867
+ }
868
+ }
869
+ }, this);
870
+ },
871
+ pluralize: function (name) {
872
+ var plurals = this.configurations.get('plurals');
873
+ return plurals && plurals[name] || name + 's';
874
+ },
875
+ singularize: function (name) {
876
+ var plurals = this.configurations.get('plurals');
877
+ if (plurals) {
878
+ for (var i in plurals) {
879
+ if (plurals[i] === name) {
880
+ return i;
881
+ }
882
+ }
883
+ }
884
+ if (name.lastIndexOf('s') === name.length - 1) {
885
+ return name.substring(0, name.length - 1);
886
+ } else {
887
+ return name;
888
+ }
889
+ }
890
+ });
891
+ });
892
+ require.define('/lib/model/index.js', function (module, exports, __dirname, __filename) {
893
+ require('/lib/model/model.js', module);
894
+ require('/lib/model/proxies.js', module);
895
+ require('/lib/model/attribute.js', module);
896
+ require('/lib/model/relationships/belongs_to.js', module);
897
+ require('/lib/model/relationships/has_many.js', module);
898
+ require('/lib/model/relationships/ext.js', module);
899
+ require('/lib/model/errors.js', module);
900
+ });
901
+ require.define('/lib/model/errors.js', function (module, exports, __dirname, __filename) {
902
+ var get = Ember.get, set = Ember.set;
903
+ Ep.Errors = Ember.ObjectProxy.extend(Ember.Copyable, {
904
+ init: function () {
905
+ this._super.apply(this, arguments);
906
+ if (!get(this, 'content'))
907
+ set(this, 'content', {});
908
+ },
909
+ forEach: function (callback, self) {
910
+ var keys = Ember.keys(this.content);
911
+ keys.forEach(function (key) {
912
+ var value = get(this.content, key);
913
+ callback.call(self, key, value);
914
+ }, this);
915
+ },
916
+ copy: function () {
917
+ return Ep.Errors.create({ content: Ember.copy(this.content) });
918
+ }
919
+ });
920
+ });
921
+ require.define('/lib/model/relationships/ext.js', function (module, exports, __dirname, __filename) {
922
+ var get = Ember.get, set = Ember.set;
923
+ Ep.Model.reopen({
924
+ didDefineProperty: function (proto, key, value) {
925
+ if (value instanceof Ember.Descriptor) {
926
+ var meta = value.meta();
927
+ if (meta.isRelationship && meta.kind === 'belongsTo') {
928
+ Ember.addObserver(proto, key, null, 'belongsToDidChange');
929
+ Ember.addBeforeObserver(proto, key, null, 'belongsToWillChange');
930
+ }
931
+ if (meta.isAttribute) {
932
+ Ember.addBeforeObserver(proto, key, null, 'attributeWillChange');
933
+ }
934
+ meta.parentType = proto.constructor;
935
+ }
936
+ },
937
+ _suspendedRelationships: false,
938
+ suspendRelationshipObservers: function (callback, binding) {
939
+ var observers = get(this.constructor, 'relationshipNames').belongsTo;
940
+ var self = this;
941
+ if (this._suspendedRelationships) {
942
+ return callback.call(binding || self);
943
+ }
944
+ try {
945
+ this._suspendedRelationships = true;
946
+ Ember._suspendObservers(self, observers, null, 'belongsToDidChange', function () {
947
+ Ember._suspendBeforeObservers(self, observers, null, 'belongsToWillChange', function () {
948
+ callback.call(binding || self);
949
+ });
950
+ });
951
+ } finally {
952
+ this._suspendedRelationships = false;
953
+ }
954
+ },
955
+ _registerRelationships: function () {
956
+ var session = get(this, 'session');
957
+ Ember.assert('Must be attached to a session', !!session);
958
+ this.eachRelationship(function (name, relationship) {
959
+ if (relationship.kind === 'belongsTo') {
960
+ var model = get(this, name);
961
+ if (model) {
962
+ session.belongsToManager.register(model, name, this);
963
+ }
964
+ } else if (relationship.kind === 'hasMany') {
965
+ var children = get(this, name);
966
+ children.forEach(function (model) {
967
+ session.collectionManager.register(children, model);
968
+ }, this);
969
+ }
970
+ }, this);
971
+ }
972
+ });
973
+ Ep.Model.reopenClass({
974
+ typeForRelationship: function (name) {
975
+ var relationship = get(this, 'relationshipsByName').get(name);
976
+ return relationship && relationship.type;
977
+ },
978
+ inverseFor: function (name) {
979
+ var inverseType = this.typeForRelationship(name);
980
+ if (!inverseType) {
981
+ return null;
982
+ }
983
+ var options = this.metaForProperty(name).options;
984
+ var inverseName, inverseKind;
985
+ if (options.inverse) {
986
+ inverseName = options.inverse;
987
+ inverseKind = Ember.get(inverseType, 'relationshipsByName').get(inverseName).kind;
988
+ } else {
989
+ var possibleRelationships = findPossibleInverses(this, inverseType);
990
+ if (possibleRelationships.length === 0) {
991
+ return null;
992
+ }
993
+ Ember.assert('You defined the \'' + name + '\' relationship on ' + this + ', but multiple possible inverse relationships of type ' + this + ' were found on ' + inverseType + '.', possibleRelationships.length === 1);
994
+ inverseName = possibleRelationships[0].name;
995
+ inverseKind = possibleRelationships[0].kind;
996
+ }
997
+ function findPossibleInverses(type, inverseType, possibleRelationships) {
998
+ possibleRelationships = possibleRelationships || [];
999
+ var relationshipMap = get(inverseType, 'relationships');
1000
+ if (!relationshipMap) {
1001
+ return;
1002
+ }
1003
+ var relationships = relationshipMap.get(type);
1004
+ if (relationships) {
1005
+ possibleRelationships.push.apply(possibleRelationships, relationshipMap.get(type));
1006
+ }
1007
+ if (type.superclass) {
1008
+ findPossibleInverses(type.superclass, inverseType, possibleRelationships);
1009
+ }
1010
+ return possibleRelationships;
1011
+ }
1012
+ return {
1013
+ type: inverseType,
1014
+ name: inverseName,
1015
+ kind: inverseKind
1016
+ };
1017
+ },
1018
+ relationships: Ember.computed(function () {
1019
+ var map = new Ember.MapWithDefault({
1020
+ defaultValue: function () {
1021
+ return [];
1022
+ }
1023
+ });
1024
+ this.eachComputedProperty(function (name, meta) {
1025
+ if (meta.isRelationship) {
1026
+ if (typeof meta.type === 'string') {
1027
+ meta.type = Ep.__container__.lookup('model:' + type);
1028
+ }
1029
+ var relationshipsForType = map.get(meta.type);
1030
+ relationshipsForType.push({
1031
+ name: name,
1032
+ kind: meta.kind
1033
+ });
1034
+ }
1035
+ });
1036
+ return map;
1037
+ }),
1038
+ relationshipNames: Ember.computed(function () {
1039
+ var names = {
1040
+ hasMany: [],
1041
+ belongsTo: []
1042
+ };
1043
+ this.eachComputedProperty(function (name, meta) {
1044
+ if (meta.isRelationship) {
1045
+ names[meta.kind].push(name);
1046
+ }
1047
+ });
1048
+ return names;
1049
+ }),
1050
+ relatedTypes: Ember.computed(function () {
1051
+ var type, types = Ember.A([]);
1052
+ this.eachComputedProperty(function (name, meta) {
1053
+ if (meta.isRelationship) {
1054
+ type = meta.type;
1055
+ if (typeof type === 'string') {
1056
+ type = Ep.__container__.lookup('model:' + type);
1057
+ }
1058
+ Ember.assert('You specified a hasMany (' + meta.type + ') on ' + meta.parentType + ' but ' + meta.type + ' was not found.', type);
1059
+ if (!types.contains(type)) {
1060
+ Ember.assert('Trying to sideload ' + name + ' on ' + this.toString() + ' but the type doesn\'t exist.', !!type);
1061
+ types.push(type);
1062
+ }
1063
+ }
1064
+ });
1065
+ return types;
1066
+ }),
1067
+ relationshipsByName: Ember.computed(function () {
1068
+ var map = Ember.Map.create(), type;
1069
+ this.eachComputedProperty(function (name, meta) {
1070
+ if (meta.isRelationship) {
1071
+ meta.key = name;
1072
+ type = meta.type;
1073
+ if (typeof type === 'string') {
1074
+ type = Ep.__container__.lookup('model:' + type);
1075
+ }
1076
+ map.set(name, meta);
1077
+ }
1078
+ });
1079
+ return map;
1080
+ }),
1081
+ fields: Ember.computed(function () {
1082
+ var map = Ember.Map.create();
1083
+ this.eachComputedProperty(function (name, meta) {
1084
+ if (meta.isRelationship) {
1085
+ map.set(name, meta.kind);
1086
+ } else if (meta.isAttribute) {
1087
+ map.set(name, 'attribute');
1088
+ }
1089
+ });
1090
+ return map;
1091
+ }),
1092
+ eachRelationship: function (callback, binding) {
1093
+ get(this, 'relationshipsByName').forEach(function (name, relationship) {
1094
+ callback.call(binding, name, relationship);
1095
+ });
1096
+ },
1097
+ eachRelatedType: function (callback, binding) {
1098
+ get(this, 'relatedTypes').forEach(function (type) {
1099
+ callback.call(binding, type);
1100
+ });
1101
+ }
1102
+ });
1103
+ Ep.Model.reopen({
1104
+ eachRelationship: function (callback, binding) {
1105
+ this.constructor.eachRelationship(callback, binding);
1106
+ },
1107
+ eachRelatedModel: function (callback, binding, cache) {
1108
+ if (!cache)
1109
+ cache = Ember.Set.create();
1110
+ if (cache.contains(this))
1111
+ return;
1112
+ cache.add(this);
1113
+ callback.call(binding || this, this);
1114
+ if (!get(this, 'isLoaded'))
1115
+ return;
1116
+ this.eachRelationship(function (name, relationship) {
1117
+ if (relationship.kind === 'belongsTo') {
1118
+ var child = get(this, name);
1119
+ if (!child)
1120
+ return;
1121
+ this.eachRelatedModel.call(child, callback, binding, cache);
1122
+ } else if (relationship.kind === 'hasMany') {
1123
+ var children = get(this, name);
1124
+ children.forEach(function (child) {
1125
+ this.eachRelatedModel.call(child, callback, binding, cache);
1126
+ }, this);
1127
+ }
1128
+ }, this);
1129
+ }
1130
+ });
1131
+ });
1132
+ require.define('/lib/model/relationships/has_many.js', function (module, exports, __dirname, __filename) {
1133
+ var get = Ember.get, set = Ember.set, forEach = Ember.ArrayPolyfills.forEach;
1134
+ require('/lib/model/model.js', module);
1135
+ require('/lib/collections/model_array.js', module);
1136
+ Ep.hasMany = function (type, options) {
1137
+ Ember.assert('The type passed to Ep.hasMany must be defined', !!type);
1138
+ options = options || {};
1139
+ var meta = {
1140
+ type: type,
1141
+ isRelationship: true,
1142
+ options: options,
1143
+ kind: 'hasMany'
1144
+ };
1145
+ return Ember.computed(function (key, value, cached) {
1146
+ var content;
1147
+ if (arguments.length === 1) {
1148
+ content = [];
1149
+ } else {
1150
+ content = value;
1151
+ }
1152
+ var session = get(this, 'session');
1153
+ if (session) {
1154
+ content = content.map(function (model) {
1155
+ return session.add(model);
1156
+ }, this);
1157
+ }
1158
+ if (cached) {
1159
+ set(cached, 'content', content);
1160
+ return cached;
1161
+ }
1162
+ return Ep.HasManyArray.create({
1163
+ owner: this,
1164
+ name: key,
1165
+ session: session,
1166
+ content: content
1167
+ });
1168
+ }).property().meta(meta);
1169
+ };
1170
+ Ep.HasManyArray = Ep.ModelArray.extend({
1171
+ name: null,
1172
+ owner: null,
1173
+ replaceContent: function (idx, amt, objects) {
1174
+ var session = get(this, 'session');
1175
+ if (session) {
1176
+ objects = objects.map(function (model) {
1177
+ return session.add(model);
1178
+ });
1179
+ }
1180
+ this._super(idx, amt, objects);
1181
+ },
1182
+ arrayContentWillChange: function (index, removed, added) {
1183
+ var owner = get(this, 'owner'), name = get(this, 'name'), session = get(owner, 'session');
1184
+ if (session) {
1185
+ session.modelWillBecomeDirty(owner);
1186
+ }
1187
+ if (!owner._suspendedRelationships) {
1188
+ var inverse = owner.constructor.inverseFor(name);
1189
+ if (inverse) {
1190
+ for (var i = index; i < index + removed; i++) {
1191
+ var model = this.objectAt(i);
1192
+ if (!get(model, 'isLoaded'))
1193
+ continue;
1194
+ model.suspendRelationshipObservers(function () {
1195
+ if (inverse.kind === 'hasMany') {
1196
+ get(model, inverse.name).removeObject(owner);
1197
+ } else if (inverse.kind === 'belongsTo') {
1198
+ set(model, inverse.name, null);
1199
+ if (session) {
1200
+ session.modelWillBecomeDirty(model);
1201
+ session.belongsToManager.unregister(model, inverse.name, owner);
1202
+ }
1203
+ }
1204
+ });
1205
+ }
1206
+ }
1207
+ }
1208
+ return this._super.apply(this, arguments);
1209
+ },
1210
+ arrayContentDidChange: function (index, removed, added) {
1211
+ this._super.apply(this, arguments);
1212
+ var owner = get(this, 'owner'), name = get(this, 'name');
1213
+ if (!owner._suspendedRelationships) {
1214
+ var inverse = owner.constructor.inverseFor(name);
1215
+ if (inverse) {
1216
+ for (var i = index; i < index + added; i++) {
1217
+ var model = this.objectAt(i);
1218
+ if (!get(model, 'isLoaded'))
1219
+ continue;
1220
+ model.suspendRelationshipObservers(function () {
1221
+ if (inverse.kind === 'hasMany') {
1222
+ get(model, inverse.name).addObject(owner);
1223
+ } else if (inverse.kind === 'belongsTo') {
1224
+ set(model, inverse.name, owner);
1225
+ var session = get(owner, 'session');
1226
+ if (session) {
1227
+ session.belongsToManager.register(model, inverse.name, owner);
1228
+ }
1229
+ }
1230
+ });
1231
+ }
1232
+ }
1233
+ }
1234
+ }
1235
+ });
1236
+ });
1237
+ require.define('/lib/collections/model_array.js', function (module, exports, __dirname, __filename) {
1238
+ var get = Ember.get, set = Ember.set;
1239
+ Ep.ModelArray = Ember.ArrayProxy.extend({
1240
+ session: null,
1241
+ meta: null,
1242
+ arrayContentWillChange: function (index, removed, added) {
1243
+ for (var i = index; i < index + removed; i++) {
1244
+ var model = this.objectAt(i);
1245
+ if (this.session) {
1246
+ this.session.collectionManager.unregister(this, model);
1247
+ }
1248
+ }
1249
+ this._super.apply(this, arguments);
1250
+ },
1251
+ arrayContentDidChange: function (index, removed, added) {
1252
+ this._super.apply(this, arguments);
1253
+ for (var i = index; i < index + added; i++) {
1254
+ var model = this.objectAt(i);
1255
+ if (this.session) {
1256
+ this.session.collectionManager.register(this, model);
1257
+ }
1258
+ }
1259
+ },
1260
+ removeObject: function (obj) {
1261
+ var loc = get(this, 'length') || 0;
1262
+ while (--loc >= 0) {
1263
+ var curObject = this.objectAt(loc);
1264
+ if (curObject.isEqual(obj))
1265
+ this.removeAt(loc);
1266
+ }
1267
+ return this;
1268
+ },
1269
+ contains: function (obj) {
1270
+ for (var i = 0; i < get(this, 'length'); i++) {
1271
+ var m = this.objectAt(i);
1272
+ if (obj.isEqual(m))
1273
+ return true;
1274
+ }
1275
+ return false;
1276
+ },
1277
+ copyTo: function (dest) {
1278
+ var existing = Ep.ModelSet.create();
1279
+ existing.addObjects(dest);
1280
+ this.forEach(function (model) {
1281
+ if (existing.contains(model)) {
1282
+ existing.remove(model);
1283
+ } else {
1284
+ dest.addObject(model);
1285
+ }
1286
+ });
1287
+ dest.removeObjects(existing);
1288
+ },
1289
+ diff: function (arr) {
1290
+ var diff = Ember.A();
1291
+ this.forEach(function (model) {
1292
+ if (!arr.contains(model)) {
1293
+ diff.push(model);
1294
+ }
1295
+ }, this);
1296
+ arr.forEach(function (model) {
1297
+ if (!this.contains(model)) {
1298
+ diff.push(model);
1299
+ }
1300
+ }, this);
1301
+ return diff;
1302
+ },
1303
+ isEqual: function (arr) {
1304
+ return this.diff(arr).length === 0;
1305
+ }
1306
+ });
1307
+ });
1308
+ require.define('/lib/model/model.js', function (module, exports, __dirname, __filename) {
1309
+ var get = Ember.get, set = Ember.set;
1310
+ require('/lib/collections/model_set.js', module);
1311
+ Ep.ModelMixin = Ember.Mixin.create({
1312
+ id: null,
1313
+ clientId: null,
1314
+ session: null,
1315
+ errors: null,
1316
+ isEqual: function (model) {
1317
+ var clientId = get(this, 'clientId');
1318
+ var otherClientId = get(model, 'clientId');
1319
+ if (clientId && otherClientId) {
1320
+ return clientId === otherClientId;
1321
+ }
1322
+ var id = get(this, 'id');
1323
+ var otherId = get(model, 'id');
1324
+ return this.isSameType(model) && id === otherId;
1325
+ },
1326
+ isSameType: function (model) {
1327
+ return this.hasType(get(model, 'type'));
1328
+ },
1329
+ hasType: function (type) {
1330
+ return get(this, 'type').detect(type);
1331
+ },
1332
+ type: Ember.computed(function (key, value) {
1333
+ return value || this.constructor;
1334
+ }),
1335
+ toStringExtension: function () {
1336
+ return '[' + get(this, 'id') + ', ' + get(this, 'clientId') + ']';
1337
+ },
1338
+ lazyCopy: function () {
1339
+ return Ep.LazyModel.create({
1340
+ id: get(this, 'id'),
1341
+ clientId: get(this, 'clientId'),
1342
+ type: get(this, 'type'),
1343
+ isDeleted: get(this, 'isDeleted'),
1344
+ errors: get(this, 'errors')
1345
+ });
1346
+ },
1347
+ hasErrors: Ember.computed(function () {
1348
+ return !!get(this, 'errors');
1349
+ }).volatile(),
1350
+ isDetached: Ember.computed(function () {
1351
+ return !get(this, 'session');
1352
+ }).volatile(),
1353
+ isManaged: Ember.computed(function () {
1354
+ return !!get(this, 'session');
1355
+ }).volatile()
1356
+ });
1357
+ Ep.Model = Ember.Object.extend(Ember.Copyable, Ep.ModelMixin, {
1358
+ isPromise: false,
1359
+ isProxy: false,
1360
+ isDeleted: false,
1361
+ isLoaded: true,
1362
+ isNew: Ember.computed(function () {
1363
+ return !get(this, 'id');
1364
+ }).property('id'),
1365
+ clientRevision: Ember.computed(function (key, value) {
1366
+ if (arguments.length === 1) {
1367
+ return 0;
1368
+ }
1369
+ return value;
1370
+ }),
1371
+ diff: function (model) {
1372
+ var diffs = [];
1373
+ this.eachAttribute(function (name, meta) {
1374
+ var left = get(this, name);
1375
+ var right = get(model, name);
1376
+ if (left instanceof Date && right instanceof Date) {
1377
+ left = left.getTime();
1378
+ right = right.getTime();
1379
+ }
1380
+ if (left !== right) {
1381
+ diffs.push({
1382
+ type: 'attr',
1383
+ name: name
1384
+ });
1385
+ }
1386
+ }, this);
1387
+ this.eachRelationship(function (name, relationship) {
1388
+ var left = get(this, name);
1389
+ var right = get(model, name);
1390
+ if (relationship.kind === 'belongsTo') {
1391
+ if (left && right) {
1392
+ if (!left.isEqual(right)) {
1393
+ diffs.push({
1394
+ type: 'belongsTo',
1395
+ name: name,
1396
+ relationship: relationship,
1397
+ oldValue: right
1398
+ });
1399
+ }
1400
+ } else if (left || right) {
1401
+ diffs.push({
1402
+ type: 'belongsTo',
1403
+ name: name,
1404
+ relationship: relationship,
1405
+ oldValue: right
1406
+ });
1407
+ }
1408
+ } else if (relationship.kind === 'hasMany') {
1409
+ var dirty = false;
1410
+ var cache = Ep.ModelSet.create();
1411
+ left.forEach(function (model) {
1412
+ cache.add(model);
1413
+ });
1414
+ right.forEach(function (model) {
1415
+ if (dirty)
1416
+ return;
1417
+ if (!cache.contains(model)) {
1418
+ dirty = true;
1419
+ } else {
1420
+ cache.remove(model);
1421
+ }
1422
+ });
1423
+ if (dirty || get(cache, 'length') > 0) {
1424
+ diffs.push({
1425
+ type: 'hasMany',
1426
+ name: name,
1427
+ relationship: relationship
1428
+ });
1429
+ }
1430
+ }
1431
+ }, this);
1432
+ return diffs;
1433
+ },
1434
+ copy: function () {
1435
+ var dest = this.constructor.create();
1436
+ dest.beginPropertyChanges();
1437
+ this.copyAttributes(dest);
1438
+ this.eachRelationship(function (name, relationship) {
1439
+ if (relationship.kind === 'belongsTo') {
1440
+ var child = get(this, name);
1441
+ if (child) {
1442
+ set(dest, name, child.lazyCopy());
1443
+ }
1444
+ } else if (relationship.kind === 'hasMany') {
1445
+ var children = get(this, name);
1446
+ var destChildren = get(dest, name);
1447
+ children.forEach(function (child) {
1448
+ destChildren.addObject(child.lazyCopy());
1449
+ });
1450
+ }
1451
+ }, this);
1452
+ dest.endPropertyChanges();
1453
+ return dest;
1454
+ },
1455
+ copyAttributes: function (dest) {
1456
+ dest.beginPropertyChanges();
1457
+ set(dest, 'id', get(this, 'id'));
1458
+ set(dest, 'clientId', get(this, 'clientId'));
1459
+ set(dest, 'errors', Ember.copy(get(this, 'errors')));
1460
+ set(dest, 'isDeleted', get(this, 'isDeleted'));
1461
+ this.eachAttribute(function (name, meta) {
1462
+ var left = get(this, name);
1463
+ var right = get(dest, name);
1464
+ set(dest, name, left);
1465
+ }, this);
1466
+ dest.endPropertyChanges();
1467
+ }
1468
+ });
1469
+ Ep.Model.reopenClass({
1470
+ find: function (id) {
1471
+ if (!Ep.__container__) {
1472
+ throw new Ember.Error('The Ep.__container__ property must be set in order to use static find methods.');
1473
+ }
1474
+ var container = Ep.__container__;
1475
+ var session = container.lookup('session:main');
1476
+ return session.find(this, id);
1477
+ }
1478
+ });
1479
+ });
1480
+ require.define('/lib/collections/model_set.js', function (module, exports, __dirname, __filename) {
1481
+ var get = Ember.get, set = Ember.set, isNone = Ember.isNone, fmt = Ember.String.fmt;
1482
+ function guidFor(model) {
1483
+ return get(model, 'clientId');
1484
+ }
1485
+ Ep.ModelSet = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Ember.Freezable, {
1486
+ length: 0,
1487
+ clear: function () {
1488
+ if (this.isFrozen) {
1489
+ throw new Error(Ember.FROZEN_ERROR);
1490
+ }
1491
+ var len = get(this, 'length');
1492
+ if (len === 0) {
1493
+ return this;
1494
+ }
1495
+ var guid;
1496
+ this.enumerableContentWillChange(len, 0);
1497
+ Ember.propertyWillChange(this, 'firstObject');
1498
+ Ember.propertyWillChange(this, 'lastObject');
1499
+ for (var i = 0; i < len; i++) {
1500
+ guid = guidFor(this[i]);
1501
+ delete this[guid];
1502
+ delete this[i];
1503
+ }
1504
+ set(this, 'length', 0);
1505
+ Ember.propertyDidChange(this, 'firstObject');
1506
+ Ember.propertyDidChange(this, 'lastObject');
1507
+ this.enumerableContentDidChange(len, 0);
1508
+ return this;
1509
+ },
1510
+ isEqual: function (obj) {
1511
+ if (!Ember.Enumerable.detect(obj))
1512
+ return false;
1513
+ var loc = get(this, 'length');
1514
+ if (get(obj, 'length') !== loc)
1515
+ return false;
1516
+ while (--loc >= 0) {
1517
+ if (!obj.contains(this[loc]))
1518
+ return false;
1519
+ }
1520
+ return true;
1521
+ },
1522
+ add: Ember.aliasMethod('addObject'),
1523
+ remove: Ember.aliasMethod('removeObject'),
1524
+ pop: function () {
1525
+ if (get(this, 'isFrozen'))
1526
+ throw new Error(Ember.FROZEN_ERROR);
1527
+ var obj = this.length > 0 ? this[this.length - 1] : null;
1528
+ this.remove(obj);
1529
+ return obj;
1530
+ },
1531
+ push: Ember.aliasMethod('addObject'),
1532
+ shift: Ember.aliasMethod('pop'),
1533
+ unshift: Ember.aliasMethod('push'),
1534
+ addEach: Ember.aliasMethod('addObjects'),
1535
+ removeEach: Ember.aliasMethod('removeObjects'),
1536
+ init: function (items) {
1537
+ this._super();
1538
+ if (items)
1539
+ this.addObjects(items);
1540
+ },
1541
+ nextObject: function (idx) {
1542
+ return this[idx];
1543
+ },
1544
+ firstObject: Ember.computed(function () {
1545
+ return this.length > 0 ? this[0] : undefined;
1546
+ }),
1547
+ lastObject: Ember.computed(function () {
1548
+ return this.length > 0 ? this[this.length - 1] : undefined;
1549
+ }),
1550
+ addObject: function (obj) {
1551
+ if (get(this, 'isFrozen'))
1552
+ throw new Error(Ember.FROZEN_ERROR);
1553
+ if (isNone(obj))
1554
+ return this;
1555
+ var guid = guidFor(obj), idx = this[guid], len = get(this, 'length'), added;
1556
+ if (idx >= 0 && idx < len && (this[idx] && this[idx].isEqual(obj))) {
1557
+ if (this[idx] !== obj) {
1558
+ this[idx] = obj;
1559
+ }
1560
+ return this;
1561
+ }
1562
+ added = [obj];
1563
+ this.enumerableContentWillChange(null, added);
1564
+ Ember.propertyWillChange(this, 'lastObject');
1565
+ len = get(this, 'length');
1566
+ this[guid] = len;
1567
+ this[len] = obj;
1568
+ set(this, 'length', len + 1);
1569
+ Ember.propertyDidChange(this, 'lastObject');
1570
+ this.enumerableContentDidChange(null, added);
1571
+ return this;
1572
+ },
1573
+ removeObject: function (obj) {
1574
+ if (get(this, 'isFrozen'))
1575
+ throw new Error(Ember.FROZEN_ERROR);
1576
+ if (isNone(obj))
1577
+ return this;
1578
+ var guid = guidFor(obj), idx = this[guid], len = get(this, 'length'), isFirst = idx === 0, isLast = idx === len - 1, last, removed;
1579
+ if (idx >= 0 && idx < len && (this[idx] && this[idx].isEqual(obj))) {
1580
+ removed = [obj];
1581
+ this.enumerableContentWillChange(removed, null);
1582
+ if (isFirst) {
1583
+ Ember.propertyWillChange(this, 'firstObject');
1584
+ }
1585
+ if (isLast) {
1586
+ Ember.propertyWillChange(this, 'lastObject');
1587
+ }
1588
+ if (idx < len - 1) {
1589
+ last = this[len - 1];
1590
+ this[idx] = last;
1591
+ this[guidFor(last)] = idx;
1592
+ }
1593
+ delete this[guid];
1594
+ delete this[len - 1];
1595
+ set(this, 'length', len - 1);
1596
+ if (isFirst) {
1597
+ Ember.propertyDidChange(this, 'firstObject');
1598
+ }
1599
+ if (isLast) {
1600
+ Ember.propertyDidChange(this, 'lastObject');
1601
+ }
1602
+ this.enumerableContentDidChange(removed, null);
1603
+ }
1604
+ return this;
1605
+ },
1606
+ contains: function (obj) {
1607
+ return this[guidFor(obj)] >= 0;
1608
+ },
1609
+ copy: function (deep) {
1610
+ var C = this.constructor, ret = new C(), loc = get(this, 'length');
1611
+ set(ret, 'length', loc);
1612
+ while (--loc >= 0) {
1613
+ ret[loc] = deep ? this[loc].copy() : this[loc];
1614
+ ret[guidFor(this[loc])] = loc;
1615
+ }
1616
+ return ret;
1617
+ },
1618
+ toString: function () {
1619
+ var len = this.length, idx, array = [];
1620
+ for (idx = 0; idx < len; idx++) {
1621
+ array[idx] = this[idx];
1622
+ }
1623
+ return fmt('Ep.ModelSet<%@>', [array.join(',')]);
1624
+ },
1625
+ getModel: function (model) {
1626
+ var idx = this[guidFor(model)];
1627
+ if (idx === undefined)
1628
+ return;
1629
+ return this[idx];
1630
+ },
1631
+ getForClientId: function (clientId) {
1632
+ var idx = this[clientId];
1633
+ if (idx === undefined)
1634
+ return;
1635
+ return this[idx];
1636
+ }
1637
+ });
1638
+ Ep.ModelSet.reopenClass({
1639
+ fromArray: function (models) {
1640
+ var res = this.create();
1641
+ res.addObjects(models);
1642
+ return res;
1643
+ }
1644
+ });
1645
+ });
1646
+ require.define('/lib/model/relationships/belongs_to.js', function (module, exports, __dirname, __filename) {
1647
+ var get = Ember.get, set = Ember.set, isNone = Ember.isNone;
1648
+ Ep.belongsTo = function (type, options) {
1649
+ Ember.assert('The type passed to Ep.belongsTo must be defined', !!type);
1650
+ options = options || {};
1651
+ var meta = {
1652
+ type: type,
1653
+ isRelationship: true,
1654
+ options: options,
1655
+ kind: 'belongsTo'
1656
+ };
1657
+ return Ember.computed(function (key, value) {
1658
+ if (arguments.length === 1) {
1659
+ return null;
1660
+ } else {
1661
+ var session = get(this, 'session');
1662
+ if (value && session) {
1663
+ value = session.add(value);
1664
+ }
1665
+ return value;
1666
+ }
1667
+ }).property().meta(meta);
1668
+ };
1669
+ Ep.Model.reopen({
1670
+ belongsToWillChange: Ember.beforeObserver(function (model, key) {
1671
+ var oldParent = get(model, key);
1672
+ var session = get(model, 'session');
1673
+ if (session) {
1674
+ session.modelWillBecomeDirty(model);
1675
+ }
1676
+ if (oldParent && session) {
1677
+ session.belongsToManager.unregister(model, key, oldParent);
1678
+ }
1679
+ if (oldParent && get(oldParent, 'isLoaded')) {
1680
+ var inverse = get(model, 'type').inverseFor(key);
1681
+ if (inverse) {
1682
+ oldParent.suspendRelationshipObservers(function () {
1683
+ if (inverse.kind === 'hasMany' && model) {
1684
+ get(oldParent, inverse.name).removeObject(model);
1685
+ } else if (inverse.kind === 'belongsTo') {
1686
+ set(oldParent, inverse.name, null);
1687
+ if (session) {
1688
+ session.modelWillBecomeDirty(oldParent);
1689
+ session.belongsToManager.unregister(oldParent, inverse.name, model);
1690
+ }
1691
+ }
1692
+ });
1693
+ }
1694
+ }
1695
+ }),
1696
+ belongsToDidChange: Ember.immediateObserver(function (model, key) {
1697
+ var parent = get(model, key);
1698
+ var session = get(model, 'session');
1699
+ if (parent && session) {
1700
+ session.belongsToManager.register(model, key, parent);
1701
+ }
1702
+ if (parent && get(parent, 'isLoaded')) {
1703
+ var inverse = get(model, 'type').inverseFor(key);
1704
+ if (inverse) {
1705
+ parent.suspendRelationshipObservers(function () {
1706
+ if (inverse.kind === 'hasMany' && model) {
1707
+ get(parent, inverse.name).addObject(model);
1708
+ } else if (inverse.kind === 'belongsTo') {
1709
+ set(parent, inverse.name, model);
1710
+ if (session)
1711
+ session.belongsToManager.register(parent, inverse.name, model);
1712
+ }
1713
+ });
1714
+ }
1715
+ }
1716
+ })
1717
+ });
1718
+ });
1719
+ require.define('/lib/model/attribute.js', function (module, exports, __dirname, __filename) {
1720
+ var get = Ember.get, set = Ember.set;
1721
+ Ep.Model.reopenClass({
1722
+ attributes: Ember.computed(function () {
1723
+ var map = Ember.Map.create();
1724
+ this.eachComputedProperty(function (name, meta) {
1725
+ if (meta.isAttribute) {
1726
+ Ember.assert('You may not set `id` as an attribute on your model. Please remove any lines that look like: `id: Ep.attr(\'<type>\')` from ' + this.toString(), name !== 'id');
1727
+ meta.name = name;
1728
+ map.set(name, meta);
1729
+ }
1730
+ });
1731
+ return map;
1732
+ })
1733
+ });
1734
+ Ep.Model.reopen({
1735
+ eachAttribute: function (callback, binding) {
1736
+ get(this.constructor, 'attributes').forEach(function (name, meta) {
1737
+ callback.call(binding, name, meta);
1738
+ }, binding);
1739
+ },
1740
+ attributeWillChange: Ember.beforeObserver(function (record, key) {
1741
+ var session = get(this, 'session');
1742
+ if (!session)
1743
+ return;
1744
+ session.modelWillBecomeDirty(this);
1745
+ })
1746
+ });
1747
+ Ep.attr = function (type, options) {
1748
+ options = options || {};
1749
+ var meta = {
1750
+ type: type,
1751
+ isAttribute: true,
1752
+ options: options
1753
+ };
1754
+ return Ember.computed(function (key, value, oldValue) {
1755
+ if (arguments.length > 1) {
1756
+ Ember.assert('You may not set `id` as an attribute on your model. Please remove any lines that look like: `id: Ep.attr(\'<type>\')` from ' + this.constructor.toString(), key !== 'id');
1757
+ }
1758
+ return value;
1759
+ }).meta(meta);
1760
+ };
1761
+ });
1762
+ require.define('/lib/model/proxies.js', function (module, exports, __dirname, __filename) {
1763
+ var get = Ember.get, set = Ember.set;
1764
+ function triggerLoad(async) {
1765
+ return function () {
1766
+ if (!get(this, 'content') && !get(this, 'isLoading')) {
1767
+ if (async) {
1768
+ Ember.run.later(this, 'load', 0);
1769
+ } else {
1770
+ this.load();
1771
+ }
1772
+ }
1773
+ return this._super.apply(this, arguments);
1774
+ };
1775
+ }
1776
+ function passThrough(key, defaultValue) {
1777
+ return Ember.computed(function (key, value) {
1778
+ var content = get(this, 'content');
1779
+ if (arguments.length === 1) {
1780
+ if (content) {
1781
+ return get(content, key);
1782
+ } else {
1783
+ return defaultValue;
1784
+ }
1785
+ }
1786
+ if (content) {
1787
+ return set(content, key, value);
1788
+ }
1789
+ return value;
1790
+ }).property('content.' + key);
1791
+ }
1792
+ function passThroughMethod(name, defaultReturn) {
1793
+ return function () {
1794
+ var content = get(this, 'content');
1795
+ if (!content)
1796
+ return defaultReturn;
1797
+ return content[name].apply(content, arguments);
1798
+ };
1799
+ }
1800
+ Ep.ModelProxy = Ember.ObjectProxy.extend(Ember.Copyable, Ep.ModelMixin, {
1801
+ id: passThrough('id'),
1802
+ clientId: passThrough('clientId'),
1803
+ type: passThrough('type'),
1804
+ isPromise: false,
1805
+ isLoaded: passThrough('isLoaded', false),
1806
+ isLoading: false,
1807
+ isDeleted: passThrough('isDeleted', false),
1808
+ isNew: passThrough('isNew', false),
1809
+ isProxy: true,
1810
+ errors: passThrough('errors'),
1811
+ copy: function () {
1812
+ var content = get(this, 'content');
1813
+ if (content) {
1814
+ return content.copy();
1815
+ }
1816
+ return this.lazyCopy();
1817
+ }
1818
+ });
1819
+ Ep.LoadError = Ep.ModelProxy.extend({});
1820
+ Ep.ModelPromise = Ep.ModelProxy.extend(Ember.DeferredMixin, {
1821
+ isPromise: true,
1822
+ isNew: false,
1823
+ resolve: function (model) {
1824
+ set(this, 'content', model);
1825
+ return this._super.apply(this, arguments);
1826
+ },
1827
+ hasIdentifiers: Ember.computed(function () {
1828
+ return get(this, 'type') && (get(this, 'id') || get(this, 'clientId'));
1829
+ }).volatile(),
1830
+ toStringExtension: function () {
1831
+ var content = get(this, 'content');
1832
+ if (content) {
1833
+ return content.toString();
1834
+ } else if (get(this, 'hasIdentifiers')) {
1835
+ var type = get(this, 'type');
1836
+ return '(unloaded ' + type.toString() + '):' + this._super();
1837
+ } else {
1838
+ return '(no identifiers)';
1839
+ }
1840
+ },
1841
+ diff: passThroughMethod('diff', []),
1842
+ suspendRelationshipObservers: passThroughMethod('suspendRelationshipObservers'),
1843
+ eachAttribute: passThroughMethod('eachAttribute'),
1844
+ eachRelationship: passThroughMethod('eachRelationship'),
1845
+ _registerRelationships: passThroughMethod('_registerRelationships')
1846
+ });
1847
+ Ep.LazyModel = Ep.ModelPromise.extend({
1848
+ willWatchProperty: triggerLoad(true),
1849
+ unknownProperty: triggerLoad(),
1850
+ setUnknownProperty: triggerLoad(),
1851
+ then: triggerLoad(true),
1852
+ resolve: function () {
1853
+ set(this, 'isLoading', false);
1854
+ return this._super.apply(this, arguments);
1855
+ },
1856
+ load: function () {
1857
+ if (get(this, 'isLoading'))
1858
+ return this;
1859
+ var session = get(this, 'session');
1860
+ var type = get(this, 'type');
1861
+ var id = get(this, 'id');
1862
+ set(this, 'isLoading', true);
1863
+ Ember.assert('Must be attached to a session.', get(this, 'session'));
1864
+ Ember.assert('Must have an id to load.', id);
1865
+ var promise = this.session.load(type, id);
1866
+ if (get(promise, 'isLoaded')) {
1867
+ this.resolve(Ep.unwrap(promise));
1868
+ } else {
1869
+ var proxy = this;
1870
+ promise.then(function (model) {
1871
+ proxy.resolve(model);
1872
+ return model;
1873
+ }, function (err) {
1874
+ proxy.reject(err);
1875
+ return err;
1876
+ });
1877
+ }
1878
+ return this;
1879
+ }
1880
+ });
1881
+ Ep.unwrap = function (modelOrPromise) {
1882
+ if (get(modelOrPromise, 'isProxy')) {
1883
+ return get(modelOrPromise, 'content');
1884
+ }
1885
+ return modelOrPromise;
1886
+ };
1887
+ Ep.resolveModel = function (modelOrPromise, type, id, session) {
1888
+ if (modelOrPromise instanceof Ep.ModelPromise) {
1889
+ return modelOrPromise;
1890
+ }
1891
+ id = get(modelOrPromise, 'id') || id;
1892
+ var clientId = get(modelOrPromise, 'clientId');
1893
+ type = get(modelOrPromise, 'type') || type;
1894
+ session = get(modelOrPromise, 'session') || session;
1895
+ var promise = Ep.ModelPromise.create({
1896
+ id: id,
1897
+ clientId: clientId,
1898
+ type: type,
1899
+ session: session
1900
+ });
1901
+ if (typeof modelOrPromise.then !== 'function') {
1902
+ promise.resolve(modelOrPromise);
1903
+ } else {
1904
+ modelOrPromise.then(function (model) {
1905
+ promise.resolve(model);
1906
+ return model;
1907
+ }, function (err) {
1908
+ promise.reject(err);
1909
+ throw err;
1910
+ });
1911
+ }
1912
+ return promise;
1913
+ };
1914
+ });
1915
+ require.define('/lib/rest/rest_adapter.js', function (module, exports, __dirname, __filename) {
1916
+ require('/lib/adapter.js', module);
1917
+ require('/lib/rest/embedded_manager.js', module);
1918
+ require('/lib/rest/operation_graph.js', module);
1919
+ require('/lib/rest/rest_errors.js', module);
1920
+ var get = Ember.get, set = Ember.set;
1921
+ Ep.RestAdapter = Ep.Adapter.extend({
1922
+ init: function () {
1923
+ this._super.apply(this, arguments);
1924
+ this._embeddedManager = Ep.EmbeddedManager.create({ adapter: this });
1925
+ this._pendingOps = {};
1926
+ },
1927
+ load: function (type, id) {
1928
+ var root = this.rootForType(type), adapter = this;
1929
+ return this.ajax(this.buildURL(root, id), 'GET').then(function (json) {
1930
+ return Ember.run(adapter, 'didReceiveDataForLoad', json, type, id);
1931
+ }, function (xhr) {
1932
+ var model = Ep.LoadError.create({
1933
+ id: id,
1934
+ type: type
1935
+ });
1936
+ throw Ember.run(adapter, 'didError', xhr, model);
1937
+ });
1938
+ },
1939
+ refresh: function (model) {
1940
+ var type = get(model, 'type');
1941
+ var root = this.rootForType(type), adapter = this;
1942
+ var id = get(model, 'id');
1943
+ return this.ajax(this.buildURL(root, id), 'GET').then(function (json) {
1944
+ return Ember.run(adapter, 'didReceiveData', json, model);
1945
+ }, function (xhr) {
1946
+ throw Ember.run(adapter, 'didError', xhr, model);
1947
+ });
1948
+ },
1949
+ update: function (model) {
1950
+ var id, root, adapter, data, type = get(model, 'type');
1951
+ id = get(model, 'id');
1952
+ root = this.rootForType(type);
1953
+ adapter = this;
1954
+ data = {};
1955
+ data[root] = get(this, 'serializer').serialize(model);
1956
+ return this.ajax(this.buildURL(root, id), 'PUT', { data: data }).then(function (json) {
1957
+ return Ember.run(adapter, 'didReceiveData', json, model);
1958
+ }, function (xhr) {
1959
+ throw Ember.run(adapter, 'didError', xhr, model);
1960
+ });
1961
+ },
1962
+ create: function (model) {
1963
+ var type = get(model, 'type');
1964
+ var root = this.rootForType(type);
1965
+ var adapter = this;
1966
+ var data = {};
1967
+ data[root] = get(this, 'serializer').serialize(model, { includeId: true });
1968
+ return this.ajax(this.buildURL(root), 'POST', { data: data }).then(function (json) {
1969
+ return Ember.run(adapter, 'didReceiveDataForCreate', json, model);
1970
+ }, function (xhr) {
1971
+ throw Ember.run(adapter, 'didError', xhr, model);
1972
+ });
1973
+ },
1974
+ deleteModel: function (model) {
1975
+ var id, root, adapter, type = get(model, 'type');
1976
+ id = get(model, 'id');
1977
+ root = this.rootForType(type);
1978
+ adapter = this;
1979
+ return this.ajax(this.buildURL(root, id), 'DELETE').then(function (json) {
1980
+ return Ember.run(adapter, 'didReceiveData', json, model);
1981
+ }, function (xhr) {
1982
+ throw Ember.run(adapter, 'didError', xhr, model);
1983
+ });
1984
+ },
1985
+ query: function (type, query) {
1986
+ var root = this.rootForType(type), adapter = this;
1987
+ return this.ajax(this.buildURL(root), 'GET', { data: query }).then(function (json) {
1988
+ return Ember.run(adapter, 'didReceiveDataForFind', json, type);
1989
+ }, function (xhr) {
1990
+ throw xhr;
1991
+ });
1992
+ },
1993
+ remoteCall: function (context, name, params) {
1994
+ var url, adapter = this;
1995
+ if (typeof context === 'string') {
1996
+ context = this.lookupType(context);
1997
+ }
1998
+ if (typeof context === 'function') {
1999
+ url = this.buildURL(this.rootForType(context));
2000
+ } else {
2001
+ var id = get(context, 'id');
2002
+ Ember.assert('Cannot perform a remote call with a context that doesn\'t have an id', id);
2003
+ url = this.buildURL(this.rootForType(context.constructor), id);
2004
+ }
2005
+ url = url + '/' + name;
2006
+ var data = params;
2007
+ var method = 'POST';
2008
+ return this.ajax(url, method, { data: data }).then(function (json) {
2009
+ return Ember.run(adapter, 'didReceiveDataForRpc', json, context);
2010
+ }, function (xhr) {
2011
+ throw Ember.run(adapter, 'didError', xhr, context);
2012
+ });
2013
+ },
2014
+ lookupType: function (type) {
2015
+ return this.container.lookup('model:' + type);
2016
+ },
2017
+ didReceiveData: function (data, targetModel) {
2018
+ var result = null;
2019
+ this.processData(data, function (model) {
2020
+ if (targetModel && model.isEqual(targetModel)) {
2021
+ result = model;
2022
+ }
2023
+ });
2024
+ return result || targetModel;
2025
+ },
2026
+ didReceiveDataForCreate: function (data, targetModel) {
2027
+ var result = null;
2028
+ this.processData(data, function (model) {
2029
+ if (targetModel && model.isEqual(targetModel)) {
2030
+ result = model;
2031
+ }
2032
+ });
2033
+ set(targetModel, 'id', get(result, 'id'));
2034
+ return result;
2035
+ },
2036
+ didReceiveDataForLoad: function (data, type, id) {
2037
+ var result = null;
2038
+ this.processData(data, function (model) {
2039
+ if (model.hasType(type) && get(model, 'id') === id) {
2040
+ result = model;
2041
+ }
2042
+ });
2043
+ return result;
2044
+ },
2045
+ didReceiveDataForFind: function (data, type) {
2046
+ var result = [];
2047
+ this.processData(data, function (model) {
2048
+ if (model.hasType(type)) {
2049
+ result.pushObject(model);
2050
+ }
2051
+ });
2052
+ return Ep.ModelArray.create({ content: result });
2053
+ },
2054
+ didReceiveDataForRpc: function (data, context) {
2055
+ return this.didReceiveData(data, context);
2056
+ },
2057
+ processData: function (data, callback, binding) {
2058
+ var models = get(this, 'serializer').deserialize(data);
2059
+ models.forEach(function (model) {
2060
+ this.willLoadModel(model);
2061
+ }, this);
2062
+ models.forEach(function (model) {
2063
+ this.didLoadModel(model);
2064
+ callback.call(binding || this, model);
2065
+ }, this);
2066
+ this.materializeRelationships(models);
2067
+ },
2068
+ willLoadModel: function (model) {
2069
+ model.eachRelatedModel(function (relative) {
2070
+ if (get(relative, 'clientId')) {
2071
+ this.reifyClientId(model);
2072
+ }
2073
+ }, this);
2074
+ },
2075
+ didLoadModel: function (model) {
2076
+ model.eachRelatedModel(function (relative) {
2077
+ this.reifyClientId(relative);
2078
+ }, this);
2079
+ this._embeddedManager.updateParents(model);
2080
+ },
2081
+ didError: function (xhr, model) {
2082
+ var errors;
2083
+ if (xhr.status === 422) {
2084
+ var json = JSON.parse(xhr.responseText), serializer = get(this, 'serializer'), validationErrors = serializer.extractValidationErrors(get(model, 'type'), json);
2085
+ errors = Ep.RestErrors.create({ content: validationErrors });
2086
+ } else {
2087
+ errors = Ep.RestErrors.create();
2088
+ }
2089
+ set(errors, 'status', xhr.status);
2090
+ set(errors, 'xhr', xhr);
2091
+ set(model, 'errors', errors);
2092
+ throw model;
2093
+ },
2094
+ flush: function (session) {
2095
+ var models = get(session, 'dirtyModels').copy(true);
2096
+ var shadows = Ep.ModelSet.fromArray(models.map(function (model) {
2097
+ return session.shadows.getModel(model);
2098
+ }));
2099
+ this.dirtyEmbedded(models, shadows, session);
2100
+ this.materializeRelationships(models);
2101
+ var op = Ep.OperationGraph.create({
2102
+ models: models,
2103
+ shadows: shadows,
2104
+ adapter: this
2105
+ });
2106
+ return this._performFlush(op);
2107
+ },
2108
+ _performFlush: function (op) {
2109
+ var models = get(op, 'models'), pending = Ember.Set.create();
2110
+ models.forEach(function (model) {
2111
+ var op = this._pendingOps[model.clientId];
2112
+ if (op)
2113
+ pending.add(op);
2114
+ }, this);
2115
+ var adapter = this;
2116
+ if (get(pending, 'length') > 0) {
2117
+ return Ember.RSVP.all(pending.toArray()).then(function () {
2118
+ return adapter._performFlush(op);
2119
+ });
2120
+ }
2121
+ var promise = op.perform();
2122
+ models.forEach(function (model) {
2123
+ this._pendingOps[model.clientId] = promise;
2124
+ }, this);
2125
+ return promise.then(function (res) {
2126
+ models.forEach(function (model) {
2127
+ delete adapter._pendingOps[model.clientId];
2128
+ });
2129
+ return res;
2130
+ }, function (err) {
2131
+ models.forEach(function (model) {
2132
+ delete adapter._pendingOps[model.clientId];
2133
+ });
2134
+ throw err;
2135
+ });
2136
+ },
2137
+ rebuildRelationships: function (children, parent) {
2138
+ var serializer = get(this, 'serializer');
2139
+ parent.suspendRelationshipObservers(function () {
2140
+ for (var i = 0; i < children.length; i++) {
2141
+ var child = children[i];
2142
+ child.eachRelationship(function (name, relationship) {
2143
+ if (relationship.kind === 'belongsTo') {
2144
+ var value = get(child, name);
2145
+ var inverse = child.constructor.inverseFor(name);
2146
+ if (inverse) {
2147
+ if (serializer.embeddedType(inverse.type, inverse.name)) {
2148
+ return;
2149
+ }
2150
+ if (inverse.kind === 'hasMany') {
2151
+ var parentCollection = get(parent, inverse.name);
2152
+ if (child.get('isDeleted')) {
2153
+ parentCollection.removeObject(child);
2154
+ } else if (value && value.isEqual(parent)) {
2155
+ parentCollection.addObject(child);
2156
+ }
2157
+ }
2158
+ }
2159
+ }
2160
+ });
2161
+ }
2162
+ });
2163
+ },
2164
+ isRelationshipOwner: function (relationship) {
2165
+ var serializer = get(this, 'serializer');
2166
+ var owner = serializer.mappingOption(relationship.parentType, relationship.key, 'owner');
2167
+ return relationship.kind === 'belongsTo' && owner !== false || relationship.kind === 'hasMany' && owner === true;
2168
+ },
2169
+ isDirtyFromRelationships: function (model, cached, relDiff) {
2170
+ var serializer = get(this, 'serializer');
2171
+ for (var i = 0; i < relDiff.length; i++) {
2172
+ var diff = relDiff[i];
2173
+ if (this.isRelationshipOwner(diff.relationship) || serializer.embeddedType(model.constructor, diff.name) === 'always') {
2174
+ return true;
2175
+ }
2176
+ }
2177
+ return false;
2178
+ },
2179
+ shouldSave: function (model) {
2180
+ return !this.isEmbedded(model);
2181
+ },
2182
+ isEmbedded: function (model) {
2183
+ return this._embeddedManager.isEmbedded(model);
2184
+ },
2185
+ dirtyEmbedded: function (models, shadows, session) {
2186
+ this.dirtyEmbeddedParents(models, shadows, session);
2187
+ models.forEach(function (model) {
2188
+ this.dirtyEmbeddedTree(model, models, shadows, session);
2189
+ }, this);
2190
+ },
2191
+ dirtyEmbeddedParents: function (models, shadows, session) {
2192
+ models.forEach(function (model) {
2193
+ var parent;
2194
+ while (parent = this._embeddedManager.findParent(model)) {
2195
+ model = session.getModel(parent);
2196
+ if (!models.contains(model)) {
2197
+ var copy = model.copy();
2198
+ models.add(copy);
2199
+ shadows.add(copy);
2200
+ }
2201
+ }
2202
+ }, this);
2203
+ },
2204
+ dirtyEmbeddedTree: function (model, models, shadows, session) {
2205
+ get(this, 'serializer').eachEmbeddedRecord(model, function (embeddedRecord, embeddedType) {
2206
+ if (embeddedType !== 'always') {
2207
+ return;
2208
+ }
2209
+ if (models.contains(embeddedRecord)) {
2210
+ return;
2211
+ }
2212
+ embeddedRecord = session.getModel(embeddedRecord);
2213
+ if (!embeddedRecord)
2214
+ return;
2215
+ if (!models.contains(embeddedRecord)) {
2216
+ var copy = embeddedRecord.copy();
2217
+ models.add(copy);
2218
+ shadows.add(copy);
2219
+ }
2220
+ this.dirtyEmbeddedTree(embeddedRecord, models, shadows, session);
2221
+ }, this);
2222
+ },
2223
+ findEmbeddedRoot: function (model, models) {
2224
+ var parent = model;
2225
+ while (parent) {
2226
+ model = parent;
2227
+ parent = this._embeddedManager.findParent(model);
2228
+ }
2229
+ return models.getModel(model);
2230
+ },
2231
+ materializeRelationships: function (models) {
2232
+ if (!(models instanceof Ep.ModelSet)) {
2233
+ models = Ep.ModelSet.fromArray(models);
2234
+ }
2235
+ models.forEach(function (model) {
2236
+ model.eachRelationship(function (name, relationship) {
2237
+ if (relationship.kind === 'belongsTo') {
2238
+ var child = get(model, name);
2239
+ if (child) {
2240
+ child = models.getModel(child) || child;
2241
+ set(model, name, child);
2242
+ }
2243
+ } else if (relationship.kind === 'hasMany') {
2244
+ var children = get(model, name);
2245
+ var lazyChildren = Ep.ModelSet.create();
2246
+ lazyChildren.addObjects(children);
2247
+ children.clear();
2248
+ lazyChildren.forEach(function (child) {
2249
+ child = models.getModel(child) || child;
2250
+ children.addObject(child);
2251
+ });
2252
+ }
2253
+ }, this);
2254
+ }, this);
2255
+ },
2256
+ ajax: function (url, type, hash) {
2257
+ try {
2258
+ hash = hash || {};
2259
+ hash.url = url;
2260
+ hash.type = type;
2261
+ hash.dataType = 'json';
2262
+ hash.context = this;
2263
+ if (hash.data && type !== 'GET') {
2264
+ hash.contentType = 'application/json; charset=utf-8';
2265
+ hash.data = JSON.stringify(hash.data);
2266
+ }
2267
+ return Ember.RSVP.resolve(jQuery.ajax(hash));
2268
+ } catch (error) {
2269
+ return Ember.RSVP.resolve(error);
2270
+ }
2271
+ },
2272
+ url: '',
2273
+ rootForType: function (type) {
2274
+ var serializer = get(this, 'serializer');
2275
+ return serializer.rootForType(type);
2276
+ },
2277
+ pluralize: function (string) {
2278
+ var serializer = get(this, 'serializer');
2279
+ return serializer.pluralize(string);
2280
+ },
2281
+ buildURL: function (record, suffix) {
2282
+ var url = [this.url];
2283
+ Ember.assert('Namespace URL (' + this.namespace + ') must not start with slash', !this.namespace || this.namespace.toString().charAt(0) !== '/');
2284
+ Ember.assert('Record URL (' + record + ') must not start with slash', !record || record.toString().charAt(0) !== '/');
2285
+ Ember.assert('URL suffix (' + suffix + ') must not start with slash', !suffix || suffix.toString().charAt(0) !== '/');
2286
+ if (!Ember.isNone(this.namespace)) {
2287
+ url.push(this.namespace);
2288
+ }
2289
+ url.push(this.pluralize(record));
2290
+ if (suffix !== undefined) {
2291
+ url.push(suffix);
2292
+ }
2293
+ return url.join('/');
2294
+ }
2295
+ });
2296
+ });
2297
+ require.define('/lib/rest/rest_errors.js', function (module, exports, __dirname, __filename) {
2298
+ var get = Ember.get, set = Ember.set;
2299
+ Ep.RestErrors = Ep.Errors.extend({
2300
+ status: null,
2301
+ xhr: null,
2302
+ copy: function () {
2303
+ return Ep.RestErrors.create({
2304
+ content: Ember.copy(this.content),
2305
+ status: this.status,
2306
+ xhr: this.xhr
2307
+ });
2308
+ }
2309
+ });
2310
+ });
2311
+ require.define('/lib/rest/operation_graph.js', function (module, exports, __dirname, __filename) {
2312
+ require('/lib/rest/operation.js', module);
2313
+ var get = Ember.get, set = Ember.set;
2314
+ var Node = function (model) {
2315
+ this.op = null;
2316
+ this.children = Ember.Set.create();
2317
+ this.parents = Ember.Set.create();
2318
+ this.dirty = false;
2319
+ this.dirtyEmbeddedChildren = false;
2320
+ };
2321
+ Node.prototype = {
2322
+ addChild: function (childNode) {
2323
+ this.children.add(childNode);
2324
+ childNode.parents.add(this);
2325
+ },
2326
+ isRoot: function () {
2327
+ return this.parents.every(function (parent) {
2328
+ return !get(parent, 'dirty') && parent.isRoot();
2329
+ });
2330
+ },
2331
+ toString: function (depth) {
2332
+ if (!depth)
2333
+ depth = 0;
2334
+ var prefix = '';
2335
+ for (var i = 0; i < depth; i++) {
2336
+ prefix += ' ';
2337
+ }
2338
+ return prefix + this.op.toString() + this.children.map(function (child) {
2339
+ return '\n' + child.toString(depth + 1);
2340
+ });
2341
+ }
2342
+ };
2343
+ Ep.OperationGraph = Ember.Object.extend({
2344
+ models: null,
2345
+ shadows: null,
2346
+ rootNodes: null,
2347
+ adapter: null,
2348
+ nodes: null,
2349
+ init: function () {
2350
+ this.nodes = Ember.MapWithDefault.create({
2351
+ defaultValue: function (model) {
2352
+ return new Node(model);
2353
+ }
2354
+ });
2355
+ this.rootNodes = Ember.Set.create();
2356
+ this.build();
2357
+ },
2358
+ perform: function () {
2359
+ return this.createPromise();
2360
+ },
2361
+ build: function () {
2362
+ var adapter = get(this, 'adapter');
2363
+ var models = get(this, 'models');
2364
+ var shadows = get(this, 'shadows');
2365
+ var rootNodes = get(this, 'rootNodes');
2366
+ var nodes = get(this, 'nodes');
2367
+ models.forEach(function (model) {
2368
+ if (!get(model, 'isLoaded')) {
2369
+ return;
2370
+ }
2371
+ var shadow = shadows.getModel(model);
2372
+ var node = nodes.get(model);
2373
+ node.op = Ep.Operation.create({
2374
+ model: model,
2375
+ shadow: shadow,
2376
+ graph: this,
2377
+ adapter: adapter
2378
+ });
2379
+ node.dirty = node.dirty || !!get(node.op, 'dirtyType');
2380
+ if (node.dirty && adapter.isEmbedded(model) && !get(model, 'isNew')) {
2381
+ var root = adapter.findEmbeddedRoot(model, models);
2382
+ var rootNode = nodes.get(root);
2383
+ rootNode.dirty = true;
2384
+ rootNode.dirtyEmbeddedChildren = true;
2385
+ }
2386
+ var rels = get(node.op, 'dirtyRelationships');
2387
+ for (var i = 0; i < rels.length; i++) {
2388
+ var d = rels[i];
2389
+ var name = d.name;
2390
+ var parentModel = model.get(name) || shadows.getModel(d.oldValue);
2391
+ if (parentModel) {
2392
+ parentModel = models.getModel(parentModel);
2393
+ var parentNode = nodes.get(parentModel);
2394
+ parentNode.addChild(node);
2395
+ }
2396
+ }
2397
+ }, this);
2398
+ nodes.forEach(function (model, node) {
2399
+ if (node.dirty && node.isRoot()) {
2400
+ rootNodes.add(node);
2401
+ }
2402
+ }, this);
2403
+ },
2404
+ createPromise: function () {
2405
+ var rootNodes = get(this, 'rootNodes'), adapter = get(this, 'adapter'), cumulative = [];
2406
+ function createNestedPromise(node) {
2407
+ var promise = node.op.perform(node.dirtyEmbeddedChildren);
2408
+ promise = promise.then(function (model) {
2409
+ if (model === get(node.op, 'model')) {
2410
+ cumulative.push(model.lazyCopy());
2411
+ } else {
2412
+ cumulative.push(model);
2413
+ }
2414
+ return model;
2415
+ }, function (model) {
2416
+ cumulative.push(model);
2417
+ throw model;
2418
+ });
2419
+ if (node.children.length > 0) {
2420
+ promise = promise.then(function (model) {
2421
+ var childPromises = node.children.map(createNestedPromise);
2422
+ return Ember.RSVP.all(childPromises).then(function (models) {
2423
+ adapter.rebuildRelationships(models, model);
2424
+ return model;
2425
+ });
2426
+ });
2427
+ }
2428
+ return promise;
2429
+ }
2430
+ return Ember.RSVP.all(rootNodes.map(createNestedPromise)).then(function () {
2431
+ return cumulative;
2432
+ }, function (err) {
2433
+ throw cumulative;
2434
+ });
2435
+ },
2436
+ toStringExtension: function () {
2437
+ var result = '';
2438
+ var rootNodes = get(this, 'rootNodes');
2439
+ rootNodes.forEach(function (node) {
2440
+ result += '\n' + node.toString(1);
2441
+ });
2442
+ return result + '\n';
2443
+ }
2444
+ });
2445
+ });
2446
+ require.define('/lib/rest/operation.js', function (module, exports, __dirname, __filename) {
2447
+ var get = Ember.get, set = Ember.set;
2448
+ Ep.Operation = Ember.Object.extend({
2449
+ model: null,
2450
+ shadow: null,
2451
+ adapter: null,
2452
+ init: function () {
2453
+ this.children = Ember.Set.create();
2454
+ this.parents = Ember.Set.create();
2455
+ },
2456
+ dirtyRelationships: Ember.computed(function () {
2457
+ var adapter = get(this, 'adapter'), model = get(this, 'model'), rels = [], shadow = get(this, 'shadow');
2458
+ if (get(model, 'isNew')) {
2459
+ model.eachRelationship(function (name, relationship) {
2460
+ if (adapter.isRelationshipOwner(relationship)) {
2461
+ rels.push({
2462
+ name: name,
2463
+ type: relationship.kind,
2464
+ relationship: relationship,
2465
+ oldValue: null
2466
+ });
2467
+ }
2468
+ }, this);
2469
+ } else {
2470
+ var diff = model.diff(shadow);
2471
+ for (var i = 0; i < diff.length; i++) {
2472
+ var d = diff[i];
2473
+ if (d.relationship && adapter.isRelationshipOwner(d.relationship)) {
2474
+ rels.push(d);
2475
+ }
2476
+ }
2477
+ }
2478
+ return rels;
2479
+ }),
2480
+ isDirty: Ember.computed(function () {
2481
+ var model = get(this, 'model'), shadow = get(this, 'shadow'), adapter = get(this, 'adapter');
2482
+ var diff = model.diff(shadow);
2483
+ var dirty = false;
2484
+ var relDiff = [];
2485
+ for (var i = 0; i < diff.length; i++) {
2486
+ var d = diff[i];
2487
+ if (d.type == 'attr') {
2488
+ dirty = true;
2489
+ } else {
2490
+ relDiff.push(d);
2491
+ }
2492
+ }
2493
+ return dirty || adapter.isDirtyFromRelationships(model, shadow, relDiff);
2494
+ }),
2495
+ dirtyType: Ember.computed(function () {
2496
+ var model = get(this, 'model');
2497
+ if (get(model, 'isNew')) {
2498
+ return 'created';
2499
+ } else if (get(model, 'isDeleted')) {
2500
+ return 'deleted';
2501
+ } else if (get(this, 'isDirty')) {
2502
+ return 'updated';
2503
+ }
2504
+ }),
2505
+ perform: function (forceUpdate) {
2506
+ var adapter = get(this, 'adapter'), dirtyType = get(this, 'dirtyType'), model = get(this, 'model'), shadow = get(this, 'shadow'), promise;
2507
+ if (!dirtyType && forceUpdate) {
2508
+ dirtyType = 'updated';
2509
+ }
2510
+ if (!dirtyType || !adapter.shouldSave(model)) {
2511
+ promise = Ember.RSVP.resolve(model);
2512
+ } else if (dirtyType === 'created') {
2513
+ promise = adapter.create(model);
2514
+ } else if (dirtyType === 'updated') {
2515
+ promise = adapter.update(model);
2516
+ } else if (dirtyType === 'deleted') {
2517
+ promise = adapter.deleteModel(model);
2518
+ }
2519
+ return promise.then(null, function (model) {
2520
+ if (shadow) {
2521
+ shadow.set('errors', model.get('errors'));
2522
+ throw shadow;
2523
+ }
2524
+ throw model;
2525
+ });
2526
+ },
2527
+ toStringExtension: function () {
2528
+ return '( ' + get(this, 'dirtyType') + ' ' + get(this, 'model') + ' )';
2529
+ }
2530
+ });
2531
+ });
2532
+ require.define('/lib/rest/embedded_manager.js', function (module, exports, __dirname, __filename) {
2533
+ var get = Ember.get, set = Ember.set;
2534
+ Ep.EmbeddedManager = Ember.Object.extend({
2535
+ adapter: null,
2536
+ init: function () {
2537
+ this._super.apply(this, arguments);
2538
+ this._parentMap = {};
2539
+ this._cachedIsEmbedded = Ember.Map.create();
2540
+ },
2541
+ updateParents: function (model) {
2542
+ var serializer = get(this, 'adapter.serializer');
2543
+ var parentType = get(model, 'type');
2544
+ serializer.eachEmbeddedRecord(model, function (embedded, kind) {
2545
+ this._parentMap[get(embedded, 'clientId')] = model;
2546
+ }, this);
2547
+ },
2548
+ findParent: function (model) {
2549
+ var parent = this._parentMap[get(model, 'clientId')];
2550
+ return parent;
2551
+ },
2552
+ isEmbedded: function (model) {
2553
+ var type = get(model, 'type');
2554
+ var result = this._cachedIsEmbedded.get(type);
2555
+ if (result === true || result === false)
2556
+ return result;
2557
+ var adapter = get(this, 'adapter');
2558
+ var mappings = get(adapter, 'serializer.mappings');
2559
+ var result = false;
2560
+ mappings.forEach(function (parentType, value) {
2561
+ for (var name in value) {
2562
+ var embedded = value[name]['embedded'];
2563
+ result = result || embedded === 'always' && parentType.typeForRelationship(name).detect(type);
2564
+ }
2565
+ });
2566
+ this._cachedIsEmbedded.set(type, result);
2567
+ return result;
2568
+ }
2569
+ });
2570
+ });
2571
+ require.define('/lib/adapter.js', function (module, exports, __dirname, __filename) {
2572
+ var get = Ember.get, set = Ember.set, merge = Ember.merge;
2573
+ require('/lib/mixins/mappable.js', module);
2574
+ function mustImplement(name) {
2575
+ return function () {
2576
+ throw new Ember.Error('Your serializer ' + this.toString() + ' does not implement the required method ' + name);
2577
+ };
2578
+ }
2579
+ var uuid = 1;
2580
+ Ep.Adapter = Ember.Object.extend(Ep._Mappable, {
2581
+ init: function () {
2582
+ this._super.apply(this, arguments);
2583
+ this.idMaps = Ember.MapWithDefault.create({
2584
+ defaultValue: function (type) {
2585
+ return Ember.Map.create();
2586
+ }
2587
+ });
2588
+ },
2589
+ newSession: function () {
2590
+ var session = this.container.lookup('session:base');
2591
+ set(session, 'adapter', this);
2592
+ return session;
2593
+ },
2594
+ serializer: Ember.computed(function (key, serializer) {
2595
+ this._attributesMap = this.createInstanceMapFor('attributes');
2596
+ this._configurationsMap = this.createInstanceMapFor('configurations');
2597
+ this.registerSerializerTransforms(this.constructor, serializer, {});
2598
+ this.registerSerializerMappings(serializer);
2599
+ return serializer;
2600
+ }),
2601
+ load: mustImplement('load'),
2602
+ query: mustImplement('find'),
2603
+ refresh: mustImplement('refresh'),
2604
+ flush: mustImplement('flush'),
2605
+ remoteCall: mustImplement('remoteCall'),
2606
+ isDirtyFromRelationships: function (model, cached, relDiff) {
2607
+ return relDiff.length > 0;
2608
+ },
2609
+ shouldSave: function (model) {
2610
+ return true;
2611
+ },
2612
+ registerSerializerTransforms: function (klass, serializer, seen) {
2613
+ var transforms = klass._registeredTransforms, superclass, prop;
2614
+ var enumTransforms = klass._registeredEnumTransforms;
2615
+ for (prop in transforms) {
2616
+ if (!transforms.hasOwnProperty(prop) || prop in seen) {
2617
+ continue;
2618
+ }
2619
+ seen[prop] = true;
2620
+ serializer.registerTransform(prop, transforms[prop]);
2621
+ }
2622
+ for (prop in enumTransforms) {
2623
+ if (!enumTransforms.hasOwnProperty(prop) || prop in seen) {
2624
+ continue;
2625
+ }
2626
+ seen[prop] = true;
2627
+ serializer.registerEnumTransform(prop, enumTransforms[prop]);
2628
+ }
2629
+ if (superclass = klass.superclass) {
2630
+ this.registerSerializerTransforms(superclass, serializer, seen);
2631
+ }
2632
+ },
2633
+ registerSerializerMappings: function (serializer) {
2634
+ var mappings = this._attributesMap, configurations = this._configurationsMap;
2635
+ mappings.forEach(serializer.map, serializer);
2636
+ configurations.forEach(serializer.configure, serializer);
2637
+ },
2638
+ reifyClientId: function (model) {
2639
+ var id = get(model, 'id'), clientId = get(model, 'clientId'), type = get(model, 'type'), idMap = this.idMaps.get(type);
2640
+ if (id && clientId) {
2641
+ var existingClientId = idMap.get(id);
2642
+ Ember.assert('clientId has changed for ' + model.toString(), !existingClientId || existingClientId === clientId);
2643
+ if (!existingClientId) {
2644
+ idMap.set(id, clientId);
2645
+ }
2646
+ } else if (!clientId) {
2647
+ if (id) {
2648
+ clientId = idMap.get(id);
2649
+ }
2650
+ if (!clientId) {
2651
+ clientId = this._generateClientId(type);
2652
+ }
2653
+ set(model, 'clientId', clientId);
2654
+ idMap.set(id, clientId);
2655
+ }
2656
+ return clientId;
2657
+ },
2658
+ getClientId: function (type, id) {
2659
+ var idMap = this.idMaps.get(type);
2660
+ return idMap.get(id);
2661
+ },
2662
+ _generateClientId: function (type) {
2663
+ return this._typeToString(type) + uuid++;
2664
+ },
2665
+ _typeToString: function (type) {
2666
+ return type.toString().split('.')[1].underscore();
2667
+ }
2668
+ });
2669
+ Ep.Adapter.reopenClass({
2670
+ registerTransform: function (attributeType, transform) {
2671
+ var registeredTransforms = this._registeredTransforms || {};
2672
+ registeredTransforms[attributeType] = transform;
2673
+ this._registeredTransforms = registeredTransforms;
2674
+ },
2675
+ registerEnumTransform: function (attributeType, objects) {
2676
+ var registeredEnumTransforms = this._registeredEnumTransforms || {};
2677
+ registeredEnumTransforms[attributeType] = objects;
2678
+ this._registeredEnumTransforms = registeredEnumTransforms;
2679
+ },
2680
+ map: Ep._Mappable.generateMapFunctionFor('attributes', function (key, newValue, map) {
2681
+ var existingValue = map.get(key);
2682
+ merge(existingValue, newValue);
2683
+ }),
2684
+ configure: Ep._Mappable.generateMapFunctionFor('configurations', function (key, newValue, map) {
2685
+ var existingValue = map.get(key);
2686
+ var mappings = newValue && newValue.mappings;
2687
+ if (mappings) {
2688
+ this.map(key, mappings);
2689
+ delete newValue.mappings;
2690
+ }
2691
+ merge(existingValue, newValue);
2692
+ }),
2693
+ resolveMapConflict: function (oldValue, newValue) {
2694
+ merge(newValue, oldValue);
2695
+ return newValue;
2696
+ }
2697
+ });
2698
+ });
2699
+ require.define('/lib/mixins/mappable.js', function (module, exports, __dirname, __filename) {
2700
+ var get = Ember.get;
2701
+ var resolveMapConflict = function (oldValue, newValue) {
2702
+ return oldValue;
2703
+ };
2704
+ var transformMapKey = function (key, value) {
2705
+ return key;
2706
+ };
2707
+ var transformMapValue = function (key, value) {
2708
+ return value;
2709
+ };
2710
+ Ep._Mappable = Ember.Mixin.create({
2711
+ createInstanceMapFor: function (mapName) {
2712
+ var instanceMeta = getMappableMeta(this);
2713
+ instanceMeta.values = instanceMeta.values || {};
2714
+ if (instanceMeta.values[mapName]) {
2715
+ return instanceMeta.values[mapName];
2716
+ }
2717
+ var instanceMap = instanceMeta.values[mapName] = new Ember.Map();
2718
+ var klass = this.constructor;
2719
+ while (klass && klass !== Ep.Store) {
2720
+ this._copyMap(mapName, klass, instanceMap);
2721
+ klass = klass.superclass;
2722
+ }
2723
+ instanceMeta.values[mapName] = instanceMap;
2724
+ return instanceMap;
2725
+ },
2726
+ _copyMap: function (mapName, klass, instanceMap) {
2727
+ var classMeta = getMappableMeta(klass);
2728
+ var classMap = classMeta[mapName];
2729
+ if (classMap) {
2730
+ classMap.forEach(eachMap, this);
2731
+ }
2732
+ function eachMap(key, value) {
2733
+ var transformedKey = (klass.transformMapKey || transformMapKey)(key, value);
2734
+ var transformedValue = (klass.transformMapValue || transformMapValue)(key, value);
2735
+ var oldValue = instanceMap.get(transformedKey);
2736
+ var newValue = transformedValue;
2737
+ if (oldValue) {
2738
+ newValue = (this.constructor.resolveMapConflict || resolveMapConflict)(oldValue, newValue);
2739
+ }
2740
+ instanceMap.set(transformedKey, newValue);
2741
+ }
2742
+ }
2743
+ });
2744
+ Ep._Mappable.generateMapFunctionFor = function (mapName, transform) {
2745
+ return function (key, value) {
2746
+ var meta = getMappableMeta(this);
2747
+ var map = meta[mapName] || Ember.MapWithDefault.create({
2748
+ defaultValue: function () {
2749
+ return {};
2750
+ }
2751
+ });
2752
+ transform.call(this, key, value, map);
2753
+ meta[mapName] = map;
2754
+ };
2755
+ };
2756
+ function getMappableMeta(obj) {
2757
+ var meta = Ember.meta(obj, true), keyName = 'Ep.Mappable', value = meta[keyName];
2758
+ if (!value) {
2759
+ meta[keyName] = {};
2760
+ }
2761
+ if (!meta.hasOwnProperty(keyName)) {
2762
+ meta[keyName] = Ember.create(meta[keyName]);
2763
+ }
2764
+ return meta[keyName];
2765
+ }
2766
+ });
2767
+ require.define('/lib/local/index.js', function (module, exports, __dirname, __filename) {
2768
+ require('/lib/local/local_adapter.js', module);
2769
+ });
2770
+ require.define('/lib/local/local_adapter.js', function (module, exports, __dirname, __filename) {
2771
+ require('/lib/adapter.js', module);
2772
+ var get = Ember.get, set = Ember.set;
2773
+ Ep.LocalAdapter = Ep.Adapter.extend({
2774
+ serializer: Ep.Serializer.create(),
2775
+ load: function (type, id) {
2776
+ return Ember.RSVP.resolve(null);
2777
+ },
2778
+ refresh: function (model) {
2779
+ return Ember.RSVP.resolve(model.copy());
2780
+ },
2781
+ flush: function (session) {
2782
+ var models = get(session, 'dirtyModels');
2783
+ return Ember.RSVP.resolve(models.copy(true));
2784
+ }
2785
+ });
2786
+ });
2787
+ require.define('/lib/session/index.js', function (module, exports, __dirname, __filename) {
2788
+ require('/lib/session/session.js', module);
2789
+ require('/lib/session/merge.js', module);
2790
+ require('/lib/session/child_session.js', module);
2791
+ });
2792
+ require.define('/lib/session/child_session.js', function (module, exports, __dirname, __filename) {
2793
+ var get = Ember.get, set = Ember.set;
2794
+ Ep.ChildSession = Ep.Session.extend({
2795
+ load: function (type, id) {
2796
+ if (typeof type === 'string') {
2797
+ type = this.lookupType(type);
2798
+ }
2799
+ id = id.toString();
2800
+ var cached = this.getForId(type, id);
2801
+ if (cached && get(cached, 'isLoaded')) {
2802
+ return Ep.resolveModel(cached);
2803
+ }
2804
+ var parentModel = get(this, 'parent').getForId(type, id);
2805
+ if (parentModel && get(parentModel, 'isLoaded')) {
2806
+ return Ep.resolveModel(this.merge(parentModel));
2807
+ }
2808
+ var session = this;
2809
+ return Ep.resolveModel(this.parent.load(type, id).then(function (model) {
2810
+ return session.merge(model);
2811
+ }, function (model) {
2812
+ throw session.merge(model);
2813
+ }), type, id, session);
2814
+ },
2815
+ query: function (type, query) {
2816
+ var session = this;
2817
+ return this.parent.query(type, query).then(function (models) {
2818
+ var merged = Ep.ModelArray.create({
2819
+ session: session,
2820
+ content: []
2821
+ });
2822
+ set(merged, 'meta', get(models, 'meta'));
2823
+ models.forEach(function (model) {
2824
+ merged.addObject(session.merge(model));
2825
+ });
2826
+ return merged;
2827
+ });
2828
+ },
2829
+ refresh: function (model) {
2830
+ var session = this;
2831
+ return this.parent.refresh(model).then(function (refreshedModel) {
2832
+ return session.merge(refreshedModel);
2833
+ }, function (refreshedModel) {
2834
+ throw session.merge(refreshedModel);
2835
+ });
2836
+ },
2837
+ flush: function () {
2838
+ var session = this, dirtyModels = get(this, 'dirtyModels'), shadows = get(this, 'shadows'), parent = this.parent;
2839
+ var dirty = get(this, 'dirtyModels');
2840
+ dirty.forEach(function (model) {
2841
+ parent.update(model);
2842
+ });
2843
+ var promise = parent.flush().then(function (models) {
2844
+ var res = models.map(function (model) {
2845
+ return session.merge(model);
2846
+ });
2847
+ return models;
2848
+ }, function (models) {
2849
+ var res = models.map(function (model) {
2850
+ return session.merge(model);
2851
+ });
2852
+ throw models;
2853
+ });
2854
+ dirtyModels.forEach(function (model) {
2855
+ this.shadows.add(model.copy());
2856
+ }, this);
2857
+ return promise;
2858
+ },
2859
+ reifyClientId: function (model) {
2860
+ return this.parent.reifyClientId(model);
2861
+ },
2862
+ getForId: function (type, id) {
2863
+ var adapter = get(this.parent, 'adapter');
2864
+ var clientId = adapter.getClientId(type, id);
2865
+ return this.models.getForClientId(clientId);
2866
+ },
2867
+ remoteCall: function (context, name) {
2868
+ var session = this;
2869
+ return this.parent.remoteCall.apply(this.parent, arguments).then(function (model) {
2870
+ return session.merge(model);
2871
+ }, function (model) {
2872
+ throw session.merge(model);
2873
+ });
2874
+ }
2875
+ });
2876
+ });
2877
+ require.define('/lib/session/merge.js', function (module, exports, __dirname, __filename) {
2878
+ var get = Ember.get, set = Ember.set;
2879
+ Ep.Session.reopen({
2880
+ merge: function (model, strategy) {
2881
+ var shadows = get(this, 'shadows'), newModels = get(this, 'newModels');
2882
+ this.reifyClientId(model);
2883
+ if (!strategy)
2884
+ strategy = get(this, 'mergeStrategy').create({ session: this });
2885
+ if (!get(model, 'hasErrors')) {
2886
+ var merged;
2887
+ this.suspendDirtyChecking(function () {
2888
+ merged = this.mergeModel(model, strategy);
2889
+ }, this);
2890
+ shadows.remove(model);
2891
+ newModels.remove(model);
2892
+ } else {
2893
+ this.suspendDirtyChecking(function () {
2894
+ merged = this.mergeErrors(model, strategy);
2895
+ }, this);
2896
+ shadows.add(model);
2897
+ }
2898
+ return merged;
2899
+ },
2900
+ mergeModel: function (model, strategy) {
2901
+ var dest = this.getModel(model);
2902
+ if (model === dest) {
2903
+ return model;
2904
+ }
2905
+ if (get(model, 'isPromise')) {
2906
+ return this.mergePromise(model, dest, strategy);
2907
+ }
2908
+ var promise;
2909
+ if (dest && get(dest, 'isPromise')) {
2910
+ promise = dest;
2911
+ dest = dest.content;
2912
+ }
2913
+ if (!dest) {
2914
+ dest = model.constructor.create();
2915
+ if (promise) {
2916
+ promise.resolve(dest);
2917
+ }
2918
+ }
2919
+ set(dest, 'id', get(model, 'id'));
2920
+ set(dest, 'clientId', get(model, 'clientId'));
2921
+ set(dest, 'isDeleted', get(model, 'isDeleted'));
2922
+ set(dest, 'errors', Ember.copy(get(model, 'errors')));
2923
+ this.adopt(dest);
2924
+ strategy.merge(model, dest);
2925
+ return dest;
2926
+ },
2927
+ mergePromise: function (promise, dest, strategy) {
2928
+ var content = get(promise, 'content');
2929
+ if (content) {
2930
+ return this.merge(content, strategy);
2931
+ }
2932
+ if (!dest) {
2933
+ dest = promise.lazyCopy();
2934
+ this.adopt(dest);
2935
+ }
2936
+ return dest;
2937
+ },
2938
+ mergeErrors: function (model, strategy) {
2939
+ var dest = this.getModel(model);
2940
+ if (!dest) {
2941
+ Ember.assert('Errors returned for non-existant model: ' + model.toString(), model instanceof Ep.LoadError);
2942
+ return model;
2943
+ }
2944
+ set(dest, 'errors', Ember.copy(get(model, 'errors')));
2945
+ return dest;
2946
+ }
2947
+ });
2948
+ });
2949
+ require.define('/lib/session/session.js', function (module, exports, __dirname, __filename) {
2950
+ require('/lib/collections/model_array.js', module);
2951
+ require('/lib/collections/model_set.js', module);
2952
+ require('/lib/session/collection_manager.js', module);
2953
+ require('/lib/session/belongs_to_manager.js', module);
2954
+ require('/lib/model/index.js', module);
2955
+ require('/lib/session/merge_strategies/index.js', module);
2956
+ var get = Ember.get, set = Ember.set;
2957
+ Ep.Session = Ember.Object.extend({
2958
+ mergeStrategy: Ep.PerField,
2959
+ _dirtyCheckingSuspended: false,
2960
+ init: function () {
2961
+ this._super.apply(this, arguments);
2962
+ this.models = Ep.ModelSet.create();
2963
+ this.collectionManager = Ep.CollectionManager.create();
2964
+ this.belongsToManager = Ep.BelongsToManager.create();
2965
+ this.shadows = Ep.ModelSet.create();
2966
+ this.newModels = Ep.ModelSet.create();
2967
+ },
2968
+ create: function (type, hash) {
2969
+ if (typeof type === 'string') {
2970
+ type = this.lookupType(type);
2971
+ }
2972
+ var model = type.create(hash);
2973
+ model = this.add(model);
2974
+ model._registerRelationships();
2975
+ return model;
2976
+ },
2977
+ adopt: function (model) {
2978
+ Ember.assert('Models instances cannot be moved between sessions. Use `add` or `update` instead.', !get(model, 'session') || get(model, 'session') === this);
2979
+ set(model, 'session', this);
2980
+ if (get(model, 'isNew')) {
2981
+ this.newModels.add(model);
2982
+ }
2983
+ this.models.add(model);
2984
+ model._registerRelationships();
2985
+ return model;
2986
+ },
2987
+ add: function (model, depth) {
2988
+ this.reifyClientId(model);
2989
+ var dest = this.getModel(model);
2990
+ if (dest && get(dest, 'isLoaded'))
2991
+ return dest;
2992
+ if (typeof depth === 'undefined') {
2993
+ depth = 2;
2994
+ }
2995
+ depth--;
2996
+ if (get(model, 'isProxy')) {
2997
+ var content = get(model, 'content');
2998
+ if (content) {
2999
+ return this.add(content);
3000
+ }
3001
+ dest = model.lazyCopy();
3002
+ return this.adopt(dest);
3003
+ }
3004
+ if (get(model, 'isDetached')) {
3005
+ dest = model;
3006
+ } else {
3007
+ dest = model.constructor.create();
3008
+ model.copyAttributes(dest);
3009
+ }
3010
+ this.adopt(dest);
3011
+ model.eachRelationship(function (name, relationship) {
3012
+ if (relationship.kind === 'belongsTo') {
3013
+ var child = get(model, name);
3014
+ if (child) {
3015
+ if (get(child, 'session') === this) {
3016
+ model.belongsToDidChange(model, name);
3017
+ } else {
3018
+ if (depth >= 0 || get(child, 'isDetached') || get(child, 'isNew')) {
3019
+ child = this.add(child, depth);
3020
+ } else {
3021
+ child = child.lazyCopy();
3022
+ }
3023
+ dest.suspendRelationshipObservers(function () {
3024
+ set(dest, name, child);
3025
+ });
3026
+ }
3027
+ }
3028
+ } else if (relationship.kind === 'hasMany') {
3029
+ var children = get(model, name);
3030
+ var copied = children.map(function (child) {
3031
+ if (depth >= 0 || get(child, 'isDetached') || get(child, 'isNew')) {
3032
+ child = this.add(child, depth);
3033
+ } else {
3034
+ child = child.lazyCopy();
3035
+ }
3036
+ return child;
3037
+ }, this);
3038
+ set(dest, name, copied);
3039
+ }
3040
+ }, this);
3041
+ return dest;
3042
+ },
3043
+ update: function (model) {
3044
+ this.reifyClientId(model);
3045
+ if (get(model, 'isProxy')) {
3046
+ var content = get(model, 'content');
3047
+ if (content) {
3048
+ return this.update(content);
3049
+ }
3050
+ throw new Ember.Error('Cannot update with an unloaded model: ' + model.toString());
3051
+ }
3052
+ var dest = this.getModel(model);
3053
+ if (get(model, 'isDetached') || !dest || !get(dest, 'isLoaded')) {
3054
+ return this.add(model);
3055
+ }
3056
+ if (get(model, 'isDeleted')) {
3057
+ if (!get(dest, 'isDeleted')) {
3058
+ this.deleteModel(dest);
3059
+ }
3060
+ return dest;
3061
+ }
3062
+ model.copyAttributes(dest);
3063
+ model.eachRelationship(function (name, relationship) {
3064
+ if (relationship.kind === 'belongsTo') {
3065
+ var child = get(model, name);
3066
+ if (child) {
3067
+ set(dest, name, child);
3068
+ }
3069
+ } else if (relationship.kind === 'hasMany') {
3070
+ var children = get(model, name);
3071
+ var destChildren = get(dest, name);
3072
+ children.copyTo(destChildren);
3073
+ }
3074
+ }, this);
3075
+ return dest;
3076
+ },
3077
+ deleteModel: function (model) {
3078
+ if (get(model, 'isNew')) {
3079
+ var newModels = get(this, 'newModels');
3080
+ newModels.remove(model);
3081
+ } else {
3082
+ this.modelWillBecomeDirty(model);
3083
+ }
3084
+ set(model, 'isDeleted', true);
3085
+ this.collectionManager.modelWasDeleted(model);
3086
+ this.belongsToManager.modelWasDeleted(model);
3087
+ },
3088
+ load: function (type, id) {
3089
+ if (typeof type === 'string') {
3090
+ type = this.lookupType(type);
3091
+ }
3092
+ id = id.toString();
3093
+ var cached = this.getForId(type, id);
3094
+ if (cached && get(cached, 'isLoaded')) {
3095
+ return Ep.resolveModel(cached);
3096
+ }
3097
+ var session = this;
3098
+ return Ep.resolveModel(this.adapter.load(type, id).then(function (model) {
3099
+ return session.merge(model);
3100
+ }, function (model) {
3101
+ throw session.merge(model);
3102
+ }), type, id, session);
3103
+ },
3104
+ find: function (type, query) {
3105
+ if (Ember.typeOf(query) === 'object') {
3106
+ return this.query(type, query);
3107
+ }
3108
+ return this.load(type, query);
3109
+ },
3110
+ query: function (type, query) {
3111
+ if (typeof type === 'string') {
3112
+ type = this.lookupType(type);
3113
+ }
3114
+ var session = this;
3115
+ return this.adapter.query(type, query).then(function (models) {
3116
+ var merged = Ep.ModelArray.create({
3117
+ session: session,
3118
+ content: []
3119
+ });
3120
+ set(merged, 'meta', get(models, 'meta'));
3121
+ models.forEach(function (model) {
3122
+ merged.addObject(session.merge(model));
3123
+ });
3124
+ return merged;
3125
+ });
3126
+ },
3127
+ refresh: function (model) {
3128
+ var session = this;
3129
+ return this.adapter.refresh(model).then(function (refreshedModel) {
3130
+ return session.merge(refreshedModel);
3131
+ }, function (refreshedModel) {
3132
+ throw session.merge(refreshedModel);
3133
+ });
3134
+ },
3135
+ flush: function () {
3136
+ var session = this, dirtyModels = get(this, 'dirtyModels'), shadows = get(this, 'shadows');
3137
+ var promise = this.adapter.flush(this).then(function (models) {
3138
+ var res = models.map(function (model) {
3139
+ return session.merge(model);
3140
+ });
3141
+ return res;
3142
+ }, function (models) {
3143
+ var res = models.map(function (model) {
3144
+ return session.merge(model);
3145
+ });
3146
+ throw res;
3147
+ });
3148
+ dirtyModels.forEach(function (model) {
3149
+ this.shadows.add(model.copy());
3150
+ }, this);
3151
+ return promise;
3152
+ },
3153
+ getModel: function (model) {
3154
+ return this.models.getModel(model);
3155
+ },
3156
+ getForId: function (type, id) {
3157
+ var clientId = this.adapter.getClientId(type, id);
3158
+ return this.models.getForClientId(clientId);
3159
+ },
3160
+ reifyClientId: function (model) {
3161
+ this.adapter.reifyClientId(model);
3162
+ },
3163
+ remoteCall: function (context, name) {
3164
+ var session = this;
3165
+ return this.adapter.remoteCall.apply(this.adapter, arguments).then(function (model) {
3166
+ return session.merge(model);
3167
+ }, function (model) {
3168
+ throw session.merge(model);
3169
+ });
3170
+ },
3171
+ modelWillBecomeDirty: function (model) {
3172
+ if (this._dirtyCheckingSuspended || get(model, 'isNew')) {
3173
+ return;
3174
+ }
3175
+ var shadow = this.shadows.getModel(model);
3176
+ if (!shadow) {
3177
+ shadow = model.copy();
3178
+ this.shadows.addObject(shadow);
3179
+ }
3180
+ },
3181
+ destroy: function () {
3182
+ this._super();
3183
+ this.models.forEach(function (model) {
3184
+ model.destroy();
3185
+ });
3186
+ this.models.destroy();
3187
+ this.collectionManager.destroy();
3188
+ this.belongsToManager.destroy();
3189
+ this.shadows.destroy();
3190
+ this.newModels.destroy();
3191
+ },
3192
+ dirtyModels: Ember.computed(function () {
3193
+ var models = Ep.ModelSet.fromArray(this.shadows.map(function (model) {
3194
+ return this.models.getModel(model);
3195
+ }, this));
3196
+ get(this, 'newModels').forEach(function (model) {
3197
+ models.add(model);
3198
+ });
3199
+ return models;
3200
+ }).volatile(),
3201
+ suspendDirtyChecking: function (callback, binding) {
3202
+ var self = this;
3203
+ if (this._dirtyCheckingSuspended) {
3204
+ return callback.call(binding || self);
3205
+ }
3206
+ try {
3207
+ this._dirtyCheckingSuspended = true;
3208
+ return callback.call(binding || self);
3209
+ } finally {
3210
+ this._dirtyCheckingSuspended = false;
3211
+ }
3212
+ },
3213
+ newSession: function () {
3214
+ var child = this.container.lookup('session:child');
3215
+ set(child, 'parent', this);
3216
+ return child;
3217
+ },
3218
+ lookupType: function (type) {
3219
+ return this.container.lookup('model:' + type);
3220
+ },
3221
+ getShadow: function (model) {
3222
+ var shadows = get(this, 'shadows');
3223
+ var models = get(this, 'models');
3224
+ return shadows.getModel(model) || models.getModel(model);
3225
+ }
3226
+ });
3227
+ });
3228
+ require.define('/lib/session/merge_strategies/index.js', function (module, exports, __dirname, __filename) {
3229
+ require('/lib/session/merge_strategies/merge_strategy.js', module);
3230
+ require('/lib/session/merge_strategies/theirs.js', module);
3231
+ require('/lib/session/merge_strategies/per_field.js', module);
3232
+ });
3233
+ require.define('/lib/session/merge_strategies/per_field.js', function (module, exports, __dirname, __filename) {
3234
+ var get = Ember.get, set = Ember.set, isEqual = Ember.isEqual;
3235
+ function mergeIfPresent(session, model, strategy) {
3236
+ if (!model)
3237
+ return null;
3238
+ return session.merge(model, strategy);
3239
+ }
3240
+ Ep.PerField = Ep.MergeStrategy.extend({
3241
+ init: function () {
3242
+ this.cache = Ep.ModelSet.create();
3243
+ },
3244
+ merge: function (theirs, ours) {
3245
+ if (this.cache.contains(ours))
3246
+ return ours;
3247
+ this.cache.addObject(theirs);
3248
+ ours.beginPropertyChanges();
3249
+ var session = get(this, 'session');
3250
+ var original = session.getShadow(ours);
3251
+ this.mergeAttributes(theirs, ours, original);
3252
+ this.mergeRelationships(theirs, ours, original);
3253
+ ours.endPropertyChanges();
3254
+ return ours;
3255
+ },
3256
+ mergeAttributes: function (theirs, ours, original) {
3257
+ ours.eachAttribute(function (name, meta) {
3258
+ var oursValue = get(ours, name);
3259
+ var theirsValue = get(theirs, name);
3260
+ var originalValue = get(original, name);
3261
+ if (oursValue === theirsValue)
3262
+ return;
3263
+ if (oursValue === originalValue) {
3264
+ set(ours, name, theirsValue);
3265
+ }
3266
+ });
3267
+ },
3268
+ mergeRelationships: function (theirs, ours, original) {
3269
+ var session = get(this, 'session');
3270
+ ours.eachRelationship(function (name, relationship) {
3271
+ if (relationship.kind === 'belongsTo') {
3272
+ var oursValue = get(ours, name);
3273
+ var theirsValue = get(theirs, name);
3274
+ var originalValue = get(original, name);
3275
+ var merged = mergeIfPresent(session, theirsValue, this);
3276
+ if (isEqual(oursValue, originalValue)) {
3277
+ set(ours, name, merged);
3278
+ }
3279
+ } else if (relationship.kind === 'hasMany') {
3280
+ var theirChildren = get(theirs, name);
3281
+ var ourChildren = get(ours, name);
3282
+ var originalChildren = get(original, name);
3283
+ if (isEqual(ourChildren, originalChildren)) {
3284
+ var existing = Ep.ModelSet.create();
3285
+ existing.addObjects(ourChildren);
3286
+ theirChildren.forEach(function (model) {
3287
+ if (existing.contains(model)) {
3288
+ session.merge(model, this);
3289
+ existing.remove(model);
3290
+ } else {
3291
+ ourChildren.addObject(session.merge(model, this));
3292
+ }
3293
+ }, this);
3294
+ ourChildren.removeObjects(existing);
3295
+ } else {
3296
+ theirChildren.forEach(function (model) {
3297
+ session.merge(model, this);
3298
+ }, this);
3299
+ }
3300
+ }
3301
+ }, this);
3302
+ }
3303
+ });
3304
+ });
3305
+ require.define('/lib/session/merge_strategies/theirs.js', function (module, exports, __dirname, __filename) {
3306
+ var get = Ember.get, set = Ember.set;
3307
+ Ep.Theirs = Ep.MergeStrategy.extend({
3308
+ init: function () {
3309
+ this.cache = Ep.ModelSet.create();
3310
+ },
3311
+ merge: function (model, dest) {
3312
+ if (this.cache.contains(model))
3313
+ return dest;
3314
+ this.cache.addObject(model);
3315
+ dest.beginPropertyChanges();
3316
+ this.copyAttributes(model, dest);
3317
+ this.copyRelationships(model, dest);
3318
+ dest.endPropertyChanges();
3319
+ return dest;
3320
+ },
3321
+ copyAttributes: function (model, dest) {
3322
+ model.eachAttribute(function (name, meta) {
3323
+ var left = get(model, name);
3324
+ var right = get(dest, name);
3325
+ if (left !== right)
3326
+ set(dest, name, left);
3327
+ });
3328
+ },
3329
+ copyRelationships: function (model, dest) {
3330
+ var session = get(this, 'session');
3331
+ model.eachRelationship(function (name, relationship) {
3332
+ if (relationship.kind === 'belongsTo') {
3333
+ var child = get(model, name);
3334
+ var destChild = get(dest, name);
3335
+ if (child && destChild) {
3336
+ session.merge(child, this);
3337
+ } else if (child) {
3338
+ set(dest, name, session.merge(child, this));
3339
+ } else if (destChild) {
3340
+ set(dest, name, null);
3341
+ }
3342
+ } else if (relationship.kind === 'hasMany') {
3343
+ var children = get(model, name);
3344
+ var destChildren = get(dest, name);
3345
+ var modelSet = Ep.ModelSet.create();
3346
+ modelSet.addObjects(destChildren);
3347
+ set(destChildren, 'meta', get(children, 'meta'));
3348
+ children.forEach(function (child) {
3349
+ if (modelSet.contains(child)) {
3350
+ session.merge(child, this);
3351
+ modelSet.remove(child);
3352
+ } else {
3353
+ destChildren.addObject(session.merge(child, this));
3354
+ }
3355
+ }, this);
3356
+ destChildren.removeObjects(modelSet);
3357
+ }
3358
+ }, this);
3359
+ }
3360
+ });
3361
+ });
3362
+ require.define('/lib/session/merge_strategies/merge_strategy.js', function (module, exports, __dirname, __filename) {
3363
+ var get = Ember.get, set = Ember.set;
3364
+ function mustImplement(name) {
3365
+ return function () {
3366
+ throw new Ember.Error('Your serializer ' + this.toString() + ' does not implement the required method ' + name);
3367
+ };
3368
+ }
3369
+ Ep.MergeStrategy = Ember.Object.extend({
3370
+ session: null,
3371
+ merge: mustImplement('merge')
3372
+ });
3373
+ });
3374
+ require.define('/lib/session/belongs_to_manager.js', function (module, exports, __dirname, __filename) {
3375
+ var get = Ember.get, set = Ember.set;
3376
+ Ep.BelongsToManager = Ember.Object.extend({
3377
+ init: function () {
3378
+ this.modelMap = Ember.MapWithDefault.create({
3379
+ defaultValue: function () {
3380
+ return Ember.A([]);
3381
+ }
3382
+ });
3383
+ },
3384
+ register: function (parent, key, model) {
3385
+ var paths = this.modelMap.get(get(model, 'clientId'));
3386
+ var path = paths.find(function (p) {
3387
+ return p.parent.isEqual(parent) && p.key === key;
3388
+ });
3389
+ if (path)
3390
+ return;
3391
+ path = {
3392
+ parent: parent,
3393
+ key: key
3394
+ };
3395
+ paths.pushObject(path);
3396
+ },
3397
+ unregister: function (parent, key, model) {
3398
+ var paths = this.modelMap.get(get(model, 'clientId'));
3399
+ var path = paths.find(function (p) {
3400
+ return p.parent.isEqual(parent) && p.key === key;
3401
+ });
3402
+ paths.removeObject(path);
3403
+ if (paths.length === 0) {
3404
+ this.modelMap.remove(get(model, 'clientId'));
3405
+ }
3406
+ },
3407
+ modelWasDeleted: function (model) {
3408
+ var paths = this.modelMap.get(get(model, 'clientId')).copy();
3409
+ paths.forEach(function (path) {
3410
+ set(path.parent, path.key, null);
3411
+ });
3412
+ }
3413
+ });
3414
+ });
3415
+ require.define('/lib/session/collection_manager.js', function (module, exports, __dirname, __filename) {
3416
+ var get = Ember.get, set = Ember.set;
3417
+ Ep.CollectionManager = Ember.Object.extend({
3418
+ init: function () {
3419
+ this.modelMap = Ember.MapWithDefault.create({
3420
+ defaultValue: function () {
3421
+ return Ember.A([]);
3422
+ }
3423
+ });
3424
+ },
3425
+ register: function (array, model) {
3426
+ var arrays = this.modelMap.get(get(model, 'clientId'));
3427
+ if (arrays.contains(array))
3428
+ return;
3429
+ arrays.pushObject(array);
3430
+ },
3431
+ unregister: function (array, model) {
3432
+ var arrays = this.modelMap.get(get(model, 'clientId'));
3433
+ arrays.removeObject(array);
3434
+ if (arrays.length === 0) {
3435
+ this.modelMap.remove(get(model, 'clientId'));
3436
+ }
3437
+ },
3438
+ modelWasDeleted: function (model) {
3439
+ var arrays = this.modelMap.get(get(model, 'clientId')).copy();
3440
+ arrays.forEach(function (array) {
3441
+ array.removeObject(model);
3442
+ });
3443
+ }
3444
+ });
3445
+ });
3446
+ require.define('/lib/initializer.js', function (module, exports, __dirname, __filename) {
3447
+ var set = Ember.set;
3448
+ Ember.onLoad('Ember.Application', function (Application) {
3449
+ Application.initializer({
3450
+ name: 'epf',
3451
+ initialize: function (container, application) {
3452
+ Ep.__container__ = container;
3453
+ application.register('store:main', application.Store || Ep.Store);
3454
+ application.register('adapter:main', application.Adapter || Ep.RestAdapter);
3455
+ application.register('session:base', application.Session || Ep.Session, { singleton: false });
3456
+ application.register('session:child', application.ChildSession || Ep.ChildSession, { singleton: false });
3457
+ application.register('session:main', application.DefaultSession || Ep.Session);
3458
+ application.register('serializer:main', application.Serializer || Ep.RestSerializer);
3459
+ application.inject('adapter', 'serializer', 'serializer:main');
3460
+ application.inject('session', 'adapter', 'adapter:main');
3461
+ container.optionsForType('model', { instantiate: false });
3462
+ application.inject('controller', 'adapter', 'adapter:main');
3463
+ application.inject('controller', 'session', 'session:main');
3464
+ application.inject('route', 'adapter', 'adapter:main');
3465
+ application.inject('route', 'session', 'session:main');
3466
+ }
3467
+ });
3468
+ });
3469
+ });
3470
+ global.epf = require('/lib/index.js');
3471
+ }.call(this, this));
3472
+ /*
3473
+ //@ sourceMappingURL=eps.js.map
3474
+ */