(function(){return function(factory){if(typeof define==="function"&&define.amd){return define("knockback",["underscore","backbone","knockout"],factory)}else{return factory.call(this)}}(function(){var COMPARE_ASCENDING,COMPARE_DESCENDING,COMPARE_EQUAL,KB_TYPE_ARRAY,KB_TYPE_COLLECTION,KB_TYPE_MODEL,KB_TYPE_SIMPLE,KB_TYPE_UNKNOWN,addStatisticsEvent,collapseOptions,copyProps,e,kb,ko,onReady,_,_argumentsAddKey,_arraySplice,_legacyWarning,_throwMissing,_throwUnexpected,_unwrapModels,_unwrapObservable,_wrappedKey,__bind=function(fn,me){return function(){return fn.apply(me,arguments)}};kb=function(){function kb(){}kb.VERSION="0.17.0";kb.TYPE_UNKNOWN=0;kb.TYPE_SIMPLE=1;kb.TYPE_ARRAY=2;kb.TYPE_MODEL=3;kb.TYPE_COLLECTION=4;kb.wasReleased=function(obj){return!obj||obj.__kb_released};kb.release=function(obj,pre_release_fn){var array,item,view_model,view_models,_i,_j,_len,_len1;if(!obj||obj!==Object(obj)||typeof obj==="function"&&!ko.isObservable(obj)||obj.__kb_released||obj instanceof kb.Model||obj instanceof kb.Collection){return this}if(_.isArray(obj)){array=obj.splice(0,obj.length);for(_i=0,_len=array.length;_i<_len;_i++){item=array[_i];kb.release(item)}return this}obj.__kb_released=true;!pre_release_fn||pre_release_fn();if(ko.isObservable(obj)||typeof obj.dispose==="function"||typeof obj.destroy==="function"||typeof obj.release==="function"){if(ko.isObservable(obj)&&_.isArray(array=obj())){if(obj.__kb_is_co||obj.__kb_is_o&&obj.valueType()===KB_TYPE_COLLECTION){if(obj.destroy){obj.destroy()}else if(obj.dispose){obj.dispose()}}else if(array.length){view_models=array.slice(0);array.splice(0,array.length);for(_j=0,_len1=view_models.length;_j<_len1;_j++){view_model=view_models[_j];kb.release(view_model)}}}else if(obj.release){obj.release()}else if(obj.destroy){obj.destroy()}else if(obj.dispose){obj.dispose()}}else{this.releaseKeys(obj)}return this};kb.releaseKeys=function(obj){var key,value;for(key in obj){value=obj[key];key==="__kb"||kb.release(value,function(){return obj[key]=null})}return this};kb.releaseOnNodeRemove=function(view_model,node){view_model||_throwUnexpected(this,"missing view model");node||_throwUnexpected(this,"missing node");return ko.utils.domNodeDisposal.addDisposeCallback(node,function(){return kb.release(view_model)})};kb.renderTemplate=function(template,view_model,options){var el,observable;if(options==null){options={}}el=document.createElement("div");observable=ko.renderTemplate(template,view_model,options,el,"replaceChildren");if(el.children.length===1){el=el.children[0]}kb.releaseOnNodeRemove(view_model,el);observable.dispose();if(view_model.afterRender&&!options.afterRender){view_model.afterRender(el)}return el};kb.applyBindings=function(view_model,node){ko.applyBindings(view_model,node);return kb.releaseOnNodeRemove(view_model,node)};return kb}();this.Knockback=this.kb=kb;if(typeof exports!=="undefined"){module.exports=kb}if(this.Parse){kb._=_=this.Parse._;kb.Parse=this.Parse;kb.Collection=this.Parse.Collection;kb.Model=this.Parse.Object;kb.Events=this.Parse.Events}else{if(!this._&&typeof require!=="undefined"){try{_=require("lodash")}catch(_error){e=_error;_=require("underscore")}}else{_=this._}kb._=_=_.hasOwnProperty("_")?_._:_;if(_.where&&!_.findWhere){_.mixin({findWhere:function(obj,attrs){var result;result=_.where(obj,attrs);if(result.length){return result[0]}else{return null}}})}kb.Backbone=!this.Backbone&&typeof require!=="undefined"?require("backbone"):this.Backbone;kb.Collection=kb.Backbone.Collection;kb.Model=kb.Backbone.Model;kb.Events=kb.Backbone.Events}kb.ko=ko=!this.ko&&typeof require!=="undefined"?require("knockout"):this.ko;_throwMissing=function(instance,message){throw""+(_.isString(instance)?instance:instance.constructor.name)+": "+message+" is missing"};_throwUnexpected=function(instance,message){throw""+(_.isString(instance)?instance:instance.constructor.name)+": "+message+" is unexpected"};_legacyWarning=function(identifier,last_version,message){var _base;this._legacy_warnings||(this._legacy_warnings={});(_base=this._legacy_warnings)[identifier]||(_base[identifier]=0);this._legacy_warnings[identifier]++;return console.warn("warning: '"+identifier+"' has been deprecated (will be removed in Knockback after "+last_version+"). "+message+".")};_arraySplice=Array.prototype.splice;_unwrapObservable=ko.utils.unwrapObservable;collapseOptions=function(options){var result;result=_.clone(options);while(options.options){_.defaults(result,options.options);options=options.options}delete result.options;return result};copyProps=function(dest,source){var key,value;for(key in source){value=source[key];dest[key]=value}return dest};var ctor=function(){};var inherits=function(parent,protoProps,staticProps){var child;if(protoProps&&protoProps.hasOwnProperty("constructor")){child=protoProps.constructor}else{child=function(){parent.apply(this,arguments)}}copyProps(child,parent);ctor.prototype=parent.prototype;child.prototype=new ctor;if(protoProps)copyProps(child.prototype,protoProps);if(staticProps)copyProps(child,staticProps);child.prototype.constructor=child;child.__super__=parent.prototype;return child};var extend=function(protoProps,classProps){var child=inherits(this,protoProps,classProps);child.extend=this.extend;return child};kb.extend=extend;KB_TYPE_UNKNOWN=kb.TYPE_UNKNOWN;KB_TYPE_SIMPLE=kb.TYPE_SIMPLE;KB_TYPE_ARRAY=kb.TYPE_ARRAY;KB_TYPE_MODEL=kb.TYPE_MODEL;KB_TYPE_COLLECTION=kb.TYPE_COLLECTION;_wrappedKey=function(obj,key,value){if(arguments.length===2){if(obj&&obj.__kb&&obj.__kb.hasOwnProperty(key)){return obj.__kb[key]}else{return void 0}}obj||_throwUnexpected(this,"no obj for wrapping "+key);obj.__kb||(obj.__kb={});obj.__kb[key]=value;return value};_argumentsAddKey=function(args,key){_arraySplice.call(args,1,0,key);return args};_unwrapModels=function(obj){var key,result,value;if(!obj){return obj}if(obj.__kb){if("object"in obj.__kb){return obj.__kb.object}else{return obj}}else if(_.isArray(obj)){return _.map(obj,function(test){return _unwrapModels(test)})}else if(_.isObject(obj)&&obj.constructor==={}.constructor){result={};for(key in obj){value=obj[key];result[key]=_unwrapModels(value)}return result}return obj};kb.utils=function(){function utils(){}utils.wrappedObservable=function(obj,value){return _wrappedKey.apply(this,_argumentsAddKey(arguments,"observable"))};utils.wrappedObject=function(obj,value){return _wrappedKey.apply(this,_argumentsAddKey(arguments,"object"))};utils.wrappedModel=function(obj,value){if(arguments.length===1){value=_wrappedKey(obj,"object");if(_.isUndefined(value)){return obj}else{return value}}else{return _wrappedKey(obj,"object",value)}};utils.wrappedStore=function(obj,value){return _wrappedKey.apply(this,_argumentsAddKey(arguments,"store"))};utils.wrappedStoreIsOwned=function(obj,value){return _wrappedKey.apply(this,_argumentsAddKey(arguments,"store_is_owned"))};utils.wrappedFactory=function(obj,value){return _wrappedKey.apply(this,_argumentsAddKey(arguments,"factory"))};utils.wrappedEventWatcher=function(obj,value){return _wrappedKey.apply(this,_argumentsAddKey(arguments,"event_watcher"))};utils.wrappedEventWatcherIsOwned=function(obj,value){return _wrappedKey.apply(this,_argumentsAddKey(arguments,"event_watcher_is_owned"))};utils.wrappedDestroy=function(obj){var __kb;if(!obj.__kb){return}if(obj.__kb.event_watcher){obj.__kb.event_watcher.releaseCallbacks(obj)}__kb=obj.__kb;obj.__kb=null;if(__kb.observable){__kb.observable.destroy=__kb.observable.release=null;this.wrappedDestroy(__kb.observable);__kb.observable=null}__kb.factory=null;if(__kb.event_watcher_is_owned){__kb.event_watcher.destroy()}__kb.event_watcher=null;if(__kb.store_is_owned){__kb.store.destroy()}return __kb.store=null};utils.valueType=function(observable){if(!observable){return KB_TYPE_UNKNOWN}if(observable.__kb_is_o){return observable.valueType()}if(observable.__kb_is_co||observable instanceof kb.Collection){return KB_TYPE_COLLECTION}if(observable instanceof kb.ViewModel||observable instanceof kb.Model){return KB_TYPE_MODEL}if(_.isArray(observable)){return KB_TYPE_ARRAY}return KB_TYPE_SIMPLE};utils.pathJoin=function(path1,path2){return(path1?path1[path1.length-1]!=="."?""+path1+".":path1:"")+path2};utils.optionsPathJoin=function(options,path){return _.defaults({path:this.pathJoin(options.path,path)},options)};utils.inferCreator=function(value,factory,path,owner,key){var creator,relation;if(factory){creator=factory.creatorForPath(value,path)}if(creator){return creator}if(owner&&kb.Backbone&&kb.Backbone.RelationalModel&&owner instanceof kb.Backbone.RelationalModel){key=_unwrapObservable(key);relation=_.find(owner.getRelations(),function(test){return test.key===key});if(relation){if(relation.collectionType||_.isArray(relation.keyContents)){return kb.CollectionObservable}else{return kb.ViewModel}}}if(!value){return null}if(value instanceof kb.Model){return kb.ViewModel}if(value instanceof kb.Collection){return kb.CollectionObservable}return null};utils.createFromDefaultCreator=function(obj,options){if(obj instanceof kb.Model){return kb.viewModel(obj,options)}if(obj instanceof kb.Collection){return kb.collectionObservable(obj,options)}if(_.isArray(obj)){return ko.observableArray(obj)}return ko.observable(obj)};utils.hasModelSignature=function(obj){return obj&&obj.attributes&&!obj.models&&typeof obj.get==="function"&&typeof obj.trigger==="function"};utils.hasCollectionSignature=function(obj){return obj&&obj.models&&typeof obj.get==="function"&&typeof obj.trigger==="function"};return utils}();kb.Factory=function(){Factory.useOptionsOrCreate=function(options,obj,owner_path){var factory;if(options.factory&&(!options.factories||options.factories&&options.factory.hasPathMappings(options.factories,owner_path))){return kb.utils.wrappedFactory(obj,options.factory)}factory=kb.utils.wrappedFactory(obj,new kb.Factory(options.factory));if(options.factories){factory.addPathMappings(options.factories,owner_path)}return factory};function Factory(parent_factory){this.parent_factory=parent_factory;this.paths={}}Factory.prototype.hasPath=function(path){return this.paths.hasOwnProperty(path)||this.parent_factory&&this.parent_factory.hasPath(path)};Factory.prototype.addPathMapping=function(path,create_info){return this.paths[path]=create_info};Factory.prototype.addPathMappings=function(factories,owner_path){var create_info,path;for(path in factories){create_info=factories[path];this.paths[kb.utils.pathJoin(owner_path,path)]=create_info}};Factory.prototype.hasPathMappings=function(factories,owner_path){var all_exist,creator,existing_creator,path;all_exist=true;for(path in factories){creator=factories[path];all_exist&=(existing_creator=this.creatorForPath(null,kb.utils.pathJoin(owner_path,path)))&&creator===existing_creator}return all_exist};Factory.prototype.creatorForPath=function(obj,path){var creator;if(creator=this.paths[path]){if(creator.view_model){return creator.view_model}else{return creator}}if(this.parent_factory){if(creator=this.parent_factory.creatorForPath(obj,path)){return creator}}return null};return Factory}();kb.Store=function(){Store.useOptionsOrCreate=function(options,obj,observable){if(options.store){options.store.register(obj,observable,options);return kb.utils.wrappedStore(observable,options.store)}else{kb.utils.wrappedStoreIsOwned(observable,true);return kb.utils.wrappedStore(observable,new kb.Store)}};function Store(){this.observable_records=[];this.replaced_observables=[]}Store.prototype.destroy=function(){return this.clear()};Store.prototype.clear=function(){var record,_i,_len,_ref;_ref=this.observable_records.splice(0,this.observable_records.length);for(_i=0,_len=_ref.length;_i<_len;_i++){record=_ref[_i];kb.release(record.observable)}kb.release(this.replaced_observables)};Store.prototype.register=function(obj,observable,options){var creator;if(!observable){return}if(ko.isObservable(observable)||observable.__kb_is_co){return}kb.utils.wrappedObject(observable,obj);obj||(observable.__kb_null=true);creator=options.creator?options.creator:options.path&&options.factory?options.factory.creatorForPath(obj,options.path):null;if(!creator){creator=observable.constructor}this.observable_records.push({obj:obj,observable:observable,creator:creator});return observable};Store.prototype.findIndex=function(obj,creator){var index,record,_ref;if(!obj||obj instanceof kb.Model){_ref=this.observable_records;for(index in _ref){record=_ref[index];if(!record.observable){continue}if(record.observable.__kb_released){record.obj=null;record.observable=null;continue}if(!obj&&!record.observable.__kb_null||obj&&(record.observable.__kb_null||record.obj!==obj)){continue}else if(record.creator===creator||record.creator.create&&record.creator.create===creator.create){return index}}}return-1};Store.prototype.find=function(obj,creator){var index;if((index=this.findIndex(obj,creator))<0){return null}else{return this.observable_records[index].observable}};Store.prototype.isRegistered=function(observable){var record,_i,_len,_ref;_ref=this.observable_records;for(_i=0,_len=_ref.length;_i<_len;_i++){record=_ref[_i];if(record.observable===observable){return true}}return false};Store.prototype.findOrCreate=function(obj,options){var creator,observable;options.store=this;options.creator||(options.creator=kb.utils.inferCreator(obj,options.factory,options.path));if(!options.creator&&obj instanceof kb.Model){options.creator=kv.ViewModel}creator=options.creator;if(!creator){return kb.utils.createFromDefaultCreator(obj,options)}else if(creator.models_only){return obj}if(creator){observable=this.find(obj,creator)}if(observable){return observable}if(creator.create){observable=creator.create(obj,options)}else{observable=new creator(obj,options)}observable||(observable=ko.observable(null));if(!ko.isObservable(observable)){this.isRegistered(observable)||this.register(obj,observable,options)}return observable};Store.prototype.findOrReplace=function(obj,creator,observable){var index,record;obj||_throwUnexpected(this,"obj missing");if((index=this.findIndex(obj,creator))<0){return this.register(obj,observable,{creator:creator})}else{record=this.observable_records[index];kb.utils.wrappedObject(record.observable)===obj||_throwUnexpected(this,"different object");if(record.observable!==observable){record.observable.constructor===observable.constructor||_throwUnexpected(this,"replacing different type");this.replaced_observables.push(record.observable);record.observable=observable}return observable}};return Store}();addStatisticsEvent=function(emitter,event_name,info){return!kb.statistics||kb.statistics.addModelEvent({name:event_name,emitter:emitter,key:info.key,path:info.path})};kb.EventWatcher=function(){EventWatcher.useOptionsOrCreate=function(options,emitter,obj,callback_options){if(options.event_watcher){if(!(options.event_watcher.emitter()===emitter||options.event_watcher.model_ref===emitter)){_throwUnexpected(this,"emitter not matching")}return kb.utils.wrappedEventWatcher(obj,options.event_watcher).registerCallbacks(obj,callback_options)}else{kb.utils.wrappedEventWatcherIsOwned(obj,true);return kb.utils.wrappedEventWatcher(obj,new kb.EventWatcher(emitter)).registerCallbacks(obj,callback_options)}};function EventWatcher(emitter,obj,callback_options){this._onModelUnloaded=__bind(this._onModelUnloaded,this);this._onModelLoaded=__bind(this._onModelLoaded,this);this.__kb||(this.__kb={});this.__kb.callbacks={};this.__kb._onModelLoaded=_.bind(this._onModelLoaded,this);this.__kb._onModelUnloaded=_.bind(this._onModelUnloaded,this);if(callback_options){this.registerCallbacks(obj,callback_options)}if(emitter){this.emitter(emitter)}else{this.ee=null}}EventWatcher.prototype.destroy=function(){this.emitter(null);this.__kb.callbacks=null;return kb.utils.wrappedDestroy(this)};EventWatcher.prototype.emitter=function(new_emitter){var callbacks,event_name,info,list,previous_emitter,_i,_len,_ref;if(arguments.length===0||this.ee===new_emitter){return this.ee}if(this.model_ref){this.model_ref.unbind("loaded",this.__kb._onModelLoaded);this.model_ref.unbind("unloaded",this.__kb._onModelUnloaded);this.model_ref.release();this.model_ref=null}if(kb.Backbone&&kb.Backbone.ModelRef&&new_emitter instanceof kb.Backbone.ModelRef){this.model_ref=new_emitter;this.model_ref.retain();this.model_ref.bind("loaded",this.__kb._onModelLoaded);this.model_ref.bind("unloaded",this.__kb._onModelUnloaded);new_emitter=this.model_ref.model()}else{delete this.model_ref}previous_emitter=this.ee;this.ee=new_emitter;_ref=this.__kb.callbacks;for(event_name in _ref){callbacks=_ref[event_name];if(previous_emitter){previous_emitter.unbind(event_name,callbacks.fn)}if(new_emitter){this.ee.bind(event_name,callbacks.fn)}list=callbacks.list;for(_i=0,_len=list.length;_i<_len;_i++){info=list[_i];if(info.emitter){info.emitter(this.ee)}}}return new_emitter};EventWatcher.prototype.registerCallbacks=function(obj,callback_info){var callbacks,event_name,event_names,event_selector,info,list,_i,_len,_this=this;obj||_throwMissing(this,"obj");callback_info||_throwMissing(this,"info");event_selector=callback_info.event_selector?callback_info.event_selector:"change";event_names=event_selector.split(" ");for(_i=0,_len=event_names.length;_i<_len;_i++){event_name=event_names[_i];if(!event_name){continue}callbacks=this.__kb.callbacks[event_name];if(!callbacks){list=[];callbacks={list:list,fn:function(emitter){var info,_j,_len1;for(_j=0,_len1=list.length;_j<_len1;_j++){info=list[_j];if(info.update&&!info.rel_fn){if(emitter&&info.key&&emitter.hasChanged&&!emitter.hasChanged(_unwrapObservable(info.key))){continue}!kb.statistics||addStatisticsEvent(emitter,event_name,info);info.update()}}return null}};this.__kb.callbacks[event_name]=callbacks;if(this.ee){this.ee.bind(event_name,callbacks.fn)}}info=_.defaults({obj:obj},callback_info);callbacks.list.push(info)}if(this.ee){if(kb.Backbone&&kb.Backbone.RelationalModel&&this.ee instanceof kb.Backbone.RelationalModel&&_.contains(event_names,"change")){this._modelBindRelatationalInfo("change",info)}info.emitter(this.ee)&&info.emitter}};EventWatcher.prototype.releaseCallbacks=function(obj){var callbacks,event_name,index,info,_ref,_ref1;if(!this.__kb.callbacks){return}_ref=this.__kb.callbacks;for(event_name in _ref){callbacks=_ref[event_name];_ref1=callbacks.list;for(index in _ref1){info=_ref1[index];if(info.obj!==obj){continue}callbacks.list.splice(index,1);if(info.rel_fn){this._modelUnbindRelatationalInfo(event_name,info)}if(!kb.wasReleased(obj)&&info.emitter){info.emitter(null)}return}}};EventWatcher.prototype._onModelLoaded=function(model){var callbacks,event_name,info,is_relational,list,_i,_len,_ref;is_relational=kb.Backbone&&kb.Backbone.RelationalModel&&model instanceof kb.Backbone.RelationalModel;this.ee=model;_ref=this.__kb.callbacks;for(event_name in _ref){callbacks=_ref[event_name];this.ee.bind(event_name,callbacks.fn);list=callbacks.list;for(_i=0,_len=list.length;_i<_len;_i++){info=list[_i];if(is_relational){this._modelBindRelatationalInfo(event_name,info)}if(info.emitter){info.emitter(this.ee)}}}};EventWatcher.prototype._onModelUnloaded=function(model){var callbacks,event_name,info,list,_i,_len,_ref;this.ee=null;_ref=this.__kb.callbacks;for(event_name in _ref){callbacks=_ref[event_name];model.unbind(event_name,callbacks.fn);list=callbacks.list;for(_i=0,_len=list.length;_i<_len;_i++){info=list[_i];if(info.rel_fn){this._modelUnbindRelatationalInfo(event_name,info)}if(info.emitter){info.emitter(null)}}}};EventWatcher.prototype._modelBindRelatationalInfo=function(event_name,info){var key,relation;if(event_name==="change"&&info.key&&info.update){key=_unwrapObservable(info.key);relation=_.find(this.ee.getRelations(),function(test){return test.key===key});if(!relation){return}info.rel_fn=function(emitter){!kb.statistics||addStatisticsEvent(emitter,""+event_name+" (relational)",info);return info.update()};if(relation.collectionType||_.isArray(relation.keyContents)){info.is_collection=true;this.ee.bind("add:"+info.key,info.rel_fn);this.ee.bind("remove:"+info.key,info.rel_fn)}else{this.ee.bind(Backbone.Relation.prototype.sanitizeOptions?"update:"+info.key:"change:"+info.key,info.rel_fn)}}};EventWatcher.prototype._modelUnbindRelatationalInfo=function(event_name,info){if(!info.rel_fn){return}if(info.is_collection){this.ee.unbind("add:"+info.key,info.rel_fn);this.ee.unbind("remove:"+info.key,info.rel_fn)}else{this.ee.unbind(Backbone.Relation.prototype.sanitizeOptions?"update:"+info.key:"change:"+info.key,info.rel_fn)}info.rel_fn=null};return EventWatcher}();kb.emitterObservable=function(emitter,observable){return new kb.EventWatcher(emitter,observable)};kb.Observable=function(){function Observable(model,options,vm){var create_options,event_watcher,observable,_this=this;this.vm=vm;options||_throwMissing(this,"options");this.vm||(this.vm={});if(_.isString(options)||ko.isObservable(options)){create_options=this.create_options={key:options}}else{create_options=this.create_options=collapseOptions(options)}this.key=create_options.key;delete create_options.key;this.key||_throwMissing(this,"key");!create_options.args||(this.args=create_options.args,delete create_options.args);!create_options.read||(this.read=create_options.read,delete create_options.read);!create_options.write||(this.write=create_options.write,delete create_options.write);event_watcher=create_options.event_watcher;delete create_options.event_watcher;this.vo=ko.observable(null);this._model=ko.observable();observable=kb.utils.wrappedObservable(this,ko.dependentObservable({read:function(){var arg,args,new_value,_i,_len,_ref;args=[_unwrapObservable(_this.key)];if(_this.args){if(_.isArray(_this.args)){_ref=_this.args;for(_i=0,_len=_ref.length;_i<_len;_i++){arg=_ref[_i];args.push(_unwrapObservable(arg))}}else{args.push(_unwrapObservable(_this.args))}}if(_this._mdl===_this._model()&&_this._mdl){new_value=_this.read?_this.read.apply(_this.vm,args):_this._mdl.get.apply(_this._mdl,args);_this.update(new_value)}return _unwrapObservable(_this.vo())},write:function(new_value){var arg,args,set_info,unwrapped_new_value,_i,_len,_ref;unwrapped_new_value=_unwrapModels(new_value);set_info={};set_info[_unwrapObservable(_this.key)]=unwrapped_new_value;args=_this.write?[unwrapped_new_value]:[set_info];if(_this.args){if(_.isArray(_this.args)){_ref=_this.args;for(_i=0,_len=_ref.length;_i<_len;_i++){arg=_ref[_i];args.push(_unwrapObservable(arg))}}else{args.push(_unwrapObservable(_this.args))}}if(_this._mdl){if(_this.write){_this.write.apply(_this.vm,args)}else{_this._mdl.set.apply(_this._mdl,args)}}return _this.update(new_value)},owner:this.vm}));observable.__kb_is_o=true;create_options.store=kb.utils.wrappedStore(observable,create_options.store);create_options.path=kb.utils.pathJoin(create_options.path,this.key);if(create_options.factories&&(typeof create_options.factories==="function"||create_options.factories.create)){create_options.factory=kb.utils.wrappedFactory(observable,new kb.Factory(create_options.factory));create_options.factory.addPathMapping(create_options.path,create_options.factories)}else{create_options.factory=kb.Factory.useOptionsOrCreate(create_options,observable,create_options.path)}delete create_options.factories;observable.value=_.bind(this.value,this);observable.valueType=_.bind(this.valueType,this);observable.destroy=_.bind(this.destroy,this);observable.model=this.model=ko.dependentObservable({read:function(){_this._model();return _this._mdl},write:function(new_model){if(_this.__kb_released||_this._mdl===new_model){return}_this._mdl=new_model;_this.update(null);return _this._model(new_model)}});kb.EventWatcher.useOptionsOrCreate({event_watcher:event_watcher},model,this,{emitter:this.model,update:_.bind(this.update,this),key:this.key,path:create_options.path});this.__kb_value||this.update();if(kb.LocalizedObservable&&create_options.localizer){observable=new create_options.localizer(observable);delete create_options.localizer}if(kb.DefaultObservable&&create_options.hasOwnProperty("default")){observable=kb.defaultObservable(observable,create_options["default"]);delete create_options["default"]}return observable}Observable.prototype.destroy=function(){var observable;observable=kb.utils.wrappedObservable(this);this.__kb_released=true;kb.release(this.__kb_value);this.__kb_value=null;this.model.dispose();this._mdl=this.model=observable.model=null;return kb.utils.wrappedDestroy(this)};Observable.prototype.value=function(){return this.__kb_value};Observable.prototype.valueType=function(){var new_value;new_value=this._mdl?this._mdl.get(this.key):null;this.value_type||this._updateValueObservable(new_value);return this.value_type};Observable.prototype.update=function(new_value){var new_type,value;if(this.__kb_released){return}if(this._mdl&&!arguments.length){new_value=this._mdl.get(_unwrapObservable(this.key))}new_value!==void 0||(new_value=null);new_type=kb.utils.valueType(new_value);if(!this.__kb_value||this.__kb_value.__kb_released||this.__kb_value.__kb_null&&new_value){this.__kb_value=void 0;this.value_type=void 0}value=this.__kb_value;if(_.isUndefined(this.value_type)||this.value_type!==new_type&&new_type!==KB_TYPE_UNKNOWN){if(this.value_type===KB_TYPE_COLLECTION&&new_type===KB_TYPE_ARRAY){return value(new_value)}else{return this._updateValueObservable(new_value)}}else if(this.value_type===KB_TYPE_MODEL){if(typeof value.model==="function"){if(value.model()!==new_value){return value.model(new_value)}}else if(kb.utils.wrappedObject(value)!==new_value){return this._updateValueObservable(new_value)}}else if(this.value_type===KB_TYPE_COLLECTION){if(value.collection()!==new_value){return value.collection(new_value)}}else{if(value()!==new_value){return value(new_value)}}};Observable.prototype._updateValueObservable=function(new_value){var create_options,creator,previous_value,value;create_options=this.create_options;create_options.creator=kb.utils.inferCreator(new_value,create_options.factory,create_options.path,this._mdl,this.key);this.value_type=KB_TYPE_UNKNOWN;creator=create_options.creator;previous_value=this.__kb_value;this.__kb_value=void 0;if(previous_value){kb.release(previous_value)}if(creator){if(create_options.store){value=create_options.store.findOrCreate(new_value,create_options)}else{if(creator.models_only){value=new_value;this.value_type=KB_TYPE_SIMPLE}else if(creator.create){value=creator.create(new_value,create_options)}else{value=new creator(new_value,create_options)}}}else{if(_.isArray(new_value)){this.value_type=KB_TYPE_ARRAY;value=ko.observableArray(new_value)}else{this.value_type=KB_TYPE_SIMPLE;value=ko.observable(new_value)}}if(this.value_type===KB_TYPE_UNKNOWN){if(!ko.isObservable(value)){this.value_type=KB_TYPE_MODEL;if(typeof value.model!=="function"){kb.utils.wrappedObject(value,new_value)}}else if(value.__kb_is_co){this.value_type=KB_TYPE_COLLECTION}else{this.value_type=KB_TYPE_SIMPLE}}this.__kb_value=value;return this.vo(value)};return Observable}();kb.observable=function(model,options,view_model){return new kb.Observable(model,options,view_model)};kb.ViewModel=function(){ViewModel.extend=kb.extend;function ViewModel(model,options,view_model){var attribute_keys,bb_model,event_watcher,keys,mapped_keys,mapping_info,vm_key,_mdl,_ref,_this=this;!model||model instanceof kb.Model||typeof model.get==="function"&&typeof model.bind==="function"||_throwUnexpected(this,"not a model");options||(options={});view_model||(view_model={});if(_.isArray(options)){options={keys:options}}else{options=collapseOptions(options)}this.__kb||(this.__kb={});this.__kb.vm_keys={};this.__kb.model_keys={};this.__kb.view_model=_.isUndefined(view_model)?this:view_model;!options.internals||(this.__kb.internals=options.internals);!options.excludes||(this.__kb.excludes=options.excludes);kb.Store.useOptionsOrCreate(options,model,this);this.__kb.path=options.path;kb.Factory.useOptionsOrCreate(options,this,options.path);_mdl=_wrappedKey(this,"_mdl",ko.observable());this.model=ko.dependentObservable({read:function(){_mdl();return kb.utils.wrappedObject(_this)},write:function(new_model){var event_watcher,missing;if(kb.utils.wrappedObject(_this)===new_model){return}if(_this.__kb_null){!new_model||_throwUnexpected(_this,"model set on shared null");return}kb.utils.wrappedObject(_this,new_model);event_watcher=kb.utils.wrappedEventWatcher(_this);if(!event_watcher){_mdl(new_model);return}event_watcher.emitter(new_model);if(!(_this.__kb.keys||!new_model||!new_model.attributes)){missing=_.difference(_.keys(new_model.attributes),_.keys(_this.__kb.model_keys));if(missing){_this._createObservables(new_model,missing)}}_mdl(new_model)}});event_watcher=kb.utils.wrappedEventWatcher(this,new kb.EventWatcher(model,this,{emitter:this.model}));if(options.requires&&_.isArray(options.requires)){keys=_.clone(options.requires)}if(this.__kb.internals){keys=keys?_.union(keys,this.__kb.internals):_.clone(this.__kb.internals)}if(options.keys){if(_.isArray(options.keys)){this.__kb.keys=options.keys;keys=keys?_.union(keys,options.keys):_.clone(options.keys)}else{mapped_keys={};_ref=options.keys;for(vm_key in _ref){mapping_info=_ref[vm_key];mapped_keys[_.isString(mapping_info)?mapping_info:mapping_info.key?mapping_info.key:vm_key]=true}this.__kb.keys=_.keys(mapped_keys)}}else{bb_model=event_watcher.emitter();if(bb_model&&bb_model.attributes){attribute_keys=_.keys(bb_model.attributes);keys=keys?_.union(keys,attribute_keys):attribute_keys}}if(keys&&this.__kb.excludes){keys=_.difference(keys,this.__kb.excludes)}if(_.isObject(options.keys)&&!_.isArray(options.keys)){this._mapObservables(model,options.keys)}if(_.isObject(options.requires)&&!_.isArray(options.requires)){this._mapObservables(model,options.requires)}!options.mappings||this._mapObservables(model,options.mappings);!keys||this._createObservables(model,keys);!kb.statistics||kb.statistics.register("ViewModel",this)}ViewModel.prototype.destroy=function(){var vm_key;if(this.__kb.view_model!==this){for(vm_key in this.__kb.vm_keys){this.__kb.view_model[vm_key]=null}}this.__kb.view_model=null;kb.releaseKeys(this);kb.utils.wrappedDestroy(this);return!kb.statistics||kb.statistics.unregister("ViewModel",this)};ViewModel.prototype.shareOptions=function(){return{store:kb.utils.wrappedStore(this),factory:kb.utils.wrappedFactory(this)}};ViewModel.prototype._createObservables=function(model,keys){var create_options,key,vm_key,_i,_len;create_options={store:kb.utils.wrappedStore(this),factory:kb.utils.wrappedFactory(this),path:this.__kb.path,event_watcher:kb.utils.wrappedEventWatcher(this)};for(_i=0,_len=keys.length;_i<_len;_i++){key=keys[_i];vm_key=this.__kb.internals&&_.contains(this.__kb.internals,key)?"_"+key:key;if(this[vm_key]){continue}this.__kb.vm_keys[vm_key]=true;this.__kb.model_keys[key]=true;create_options.key=key;this[vm_key]=this.__kb.view_model[vm_key]=kb.observable(model,create_options,this)}};ViewModel.prototype._mapObservables=function(model,mappings){var create_options,mapping_info,vm_key;create_options={store:kb.utils.wrappedStore(this),factory:kb.utils.wrappedFactory(this),path:this.__kb.path,event_watcher:kb.utils.wrappedEventWatcher(this)};for(vm_key in mappings){mapping_info=mappings[vm_key];if(this[vm_key]){continue}mapping_info=_.isString(mapping_info)?{key:mapping_info}:_.clone(mapping_info);mapping_info.key||(mapping_info.key=vm_key);this.__kb.vm_keys[vm_key]=true;this.__kb.model_keys[mapping_info.key]=true;this[vm_key]=this.__kb.view_model[vm_key]=kb.observable(model,_.defaults(mapping_info,create_options),this)}};return ViewModel}();kb.viewModel=function(model,options,view_model){return new kb.ViewModel(model,options,view_model)};COMPARE_EQUAL=0;COMPARE_ASCENDING=-1;COMPARE_DESCENDING=1;kb.compare=function(value_a,value_b){if(_.isString(value_a)){return value_a.localeCompare(""+value_b)}if(_.isString(value_b)){return value_b.localeCompare(""+value_a)}if(value_a===value_b){return COMPARE_EQUAL}else{if(value_a