!function(e,t){"function"==typeofdefine&&define.amd?define(["exports","backbone","underscore"],t):"undefined"!=typeofexports?t(exports,require("backbone"),require("underscore")):t(e,e.Backbone,e._)}(this,function(e,t,i){"use strict";t.Relational={showWarnings:!0},t.Semaphore={_permitsAvailable:null,_permitsUsed:0,acquire:function(){if(this._permitsAvailable&&this._permitsUsed>=this._permitsAvailable)thrownewError("Max permits acquired");this._permitsUsed++},release:function(){if(0===this._permitsUsed)thrownewError("All permits released");this._permitsUsed--},isLocked:function(){returnthis._permitsUsed>0},setAvailablePermits:function(e){if(this._permitsUsed>e)thrownewError("Available permits cannot be less than used permits");this._permitsAvailable=e}},t.BlockingQueue=function(){this._queue=[]},i.extend(t.BlockingQueue.prototype,t.Semaphore,{_queue:null,add:function(e){this.isBlocked()?this._queue.push(e):e()},process:function(){vare=this._queue;for(this._queue=[];e&&e.length;)e.shift()()},block:function(){this.acquire()},unblock:function(){this.release(),this.isBlocked()||this.process()},isBlocked:function(){returnthis.isLocked()}}),t.Relational.eventQueue=newt.BlockingQueue,t.Store=function(){this._collections=[],this._reverseRelations=[],this._orphanRelations=[],this._subModels=[],this._modelScopes=[e]},i.extend(t.Store.prototype,t.Events,{initializeRelation:function(e,o,n){vars=i.isString(o.type)?t[o.type]||this.getObjectByName(o.type):o.type;if(s&&s.prototypeinstanceoft.Relation){news(e,o,n)}elset.Relational.showWarnings&&"undefined"!=typeofconsole&&console.warn("Relation=%o; missing or invalid relation type!",o)},addModelScope:function(e){this._modelScopes.push(e)},removeModelScope:function(e){this._modelScopes=i.without(this._modelScopes,e)},addSubModels:function(e,t){this._subModels.push({superModelType:t,subModels:e})},setupSuperModel:function(e){i.find(this._subModels,function(t){returni.filter(t.subModels||[],function(i,o){varn=this.getObjectByName(i);returne===n?(t.superModelType._subModels[o]=e,e._superModel=t.superModelType,e._subModelTypeValue=o,e._subModelTypeAttribute=t.superModelType.prototype.subModelTypeAttribute,!0):void0},this).length},this)},addReverseRelation:function(e){vart=i.any(this._reverseRelations,function(t){returni.all(e||[],function(e,i){returne===t[i]})});!t&&e.model&&e.type&&(this._reverseRelations.push(e),this._addRelation(e.model,e),this.retroFitRelation(e))},addOrphanRelation:function(e){vart=i.any(this._orphanRelations,function(t){returni.all(e||[],function(e,i){returne===t[i]})});!t&&e.model&&e.type&&this._orphanRelations.push(e)},processOrphanRelations:function(){i.each(this._orphanRelations.slice(0),function(e){varo=t.Relational.store.getObjectByName(e.relatedModel);o&&(this.initializeRelation(null,e),this._orphanRelations=i.without(this._orphanRelations,e))},this)},_addRelation:function(e,t){e.prototype.relations||(e.prototype.relations=[]),e.prototype.relations.push(t),i.each(e._subModels||[],function(e){this._addRelation(e,t)},this)},retroFitRelation:function(e){vart=this.getCollection(e.model,!1);t&&t.each(function(t){if(tinstanceofe.model){newe.type(t,e)}},this)},getCollection:function(e,o){einstanceoft.RelationalModel&&(e=e.constructor);for(varn=e;n._superModel;)n=n._superModel;vars=i.find(this._collections,function(e){returne.model===n});returns||o===!1||(s=this._createCollection(n)),s},getObjectByName:function(e){vart=e.split("."),o=null;returni.find(this._modelScopes,function(e){returno=i.reduce(t||[],function(e,t){returne?e[t]:void0},e),o&&o!==e?!0:void0},this),o},_createCollection:function(e){vari;returneinstanceoft.RelationalModel&&(e=e.constructor),e.prototypeinstanceoft.RelationalModel&&(i=newt.Collection,i.model=e,this._collections.push(i)),i},resolveIdForItem:function(e,o){varn=i.isString(o)||i.isNumber(o)?o:null;returnnull===n&&(oinstanceoft.RelationalModel?n=o.id:i.isObject(o)&&(n=o[e.prototype.idAttribute])),n||0===n||(n=null),n},find:function(e,t){vari=this.resolveIdForItem(e,t),o=this.getCollection(e);if(o){varn=o.get(i);if(ninstanceofe)returnn}returnnull},register:function(e){vart=this.getCollection(e);if(t){vari=e.collection;t.add(e),e.collection=i}},checkId:function(e,i){varo=this.getCollection(e),n=o&&o.get(i);if(n&&e!==n)throwt.Relational.showWarnings&&"undefined"!=typeofconsole&&console.warn("Duplicate id! Old RelationalModel=%o, new RelationalModel=%o",n,e),newError("Cannot instantiate more than one Backbone.RelationalModel with the same id per type!")},update:function(e){vart=this.getCollection(e);t.contains(e)||this.register(e),t._onModelEvent("change:"+e.idAttribute,e,t),e.trigger("relational:change:id",e,t)},unregister:function(e){varo,n;einstanceoft.Model?(o=this.getCollection(e),n=[e]):einstanceoft.Collection?(o=this.getCollection(e.model),n=i.clone(e.models)):(o=this.getCollection(e),n=i.clone(o.models)),i.each(n,function(e){this.stopListening(e),i.invoke(e.getRelations(),"stopListening")},this),i.contains(this._collections,e)?o.reset([]):i.each(n,function(e){o.get(e)?o.remove(e):o.trigger("relational:remove",e,o)},this)},reset:function(){this.stopListening(),i.each(this._collections,function(e){this.unregister(e)},this),this._collections=[],this._subModels=[],this._modelScopes=[e]}}),t.Relational.store=newt.Store,t.Relation=function(e,o,n){if(this.instance=e,o=i.isObject(o)?o:{},this.reverseRelation=i.defaults(o.reverseRelation||{},this.options.reverseRelation),this.options=i.defaults(o,this.options,t.Relation.prototype.options),this.reverseRelation.type=i.isString(this.reverseRelation.type)?t[this.reverseRelation.type]||t.Relational.store.getObjectByName(this.reverseRelation.type):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,i.isUndefined(this.relatedModel)&&(this.relatedModel=this.model),!i.isFunction(this.relatedModel)||this.relatedModel.prototypeinstanceoft.RelationalModel||(this.relatedModel=i.result(this,"relatedModel")),i.isString(this.relatedModel)&&(this.relatedModel=t.Relational.store.getObjectByName(this.relatedModel)),this.checkPreconditions()&&(!this.options.isAutoRelation&&this.reverseRelation.type&&this.reverseRelation.key&&t.Relational.store.addReverseRelation(i.defaults({isAutoRelation:!0,model:this.relatedModel,relatedModel:this.model,reverseRelation:this.options},this.reverseRelation)),e)){vars=this.keySource;s!==this.key&&i.isObject(this.instance.get(this.key))&&(s=this.key),this.setKeyContents(this.instance.get(s)),this.relatedCollection=t.Relational.store.getCollection(this.relatedModel),this.keySource!==this.key&&deletethis.instance.attributes[this.keySource],this.instance._relations[this.key]=this,this.initialize(n),this.options.autoFetch&&this.instance.getAsync(this.key,i.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)}},t.Relation.extend=t.Model.extend,i.extend(t.Relation.prototype,t.Events,t.Semaphore,{options:{createModels:!0,includeInJSON:!0,isAutoRelation:!1,autoFetch:!1,parse:!1},instance:null,key:null,keyContents:null,relatedModel:null,relatedCollection:null,reverseRelation:null,related:null,checkPreconditions:function(){vare=this.instance,o=this.key,n=this.model,s=this.relatedModel,l=t.Relational.showWarnings&&"undefined"!=typeofconsole;if(!n||!o||!s)returnl&&console.warn("Relation=%o: missing model, key or relatedModel (%o, %o, %o).",this,n,o,s),!1;if(!(n.prototypeinstanceoft.RelationalModel))returnl&&console.warn("Relation=%o: model does not inherit from Backbone.RelationalModel (%o).",this,e),!1;if(!(s.prototypeinstanceoft.RelationalModel))returnl&&console.warn("Relation=%o: relatedModel does not inherit from Backbone.RelationalModel (%o).",this,s),!1;if(thisinstanceoft.HasMany&&this.reverseRelation.type===t.HasMany)returnl&&console.warn("Relation=%o: relation is a HasMany, and the reverseRelation is HasMany as well.",this),!1;if(e&&i.keys(e._relations).length){varr=i.find(e._relations,function(e){returne.key===o},this);if(r)returnl&&console.warn("Cannot create relation=%o on %o for model=%o: already taken by relation=%o.",this,o,e,r),!1}return!0},setRelated:function(e){this.related=e,this.instance.attributes[this.key]=e},_isReverseRelation:function(e){returne.instanceinstanceofthis.relatedModel&&this.reverseRelation.key===e.key&&this.key===e.reverseRelation.key},getReverseRelations:function(e){for(vart=[],o=i.isUndefined(e)?this.related&&(this.related.models||[this.related]):[e],n=null,s=null,l=0;l<(o||[]).length;l++){n=o[l].getRelations()||[];for(varr=0;r<n.length;r++)s=n[r],this._isReverseRelation(s)&&t.push(s)}returnt},destroy:function(){this.stopListening(),thisinstanceoft.HasOne?this.setRelated(null):thisinstanceoft.HasMany&&this.setRelated(this._prepareCollection()),i.each(this.getReverseRelations(),function(e){e.removeRelated(this.instance)},this)}}),t.HasOne=t.Relation.extend({options:{reverseRelation:{type:"HasMany"}},initialize:function(e){this.listenTo(this.instance,"relational:change:"+this.key,this.onChange);vart=this.findRelated(e);this.setRelated(t),i.each(this.getReverseRelations(),function(t){t.addRelated(this.instance,e)},this)},findRelated:function(e){vart=null;if(e=i.defaults({parse:this.options.parse},e),this.keyContentsinstanceofthis.relatedModel)t=this.keyContents;elseif(this.keyContents||0===this.keyContents){varo=i.defaults({create:this.options.createModels},e);t=this.relatedModel.findOrCreate(this.keyContents,o)}returnt&&(this.keyId=null),t},setKeyContents:function(e){this.keyContents=e,this.keyId=t.Relational.store.resolveIdForItem(this.relatedModel,this.keyContents)},onChange:function(e,o,n){if(!this.isLocked()){this.acquire(),n=n?i.clone(n):{};vars=i.isUndefined(n.__related),l=s?this.related:n.__related;if(s){this.setKeyContents(o);varr=this.findRelated(n);this.setRelated(r)}if(l&&this.related!==l&&i.each(this.getReverseRelations(l),function(e){e.removeRelated(this.instance,null,n)},this),i.each(this.getReverseRelations(),function(e){e.addRelated(this.instance,n)},this),!n.silent&&this.related!==l){vara=this;this.changed=!0,t.Relational.eventQueue.add(function(){a.instance.trigger("change:"+a.key,a.instance,a.related,n,!0),a.changed=!1})}this.release()}},tryAddRelated:function(e,t,i){!this.keyId&&0!==this.keyId||e.id!==this.keyId||(this.addRelated(e,i),this.keyId=null)},addRelated:function(e,t){varo=this;e.queue(function(){if(e!==o.related){varn=o.related||null;o.setRelated(e),o.onChange(o.instance,e,i.defaults({__related:n},t))}})},removeRelated:function(e,t,o){if(this.related&&e===this.related){varn=this.related||null;this.setRelated(null),this.onChange(this.instance,e,i.defaults({__related:n},o))}}}),t.HasMany=t.Relation.extend({collectionType:null,options:{reverseRelation:{type:"HasOne"},collectionType:t.Collection,collectionKey:!0,collectionOptions:{}},initialize:function(e){if(this.listenTo(this.instance,"relational:change:"+this.key,this.onChange),this.collectionType=this.options.collectionType,!i.isFunction(this.collectionType)||this.collectionType===t.Collection||this.collectionType.prototypeinstanceoft.Collection||(this.collectionType=i.result(this,"collectionType")),i.isString(this.collectionType)&&(this.collectionType=t.Relational.store.getObjectByName(this.collectionType)),this.collectionType!==t.Collection&&!(this.collectionType.prototypeinstanceoft.Collection))thrownewError("`collectionType` must inherit from Backbone.Collection");varo=this.findRelated(e);this.setRelated(o)},_prepareCollection:function(e){if(this.related&&this.stopListening(this.related),!(e&&einstanceoft.Collection)){varo=i.isFunction(this.options.collectionOptions)?this.options.collectionOptions(this.instance):this.options.collectionOptions;e=newthis.collectionType(null,o)}if(e.model=this.relatedModel,this.options.collectionKey){varn=this.options.collectionKey===!0?this.options.reverseRelation.key:this.options.collectionKey;e[n]&&e[n]!==this.instance?t.Relational.showWarnings&&"undefined"!=typeofconsole&&console.warn("Relation=%o; collectionKey=%s already exists on collection=%o",this,n,this.options.collectionKey):n&&(e[n]=this.instance)}returnthis.listenTo(e,"relational:add",this.handleAddition).listenTo(e,"relational:remove",this.handleRemoval).listenTo(e,"relational:reset",this.handleReset),e},findRelated:function(e){varo=null;if(e=i.defaults({parse:this.options.parse},e),this.keyContentsinstanceoft.Collection)this._prepareCollection(this.keyContents),o=this.keyContents;else{varn=[];i.each(this.keyContents,function(t){varo=null;o=tinstanceofthis.relatedModel?t:this.relatedModel.findOrCreate(t,i.extend({merge:!0},e,{create:this.options.createModels})),o&&n.push(o)},this),o=this.relatedinstanceoft.Collection?this.related:this._prepareCollection(),o.set(n,i.defaults({merge:!1,parse:!1},e))}returnthis.keyIds=i.difference(this.keyIds,i.pluck(o.models,"id")),o},setKeyContents:function(e){this.keyContents=einstanceoft.Collection?e:null,this.keyIds=[],this.keyContents||!e&&0!==e||(this.keyContents=i.isArray(e)?e:[e],i.each(this.keyContents,function(e){vari=t.Relational.store.resolveIdForItem(this.relatedModel,e);(i||0===i)&&this.keyIds.push(i)},this))},onChange:function(e,o,n){n=n?i.clone(n):{},this.setKeyContents(o),this.changed=!1;vars=this.findRelated(n);if(this.setRelated(s),!n.silent){varl=this;t.Relational.eventQueue.add(function(){l.changed&&(l.instance.trigger("change:"+l.key,l.instance,l.related,n,!0),l.changed=!1)})}},handleAddition:function(e,o,n){n=n?i.clone(n):{},this.changed=!0,i.each(this.getReverseRelations(e),function(e){e.addRelated(this.instance,n)},this);vars=this;!n.silent&&t.Relational.eventQueue.add(function(){s.instance.trigger("add:"+s.key,e,s.related,n)})},handleRemoval:function(e,o,n){n=n?i.clone(n):{},this.changed=!0,i.each(this.getReverseRelations(e),function(e){e.removeRelated(this.instance,null,n)},this);vars=this;!n.silent&&t.Relational.eventQueue.add(function(){s.instance.trigger("remove:"+s.key,e,s.related,n)})},handleReset:function(e,o){varn=this;o=o?i.clone(o):{},!o.silent&&t.Relational.eventQueue.add(function(){n.instance.trigger("reset:"+n.key,n.related,o)})},tryAddRelated:function(e,t,o){varn=i.contains(this.keyIds,e.id);n&&(this.addRelated(e,o),this.keyIds=i.without(this.keyIds,e.id))},addRelated:function(e,t){varo=this;e.queue(function(){o.related&&!o.related.get(e)&&o.related.add(e,i.defaults({parse:!1},t))})},removeRelated:function(e,t,i){this.related.get(e)&&this.related.remove(e,i)}}),t.RelationalModel=t.Model.extend({relations:null,_relations:null,_isInitialized:!1,_deferProcessing:!1,_queue:null,_attributeChangeFired:!1,subModelTypeAttribute:"type",subModelTypes:null,constructor:function(e,o){if(o&&o.collection){varn=this,s=this.collection=o.collection;deleteo.collection,this._deferProcessing=!0;varl=function(e){e===n&&(n._deferProcessing=!1,n.processQueue(),s.off("relational:add",l))};s.on("relational:add",l),i.defer(function(){l(n)})}t.Relational.store.processOrphanRelations(),t.Relational.store.listenTo(this,"relational:unregister",t.Relational.store.unregister),this._queue=newt.BlockingQueue,this._queue.block(),t.Relational.eventQueue.block();try{t.Model.apply(this,arguments)}finally{t.Relational.eventQueue.unblock()}},trigger:function(e){if(e.length>5&&0===e.indexOf("change")){vari=this,o=arguments;t.Relational.eventQueue.isLocked()?t.Relational.eventQueue.add(function(){varn=!0;if("change"===e)n=i.hasChanged()||i._attributeChangeFired,i._attributeChangeFired=!1;else{vars=e.slice(7),l=i.getRelation(s);l?(n=o[4]===!0,n?i.changed[s]=o[2]:l.changed||deletei.changed[s]):n&&(i._attributeChangeFired=!0)}n&&t.Model.prototype.trigger.apply(i,o)}):t.Model.prototype.trigger.apply(i,o)}else"destroy"===e?(t.Model.prototype.trigger.apply(this,arguments),t.Relational.store.unregister(this)):t.Model.prototype.trigger.apply(this,arguments);returnthis},initializeRelations:function(e){this.acquire(),this._relations={},i.each(this.relations||[],function(i){t.Relational.store.initializeRelation(this,i,e)},this),this._isInitialized=!0,this.release(),this.processQueue()},updateRelations:function(e,t){this._isInitialized&&!this.isLocked()&&i.each(this._relations,function(i){if(!e||i.keySourceine||i.keyine){varo=this.attributes[i.keySource]||this.attributes[i.key],n=e&&(e[i.keySource]||e[i.key]);(i.related!==o||null===o&&null===n)&&this.trigger("relational:change:"+i.key,this,o,t||{})}i.keySource!==i.key&&deletethis.attributes[i.keySource]},this)},queue:function(e){this._queue.add(e)},processQueue:function(){this._isInitialized&&!this._deferProcessing&&this._queue.isBlocked()&&this._queue.unblock()},getRelation:function(e){returnthis._relations[e]},getRelations:function(){returni.values(this._relations)},getIdsToFetch:function(e,o){varn=einstanceoft.Relation?e:this.getRelation(e),s=n?n.keyIds&&n.keyIds.slice(0)||(n.keyId||0===n.keyId?[n.keyId]:[]):[];if(o){varl=n.related&&(n.related.models||[n.related]);i.each(l,function(e){(e.id||0===e.id)&&s.push(e.id)})}returns},getAsync:function(e,o){o=i.extend({add:!0,remove:!1,refresh:!1},o);varn=this,s=[],l=this.getRelation(e),r=l&&this.getIdsToFetch(l,o.refresh),a=l.relatedinstanceoft.Collection?l.related:l.relatedCollection;if(r&&r.length){varh,c=[],d=[],u=function(){c=i.map(r,function(e){vart=l.relatedModel.findModel(e);if(!t){vari={};i[l.relatedModel.prototype.idAttribute]=e,t=l.relatedModel.findOrCreate(i,o),d.push(t)}returnt},this)};if(ainstanceoft.Collection&&i.isFunction(a.url)){varp=a.url();h=a.url(r),h===p&&(u(),h=a.url(c),h===p&&(h=null))}if(h){varf=i.defaults({error:function(){i.each(d,function(e){e.trigger("destroy",e,e.collection,o)}),o.error&&o.error.apply(c,arguments)},url:h},o);s=[a.fetch(f)]}elsec.length||u(),s=i.map(c,function(e){vart=i.defaults({error:function(){i.contains(d,e)&&e.trigger("destroy",e,e.collection,o),o.error&&o.error.apply(c,arguments)}},o);returne.fetch(t)},this)}return$.when.apply(null,s).then(function(){returnt.Model.prototype.get.call(n,e)})},set:function(e,o,n){t.Relational.eventQueue.block();vars,l;i.isObject(e)||null==e?(s=e,n=o):(s={},s[e]=o);try{varr=this.id,a=s&&this.idAttributeins&&s[this.idAttribute];t.Relational.store.checkId(this,a),l=t.Model.prototype.set.apply(this,arguments),this._isInitialized||this.isLocked()?a&&a!==r&&t.Relational.store.update(this):(this.constructor.initializeModelHierarchy(),(a||0===a)&&t.Relational.store.register(this),this.initializeRelations(n)),s&&this.updateRelations(s,n)}finally{t.Relational.eventQueue.unblock()}returnl},clone:function(){vare=i.clone(this.attributes);returni.isUndefined(e[this.idAttribute])||(e[this.idAttribute]=null),i.each(this.getRelations(),function(t){deletee[t.key]}),newthis.constructor(e)},toJSON:function(e){if(this.isLocked())returnthis.id;this.acquire();varo=t.Model.prototype.toJSON.call(this,e);return!this.constructor._superModel||this.constructor._subModelTypeAttributeino||(o[this.constructor._subModelTypeAttribute]=this.constructor._subModelTypeValue),i.each(this._relations,function(n){vars=o[n.key],l=n.options.includeInJSON,r=null;l===!0?s&&i.isFunction(s.toJSON)&&(r=s.toJSON(e)):i.isString(l)?(sinstanceoft.Collection?r=s.pluck(l):sinstanceoft.Model&&(r=s.get(l)),l===n.relatedModel.prototype.idAttribute&&(ninstanceoft.HasMany?r=r.concat(n.keyIds):ninstanceoft.HasOne&&(r=r||n.keyId,r||i.isObject(n.keyContents)||(r=n.keyContents||null)))):i.isArray(l)?sinstanceoft.Collection?(r=[],s.each(function(e){vart={};i.each(l,function(i){t[i]=e.get(i)}),r.push(t)})):sinstanceoft.Model&&(r={},i.each(l,function(e){r[e]=s.get(e)})):deleteo[n.key],null===r&&e&&e.wait&&(r=s),l&&(o[n.keyDestination]=r),n.keyDestination!==n.key&&deleteo[n.key]}),this.release(),o}},{setup:function(){returnthis.prototype.relations=(this.prototype.relations||[]).slice(0),this._subModels={},this._superModel=null,this.prototype.hasOwnProperty("subModelTypes")?t.Relational.store.addSubModels(this.prototype.subModelTypes,this):this.prototype.subModelTypes=null,i.each(this.prototype.relations||[],function(e){if(e.model||(e.model=this),e.reverseRelation&&e.model===this){varo=!0;if(i.isString(e.relatedModel)){varn=t.Relational.store.getObjectByName(e.relatedModel);o=n&&n.prototypeinstanceoft.RelationalModel}o?t.Relational.store.initializeRelation(null,e):i.isString(e.relatedModel)&&t.Relational.store.addOrphanRelation(e)}},this),this},build:function(e,t){this.initializeModelHierarchy();vari=this._findSubModelType(this,e)||this;returnnewi(e,t)},_findSubModelType:function(e,t){if(e._subModels&&e.prototype.subModelTypeAttributeint){vari=t[e.prototype.subModelTypeAttribute],o=e._subModels[i];if(o)returno;for(iine._subModels)if(o=this._findSubModelType(e._subModels[i],t))returno}returnnull},initializeModelHierarchy:function(){if(this.inheritRelations(),this.prototype.subModelTypes){vare=i.keys(this._subModels),o=i.omit(this.prototype.subModelTypes,e);i.each(o,function(e){vari=t.Relational.store.getObjectByName(e);i&&i.initializeModelHierarchy()})}},inheritRelations:function(){if(i.isUndefined(this._superModel)||i.isNull(this._superModel))if(t.Relational.store.setupSuperModel(this),this._superModel){if(this._superModel.inheritRelations(),this._superModel.prototype.relations){vare=i.filter(this._superModel.prototype.relations||[],function(e){return!i.any(this.prototype.relations||[],function(t){returne.relatedModel===t.relatedModel&&e.key===t.key},this)},this);this.prototype.relations=e.concat(this.prototype.relations)}}elsethis._superModel=!1},findOrCreate:function(e,t){t||(t={});varo=i.isObject(e)&&t.parse&&this.prototype.parse?this.prototype.parse(i.clone(e)):e,n=this.findModel(o);returni.isObject(e)&&(n&&t.merge!==!1?(deletet.collection,deletet.url,n.set(o,t)):n||t.create===!1||(n=this.build(o,i.defaults({parse:!1},t)))),n},find:function(e,t){returnt||(t={}),t.create=!1,this.findOrCreate(e,t)},findModel:function(e){returnt.Relational.store.find(this,e)}}),i.extend(t.RelationalModel.prototype,t.Semaphore),t.Collection.prototype.__prepareModel=t.Collection.prototype._prepareModel,t.Collection.prototype._prepareModel=function(e,o){varn;returneinstanceoft.Model?(e.collection||(e.collection=this),n=e):(o=o?i.clone(o):{},o.collection=this,n="undefined"!=typeofthis.model.findOrCreate?this.model.findOrCreate(e,o):newthis.model(e,o),n&&n.validationError&&(this.trigger("invalid",this,e,o),n=!1)),n};varo=t.Collection.prototype.__set=t.Collection.prototype.set;t.Collection.prototype.set=function(e,n){if(!(this.model.prototypeinstanceoft.RelationalModel))returno.call(this,e,n);n&&n.parse&&(e=this.parse(e,n));vars=!i.isArray(e),l=[],r=[],a=null;e=s?e?[e]:[]:i.clone(e);for(varh=0;h<e.length;h++)a=e[h],ainstanceoft.Model||(a=t.Collection.prototype._prepareModel.call(this,a,n)),a&&(r.push(a),this.get(a)||this.get(a.cid)?null!==a.id&&void0!==a.id&&(this._byId[a.id]=a):l.push(a));r=s?r.length?r[0]:null:r;varc=o.call(this,r,i.defaults({merge:!1,parse:!1},n));for(h=0;h<l.length;h++)a=l[h],(this.get(a)||this.get(a.cid))&&this.trigger("relational:add",a,this,n);returnc};varn=t.Collection.prototype.__remove=t.Collection.prototype.remove;t.Collection.prototype.remove=function(e,o){if(!(this.model.prototypeinstanceoft.RelationalModel))returnn.call(this,e,o);vars=!i.isArray(e),l=[];e=s?e?[e]:[]:i.clone(e),o||(o={}),i.each(e,function(e){e=this.get(e)||e&&this.get(e.cid),e&&l.push(e)},this);varr=n.call(this,s?l.length?l[0]:null:l,o);returni.each(l,function(e){this.trigger("relational:remove",e,this,o)},this),r};vars=t.Collection.prototype.__reset=t.Collection.prototype.reset;t.Collection.prototype.reset=function(e,o){o=i.extend({merge:!0},o);varn=s.call(this,e,o);returnthis.model.prototypeinstanceoft.RelationalModel&&this.trigger("relational:reset",this,o),n};varl=t.Collection.prototype.__sort=t.Collection.prototype.sort;t.Collection.prototype.sort=function(e){vari=l.call(this,e);returnthis.model.prototypeinstanceoft.RelationalModel&&this.trigger("relational:reset",this,e),i};varr=t.Collection.prototype.__trigger=t.Collection.prototype.trigger;t.Collection.prototype.trigger=function(e){if(!(this.model.prototypeinstanceoft.RelationalModel))returnr.apply(this,arguments);if("add"===e||"remove"===e||"reset"===e||"sort"===e){varo=this,n=arguments;i.isObject(n[3])&&(n=i.toArray(n),n[3]=i.clone(n[3])),t.Relational.eventQueue.add(function(){r.apply(o,n)})}elser.apply(this,arguments);returnthis},t.RelationalModel.extend=function(e,i){varo=t.Model.extend.call(this,e,i);returno.setup(this),o}});