function CircularBuffer(capacity){ if(!(this instanceof CircularBuffer))return new CircularBuffer(capacity); if(typeof capacity=="object"&& Array.isArray(capacity["_buffer"])&& typeof capacity._capacity=="number"&& typeof capacity._first=="number"&& typeof capacity._size=="number"){ for(var prop in capacity){ if(capacity.hasOwnProperty(prop))this[prop]=capacity[prop]; } } else { if(typeof capacity!="number"||capacity%1!=0||capacity<1) throw new TypeError("Invalid capacity"); this._buffer=new Array(capacity); this._capacity=capacity; this._first=0; this._size=0; } } CircularBuffer.prototype={ size:function(){return this._size;}, capacity:function(){return this._capacity;}, enq:function(value){ if(this._first>0)this._first--; else this._first=this._capacity-1; this._buffer[this._first]=value; if(this._size=this._size)throw new RangeError("Index past end of buffer: "+start); if(end==undefined)return this._buffer[(this._first+start)%this._capacity]; if(typeof end!="number"||end%1!=0||end<0)throw new TypeError("Invalid end"); if(end>=this._size)throw new RangeError("Index past end of buffer: "+end); if(this._first+start>=this._capacity){ //make sure first+start and first+end are in a normal range start-=this._capacity; //becomes a negative number end-=this._capacity; } if(this._first+end