!function(a){"object"==typeof exports?module.exports=a(require("underscore"),require("backbone")):"function"==typeof define&&define.amd?define(["underscore","backbone"],a):a(_,Backbone)}(function(a,b){"use strict";function c(b,c){var d=[b,null].concat(c),e=a.bind.apply(b,d);return new e}function d(b){return function(){return c(b,a.toArray(arguments))}}if(!b)throw"Please include Backbone before Geppetto";var e="no mapping found for key: ",f={SINGLETON:"singleton",VIEW:"view",OTHER:"other"},g=function(a,b){var c,d;return a.hasOwnProperty("ctor")?(c=a.ctor,d=a.wiring):c=a,[b,c,d]},h=function(b,c,d){if(!a.isObject(b)||!a.isFunction(b.listenTo)||!a.isFunction(b.stopListening))throw"Target for listen() must define a 'listenTo' and 'stopListening' function";if(!a.isString(c))throw"eventName must be a String";if(!a.isFunction(d))throw"callback must be a function"},i={};i.version="0.7.1",i.EVENT_CONTEXT_SHUTDOWN="Geppetto:contextShutdown";var j={};i.Context=function(c){this._mappings={},this.options=c||{},this.parentContext=this.options.parentContext,this.vent={},a.extend(this.vent,b.Events),this._contextId=a.uniqueId("Context"),j[this._contextId]=this;var d=this.wiring||this.options.wiring;d&&this._configureWirings(d),a.isFunction(this.initialize)&&this.initialize.apply(this,arguments)},i.Context.extend=b.View.extend,a.extend(i.Context.prototype,{_configureWirings:function(b){a.each(b.singletons,function(a,b){this.wireSingleton.apply(this,g(a,b))},this),a.each(b.classes,function(a,b){this.wireClass.apply(this,g(a,b))},this),a.each(b.values,function(a,b){this.wireValue(b,a)},this),a.each(b.views,function(a,b){this.wireView.apply(this,g(a,b))},this),this.wireCommands(b.commands)},_createAndSetupInstance:function(b){var d;if(b.params){var e=a.map(b.params,function(b){return a.isFunction(b)&&(b=b(this)),b},this);d=c(b.clazz,e)}else d=new b.clazz;return d.initialize||this.resolve(d,b.wiring),d},_retrieveFromCacheOrCreate:function(a,b){var c;if(this._mappings.hasOwnProperty(a)){var d=this._mappings[a];b||d.type!==f.SINGLETON?d.type===f.VIEW?c=d.clazz:d.clazz&&(c=this._createAndSetupInstance(d)):(d.object||(d.object=this._createAndSetupInstance(d)),c=d.object)}else{if(!this.parentContext||!this.parentContext.hasWiring(a))throw new Error(e+a);c=this.parentContext._retrieveFromCacheOrCreate(a,b)}return c},_wrapConstructor:function(a,b){var c=this;return a.extend?a.extend({constructor:function(){c.resolve(this,b),a.prototype.constructor.apply(this,arguments)}}):a},_mapContextEvents:function(b){a.each(b.contextEvents,function(c,d){a.isFunction(c)?this.listen(b,d,c):a.isString(c)&&this.listen(b,d,b[c])},this)},addPubSub:function(b){b.listen=a.bind(this.listen,this),b.dispatch=a.bind(this.dispatch,this)},listen:function(a,b,c){return h(a,b,c),a.listenTo(this.vent,b,c,a)},listenToOnce:function(a,b,c){return h(a,b,c),a.listenToOnce(this.vent,b,c,a)},dispatch:function(b,c){if(!a.isUndefined(c)&&!a.isObject(c))throw"Event payload must be an object";c=c||{},c.eventName=b,this.vent.trigger(b,c)},dispatchToParent:function(a,b){this.parentContext&&this.parentContext.vent.trigger(a,b)},dispatchToParents:function(a,b){!this.parentContext||b&&b.propagationDisabled||(this.parentContext.vent.trigger(a,b),this.parentContext&&this.parentContext.dispatchToParents(a,b))},dispatchGlobally:function(b,c){a.each(j,function(a){return a?void a.vent.trigger(b,c):!0})},wireCommand:function(b,c,d){var e=this;if(!a.isFunction(c))throw"Command must be constructable";this.vent.listenTo(this.vent,b,function(f){var g=new c(e,b,f);g.context=e,g.eventName=b,g.eventData=f,e.resolve(g,d),a.isFunction(g.execute)&&g.execute()})},wireCommands:function(b){var c=this;a.each(b,function(b,d){a.isArray(b)?a.each(b,function(a){c.wireCommand(d,a)}):c.wireCommand(d,b)})},wireValue:function(a,b){return this._mappings[a]={clazz:null,object:b,type:f.SINGLETON},this},wireClass:function(a,b,c){return this._mappings[a]={clazz:this._wrapConstructor(b,c),object:null,type:f.OTHER,wiring:c},this},wireView:function(a,b,c){return this._mappings[a]={clazz:d(this._wrapConstructor(b,c)),object:null,type:f.VIEW},this},wireSingleton:function(a,b,c){return this._mappings[a]={clazz:this._wrapConstructor(b,c),object:null,type:f.SINGLETON,wiring:c},this},configure:function(b){var c=this._mappings[b];if("undefined"==typeof c)throw new Error(e+b);if(!c.clazz||c.type===f.VIEW)throw new Error("Cannot configure "+b+": only possible for wirings of type singleton or class");c.params=a.toArray(arguments).slice(1)},hasWiring:function(a){return this._mappings.hasOwnProperty(a)||!!this.parentContext&&this.parentContext.hasWiring(a)},getObject:function(a){return this._retrieveFromCacheOrCreate(a,!1)},instantiate:function(a){return this._retrieveFromCacheOrCreate(a,!0)},resolve:function(b,c){if(c=c||b.wiring){var d=Number(!a.isArray(c));a.each(c,function(a){b[arguments[d]]=this.getObject(a)},this)}return this.addPubSub(b),this._mapContextEvents(b),this},release:function(a){return delete this._mappings[a],this},releaseAll:function(){return this._mappings={},this},destroy:function(){this.vent.stopListening(),this.releaseAll(),delete j[this._contextId],this.dispatchToParent(i.EVENT_CONTEXT_SHUTDOWN)}}),i.bindContext=function(a){this.options=a||{};var b=this.options.view,c=null;"function"==typeof this.options.context?(c=new this.options.context(this.options),b.close||(b.close=function(){b.trigger("close"),b.remove()}),b.on("close",function(){b.off("close"),c.destroy()})):"object"==typeof this.options.context&&(c=this.options.context),c.resolve(b);var d;return b.wiring||(b.context=c,d=c),d};var k={contexts:j,countEvents:function(){var b=0;return a.each(j,function(c,d){j.hasOwnProperty(d)&&(b+=a.size(c.vent._events))}),b},countContexts:function(){var b=0;return a.each(j,function(a,c){j.hasOwnProperty(c)&&b++}),b}};return i.setDebug=function(a){return this.debug=a?k:void 0,this.debug},b.Geppetto=i,i});