define(function(require,exports,module){var EventDispatcher=require("utils/EventDispatcher"),CONNECTION_ATTEMPTS=10,CONNECTION_TIMEOUT=1e4,RETRY_DELAY=500,MAX_COUNTER_VALUE=4294967295;function setDeferredTimeout(deferred,delay){var timer=setTimeout(function(){deferred.reject("timeout")},delay);deferred.always(function(){clearTimeout(timer)})}function attemptSingleConnect(){var deferred=$.Deferred(),port=null,ws=null;return setDeferredTimeout(deferred,CONNECTION_TIMEOUT),brackets.app.getNodeState(function(err,nodePort){!err&&nodePort&&"rejected"!==deferred.state()?(port=nodePort,(ws=new WebSocket("ws://localhost:"+port)).binaryType="arraybuffer",ws.onclose=function(){deferred.reject("WebSocket closed")},ws.onopen=function(){ws.onclose=null,deferred.resolveWith(null,[ws,port])}):deferred.reject("brackets.app.getNodeState error: "+err)}),deferred.promise()}function NodeConnection(){this.domains={},this._registeredModules=[],this._pendingInterfaceRefreshDeferreds=[],this._pendingCommandDeferreds=[]}EventDispatcher.makeEventDispatcher(NodeConnection.prototype),NodeConnection.prototype.domains=null,NodeConnection.prototype._registeredModules=null,NodeConnection.prototype._ws=null,NodeConnection.prototype._port=null,NodeConnection.prototype._commandCount=1,NodeConnection.prototype._autoReconnect=!1,NodeConnection.prototype._pendingInterfaceRefreshDeferreds=null,NodeConnection.prototype._pendingCommandDeferreds=null,NodeConnection.prototype._getNextCommandID=function(){var nextID;return nextID=this._commandCount>4294967295?this._commandCount=0:this._commandCount++},NodeConnection.prototype._cleanup=function(){if(this.domains={},this._ws&&this._ws.readyState!==WebSocket.CLOSED)try{this._ws.close()}catch(e){}var failedDeferreds;this._pendingInterfaceRefreshDeferreds.concat(this._pendingCommandDeferreds).forEach(function(d){d.reject("cleanup")}),this._pendingInterfaceRefreshDeferreds=[],this._pendingCommandDeferreds=[],this._ws=null,this._port=null},NodeConnection.prototype.connect=function(autoReconnect){var self=this;self._autoReconnect=autoReconnect;var deferred=$.Deferred(),attemptCount=0,attemptTimestamp=null;function registerHandlersAndDomains(ws,port){function success(){self._ws.onclose=function(){if(self._autoReconnect){var $promise=self.connect(!0);self.trigger("close",$promise)}else self._cleanup(),self.trigger("close")},deferred.resolve()}function fail(err){self._cleanup(),deferred.reject(err)}self._ws=ws,self._port=port,self._ws.onmessage=self._receive.bind(self),self._refreshInterface().then(function(){self._registeredModules.length>0?self.loadDomains(self._registeredModules,!1).then(success,fail):success()},fail)}function doConnect(){attemptCount++,attemptTimestamp=new Date,attemptSingleConnect().then(registerHandlersAndDomains,function(){if(attemptCount