Skip to content
Browse files

Merge branch 'master' of github.com:socketstream/socketstream

Conflicts:
	README.md
  • Loading branch information...
2 parents f520c9f + 36fa7f4 commit 33c2d260c10ce8c1920d549de9692b7c5d8d94a3 @paulbjensen paulbjensen committed Jul 1, 2011
View
17 HISTORY.md
@@ -1,8 +1,21 @@
-0.1.01 / 2011-06-24
-===================
+0.1.2 / 2011-06-30
+==================
+
+* Added a new client-side helper file (think ActiveSupport in Rails). Checkout the README for full details (addyosmani, paulbjensen)
+
+Bug fixes:
+
+* Multi-byte UTF8 characters now supported by asset packer (elisee)
+* We now ensure /public/assets exists on startup (pusewicz)
+* OS X Dashboard 'WebClip' user agent now recognised as friendly by the browser_check middleware (paulbjensen)
+
+
+0.1.1 / 2011-06-24
+==================
* Fixed bug in the browser check middleware (was not able to handle headless browsers)
+
0.1.00 / 2011-06-23
===================
View
26 README.md
@@ -1,9 +1,9 @@
![SocketStream!](https://github.com/socketstream/socketstream/raw/master/new_project/public/images/logo.png)
-Latest release: 0.1.01 ([view changelog](https://github.com/socketstream/socketstream/blob/master/HISTORY.md))
+Latest release: 0.1.2 ([view changelog](https://github.com/socketstream/socketstream/blob/master/HISTORY.md))
-Twitter: socketstream - Google Group: http://groups.google.com/group/socketstream
+Twitter: [@socketstream](http://twitter.com/#!/socketstream) - Google Group: http://groups.google.com/group/socketstream
### Introduction
@@ -12,8 +12,7 @@ SocketStream is a new full stack web framework built around the [Single-page App
Project status: Highly experimental but usable. Improving almost every day.
-Follow @socketstream for the latest developments and thinking. Website coming soon.
-
+Follow [@socketstream](http://twitter.com/#!/socketstream) for the latest developments and thinking. Website coming soon.
### Features
@@ -407,6 +406,11 @@ All Shared code is pre-loaded and added to the SS.shared API tree which may be i
**Warning** All code within /app/shared will be compressed and transmitted to the client upon initial connection. So make sure you don't include any proprietary secret sauce or use any database/filesystem calls.
+### Helpers
+
+As of 1.0.2 SocketStream comes with a number of suggested JavaScript prototype helper methods, created automatically when you make a new project. The concept is very similar to ActiveSupport in Rails; however in SocketStream client-side helpers are entirely optional. Don't want them? Just delete /lib/client/3.helpers.js and they won't come back. In the near future we will have the same set of helpers in the back-end so you can feel free to use them in shared/server code.
+
+
### Sessions
SocketStream creates a new session when a browser connects to the server for the first time, storing a session cookie on the client and the details in Redis. When the same visitor returns (or presses refresh in the browser), the session is instantly retrieved.
@@ -672,7 +676,7 @@ Right now we don't have a definitive answer, but we have a number of innovative
### Tests
-Yes, we know. At the moment there are no tests. This is bad. We are currently evaluating testing frameworks in the hope of finding one we truly like. After all, we're likely to be stuck with it for a good many years, so we need to choose carefully. We will then begin writing unit and integration tests for parts of SocketStream which are unlikely to change in the near future. Right now, any help and contributions in this area would be very much appreciated.
+Yes, we know. At the moment there are very few tests. This is bad. We are currently evaluating testing frameworks in the hope of finding one we truly like. After all, we're likely to be stuck with it for a good many years, so we need to choose carefully. We will then begin writing unit and integration tests for parts of SocketStream which are unlikely to change in the near future. Right now, any help and contributions in this area would be very much appreciated.
### Known Issues
@@ -732,11 +736,15 @@ Q: Will websockets work in Opera?
A: As of this writing websockets is supported but turned off by default in Opera. In order for Opera 11 to run websockets apps you need to turn it on in the settings. Do "opera:config#Enable%20WebSockets" in the address field and hit enter. Check "Enable websockets" Save and you are good to go.
+### Core Team
-### Contributors
-
-* Owen Barnes (socketstream)
+* Owen Barnes (socketstream & owenb)
* Paul Jensen (paulbjensen)
+* Alan Milford (alz)
+* Addy Osmani (addyosmani)
+
+
+### Contributing
We welcome contributions from forward-thinking hackers keen to redefine what's possible on the web. Big, bold ideas, unconstrained by frameworks and concepts from the past will always be welcome.
@@ -749,7 +757,7 @@ If you wish to discuss an idea, or want to chat about anything else, email us at
### Credits
-Thanks to Guillermo Rauch (Socket.IO), TJ Holowaychuk (Stylus, Jade), Jeremy Ashkenas (CoffeeScript), Mihai Bazon (UglifyJS), Isaac Schlueter (NPM), Salvatore Sanfilippo (Redis) and the many others who's amazing work has made SocketStream possible.
+Thanks to Guillermo Rauch (Socket.IO), TJ Holowaychuk (Stylus, Jade), Jeremy Ashkenas (CoffeeScript), Mihai Bazon (UglifyJS), Isaac Schlueter (NPM), Salvatore Sanfilippo (Redis) and the many others who's amazing work has made SocketStream possible. Special thanks to Ryan Dahl (creator of node.js) for the inspiration to do things differently.
### Thanks!
View
10 lib/asset/index.coffee
@@ -17,6 +17,8 @@ watch_dirs = [
["#{__dirname}/../client", 'js', 'system'],
]
+default_directory_mode = 0755
+
# Load Asset sub-modules
exports.pack = require('./pack.coffee').init(@).pack
exports.compile = require('./compile.coffee').init(@).compile
@@ -62,6 +64,7 @@ ensureAssetsExist = ->
unless exports.files.js.lib? and exports.files.css.lib?
util.log "Generating essential asset files to get you started..."
try
+ ensurePublicPathExists()
exports.pack.libs()
SS.internal.state.save()
SS.internal.state.last_known = SS.internal.state.current()
@@ -88,4 +91,9 @@ findAssets = (cb) ->
f = exports.files[ext]
f[type] = file
cb()
-
+
+ensurePublicPathExists = ->
+ try
+ fs.mkdirSync(exports.public_path, default_directory_mode)
+ catch e
+ throw(e) unless e.code == 'EEXIST'
View
2 lib/client/cached/lib.min.js
@@ -17,4 +17,4 @@ return filter(k,v);}
if(/^[\],:{}\s]*$/.test(text.replace(/\\./g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof filter==='function'?walk('',j):j;}
throw new SyntaxError('parseJSON');}};}();};
var io=this.io={version:"0.6.3",setPath:function(path){window.console&&console.error&&console.error("io.setPath will be removed. Please set the variable WEB_SOCKET_SWF_LOCATION pointing to WebSocketMain.swf"),this.path=/\/$/.test(path)?path:path+"/",WEB_SOCKET_SWF_LOCATION=path+"lib/vendor/web-socket-js/WebSocketMain.swf"}};"jQuery"in this&&(jQuery.io=this.io),typeof window!="undefined"&&typeof WEB_SOCKET_SWF_LOCATION=="undefined"&&(WEB_SOCKET_SWF_LOCATION="/socket.io/lib/vendor/web-socket-js/WebSocketMain.swf"),function(){var io=this.io,pageLoaded=!1;io.util={load:function(fn){if(/loaded|complete/.test(document.readyState)||pageLoaded)return fn();"attachEvent"in window?window.attachEvent("onload",fn):window.addEventListener("load",fn,!1)},defer:function(fn){if(!io.util.webkit)return fn();io.util.load(function(){setTimeout(fn,100)})},inherit:function(ctor,superCtor){for(var i in superCtor.prototype)ctor.prototype[i]=superCtor.prototype[i]},indexOf:function(arr,item,from){for(var l=arr.length,i=from<0?Math.max(0,l+from):from||0;i<l;i++)if(arr[i]===item)return i;return-1},isArray:function(obj){return Object.prototype.toString.call(obj)==="[object Array]"},merge:function(target,additional){for(var i in additional)additional.hasOwnProperty(i)&&(target[i]=additional[i])}},io.util.webkit=/webkit/i.test(navigator.userAgent),io.util.load(function(){pageLoaded=!0})}(),function(){var io=this.io,frame="~m~",stringify=function(message){if(Object.prototype.toString.call(message)=="[object Object]"){if(!("JSON"in window)){var error="Socket.IO Error: Trying to encode as JSON, but JSON.stringify is missing.";if("console"in window&&console.error)console.error(error);else throw new Error(error);return'{ "$error": "'+error+'" }'}return"~j~"+JSON.stringify(message)}return String(message)},Transport=io.Transport=function(base,options){this.base=base,this.options={timeout:15e3},io.util.merge(this.options,options)};Transport.prototype.send=function(){throw new Error("Missing send() implementation")},Transport.prototype.connect=function(){throw new Error("Missing connect() implementation")},Transport.prototype.disconnect=function(){throw new Error("Missing disconnect() implementation")},Transport.prototype.encode=function(messages){var ret="",message;messages=io.util.isArray(messages)?messages:[messages];for(var i=0,l=messages.length;i<l;i++)message=messages[i]===null||messages[i]===undefined?"":stringify(messages[i]),ret+=frame+message.length+frame+message;return ret},Transport.prototype.decode=function(data){var messages=[],number,n;do{if(data.substr(0,3)!==frame)return messages;data=data.substr(3),number="",n="";for(var i=0,l=data.length;i<l;i++){n=Number(data.substr(i,1));if(data.substr(i,1)==n)number+=n;else{data=data.substr(number.length+frame.length),number=Number(number);break}}messages.push(data.substr(0,number)),data=data.substr(number)}while(data!=="");return messages},Transport.prototype.onData=function(data){this.setTimeout();var msgs=this.decode(data);if(msgs&&msgs.length)for(var i=0,l=msgs.length;i<l;i++)this.onMessage(msgs[i])},Transport.prototype.setTimeout=function(){var self=this;this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(function(){self.onTimeout()},this.options.timeout)},Transport.prototype.onTimeout=function(){this.onDisconnect()},Transport.prototype.onMessage=function(message){this.sessionid?message.substr(0,3)=="~h~"?this.onHeartbeat(message.substr(3)):message.substr(0,3)=="~j~"?this.base.onMessage(JSON.parse(message.substr(3))):this.base.onMessage(message):(this.sessionid=message,this.onConnect())},Transport.prototype.onHeartbeat=function(heartbeat){this.send("~h~"+heartbeat)},Transport.prototype.onConnect=function(){this.connected=!0,this.connecting=!1,this.base.onConnect(),this.setTimeout()},Transport.prototype.onDisconnect=function(){this.connecting=!1,this.connected=!1,this.sessionid=null,this.base.onDisconnect()},Transport.prototype.prepareUrl=function(){return(this.base.options.secure?"https":"http")+"://"+this.base.host+":"+this.base.options.port+"/"+this.base.options.resource+"/"+this.type+(this.sessionid?"/"+this.sessionid:"/")}}(),function(){var io=this.io,empty=new Function,XMLHttpRequestCORS=function(){if(!("XMLHttpRequest"in window))return!1;var a=new XMLHttpRequest;return a.withCredentials!=undefined}(),request=function(xdomain){if("XDomainRequest"in window&&xdomain)return new XDomainRequest;if("XMLHttpRequest"in window&&(!xdomain||XMLHttpRequestCORS))return new XMLHttpRequest;if(!xdomain){try{var a=new ActiveXObject("MSXML2.XMLHTTP");return a}catch(e){}try{var b=new ActiveXObject("Microsoft.XMLHTTP");return b}catch(e){}}return!1},XHR=io.Transport.XHR=function(){io.Transport.apply(this,arguments),this.sendBuffer=[]};io.util.inherit(XHR,io.Transport),XHR.prototype.connect=function(){this.get();return this},XHR.prototype.checkSend=function(){if(!this.posting&&this.sendBuffer.length){var encoded=this.encode(this.sendBuffer);this.sendBuffer=[],this.sendIORequest(encoded)}},XHR.prototype.send=function(data){io.util.isArray(data)?this.sendBuffer.push.apply(this.sendBuffer,data):this.sendBuffer.push(data),this.checkSend();return this},XHR.prototype.sendIORequest=function(data){var self=this;this.posting=!0,this.sendXHR=this.request("send","POST"),this.sendXHR.onreadystatechange=function(){var status;if(self.sendXHR.readyState==4){self.sendXHR.onreadystatechange=empty;try{status=self.sendXHR.status}catch(e){}self.posting=!1,status==200?self.checkSend():self.onDisconnect()}},this.sendXHR.send("data="+encodeURIComponent(data))},XHR.prototype.disconnect=function(){this.onDisconnect();return this},XHR.prototype.onDisconnect=function(){if(this.xhr){this.xhr.onreadystatechange=empty;try{this.xhr.abort()}catch(e){}this.xhr=null}if(this.sendXHR){this.sendXHR.onreadystatechange=empty;try{this.sendXHR.abort()}catch(e){}this.sendXHR=null}this.sendBuffer=[],io.Transport.prototype.onDisconnect.call(this)},XHR.prototype.request=function(url,method,multipart){var req=request(this.base.isXDomain());multipart&&(req.multipart=!0),req.open(method||"GET",this.prepareUrl()+(url?"/"+url:"")),method=="POST"&&"setRequestHeader"in req&&req.setRequestHeader("Content-type","application/x-www-form-urlencoded; charset=utf-8");return req},XHR.check=function(xdomain){try{if(request(xdomain))return!0}catch(e){}return!1},XHR.xdomainCheck=function(){return XHR.check(!0)},XHR.request=request}(),function(){var io=this.io,WS=io.Transport.websocket=function(){io.Transport.apply(this,arguments)};io.util.inherit(WS,io.Transport),WS.prototype.type="websocket",WS.prototype.connect=function(){var self=this;this.socket=new WebSocket(this.prepareUrl()),this.socket.onmessage=function(ev){self.onData(ev.data)},this.socket.onclose=function(ev){self.onDisconnect()},this.socket.onerror=function(e){self.onError(e)};return this},WS.prototype.send=function(data){this.socket&&this.socket.send(this.encode(data));return this},WS.prototype.disconnect=function(){this.socket&&this.socket.close();return this},WS.prototype.onError=function(e){this.base.emit("error",[e])},WS.prototype.prepareUrl=function(){return(this.base.options.secure?"wss":"ws")+"://"+this.base.host+":"+this.base.options.port+"/"+this.base.options.resource+"/"+this.type+(this.sessionid?"/"+this.sessionid:"")},WS.check=function(){return"WebSocket"in window&&WebSocket.prototype&&WebSocket.prototype.send&&!!WebSocket.prototype.send.toString().match(/native/i)&&typeof WebSocket!="undefined"},WS.xdomainCheck=function(){return!0}}(),function(){var io=this.io,Flashsocket=io.Transport.flashsocket=function(){io.Transport.websocket.apply(this,arguments)};io.util.inherit(Flashsocket,io.Transport.websocket),Flashsocket.prototype.type="flashsocket",Flashsocket.prototype.connect=function(){var self=this,args=arguments;WebSocket.__addTask(function(){io.Transport.websocket.prototype.connect.apply(self,args)});return this},Flashsocket.prototype.send=function(){var self=this,args=arguments;WebSocket.__addTask(function(){io.Transport.websocket.prototype.send.apply(self,args)});return this},Flashsocket.check=function(){if(typeof WebSocket=="undefined"||!("__addTask"in WebSocket)||!swfobject)return!1;return swfobject.hasFlashPlayerVersion("10.0.0")},Flashsocket.xdomainCheck=function(){return!0}}(),function(){var io=this.io,HTMLFile=io.Transport.htmlfile=function(){io.Transport.XHR.apply(this,arguments)};io.util.inherit(HTMLFile,io.Transport.XHR),HTMLFile.prototype.type="htmlfile",HTMLFile.prototype.get=function(){var self=this;this.open(),window.attachEvent("onunload",function(){self.destroy()})},HTMLFile.prototype.open=function(){this.doc=new ActiveXObject("htmlfile"),this.doc.open(),this.doc.write("<html></html>"),this.doc.parentWindow.s=this,this.doc.close();var iframeC=this.doc.createElement("div");this.doc.body.appendChild(iframeC),this.iframe=this.doc.createElement("iframe"),iframeC.appendChild(this.iframe),this.iframe.src=this.prepareUrl()+"/"+ +(new Date)},HTMLFile.prototype._=function(data,doc){this.onData(data);var script=doc.getElementsByTagName("script")[0];script.parentNode.removeChild(script)},HTMLFile.prototype.destroy=function(){if(this.iframe){try{this.iframe.src="about:blank"}catch(e){}this.doc=null,CollectGarbage()}},HTMLFile.prototype.disconnect=function(){this.destroy();return io.Transport.XHR.prototype.disconnect.call(this)},HTMLFile.check=function(){if("ActiveXObject"in window)try{var a=new ActiveXObject("htmlfile");return a&&io.Transport.XHR.check()}catch(e){}return!1},HTMLFile.xdomainCheck=function(){return!1}}(),function(){var io=this.io,XHRMultipart=io.Transport["xhr-multipart"]=function(){io.Transport.XHR.apply(this,arguments)};io.util.inherit(XHRMultipart,io.Transport.XHR),XHRMultipart.prototype.type="xhr-multipart",XHRMultipart.prototype.get=function(){var self=this;this.xhr=this.request("","GET",!0),this.xhr.onreadystatechange=function(){self.xhr.readyState==4&&self.onData(self.xhr.responseText)},this.xhr.send(null)},XHRMultipart.check=function(){return"XMLHttpRequest"in window&&"prototype"in XMLHttpRequest&&"multipart"in XMLHttpRequest.prototype},XHRMultipart.xdomainCheck=function(){return!0}}(),function(){var io=this.io,empty=new Function,XHRPolling=io.Transport["xhr-polling"]=function(){io.Transport.XHR.apply(this,arguments)};io.util.inherit(XHRPolling,io.Transport.XHR),XHRPolling.prototype.type="xhr-polling",XHRPolling.prototype.connect=function(){var self=this;io.util.defer(function(){io.Transport.XHR.prototype.connect.call(self)});return!1},XHRPolling.prototype.get=function(){var self=this;this.xhr=this.request(+(new Date),"GET"),this.xhr.onreadystatechange=function(){var status;if(self.xhr.readyState==4){self.xhr.onreadystatechange=empty;try{status=self.xhr.status}catch(e){}status==200?(self.onData(self.xhr.responseText),self.get()):self.onDisconnect()}},this.xhr.send(null)},XHRPolling.check=function(){return io.Transport.XHR.check()},XHRPolling.xdomainCheck=function(){return io.Transport.XHR.xdomainCheck()}}(),function(){var io=this.io,JSONPPolling=io.Transport["jsonp-polling"]=function(){io.Transport.XHR.apply(this,arguments),this.insertAt=document.getElementsByTagName("head")[0],this.index=io.JSONP.length,io.JSONP.push(this)};io.util.inherit(JSONPPolling,io.Transport["xhr-polling"]),io.JSONP=[],JSONPPolling.prototype.type="jsonp-polling",JSONPPolling.prototype.sendIORequest=function(data){var self=this;if(!("form"in this)){var form=document.createElement("FORM"),area=document.createElement("TEXTAREA"),id=this.iframeId="socket_io_iframe_"+this.index,iframe;form.style.position="absolute",form.style.top="-1000px",form.style.left="-1000px",form.target=id,form.method="POST",form.action=this.prepareUrl()+"/"+ +(new Date)+"/"+this.index,area.name="data",form.appendChild(area),this.insertAt.insertBefore(form,null),document.body.appendChild(form),this.form=form,this.area=area}function complete(){initIframe(),self.posting=!1,self.checkSend()}function initIframe(){self.iframe&&self.form.removeChild(self.iframe);try{iframe=document.createElement('<iframe name="'+self.iframeId+'">')}catch(e){iframe=document.createElement("iframe"),iframe.name=self.iframeId}iframe.id=self.iframeId,self.form.appendChild(iframe),self.iframe=iframe}initIframe(),this.posting=!0,this.area.value=data;try{this.form.submit()}catch(e){}this.iframe.attachEvent?iframe.onreadystatechange=function(){self.iframe.readyState=="complete"&&complete()}:this.iframe.onload=complete},JSONPPolling.prototype.get=function(){var self=this,script=document.createElement("SCRIPT");this.script&&(this.script.parentNode.removeChild(this.script),this.script=null),script.async=!0,script.src=this.prepareUrl()+"/"+ +(new Date)+"/"+this.index,script.onerror=function(){self.onDisconnect()},this.insertAt.insertBefore(script,null),this.script=script},JSONPPolling.prototype._=function(){this.onData.apply(this,arguments),this.get();return this},JSONPPolling.check=function(){return!0},JSONPPolling.xdomainCheck=function(){return!0}}(),function(){var io=this.io,Socket=io.Socket=function(host,options){this.host=host||document.domain,this.options={secure:!1,document:document,port:document.location.port||80,resource:"socket.io",transports:["websocket","flashsocket","htmlfile","xhr-multipart","xhr-polling","jsonp-polling"],transportOptions:{"xhr-polling":{timeout:25e3},"jsonp-polling":{timeout:25e3}},connectTimeout:5e3,tryTransportsOnConnectTimeout:!0,reconnect:!0,reconnectionDelay:500,maxReconnectionAttempts:10,rememberTransport:!0},io.util.merge(this.options,options),this.connected=!1,this.connecting=!1,this.reconnecting=!1,this.events={},this.transport=this.getTransport(),!this.transport&&"console"in window&&console.error("No transport available")};Socket.prototype.getTransport=function(override){var transports=override||this.options.transports,match;this.options.rememberTransport&&!override&&(match=this.options.document.cookie.match("(?:^|;)\\s*socketio=([^;]*)"),match&&(this.rememberedTransport=!0,transports=[decodeURIComponent(match[1])]));for(var i=0,transport;transport=transports[i];i++)if(io.Transport[transport]&&io.Transport[transport].check()&&(!this.isXDomain()||io.Transport[transport].xdomainCheck()))return new io.Transport[transport](this,this.options.transportOptions[transport]||{});return null},Socket.prototype.connect=function(fn){if(this.transport&&!this.connected){this.connecting&&this.disconnect(!0),this.connecting=!0,this.emit("connecting",[this.transport.type]),this.transport.connect();if(this.options.connectTimeout){var self=this;this.connectTimeoutTimer=setTimeout(function(){if(!self.connected){self.disconnect(!0);if(self.options.tryTransportsOnConnectTimeout&&!self.rememberedTransport){self.remainingTransports||(self.remainingTransports=self.options.transports.slice(0));var transports=self.remainingTransports;while(transports.length>0&&transports.splice(0,1)[0]!=self.transport.type);transports.length&&(self.transport=self.getTransport(transports),self.connect())}(!self.remainingTransports||self.remainingTransports.length==0)&&self.emit("connect_failed")}self.remainingTransports&&self.remainingTransports.length==0&&delete self.remainingTransports},this.options.connectTimeout)}}fn&&typeof fn=="function"&&this.once("connect",fn);return this},Socket.prototype.send=function(data){if(!this.transport||!this.transport.connected)return this.queue(data);this.transport.send(data);return this},Socket.prototype.disconnect=function(soft){this.connectTimeoutTimer&&clearTimeout(this.connectTimeoutTimer),soft||(this.options.reconnect=!1),this.transport.disconnect();return this},Socket.prototype.on=function(name,fn){name in this.events||(this.events[name]=[]),this.events[name].push(fn);return this},Socket.prototype.once=function(name,fn){var self=this,once=function(){self.removeEvent(name,once),fn.apply(self,arguments)};once.ref=fn,self.on(name,once);return this},Socket.prototype.emit=function(name,args){if(name in this.events){var events=this.events[name].concat();for(var i=0,ii=events.length;i<ii;i++)events[i].apply(this,args===undefined?[]:args)}return this},Socket.prototype.removeEvent=function(name,fn){if(name in this.events)for(var a=0,l=this.events[name].length;a<l;a++)(this.events[name][a]==fn||this.events[name][a].ref&&this.events[name][a].ref==fn)&&this.events[name].splice(a,1);return this},Socket.prototype.queue=function(message){"queueStack"in this||(this.queueStack=[]),this.queueStack.push(message);return this},Socket.prototype.doQueue=function(){if(!("queueStack"in this)||!this.queueStack.length)return this;this.transport.send(this.queueStack),this.queueStack=[];return this},Socket.prototype.isXDomain=function(){var locPort=window.location.port||80;return this.host!==document.domain||this.options.port!=locPort},Socket.prototype.onConnect=function(){this.connected=!0,this.connecting=!1,this.doQueue(),this.options.rememberTransport&&(this.options.document.cookie="socketio="+encodeURIComponent(this.transport.type)),this.emit("connect")},Socket.prototype.onMessage=function(data){this.emit("message",[data])},Socket.prototype.onDisconnect=function(){var wasConnected=this.connected;this.connected=!1,this.connecting=!1,this.queueStack=[],wasConnected&&(this.emit("disconnect"),this.options.reconnect&&!this.reconnecting&&this.onReconnect())},Socket.prototype.onReconnect=function(){this.reconnecting=!0,this.reconnectionAttempts=0,this.reconnectionDelay=this.options.reconnectionDelay;var self=this,tryTransportsOnConnectTimeout=this.options.tryTransportsOnConnectTimeout,rememberTransport=this.options.rememberTransport;function reset(){self.connected&&self.emit("reconnect",[self.transport.type,self.reconnectionAttempts]),self.removeEvent("connect_failed",maybeReconnect).removeEvent("connect",maybeReconnect),self.reconnecting=!1,delete self.reconnectionAttempts,delete self.reconnectionDelay,delete self.reconnectionTimer,delete self.redoTransports,self.options.tryTransportsOnConnectTimeout=tryTransportsOnConnectTimeout,self.options.rememberTransport=rememberTransport;return}function maybeReconnect(){if(!!self.reconnecting)if(!self.connected){if(self.connecting&&self.reconnecting)return self.reconnectionTimer=setTimeout(maybeReconnect,1e3);self.reconnectionAttempts++>=self.options.maxReconnectionAttempts?self.redoTransports?(self.emit("reconnect_failed"),reset()):(self.on("connect_failed",maybeReconnect),self.options.tryTransportsOnConnectTimeout=!0,self.transport=self.getTransport(self.options.transports),self.redoTransports=!0,self.connect()):(self.reconnectionDelay*=2,self.connect(),self.emit("reconnecting",[self.reconnectionDelay,self.reconnectionAttempts]),self.reconnectionTimer=setTimeout(maybeReconnect,self.reconnectionDelay))}else reset()}this.options.tryTransportsOnConnectTimeout=!1,this.reconnectionTimer=setTimeout(maybeReconnect,this.reconnectionDelay),this.on("connect",maybeReconnect)},Socket.prototype.fire=Socket.prototype.emit,Socket.prototype.addListener=Socket.prototype.addEvent=Socket.prototype.addEventListener=Socket.prototype.on,Socket.prototype.removeListener=Socket.prototype.removeEventListener=Socket.prototype.removeEvent}();var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=!1,U=[h],o=[],N=[],I=[],l,Q,E,B,J=!1,a=!1,n,G,m=!0,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):!1,X=!1,ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r)ab=t.plugins[S].description,ab&&(typeof t.mimeTypes==D||!t.mimeTypes[q]||!!t.mimeTypes[q].enabledPlugin)&&(T=!0,X=!1,ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1"),ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10),ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10),ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0);else if(typeof O.ActiveXObject!=D)try{var ad=new ActiveXObject(W);ad&&(ab=ad.GetVariable("$version"),ab&&(X=!0,ab=ab.split(" ")[1].split(","),ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]))}catch(Z){}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){!M.w3||((typeof j.readyState!=D&&j.readyState=="complete"||typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))&&f(),J||(typeof j.addEventListener!=D&&j.addEventListener("DOMContentLoaded",f,!1),M.ie&&M.win&&(j.attachEvent(x,function(){j.readyState=="complete"&&(j.detachEvent(x,arguments.callee),f())}),O==top&&function(){if(!J){try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()}}()),M.wk&&function(){if(!J){if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()}}(),s(f)))}();function f(){if(!J){try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=!0;var X=U.length;for(var Y=0;Y<X;Y++)U[Y]()}}function K(X){J?X():U[U.length]=X}function s(Y){if(typeof O.addEventListener!=D)O.addEventListener("load",Y,!1);else if(typeof j.addEventListener!=D)j.addEventListener("load",Y,!1);else if(typeof O.attachEvent!=D)i(O,"onload",Y);else if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X(),Y()}}else O.onload=Y}function h(){T?V():H()}function V(){var X=j.getElementsByTagName("body")[0],aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");ab&&(ab=ab.split(" ")[1].split(","),M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)])}else if(Y<10){Y++,setTimeout(arguments.callee,10);return}X.removeChild(aa),Z=null,H()})()}else H()}function H(){var ag=o.length;if(ag>0)for(var af=0;af<ag;af++){var Y=o[af].id,ab=o[af].callbackFn,aa={success:!1,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae)if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312))w(Y,!0),ab&&(aa.success=!0,aa.ref=z(Y),ab(aa));else if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall,ai.width=ae.getAttribute("width")||"0",ai.height=ae.getAttribute("height")||"0",ae.getAttribute("class")&&(ai.styleclass=ae.getAttribute("class")),ae.getAttribute("align")&&(ai.align=ae.getAttribute("align"));var ah={},X=ae.getElementsByTagName("param"),ac=X.length;for(var ad=0;ad<ac;ad++)X[ad].getAttribute("name").toLowerCase()!="movie"&&(ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value"));P(ai,ah,Y,ab)}else p(ae),ab&&ab(aa)}else{w(Y,!0);if(ab){var Z=z(Y);Z&&typeof Z.SetVariable!=D&&(aa.success=!0,aa.ref=Z),ab(aa)}}}}function z(aa){var X=null,Y=c(aa);if(Y&&Y.nodeName=="OBJECT")if(typeof Y.SetVariable!=D)X=Y;else{var Z=Y.getElementsByTagName(r)[0];Z&&(X=Z)}return X}function A(){return!a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=!0,E=Z||null,B={success:!1,id:X};var ae=c(X);if(ae){ae.nodeName=="OBJECT"?(l=g(ae),Q=null):(l=ae,Q=X),aa.id=R;if(typeof aa.width==D||!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)aa.width="310";if(typeof aa.height==D||!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)aa.height="137";j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;typeof ab.flashvars!=D?ab.flashvars+="&"+ac:ab.flashvars=ac;if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew",Y.setAttribute("id",X),ae.parentNode.insertBefore(Y,ae),ae.style.display="none",function(){ae.readyState==4?ae.parentNode.removeChild(ae):setTimeout(arguments.callee,10)}()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y),X.parentNode.replaceChild(g(Y),X),Y.style.display="none",function(){Y.readyState==4?Y.parentNode.removeChild(Y):setTimeout(arguments.callee,10)}()}else Y.parentNode.replaceChild(g(Y),Y)}function g(ab){var aa=C("div");if(M.win&&M.ie)aa.innerHTML=ab.innerHTML;else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++)(ad[Z].nodeType!=1||ad[Z].nodeName!="PARAM")&&ad[Z].nodeType!=8&&aa.appendChild(ad[Z].cloneNode(!0))}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312)return X;if(aa){typeof ai.id==D&&(ai.id=Y);if(M.ie&&M.win){var ah="";for(var ae in ai)ai[ae]!=Object.prototype[ae]&&(ae.toLowerCase()=="data"?ag.movie=ai[ae]:ae.toLowerCase()=="styleclass"?ah+=' class="'+ai[ae]+'"':ae.toLowerCase()!="classid"&&(ah+=" "+ae+'="'+ai[ae]+'"'));var af="";for(var ad in ag)ag[ad]!=Object.prototype[ad]&&(af+='<param name="'+ad+'" value="'+ag[ad]+'" />');aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>",N[N.length]=ai.id,X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai)ai[ac]!=Object.prototype[ac]&&(ac.toLowerCase()=="styleclass"?Z.setAttribute("class",ai[ac]):ac.toLowerCase()!="classid"&&Z.setAttribute(ac,ai[ac]));for(var ab in ag)ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"&&e(Z,ab,ag[ab]);aa.parentNode.replaceChild(Z,aa),X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X),aa.setAttribute("value",Y),Z.appendChild(aa)}function y(Y){var X=c(Y);X&&X.nodeName=="OBJECT"&&(M.ie&&M.win?(X.style.display="none",function(){X.readyState==4?b(Y):setTimeout(arguments.callee,10)}()):X.parentNode.removeChild(X))}function b(Z){var Y=c(Z);if(Y){for(var X in Y)typeof Y[X]=="function"&&(Y[X]=null);Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y),I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10),X[1]=parseInt(X[1],10)||0,X[2]=parseInt(X[2],10)||0;return Y[0]>X[0]||Y[0]==X[0]&&Y[1]>X[1]||Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]?!0:!1}function v(ac,Y,ad,ab){if(!M.ie||!M.mac){var aa=j.getElementsByTagName("head")[0];if(!aa)return;var X=ad&&typeof ad=="string"?ad:"screen";ab&&(n=null,G=null);if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css"),Z.setAttribute("media",X),n=aa.appendChild(Z),M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0&&(n=j.styleSheets[j.styleSheets.length-1]),G=X}M.ie&&M.win?n&&typeof n.addRule==r&&n.addRule(ac,Y):n&&typeof j.createTextNode!=D&&n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}function w(Z,X){if(!!m){var Y=X?"visible":"hidden";J&&c(Z)?c(Z).style.visibility=Y:v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/,X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){M.ie&&M.win&&window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++)I[ab][0].detachEvent(I[ab][1],I[ab][2]);var Z=N.length;for(var aa=0;aa<Z;aa++)y(N[aa]);for(var Y in M)M[Y]=null;M=null;for(var X in swfobject)swfobject[X]=null;swfobject=null})}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab,Y.swfVersion=X,Y.expressInstall=aa,Y.callbackFn=Z,o[o.length]=Y,w(ab,!1)}else Z&&Z({success:!1,id:ab})},getObjectById:function(X){if(M.w3)return z(X)},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:!1,id:ah};M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y?(w(ah,!1),K(function(){ae+="",ag+="";var aj={};if(af&&typeof af===r)for(var al in af)aj[al]=af[al];aj.data=ab,aj.width=ae,aj.height=ag;var am={};if(ad&&typeof ad===r)for(var ak in ad)am[ak]=ad[ak];if(Z&&typeof Z===r)for(var ai in Z)typeof am.flashvars!=D?am.flashvars+="&"+ai+"="+Z[ai]:am.flashvars=ai+"="+Z[ai];if(F(Y)){var an=u(aj,am,ah);aj.id==ah&&w(ah,!0),X.success=!0,X.ref=an}else{if(aa&&A()){aj.data=aa,P(aj,am,ah,ac);return}w(ah,!0)}ac&&ac(X)})):ac&&ac(X)},switchOffAutoHideShow:function(){m=!1},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){return M.w3?u(Z,Y,X):undefined},showExpressInstall:function(Z,aa,X,Y){M.w3&&A()&&P(Z,aa,X,Y)},removeSWF:function(X){M.w3&&y(X)},createCSS:function(aa,Z,Y,X){M.w3&&v(aa,Z,Y,X)},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){/\?/.test(Z)&&(Z=Z.split("?")[1]);if(aa==null)return L(Z);var Y=Z.split("&");for(var X=0;X<Y.length;X++)if(Y[X].substring(0,Y[X].indexOf("="))==aa)return L(Y[X].substring(Y[X].indexOf("=")+1))}return""},expressInstallCallback:function(){if(a){var X=c(R);X&&l&&(X.parentNode.replaceChild(l,X),Q&&(w(Q,!0),M.ie&&M.win&&(l.style.display="block")),E&&E(B)),a=!1}}}}();(function(){if(!window.WebSocket){var console=window.console;if(!console||!console.log||!console.error)console={log:function(){},error:function(){}};if(!swfobject.hasFlashPlayerVersion("10.0.0")){console.error("Flash Player >= 10.0.0 is required.");return}location.protocol=="file:"&&console.error("WARNING: web-socket-js doesn't work in file:///... URL unless you set Flash Security Settings properly. Open the page via Web server i.e. http://..."),WebSocket=function(url,protocols,proxyHost,proxyPort,headers){var self=this;self.__id=WebSocket.__nextId++,WebSocket.__instances[self.__id]=self,self.readyState=WebSocket.CONNECTING,self.bufferedAmount=0,self.__events={},protocols?typeof protocols=="string"&&(protocols=[protocols]):protocols=[],setTimeout(function(){WebSocket.__addTask(function(){WebSocket.__flash.create(self.__id,url,protocols,proxyHost||null,proxyPort||0,headers||null)})},0)},WebSocket.prototype.send=function(data){if(this.readyState==WebSocket.CONNECTING)throw"INVALID_STATE_ERR: Web Socket connection has not been established";var result=WebSocket.__flash.send(this.__id,encodeURIComponent(data));if(result<0)return!0;this.bufferedAmount+=result;return!1},WebSocket.prototype.close=function(){this.readyState!=WebSocket.CLOSED&&this.readyState!=WebSocket.CLOSING&&(this.readyState=WebSocket.CLOSING,WebSocket.__flash.close(this.__id))},WebSocket.prototype.addEventListener=function(type,listener,useCapture){type in this.__events||(this.__events[type]=[]),this.__events[type].push(listener)},WebSocket.prototype.removeEventListener=function(type,listener,useCapture){if(type in this.__events){var events=this.__events[type];for(var i=events.length-1;i>=0;--i)if(events[i]===listener){events.splice(i,1);break}}},WebSocket.prototype.dispatchEvent=function(event){var events=this.__events[event.type]||[];for(var i=0;i<events.length;++i)events[i](event);var handler=this["on"+event.type];handler&&handler(event)},WebSocket.prototype.__handleEvent=function(flashEvent){"readyState"in flashEvent&&(this.readyState=flashEvent.readyState),"protocol"in flashEvent&&(this.protocol=flashEvent.protocol);var jsEvent;if(flashEvent.type=="open"||flashEvent.type=="error")jsEvent=this.__createSimpleEvent(flashEvent.type);else if(flashEvent.type=="close")jsEvent=this.__createSimpleEvent("close");else{if(flashEvent.type!="message")throw"unknown event type: "+flashEvent.type;var data=decodeURIComponent(flashEvent.message);jsEvent=this.__createMessageEvent("message",data)}this.dispatchEvent(jsEvent)},WebSocket.prototype.__createSimpleEvent=function(type){if(document.createEvent&&window.Event){var event=document.createEvent("Event");event.initEvent(type,!1,!1);return event}return{type:type,bubbles:!1,cancelable:!1}},WebSocket.prototype.__createMessageEvent=function(type,data){if(document.createEvent&&window.MessageEvent&&!window.opera){var event=document.createEvent("MessageEvent");event.initMessageEvent("message",!1,!1,data,null,null,window,null);return event}return{type:type,data:data,bubbles:!1,cancelable:!1}},WebSocket.CONNECTING=0,WebSocket.OPEN=1,WebSocket.CLOSING=2,WebSocket.CLOSED=3,WebSocket.__flash=null,WebSocket.__instances={},WebSocket.__tasks=[],WebSocket.__nextId=0,WebSocket.loadFlashPolicyFile=function(url){WebSocket.__addTask(function(){WebSocket.__flash.loadManualPolicyFile(url)})},WebSocket.__initialize=function(){if(!WebSocket.__flash){WebSocket.__swfLocation&&(window.WEB_SOCKET_SWF_LOCATION=WebSocket.__swfLocation);if(!window.WEB_SOCKET_SWF_LOCATION){console.error("[WebSocket] set WEB_SOCKET_SWF_LOCATION to location of WebSocketMain.swf");return}var container=document.createElement("div");container.id="webSocketContainer",container.style.position="absolute",WebSocket.__isFlashLite()?(container.style.left="0px",container.style.top="0px"):(container.style.left="-100px",container.style.top="-100px");var holder=document.createElement("div");holder.id="webSocketFlash",container.appendChild(holder),document.body.appendChild(container),swfobject.embedSWF(WEB_SOCKET_SWF_LOCATION,"webSocketFlash","1","1","10.0.0",null,null,{hasPriority:!0,swliveconnect:!0,allowScriptAccess:"always"},null,function(e){e.success||console.error("[WebSocket] swfobject.embedSWF failed")})}},WebSocket.__onFlashInitialized=function(){setTimeout(function(){WebSocket.__flash=document.getElementById("webSocketFlash"),WebSocket.__flash.setCallerUrl(location.href),WebSocket.__flash.setDebug(!!window.WEB_SOCKET_DEBUG);for(var i=0;i<WebSocket.__tasks.length;++i)WebSocket.__tasks[i]();WebSocket.__tasks=[]},0)},WebSocket.__onFlashEvent=function(){setTimeout(function(){try{var events=WebSocket.__flash.receiveEvents();for(var i=0;i<events.length;++i)WebSocket.__instances[events[i].webSocketId].__handleEvent(events[i])}catch(e){console.error(e)}},0);return!0},WebSocket.__log=function(message){console.log(decodeURIComponent(message))},WebSocket.__error=function(message){console.error(decodeURIComponent(message))},WebSocket.__addTask=function(task){WebSocket.__flash?task():WebSocket.__tasks.push(task)},WebSocket.__isFlashLite=function(){if(!window.navigator||!window.navigator.mimeTypes)return!1;var mimeType=window.navigator.mimeTypes["application/x-shockwave-flash"];if(!mimeType||!mimeType.enabledPlugin||!mimeType.enabledPlugin.filename)return!1;return mimeType.enabledPlugin.filename.match(/flashlite/i)?!0:!1},window.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION||(window.addEventListener?window.addEventListener("load",function(){WebSocket.__initialize()},!1):window.attachEvent("onload",function(){WebSocket.__initialize()}))}})();
-Array.prototype.include=function(value){return this.indexOf(value)!=-1},Array.prototype.any=function(){return this.length>0},window.getCookie=function(c_name){if(document.cookie.length>0){c_start=document.cookie.indexOf(c_name+"=");if(c_start!=-1){c_start=c_start+c_name.length+1,c_end=document.cookie.indexOf(";",c_start),c_end==-1&&(c_end=document.cookie.length);return unescape(document.cookie.substring(c_start,c_end))}}return""},window.setCookie=function(c_name,value,expiredays){var exdate=new Date;exdate.setDate(exdate.getDate()+expiredays),document.cookie=c_name+"="+escape(value)+(expiredays==null?"":";expires="+exdate.toUTCString())};(function(){var RTM,Request,System,default_cb,error,log,send,sendHeartbeat,setupAPI,start,validLevel;window.SS={started:null,env:null,client:{},server:{},shared:{},models:{},internal:{cb_stack:{}},config:{log:{level:0}}},window.$SS=window.SS,SS.events={_events:{},on:function(name,funct){this._events[name]==null&&(this._events[name]=[]);return this._events[name].push(funct)},emit:function(name,params){var event,_i,_len,_ref,_results;if(this._events[name]){_ref=this._events[name],_results=[];for(_i=0,_len=_ref.length;_i<_len;_i++)event=_ref[_i],_results.push(event(params));return _results}return console.error("Error: Received incoming '"+name+"' event but no event handlers registered")}},SS.socket=new io.Socket(document.location.hostname,{rememberTransport:!1,port:document.location.port,secure:document.location.protocol==="https:",transports:["websocket","flashsocket"],tryTransportsOnConnectTimeout:!1}),SS.socket.on("message",function(raw){var data;data=JSON.parse(raw);return data.type?Request[data.type]!=null?Request[data.type](data):console.error("Error: Unable to find a message handler for '"+data.type+"' requests! Dropping message"):console.error("Error: No message type specified. Dropping message")}),SS.socket.on("disconnect",function(){var attemptReconnection;attemptReconnection=function(){SS.socket.connecting||SS.socket.connect();return setTimeout(arguments.callee,500)};return attemptReconnection()}),SS.socket.connect(),default_cb=function(server_response){return console.log(server_response)},SS.internal.remote=function(){var args,cb,last_arg,msg;args=arguments,msg={type:"server"},msg.method=args[0],SS.config.remote_prefix&&(msg.method=""+SS.config.remote_prefix+"."+msg.method),msg.params=args[1],msg.options=args.length>=4?args[2]:null,last_arg=args[args.length-1],cb=typeof last_arg=="function"?last_arg:default_cb,cb.options=msg.options,validLevel(4)&&(!msg.options||!msg.options.silent)&&console.log("<- "+msg.method);return send(msg,cb)},RTM=function(){function RTM(){}RTM.prototype.findById=function(id,cb){return this._send("findById",id,cb)},RTM.prototype.find=function(){var arg,args,cb,_i,_len;args=[];for(_i=0,_len=arguments.length;_i<_len;_i++)arg=arguments[_i],args.push(arg);cb=args.pop();return this._send("find",args,cb)},RTM.prototype._send=function(action,params,cb){log(2,"<~ "+this.name+"."+action);return send({type:"rtm",rtm:this.name,action:action,params:params},cb)};return RTM}(),System={init:function(data){var name,_i,_len,_ref;SS.env=data.env,SS.config=data.config||{},setCookie("session_id",data.session_id),_ref=data.api.models;for(_i=0,_len=_ref.length;_i<_len;_i++)name=_ref[_i],SS.models[name]=new RTM,SS.models[name].name=name;eval("SS.server = "+data.api.server),setupAPI(SS.server,[]),SS.socket.ready=!0,data.heartbeat&&sendHeartbeat();return start()},error:function(details){return error("SocketStream Server - "+details)}},Request={system:function(data){return System[data.method](data.params)},server:function(data){var cb,silent;cb=SS.internal.cb_stack[data.cb_id],silent=cb.msg.options&&cb.msg.options.silent,silent||log(2,"-> "+cb.msg.method,data.params),cb.funkt(data.params);return delete SS.internal.cb_stack[data.cb_id]},event:function(data){log(2,"=> "+data.event);return SS.events.emit(data.event,data.params)},rtm:function(data){var cb;cb=SS.internal.cb_stack[data.cb_id],log(2,"~> "+cb.msg.rtm+"."+cb.msg.action),cb.funkt(data.data);return delete SS.internal.cb_stack[data.cb_id]}},start=function(){if(!SS.started){jQuery?jQuery(document).ready(function(){try{return SS.client.app.init()}catch(e){return app.init()}}):app.init();return SS.started=new Date}},send=function(msg,cb){var args,cb_id,recursive,retry_ms;cb==null&&(cb=null),args=arguments;try{if(SS.socket.connected===!1&&SS.socket.connecting===!1){SS.socket.ready=!1,SS.socket.connect();throw"NOT_READY"}if(SS.socket.ready===!0)cb&&(cb_id=Math.random().toString().split(".")[1],SS.internal.cb_stack[cb_id]={funkt:cb,msg:msg},msg.cb_id=cb_id),msg=JSON.stringify(msg),SS.socket.send(msg);else throw"NOT_READY"}catch(e){if(e==="NOT_READY")retry_ms=50,recursive=function(){return send.apply(this,args)},setTimeout(recursive,retry_ms);else throw e}return},log=function(level,msg,params){var o;if(validLevel(level)){o=[msg],params&&validLevel(3)&&o.push(params);return console.log.apply(console,o)}},error=function(e){if(validLevel(1))return console.error(e)},validLevel=function(level){return SS.config.log.level>=level},setupAPI=function(root,ary){var key,ns,value,_results;_results=[];for(key in root)value=root[key],ns=ary.slice(0),ns.push(key),_results.push(typeof value=="object"?setupAPI(root[key],ns):root[key]=new Function('SS.internal.remote.apply(window, ["'+ns.join(".")+'"].concat(Array.prototype.slice.call(arguments, 0)))'));return _results},sendHeartbeat=function(){SS.socket.connected&&send({type:"heartbeat"});return setTimeout(arguments.callee,SS.config.heartbeat_interval*1e3)}}).call(this)
+window.getCookie=function(c_name){if(document.cookie.length>0){c_start=document.cookie.indexOf(c_name+"=");if(c_start!=-1){c_start=c_start+c_name.length+1,c_end=document.cookie.indexOf(";",c_start),c_end==-1&&(c_end=document.cookie.length);return unescape(document.cookie.substring(c_start,c_end))}}return""},window.setCookie=function(c_name,value,expiredays){var exdate=new Date;exdate.setDate(exdate.getDate()+expiredays),document.cookie=c_name+"="+escape(value)+(expiredays==null?"":";expires="+exdate.toUTCString())};(function(){var RTM,Request,System,default_cb,error,log,send,sendHeartbeat,setupAPI,start,validLevel;window.SS={started:null,env:null,client:{},server:{},shared:{},models:{},internal:{cb_stack:{}},config:{log:{level:0}}},SS.events={_events:{},on:function(name,funct){this._events[name]==null&&(this._events[name]=[]);return this._events[name].push(funct)},emit:function(name,params){var event,_i,_len,_ref,_results;if(this._events[name]){_ref=this._events[name],_results=[];for(_i=0,_len=_ref.length;_i<_len;_i++)event=_ref[_i],_results.push(event(params));return _results}return console.error("Error: Received incoming '"+name+"' event but no event handlers registered")}},SS.socket=new io.Socket(document.location.hostname,{rememberTransport:!1,port:document.location.port,secure:document.location.protocol==="https:",transports:["websocket","flashsocket"],tryTransportsOnConnectTimeout:!1}),SS.socket.on("message",function(raw){var data;data=JSON.parse(raw);return data.type?Request[data.type]!=null?Request[data.type](data):console.error("Error: Unable to find a message handler for '"+data.type+"' requests! Dropping message"):console.error("Error: No message type specified. Dropping message")}),SS.socket.on("disconnect",function(){var attemptReconnection;attemptReconnection=function(){SS.socket.connecting||SS.socket.connect();return setTimeout(arguments.callee,500)};return attemptReconnection()}),SS.socket.connect(),default_cb=function(server_response){return console.log(server_response)},SS.internal.remote=function(){var args,cb,last_arg,msg;args=arguments,msg={type:"server"},msg.method=args[0],SS.config.remote_prefix&&(msg.method=""+SS.config.remote_prefix+"."+msg.method),msg.params=args[1],msg.options=args.length>=4?args[2]:null,last_arg=args[args.length-1],cb=typeof last_arg=="function"?last_arg:default_cb,cb.options=msg.options,validLevel(4)&&(!msg.options||!msg.options.silent)&&console.log("<- "+msg.method);return send(msg,cb)},RTM=function(){function RTM(){}RTM.prototype.findById=function(id,cb){return this._send("findById",id,cb)},RTM.prototype.find=function(){var arg,args,cb,_i,_len;args=[];for(_i=0,_len=arguments.length;_i<_len;_i++)arg=arguments[_i],args.push(arg);cb=args.pop();return this._send("find",args,cb)},RTM.prototype._send=function(action,params,cb){log(2,"<~ "+this.name+"."+action);return send({type:"rtm",rtm:this.name,action:action,params:params},cb)};return RTM}(),System={init:function(data){var name,_i,_len,_ref;SS.env=data.env,SS.config=data.config||{},setCookie("session_id",data.session_id),_ref=data.api.models;for(_i=0,_len=_ref.length;_i<_len;_i++)name=_ref[_i],SS.models[name]=new RTM,SS.models[name].name=name;eval("SS.server = "+data.api.server),setupAPI(SS.server,[]),SS.socket.ready=!0,data.heartbeat&&sendHeartbeat();return start()},error:function(details){return error("SocketStream Server - "+details)}},Request={system:function(data){return System[data.method](data.params)},server:function(data){var cb,silent;cb=SS.internal.cb_stack[data.cb_id],silent=cb.msg.options&&cb.msg.options.silent,silent||log(2,"-> "+cb.msg.method,data.params),cb.funkt(data.params);return delete SS.internal.cb_stack[data.cb_id]},event:function(data){log(2,"=> "+data.event);return SS.events.emit(data.event,data.params)},rtm:function(data){var cb;cb=SS.internal.cb_stack[data.cb_id],log(2,"~> "+cb.msg.rtm+"."+cb.msg.action),cb.funkt(data.data);return delete SS.internal.cb_stack[data.cb_id]}},start=function(){if(!SS.started){jQuery?jQuery(document).ready(function(){try{return SS.client.app.init()}catch(e){return app.init()}}):app.init();return SS.started=new Date}},send=function(msg,cb){var args,cb_id,recursive,retry_ms;cb==null&&(cb=null),args=arguments;try{if(SS.socket.connected===!1&&SS.socket.connecting===!1){SS.socket.ready=!1,SS.socket.connect();throw"NOT_READY"}if(SS.socket.ready===!0)cb&&(cb_id=Math.random().toString().split(".")[1],SS.internal.cb_stack[cb_id]={funkt:cb,msg:msg},msg.cb_id=cb_id),msg=JSON.stringify(msg),SS.socket.send(msg);else throw"NOT_READY"}catch(e){if(e==="NOT_READY")retry_ms=50,recursive=function(){return send.apply(this,args)},setTimeout(recursive,retry_ms);else throw e}return},log=function(level,msg,params){var o;if(validLevel(level)){o=[msg],params&&validLevel(3)&&o.push(params);return console.log.apply(console,o)}},error=function(e){if(validLevel(1))return console.error(e)},validLevel=function(level){return SS.config.log.level>=level},setupAPI=function(root,ary){var key,ns,value,_results;_results=[];for(key in root)value=root[key],ns=ary.slice(0),ns.push(key),_results.push(typeof value=="object"?setupAPI(root[key],ns):root[key]=new Function('SS.internal.remote.apply(window, ["'+ns.join(".")+'"].concat(Array.prototype.slice.call(arguments, 0)))'));return _results},sendHeartbeat=function(){SS.socket.connected&&send({type:"heartbeat"});return setTimeout(arguments.callee,SS.config.heartbeat_interval*1e3)}}).call(this)
View
6 lib/client/js/3.helpers.js
@@ -1,9 +1,3 @@
-// These extensions affect ALL client side objects. Be very careful about introducing new ones as they may break existing client-side libraries
-
-Array.prototype.include = function(value){ return(this.indexOf(value) != -1); };
-Array.prototype.any = function(){ return(this.length > 0); };
-
-
// Helper methods used by SocketStream to get and set session cookies
// Cookies are set by the browser, not via the server in HTTP headers to allow full caching of the static index.html file
View
20 lib/test/jasmine/lib/jasmine-1.1.0/MIT.LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2008-2011 Pivotal Labs
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
190 lib/test/jasmine/lib/jasmine-1.1.0/jasmine-html.js
@@ -0,0 +1,190 @@
+jasmine.TrivialReporter = function(doc) {
+ this.document = doc || document;
+ this.suiteDivs = {};
+ this.logRunningSpecs = false;
+};
+
+jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
+ var el = document.createElement(type);
+
+ for (var i = 2; i < arguments.length; i++) {
+ var child = arguments[i];
+
+ if (typeof child === 'string') {
+ el.appendChild(document.createTextNode(child));
+ } else {
+ if (child) { el.appendChild(child); }
+ }
+ }
+
+ for (var attr in attrs) {
+ if (attr == "className") {
+ el[attr] = attrs[attr];
+ } else {
+ el.setAttribute(attr, attrs[attr]);
+ }
+ }
+
+ return el;
+};
+
+jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
+ var showPassed, showSkipped;
+
+ this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
+ this.createDom('div', { className: 'banner' },
+ this.createDom('div', { className: 'logo' },
+ this.createDom('span', { className: 'title' }, "Jasmine"),
+ this.createDom('span', { className: 'version' }, runner.env.versionString())),
+ this.createDom('div', { className: 'options' },
+ "Show ",
+ showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
+ this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
+ showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
+ this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
+ )
+ ),
+
+ this.runnerDiv = this.createDom('div', { className: 'runner running' },
+ this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
+ this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
+ this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
+ );
+
+ this.document.body.appendChild(this.outerDiv);
+
+ var suites = runner.suites();
+ for (var i = 0; i < suites.length; i++) {
+ var suite = suites[i];
+ var suiteDiv = this.createDom('div', { className: 'suite' },
+ this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
+ this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
+ this.suiteDivs[suite.id] = suiteDiv;
+ var parentDiv = this.outerDiv;
+ if (suite.parentSuite) {
+ parentDiv = this.suiteDivs[suite.parentSuite.id];
+ }
+ parentDiv.appendChild(suiteDiv);
+ }
+
+ this.startedAt = new Date();
+
+ var self = this;
+ showPassed.onclick = function(evt) {
+ if (showPassed.checked) {
+ self.outerDiv.className += ' show-passed';
+ } else {
+ self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
+ }
+ };
+
+ showSkipped.onclick = function(evt) {
+ if (showSkipped.checked) {
+ self.outerDiv.className += ' show-skipped';
+ } else {
+ self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
+ }
+ };
+};
+
+jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
+ var results = runner.results();
+ var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
+ this.runnerDiv.setAttribute("class", className);
+ //do it twice for IE
+ this.runnerDiv.setAttribute("className", className);
+ var specs = runner.specs();
+ var specCount = 0;
+ for (var i = 0; i < specs.length; i++) {
+ if (this.specFilter(specs[i])) {
+ specCount++;
+ }
+ }
+ var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
+ message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
+ this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
+
+ this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
+};
+
+jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
+ var results = suite.results();
+ var status = results.passed() ? 'passed' : 'failed';
+ if (results.totalCount === 0) { // todo: change this to check results.skipped
+ status = 'skipped';
+ }
+ this.suiteDivs[suite.id].className += " " + status;
+};
+
+jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
+ if (this.logRunningSpecs) {
+ this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
+ }
+};
+
+jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
+ var results = spec.results();
+ var status = results.passed() ? 'passed' : 'failed';
+ if (results.skipped) {
+ status = 'skipped';
+ }
+ var specDiv = this.createDom('div', { className: 'spec ' + status },
+ this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
+ this.createDom('a', {
+ className: 'description',
+ href: '?spec=' + encodeURIComponent(spec.getFullName()),
+ title: spec.getFullName()
+ }, spec.description));
+
+
+ var resultItems = results.getItems();
+ var messagesDiv = this.createDom('div', { className: 'messages' });
+ for (var i = 0; i < resultItems.length; i++) {
+ var result = resultItems[i];
+
+ if (result.type == 'log') {
+ messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
+ } else if (result.type == 'expect' && result.passed && !result.passed()) {
+ messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
+
+ if (result.trace.stack) {
+ messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
+ }
+ }
+ }
+
+ if (messagesDiv.childNodes.length > 0) {
+ specDiv.appendChild(messagesDiv);
+ }
+
+ this.suiteDivs[spec.suite.id].appendChild(specDiv);
+};
+
+jasmine.TrivialReporter.prototype.log = function() {
+ var console = jasmine.getGlobal().console;
+ if (console && console.log) {
+ if (console.log.apply) {
+ console.log.apply(console, arguments);
+ } else {
+ console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
+ }
+ }
+};
+
+jasmine.TrivialReporter.prototype.getLocation = function() {
+ return this.document.location;
+};
+
+jasmine.TrivialReporter.prototype.specFilter = function(spec) {
+ var paramMap = {};
+ var params = this.getLocation().search.substring(1).split('&');
+ for (var i = 0; i < params.length; i++) {
+ var p = params[i].split('=');
+ paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
+ }
+
+ if (!paramMap.spec) {
+ return true;
+ }
+ return spec.getFullName().indexOf(paramMap.spec) === 0;
+};
View
166 lib/test/jasmine/lib/jasmine-1.1.0/jasmine.css
@@ -0,0 +1,166 @@
+body {
+ font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
+}
+
+
+.jasmine_reporter a:visited, .jasmine_reporter a {
+ color: #303;
+}
+
+.jasmine_reporter a:hover, .jasmine_reporter a:active {
+ color: blue;
+}
+
+.run_spec {
+ float:right;
+ padding-right: 5px;
+ font-size: .8em;
+ text-decoration: none;
+}
+
+.jasmine_reporter {
+ margin: 0 5px;
+}
+
+.banner {
+ color: #303;
+ background-color: #fef;
+ padding: 5px;
+}
+
+.logo {
+ float: left;
+ font-size: 1.1em;
+ padding-left: 5px;
+}
+
+.logo .version {
+ font-size: .6em;
+ padding-left: 1em;
+}
+
+.runner.running {
+ background-color: yellow;
+}
+
+
+.options {
+ text-align: right;
+ font-size: .8em;
+}
+
+
+
+
+.suite {
+ border: 1px outset gray;
+ margin: 5px 0;
+ padding-left: 1em;
+}
+
+.suite .suite {
+ margin: 5px;
+}
+
+.suite.passed {
+ background-color: #dfd;
+}
+
+.suite.failed {
+ background-color: #fdd;
+}
+
+.spec {
+ margin: 5px;
+ padding-left: 1em;
+ clear: both;
+}
+
+.spec.failed, .spec.passed, .spec.skipped {
+ padding-bottom: 5px;
+ border: 1px solid gray;
+}
+
+.spec.failed {
+ background-color: #fbb;
+ border-color: red;
+}
+
+.spec.passed {
+ background-color: #bfb;
+ border-color: green;
+}
+
+.spec.skipped {
+ background-color: #bbb;
+}
+
+.messages {
+ border-left: 1px dashed gray;
+ padding-left: 1em;
+ padding-right: 1em;
+}
+
+.passed {
+ background-color: #cfc;
+ display: none;
+}
+
+.failed {
+ background-color: #fbb;
+}
+
+.skipped {
+ color: #777;
+ background-color: #eee;
+ display: none;
+}
+
+
+/*.resultMessage {*/
+ /*white-space: pre;*/
+/*}*/
+
+.resultMessage span.result {
+ display: block;
+ line-height: 2em;
+ color: black;
+}
+
+.resultMessage .mismatch {
+ color: black;
+}
+
+.stackTrace {
+ white-space: pre;
+ font-size: .8em;
+ margin-left: 10px;
+ max-height: 5em;
+ overflow: auto;
+ border: 1px inset red;
+ padding: 1em;
+ background: #eef;
+}
+
+.finished-at {
+ padding-left: 1em;
+ font-size: .6em;
+}
+
+.show-passed .passed,
+.show-skipped .skipped {
+ display: block;
+}
+
+
+#jasmine_content {
+ position:fixed;
+ right: 100%;
+}
+
+.runner {
+ border: 1px solid gray;
+ display: block;
+ margin: 5px 0;
+ padding: 2px 0 2px 10px;
+}
View
2,471 lib/test/jasmine/lib/jasmine-1.1.0/jasmine.js
2,471 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
BIN lib/test/jasmine/lib/jasmine-1.1.0/jasmine_favicon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
68 lib/test/jasmine/spec/HelpersSpec.js
@@ -0,0 +1,68 @@
+describe("Helpers", function(){
+ var testString = "helloworld",
+ testArray = ['alpha','beta','gamma','beta'],
+ emptyArray = [],
+ testHTML = "http://www.github.com and some other text",
+ testMailto = "you might want to email mailto:test@github.com",
+ testMailHTML = "example 1 is http://github.com and example 2 is mailto:test@github.com";
+
+
+ it("should remove all the duplicates from an array", function(){
+ expect(testArray.unique()).toEqual(['alpha','beta','gamma']);
+ });
+
+ it("should remove all the duplicate characters from a string", function(){
+ expect(testString.unique()).toEqual('helowrd');
+ });
+
+ it("should be able to return the last element in an array", function(){
+ expect(testArray.last()).toEqual('beta');
+ });
+
+ it("should be able to return the last character in a string", function(){
+ expect(testString.last()).toEqual('d');
+ });
+
+ it("should be able to truncate an array to a given length", function(){
+ expect(testArray.truncate(1)).toEqual(['alpha']);
+ expect(testArray.truncate(2)).toEqual(['alpha', 'beta']);
+ expect(testArray.truncate(3)).toEqual(["alpha", "beta", "gamma"]);
+ expect(testArray.truncate(4)).toEqual(["alpha", "beta", "gamma", "beta"]);
+ });
+
+ it("should be able to truncate a string to a given length", function(){
+ expect(testString.truncate(5)).toEqual("he...");
+ expect(testString.truncate(4)).toEqual("h...");
+ });
+
+ it("shoud be able to return a random element from an array", function(){
+ expect([testArray.random()].length).toEqual(1);
+ });
+
+ it("should be able to return a random character from a string", function(){
+ expect(testString.random().length).toEqual(1);
+ });
+
+ it("should be able to return true/false if a string contains a character supplied", function(){
+ expect(testString.include('w')).toBeTruthy();
+ expect(testString.include('f')).toBeFalsy();
+ });
+
+ it("should be able to return true/false if an array contains a character supplied", function(){
+ expect(testArray.include('beta')).toBeTruthy();
+ expect(testArray.include('betas')).toBeFalsy();
+ expect(testArray.include('gamma')).toBeTruthy();
+ expect(testArray.include('gammas')).toBeFalsy();
+ });
+
+ it("should be able to return true/false depending on whether an array contains any elements", function(){
+ expect(emptyArray.any()).toBeFalsy();
+ expect(testArray.any()).toBeTruthy();
+ });
+
+ it("should be able to sanitize a string containg URLs or mailto references", function(){
+ expect(testHTML.sanitize()).toEqual('<a href="http://www.github.com" target="_blank">http://www.github.com</a> and some other text');
+ expect(testMailto.sanitize()).toEqual('you might want to email mailto:<a href="mailto:test@github.com" target="_blank">test@github.com</a>');
+ expect(testMailHTML.sanitize()).toEqual('example 1 is <a href="http://github.com" target="_blank">http://github.com</a> and example 2 is mailto:<a href="mailto:test@github.com" target="_blank">test@github.com</a>');
+ });
+});
View
40 lib/test/jasmine/test.html
@@ -0,0 +1,40 @@
+<html>
+ <head>Tests</head>
+ <link rel="stylesheet" type="text/css" href="lib/jasmine-1.1.0/jasmine.css">
+ <script type="text/javascript" src="lib/jasmine-1.1.0/jasmine.js"></script>
+ <script type="text/javascript" src="lib/jasmine-1.1.0/jasmine-html.js"></script>
+ <script type="text/javascript" charset="utf-8" src="../../lib/client/js/3.helpers.js"></script>
+ <script type="text/javascript" charset="utf-8" src="spec/HelpersSpec.js"></script>
+ <script type="text/javascript">
+ (function() {
+ var jasmineEnv = jasmine.getEnv();
+ jasmineEnv.updateInterval = 1000;
+
+ var trivialReporter = new jasmine.TrivialReporter();
+
+ jasmineEnv.addReporter(trivialReporter);
+
+ jasmineEnv.specFilter = function(spec) {
+ return trivialReporter.specFilter(spec);
+ };
+
+ var currentWindowOnload = window.onload;
+
+ window.onload = function() {
+ if (currentWindowOnload) {
+ currentWindowOnload();
+ }
+ execJasmine();
+ };
+
+ function execJasmine() {
+ jasmineEnv.execute();
+ }
+
+ })();
+ </script>
+ <body>
+ <div>
+ </div>
+ </body>
+</html>
View
115 new_project/lib/client/3.helpers.js
@@ -0,0 +1,115 @@
+// Helpers
+// -------
+// These prototype helpers affect ALL your client-side and shared code. Feel free to edit or delete this file if you don't want to use these.
+// You will always be able to obtain the latest version of this file by coping/merging it in from a new project.
+// Be very careful about introducing new helpers as they may break external third-party client-side libraries.
+
+/**
+ Removes any duplicate entries from the current string
+**/
+String.prototype.unique = function(b){
+ var a = "", i, l = this.length,q="";
+ for( i=0; i<l; i++ ) {
+ if( a.indexOf( this[i], 0, b ) < 0 ) {
+ a += this[i];
+ }
+ }
+ return a;
+};
+
+/**
+ Removes any duplicate entries from the current array
+**/
+Array.prototype.unique = function( b ) {
+ var a = [], i, l = this.length;
+ for( i=0; i<l; i++ ) {
+ if( a.indexOf( this[i], 0, b ) < 0 ) { a.push( this[i] ); }
+ }
+ return a;
+};
+
+/**
+ Returns the last character in the current string
+**/
+String.prototype.last = function(){
+ return this[this.length-1];
+};
+
+/**
+ Returns the last element in the current array
+**/
+Array.prototype.last = function(){
+ return this[this.length-1];
+};
+
+/**
+ Truncates the current string to the supplied length
+**/
+String.prototype.truncate = function(length){
+ if (this.length > length) {
+ return this.slice(0, length - 3) + "...";
+ }else {
+ return this;
+ }
+};
+
+/**
+ Truncates the current array to the supplied length
+**/
+Array.prototype.truncate = function(length){
+ return this.slice(0, length);
+}
+
+/**
+ Returns a random character from the current string
+**/
+String.prototype.random = function( r ) {
+ var i = 0, l = this.length;
+ if( !r ) { r = this.length; }
+ else if( r > 0 ) { r = r % l; }
+ else { i = r; r = l + r % l; }
+ return this[ Math.floor( r * Math.random() - i ) ];
+};
+
+/**
+ Returns a random element from the current array
+**/
+Array.prototype.random = function( r ) {
+ var i = 0, l = this.length;
+ if( !r ) { r = this.length; }
+ else if( r > 0 ) { r = r % l; }
+ else { i = r; r = l + r % l; }
+ return this[ Math.floor( r * Math.random() - i ) ];
+};
+
+/**
+ Boolean check to find out if a supplied character is in the current string
+ @note: include has replaced contains
+**/
+String.prototype.include = function(value) {
+ return(this.indexOf(value) != -1);
+};
+
+/**
+ Boolean check to find out if a supplied element/string is in the current array
+ @note: include has replaced contains
+**/
+Array.prototype.include = function(value) {
+ return(this.indexOf(value) != -1);
+};
+
+/**
+ Boolean check to find out if an array contains any elements
+**/
+Array.prototype.any = function(){
+ return !(this && this.constructor==Array && this.length==0);
+};
+
+/**
+ Sanitize content containing URLs or mailto/email references
+**/
+String.prototype.sanitize = function(){
+ return this.replace(/(([fh]+t+p+s?\:\/)+([^"'\s]+))/gi,"<a href=\"$1\" target=\"_blank\">$1<\/a>").
+ replace(/([a-z0-9\-\.]+\@[a-z0-9\-]+([^"'\s]+))/gi,"<a href=\"mailto:$1\" target=\"_blank\">$1<\/a>");
+};
+
View
2 package.json
@@ -1,7 +1,7 @@
{
"name": "socketstream",
"description": "A phenomenally fast real-time web framework for Node.js",
- "version": "0.1.01",
+ "version": "0.1.2",
"homepage": "http://www.socketstream.org",
"author": "Owen Barnes <info@socketstream.org>",
"contributors": [

0 comments on commit 33c2d26

Please sign in to comment.
Something went wrong with that request. Please try again.