w
clone your own copy | download snapshot

Snapshots | iceberg

No images in this repository’s iceberg at this time

Inside this repository

backbone-relational.min.js
application/javascript

Download raw (25.2 KB)

(function(a,b){if(typeof define==="function"&&define.amd){define(["exports","backbone","underscore"],b)}else{if(typeof exports!=="undefined"){b(exports,require("backbone"),require("underscore"))}else{b(a,a.Backbone,a._)}}}(this,function(b,h,d){h.Relational={showWarnings:true};h.Semaphore={_permitsAvailable:null,_permitsUsed:0,acquire:function(){if(this._permitsAvailable&&this._permitsUsed>=this._permitsAvailable){throw new Error("Max permits acquired")}else{this._permitsUsed++}},release:function(){if(this._permitsUsed===0){throw new Error("All permits released")}else{this._permitsUsed--}},isLocked:function(){return this._permitsUsed>0},setAvailablePermits:function(i){if(this._permitsUsed>i){throw new Error("Available permits cannot be less than used permits")}this._permitsAvailable=i}};h.BlockingQueue=function(){this._queue=[]};d.extend(h.BlockingQueue.prototype,h.Semaphore,{_queue:null,add:function(i){if(this.isBlocked()){this._queue.push(i)}else{i()}},process:function(){var i=this._queue;this._queue=[];while(i&&i.length){i.shift()()}},block:function(){this.acquire()},unblock:function(){this.release();if(!this.isBlocked()){this.process()}},isBlocked:function(){return this.isLocked()}});h.Relational.eventQueue=new h.BlockingQueue();h.Store=function(){this._collections=[];this._reverseRelations=[];this._orphanRelations=[];this._subModels=[];this._modelScopes=[b]};d.extend(h.Store.prototype,h.Events,{initializeRelation:function(k,m,j){var l=!d.isString(m.type)?m.type:h[m.type]||this.getObjectByName(m.type);if(l&&l.prototype instanceof h.Relation){var i=new l(k,m,j)}else{h.Relational.showWarnings&&typeof console!=="undefined"&&console.warn("Relation=%o; missing or invalid relation type!",m)}},addModelScope:function(i){this._modelScopes.push(i)},removeModelScope:function(i){this._modelScopes=d.without(this._modelScopes,i)},addSubModels:function(i,j){this._subModels.push({superModelType:j,subModels:i})},setupSuperModel:function(i){d.find(this._subModels,function(j){return d.filter(j.subModels||[],function(l,m){var k=this.getObjectByName(l);if(i===k){j.superModelType._subModels[m]=i;i._superModel=j.superModelType;i._subModelTypeValue=m;i._subModelTypeAttribute=j.superModelType.prototype.subModelTypeAttribute;return true}},this).length},this)},addReverseRelation:function(j){var i=d.any(this._reverseRelations,function(k){return d.all(j||[],function(m,l){return m===k[l]})});if(!i&&j.model&&j.type){this._reverseRelations.push(j);this._addRelation(j.model,j);this.retroFitRelation(j)}},addOrphanRelation:function(j){var i=d.any(this._orphanRelations,function(k){return d.all(j||[],function(m,l){return m===k[l]})});if(!i&&j.model&&j.type){this._orphanRelations.push(j)}},processOrphanRelations:function(){d.each(this._orphanRelations.slice(0),function(i){var j=h.Relational.store.getObjectByName(i.relatedModel);if(j){this.initializeRelation(null,i);this._orphanRelations=d.without(this._orphanRelations,i)}},this)},_addRelation:function(i,j){if(!i.prototype.relations){i.prototype.relations=[]}i.prototype.relations.push(j);d.each(i._subModels||[],function(k){this._addRelation(k,j)},this)},retroFitRelation:function(j){var i=this.getCollection(j.model,false);i&&i.each(function(l){if(!(l instanceof j.model)){return}var k=new j.type(l,j)},this)},getCollection:function(l,k){if(l instanceof h.RelationalModel){l=l.constructor}var i=l;while(i._superModel){i=i._superModel}var j=d.find(this._collections,function(m){return m.model===i});if(!j&&k!==false){j=this._createCollection(i)}return j},getObjectByName:function(i){var k=i.split("."),j=null;d.find(this._modelScopes,function(l){j=d.reduce(k||[],function(m,n){return m?m[n]:undefined},l);if(j&&j!==l){return true}},this);return j},_createCollection:function(j){var i;if(j instanceof h.RelationalModel){j=j.constructor}if(j.prototype instanceof h.RelationalModel){i=new h.Collection();i.model=j;this._collections.push(i)}return i},resolveIdForItem:function(i,j){var k=d.isString(j)||d.isNumber(j)?j:null;if(k===null){if(j instanceof h.RelationalModel){k=j.id}else{if(d.isObject(j)){k=j[i.prototype.idAttribute]}}}if(!k&&k!==0){k=null}return k},find:function(j,k){var m=this.resolveIdForItem(j,k),i=this.getCollection(j);if(i){var l=i.get(m);if(l instanceof j){return l}}return null},register:function(j){var k=this.getCollection(j);if(k){var i=j.collection;k.add(j);j.collection=i}},checkId:function(i,l){var j=this.getCollection(i),k=j&&j.get(l);if(k&&i!==k){if(h.Relational.showWarnings&&typeof console!=="undefined"){console.warn("Duplicate id! Old RelationalModel=%o, new RelationalModel=%o",k,i)}throw new Error("Cannot instantiate more than one Backbone.RelationalModel with the same id per type!")}},update:function(i){var j=this.getCollection(i);if(!j.contains(i)){this.register(i)}j._onModelEvent("change:"+i.idAttribute,i,j);i.trigger("relational:change:id",i,j)},unregister:function(j){var i,k;if(j instanceof h.Model){i=this.getCollection(j);k=[j]}else{if(j instanceof h.Collection){i=this.getCollection(j.model);k=d.clone(j.models)}else{i=this.getCollection(j);k=d.clone(i.models)}}d.each(k,function(l){this.stopListening(l);d.invoke(l.getRelations(),"stopListening")},this);if(d.contains(this._collections,j)){i.reset([])}else{d.each(k,function(l){if(i.get(l)){i.remove(l)}else{i.trigger("relational:remove",l,i)}},this)}},reset:function(){this.stopListening();d.each(this._collections,function(i){this.unregister(i)},this);this._collections=[];this._subModels=[];this._modelScopes=[b]}});h.Relational.store=new h.Store();h.Relation=function(i,j,k){this.instance=i;j=d.isObject(j)?j:{};this.reverseRelation=d.defaults(j.reverseRelation||{},this.options.reverseRelation);this.options=d.defaults(j,this.options,h.Relation.prototype.options);this.reverseRelation.type=!d.isString(this.reverseRelation.type)?this.reverseRelation.type:h[this.reverseRelation.type]||h.Relational.store.getObjectByName(this.reverseRelation.type);this.key=this.options.key;this.keySource=this.options.keySource||this.key;this.keyDestination=this.options.keyDestination||this.keySource||this.key;this.model=this.options.model||this.instance.constructor;this.relatedModel=this.options.relatedModel;if(d.isUndefined(this.relatedModel)){this.relatedModel=this.model}if(d.isFunction(this.relatedModel)&&!(this.relatedModel.prototype instanceof h.RelationalModel)){this.relatedModel=d.result(this,"relatedModel")}if(d.isString(this.relatedModel)){this.relatedModel=h.Relational.store.getObjectByName(this.relatedModel)}if(!this.checkPreconditions()){return}if(!this.options.isAutoRelation&&this.reverseRelation.type&&this.reverseRelation.key){h.Relational.store.addReverseRelation(d.defaults({isAutoRelation:true,model:this.relatedModel,relatedModel:this.model,reverseRelation:this.options},this.reverseRelation))}if(i){var l=this.keySource;if(l!==this.key&&d.isObject(this.instance.get(this.key))){l=this.key}this.setKeyContents(this.instance.get(l));this.relatedCollection=h.Relational.store.getCollection(this.relatedModel);if(this.keySource!==this.key){delete this.instance.attributes[this.keySource]}this.instance._relations[this.key]=this;this.initialize(k);if(this.options.autoFetch){this.instance.getAsync(this.key,d.isObject(this.options.autoFetch)?this.options.autoFetch:{})}this.listenTo(this.instance,"destroy",this.destroy).listenTo(this.relatedCollection,"relational:add relational:change:id",this.tryAddRelated).listenTo(this.relatedCollection,"relational:remove",this.removeRelated)}};h.Relation.extend=h.Model.extend;d.extend(h.Relation.prototype,h.Events,h.Semaphore,{options:{createModels:true,includeInJSON:true,isAutoRelation:false,autoFetch:false,parse:false},instance:null,key:null,keyContents:null,relatedModel:null,relatedCollection:null,reverseRelation:null,related:null,checkPreconditions:function(){var n=this.instance,l=this.key,j=this.model,p=this.relatedModel,q=h.Relational.showWarnings&&typeof console!=="undefined";if(!j||!l||!p){q&&console.warn("Relation=%o: missing model, key or relatedModel (%o, %o, %o).",this,j,l,p);return false}if(!(j.prototype instanceof h.RelationalModel)){q&&console.warn("Relation=%o: model does not inherit from Backbone.RelationalModel (%o).",this,n);return false}if(!(p.prototype instanceof h.RelationalModel)){q&&console.warn("Relation=%o: relatedModel does not inherit from Backbone.RelationalModel (%o).",this,p);return false}if(this instanceof h.HasMany&&this.reverseRelation.type===h.HasMany){q&&console.warn("Relation=%o: relation is a HasMany, and the reverseRelation is HasMany as well.",this);return false}if(n&&d.keys(n._relations).length){var o=d.find(n._relations,function(i){return i.key===l},this);if(o){q&&console.warn("Cannot create relation=%o on %o for model=%o: already taken by relation=%o.",this,l,n,o);return false}}return true},setRelated:function(i){this.related=i;this.instance.attributes[this.key]=i},_isReverseRelation:function(i){return i.instance instanceof this.relatedModel&&this.reverseRelation.key===i.key&&this.key===i.reverseRelation.key},getReverseRelations:function(m){var p=[];var q=!d.isUndefined(m)?[m]:this.related&&(this.related.models||[this.related]),k=null,o=null;for(var n=0;n<(q||[]).length;n++){k=q[n].getRelations()||[];for(var l=0;l<k.length;l++){o=k[l];if(this._isReverseRelation(o)){p.push(o)}}}return p},destroy:function(){this.stopListening();if(this instanceof h.HasOne){this.setRelated(null)}else{if(this instanceof h.HasMany){this.setRelated(this._prepareCollection())}}d.each(this.getReverseRelations(),function(i){i.removeRelated(this.instance)},this)}});h.HasOne=h.Relation.extend({options:{reverseRelation:{type:"HasMany"}},initialize:function(i){this.listenTo(this.instance,"relational:change:"+this.key,this.onChange);var j=this.findRelated(i);this.setRelated(j);d.each(this.getReverseRelations(),function(k){k.addRelated(this.instance,i)},this)},findRelated:function(i){var k=null;i=d.defaults({parse:this.options.parse},i);if(this.keyContents instanceof this.relatedModel){k=this.keyContents}else{if(this.keyContents||this.keyContents===0){var j=d.defaults({create:this.options.createModels},i);k=this.relatedModel.findOrCreate(this.keyContents,j)}}if(k){this.keyId=null}return k},setKeyContents:function(i){this.keyContents=i;this.keyId=h.Relational.store.resolveIdForItem(this.relatedModel,this.keyContents)},onChange:function(l,i,k){if(this.isLocked()){return}this.acquire();k=k?d.clone(k):{};var o=d.isUndefined(k.__related),m=o?this.related:k.__related;if(o){this.setKeyContents(i);var n=this.findRelated(k);this.setRelated(n)}if(m&&this.related!==m){d.each(this.getReverseRelations(m),function(p){p.removeRelated(this.instance,null,k)},this)}d.each(this.getReverseRelations(),function(p){p.addRelated(this.instance,k)},this);if(!k.silent&&this.related!==m){var j=this;this.changed=true;h.Relational.eventQueue.add(function(){j.instance.trigger("change:"+j.key,j.instance,j.related,k,true);j.changed=false})}this.release()},tryAddRelated:function(j,k,i){if((this.keyId||this.keyId===0)&&j.id===this.keyId){this.addRelated(j,i);this.keyId=null}},addRelated:function(k,j){var i=this;k.queue(function(){if(k!==i.related){var l=i.related||null;i.setRelated(k);i.onChange(i.instance,k,d.defaults({__related:l},j))}})},removeRelated:function(j,k,i){if(!this.related){return}if(j===this.related){var l=this.related||null;this.setRelated(null);this.onChange(this.instance,j,d.defaults({__related:l},i))}}});h.HasMany=h.Relation.extend({collectionType:null,options:{reverseRelation:{type:"HasOne"},collectionType:h.Collection,collectionKey:true,collectionOptions:{}},initialize:function(i){this.listenTo(this.instance,"relational:change:"+this.key,this.onChange);this.collectionType=this.options.collectionType;if(d.isFunction(this.collectionType)&&this.collectionType!==h.Collection&&!(this.collectionType.prototype instanceof h.Collection)){this.collectionType=d.result(this,"collectionType")}if(d.isString(this.collectionType)){this.collectionType=h.Relational.store.getObjectByName(this.collectionType)}if(this.collectionType!==h.Collection&&!(this.collectionType.prototype instanceof h.Collection)){throw new Error("`collectionType` must inherit from Backbone.Collection")}var j=this.findRelated(i);this.setRelated(j)},_prepareCollection:function(k){if(this.related){this.stopListening(this.related)}if(!k||!(k instanceof h.Collection)){var i=d.isFunction(this.options.collectionOptions)?this.options.collectionOptions(this.instance):this.options.collectionOptions;k=new this.collectionType(null,i)}k.model=this.relatedModel;if(this.options.collectionKey){var j=this.options.collectionKey===true?this.options.reverseRelation.key:this.options.collectionKey;if(k[j]&&k[j]!==this.instance){if(h.Relational.showWarnings&&typeof console!=="undefined"){console.warn("Relation=%o; collectionKey=%s already exists on collection=%o",this,j,this.options.collectionKey)}}else{if(j){k[j]=this.instance}}}this.listenTo(k,"relational:add",this.handleAddition).listenTo(k,"relational:remove",this.handleRemoval).listenTo(k,"relational:reset",this.handleReset);return k},findRelated:function(i){var k=null;i=d.defaults({parse:this.options.parse},i);if(this.keyContents instanceof h.Collection){this._prepareCollection(this.keyContents);k=this.keyContents}else{var j=[];d.each(this.keyContents,function(l){var m=null;if(l instanceof this.relatedModel){m=l}else{m=(d.isObject(l)&&i.parse&&this.relatedModel.prototype.parse)?this.relatedModel.prototype.parse(d.clone(l),i):l}m&&j.push(m)},this);if(this.related instanceof h.Collection){k=this.related}else{k=this._prepareCollection()}k.set(j,d.defaults({parse:false},i))}this.keyIds=d.difference(this.keyIds,d.pluck(k.models,"id"));return k},setKeyContents:function(i){this.keyContents=i instanceof h.Collection?i:null;this.keyIds=[];if(!this.keyContents&&(i||i===0)){this.keyContents=d.isArray(i)?i:[i];d.each(this.keyContents,function(j){var k=h.Relational.store.resolveIdForItem(this.relatedModel,j);if(k||k===0){this.keyIds.push(k)}},this)}},onChange:function(l,i,k){k=k?d.clone(k):{};this.setKeyContents(i);this.changed=false;var m=this.findRelated(k);this.setRelated(m);if(!k.silent){var j=this;h.Relational.eventQueue.add(function(){if(j.changed){j.instance.trigger("change:"+j.key,j.instance,j.related,k,true);j.changed=false}})}},handleAddition:function(k,l,j){j=j?d.clone(j):{};this.changed=true;d.each(this.getReverseRelations(k),function(m){m.addRelated(this.instance,j)},this);var i=this;!j.silent&&h.Relational.eventQueue.add(function(){i.instance.trigger("add:"+i.key,k,i.related,j)})},handleRemoval:function(k,l,j){j=j?d.clone(j):{};this.changed=true;d.each(this.getReverseRelations(k),function(m){m.removeRelated(this.instance,null,j)},this);var i=this;!j.silent&&h.Relational.eventQueue.add(function(){i.instance.trigger("remove:"+i.key,k,i.related,j)})},handleReset:function(k,j){var i=this;j=j?d.clone(j):{};!j.silent&&h.Relational.eventQueue.add(function(){i.instance.trigger("reset:"+i.key,i.related,j)})},tryAddRelated:function(j,k,i){var l=d.contains(this.keyIds,j.id);if(l){this.addRelated(j,i);this.keyIds=d.without(this.keyIds,j.id)}},addRelated:function(k,j){var i=this;k.queue(function(){if(i.related&&!i.related.get(k)){i.related.add(k,d.defaults({parse:false},j))}})},removeRelated:function(j,k,i){if(this.related.get(j)){this.related.remove(j,i)}}});h.RelationalModel=h.Model.extend({relations:null,_relations:null,_isInitialized:false,_deferProcessing:false,_queue:null,_attributeChangeFired:false,subModelTypeAttribute:"type",subModelTypes:null,constructor:function(j,k){if(k&&k.collection){var i=this,m=this.collection=k.collection;delete k.collection;this._deferProcessing=true;var l=function(n){if(n===i){i._deferProcessing=false;i.processQueue();m.off("relational:add",l)}};m.on("relational:add",l);d.defer(function(){l(i)})}h.Relational.store.processOrphanRelations();h.Relational.store.listenTo(this,"relational:unregister",h.Relational.store.unregister);this._queue=new h.BlockingQueue();this._queue.block();h.Relational.eventQueue.block();try{h.Model.apply(this,arguments)}finally{h.Relational.eventQueue.unblock()}},trigger:function(j){if(j.length>5&&j.indexOf("change")===0){var i=this,k=arguments;if(!h.Relational.eventQueue.isBlocked()){h.Model.prototype.trigger.apply(i,k)}else{h.Relational.eventQueue.add(function(){var n=true;if(j==="change"){n=i.hasChanged()||i._attributeChangeFired;i._attributeChangeFired=false}else{var m=j.slice(7),l=i.getRelation(m);if(l){n=(k[4]===true);if(n){i.changed[m]=k[2]}else{if(!l.changed){delete i.changed[m]}}}else{if(n){i._attributeChangeFired=true}}}n&&h.Model.prototype.trigger.apply(i,k)})}}else{if(j==="destroy"){h.Model.prototype.trigger.apply(this,arguments);h.Relational.store.unregister(this)}else{h.Model.prototype.trigger.apply(this,arguments)}}return this},initializeRelations:function(i){this.acquire();this._relations={};d.each(this.relations||[],function(j){h.Relational.store.initializeRelation(this,j,i)},this);this._isInitialized=true;this.release();this.processQueue()},updateRelations:function(j,i){if(this._isInitialized&&!this.isLocked()){d.each(this._relations,function(l){if(!j||(l.keySource in j||l.key in j)){var m=this.attributes[l.keySource]||this.attributes[l.key],k=j&&(j[l.keySource]||j[l.key]);if(l.related!==m||(m===null&&k===null)){this.trigger("relational:change:"+l.key,this,m,i||{})}}if(l.keySource!==l.key){delete this.attributes[l.keySource]}},this)}},queue:function(i){this._queue.add(i)},processQueue:function(){if(this._isInitialized&&!this._deferProcessing&&this._queue.isBlocked()){this._queue.unblock()}},getRelation:function(i){return this._relations[i]},getRelations:function(){return d.values(this._relations)},getIdsToFetch:function(j,l){var i=j instanceof h.Relation?j:this.getRelation(j),k=i?(i.keyIds&&i.keyIds.slice(0))||((i.keyId||i.keyId===0)?[i.keyId]:[]):[];if(l){var m=i.related&&(i.related.models||[i.related]);d.each(m,function(n){if(n.id||n.id===0){k.push(n.id)}})}return k},getAsync:function(r,u){u=d.extend({add:true,remove:false,refresh:false},u);var n=this,j=[],t=this.getRelation(r),m=t&&this.getIdsToFetch(t,u.refresh),k=t.related instanceof h.Collection?t.related:t.relatedCollection;if(m&&m.length){var l=[],s=[],o,p=function(){l=d.map(m,function(x){var w=t.relatedModel.findModel(x);if(!w){var v={};v[t.relatedModel.prototype.idAttribute]=x;w=t.relatedModel.findOrCreate(v,u);s.push(w)}return w},this)};if(k instanceof h.Collection&&d.isFunction(k.url)){var q=k.url();o=k.url(m);if(o===q){p();o=k.url(l);if(o===q){o=null}}}if(o){var i=d.defaults({error:function(){d.each(s,function(v){v.trigger("destroy",v,v.collection,u)});u.error&&u.error.apply(l,arguments)},url:o},u);j=[k.fetch(i)]}else{if(!l.length){p()}j=d.map(l,function(v){var w=d.defaults({error:function(){if(d.contains(s,v)){v.trigger("destroy",v,v.collection,u)}u.error&&u.error.apply(l,arguments)}},u);return v.fetch(w)},this)}}return this.deferArray(j).then(function(){return h.Model.prototype.get.call(n,r)})},deferArray:function(i){return h.$.when.apply(null,i)},set:function(m,n,l){h.Relational.eventQueue.block();var j,i;if(d.isObject(m)||m==null){j=m;l=n}else{j={};j[m]=n}try{var o=this.id,k=j&&this.idAttribute in j&&j[this.idAttribute];h.Relational.store.checkId(this,k);i=h.Model.prototype.set.apply(this,arguments);if(!this._isInitialized&&!this.isLocked()){this.constructor.initializeModelHierarchy();if(k||k===0){h.Relational.store.register(this)}this.initializeRelations(l)}else{if(k&&k!==o){h.Relational.store.update(this)}}if(j){this.updateRelations(j,l)}}finally{h.Relational.eventQueue.unblock()}return i},clone:function(){var i=d.clone(this.attributes);if(!d.isUndefined(i[this.idAttribute])){i[this.idAttribute]=null}d.each(this.getRelations(),function(j){delete i[j.key]});return new this.constructor(i)},toJSON:function(i){if(this.isLocked()){return this.id}this.acquire();var j=h.Model.prototype.toJSON.call(this,i);if(this.constructor._superModel&&!(this.constructor._subModelTypeAttribute in j)){j[this.constructor._subModelTypeAttribute]=this.constructor._subModelTypeValue}d.each(this._relations,function(k){var m=j[k.key],n=k.options.includeInJSON,l=null;if(n===true){if(m&&d.isFunction(m.toJSON)){l=m.toJSON(i)}}else{if(d.isString(n)){if(m instanceof h.Collection){l=m.pluck(n)}else{if(m instanceof h.Model){l=m.get(n)}}if(n===k.relatedModel.prototype.idAttribute){if(k instanceof h.HasMany){l=l.concat(k.keyIds)}else{if(k instanceof h.HasOne){l=l||k.keyId;if(!l&&!d.isObject(k.keyContents)){l=k.keyContents||null}}}}}else{if(d.isArray(n)){if(m instanceof h.Collection){l=[];m.each(function(p){var o={};d.each(n,function(q){o[q]=p.get(q)});l.push(o)})}else{if(m instanceof h.Model){l={};d.each(n,function(o){l[o]=m.get(o)})}}}else{delete j[k.key]}}}if(l===null&&i&&i.wait){l=m}if(n){j[k.keyDestination]=l}if(k.keyDestination!==k.key){delete j[k.key]}});this.release();return j}},{setup:function(i){this.prototype.relations=(this.prototype.relations||[]).slice(0);this._subModels={};this._superModel=null;if(this.prototype.hasOwnProperty("subModelTypes")){h.Relational.store.addSubModels(this.prototype.subModelTypes,this)}else{this.prototype.subModelTypes=null}d.each(this.prototype.relations||[],function(j){if(!j.model){j.model=this}if(j.reverseRelation&&j.model===this){var l=true;if(d.isString(j.relatedModel)){var k=h.Relational.store.getObjectByName(j.relatedModel);l=k&&(k.prototype instanceof h.RelationalModel)}if(l){h.Relational.store.initializeRelation(null,j)}else{if(d.isString(j.relatedModel)){h.Relational.store.addOrphanRelation(j)}}}},this);return this},build:function(i,k){this.initializeModelHierarchy();var j=this._findSubModelType(this,i)||this;return new j(i,k)},_findSubModelType:function(l,k){if(l._subModels&&l.prototype.subModelTypeAttribute in k){var j=k[l.prototype.subModelTypeAttribute];var i=l._subModels[j];if(i){return i}else{for(j in l._subModels){i=this._findSubModelType(l._subModels[j],k);if(i){return i}}}}return null},initializeModelHierarchy:function(){this.inheritRelations();if(this.prototype.subModelTypes){var j=d.keys(this._subModels);var i=d.omit(this.prototype.subModelTypes,j);d.each(i,function(l){var k=h.Relational.store.getObjectByName(l);k&&k.initializeModelHierarchy()})}},inheritRelations:function(){if(!d.isUndefined(this._superModel)&&!d.isNull(this._superModel)){return}h.Relational.store.setupSuperModel(this);if(this._superModel){this._superModel.inheritRelations();if(this._superModel.prototype.relations){var i=d.filter(this._superModel.prototype.relations||[],function(j){return !d.any(this.prototype.relations||[],function(k){return j.relatedModel===k.relatedModel&&j.key===k.key},this)},this);this.prototype.relations=i.concat(this.prototype.relations)}}else{this._superModel=false}},findOrCreate:function(i,k){k||(k={});var l=(d.isObject(i)&&k.parse&&this.prototype.parse)?this.prototype.parse(d.clone(i),k):i;var j=this.findModel(l);if(d.isObject(i)){if(j&&k.merge!==false){delete k.collection;delete k.url;j.set(l,k)}else{if(!j&&k.create!==false){j=this.build(l,d.defaults({parse:false},k))}}}return j},find:function(i,j){j||(j={});j.create=false;return this.findOrCreate(i,j)},findModel:function(i){return h.Relational.store.find(this,i)}});d.extend(h.RelationalModel.prototype,h.Semaphore);h.Collection.prototype.__prepareModel=h.Collection.prototype._prepareModel;h.Collection.prototype._prepareModel=function(k,j){var i;if(k instanceof h.Model){if(!k.collection){k.collection=this}i=k}else{j=j?d.clone(j):{};j.collection=this;if(typeof this.model.findOrCreate!=="undefined"){i=this.model.findOrCreate(k,j)}else{i=new this.model(k,j)}if(i&&i.validationError){this.trigger("invalid",this,k,j);i=false}}return i};var g=h.Collection.prototype.__set=h.Collection.prototype.set;h.Collection.prototype.set=function(q,m){if(!(this.model.prototype instanceof h.RelationalModel)){return g.call(this,q,m)}if(m&&m.parse){q=this.parse(q,m)}var p=!d.isArray(q),k=[],o=[],l=null;q=p?(q?[q]:[]):d.clone(q);for(var n=0;n<q.length;n++){l=q[n];if(!(l instanceof h.Model)){l=h.Collection.prototype._prepareModel.call(this,l,m)}if(l){o.push(l);if(!(this.get(l)||this.get(l.cid))){k.push(l)}else{if(l.id!==null&&l.id!==undefined){this._byId[l.id]=l}}}}o=p?(o.length?o[0]:null):o;var j=g.call(this,o,d.defaults({merge:false,parse:false},m));for(n=0;n<k.length;n++){l=k[n];if(this.get(l)||this.get(l.cid)){this.trigger("relational:add",l,this,m)}}return j};var a=h.Collection.prototype.___removeModels=h.Collection.prototype._removeModels;h.Collection.prototype._removeModels=function(l,j){if(!(this.model.prototype instanceof h.RelationalModel)){return a.call(this,l,j)}var k=[];d.each(l,function(m){m=this.get(m)||(m&&this.get(m.cid));m&&k.push(m)},this);var i=a.call(this,k,j);d.each(k,function(m){this.trigger("relational:remove",m,this,j)},this);return i};var f=h.Collection.prototype.__reset=h.Collection.prototype.reset;h.Collection.prototype.reset=function(k,j){j=d.extend({merge:true},j);var i=f.call(this,k,j);if(this.model.prototype instanceof h.RelationalModel){this.trigger("relational:reset",this,j)}return i};var e=h.Collection.prototype.__sort=h.Collection.prototype.sort;h.Collection.prototype.sort=function(j){var i=e.call(this,j);if(this.model.prototype instanceof h.RelationalModel){this.trigger("relational:reset",this,j)}return i};var c=h.Collection.prototype.__trigger=h.Collection.prototype.trigger;h.Collection.prototype.trigger=function(j){if(!(this.model.prototype instanceof h.RelationalModel)){return c.apply(this,arguments)}if(j==="add"||j==="remove"||j==="reset"||j==="sort"){var i=this,k=arguments;if(d.isObject(k[3])){k=d.toArray(k);k[3]=d.clone(k[3])}h.Relational.eventQueue.add(function(){c.apply(i,k)})}else{c.apply(this,arguments)}return this};h.RelationalModel.extend=function(i,j){var k=h.Model.extend.call(this,i,j);k.setup(this);return k}}));