} else if( format.charAt( i + 2 ) == 'v' ) {
vector_delimiter = arguments[num];
}else {
flags['width'] = arguments[num];
}
relative = false;
} else {
fixed = true;
current_index = num;
}
++i;
} else if( precision ) {
flags['precision'] = num;
precision = false;
} else {
flags['width'] = num;
}
} else if ( relative && !/\d/.test( format.charAt( i + 1 ) ) ) {
if( precision ) {
flags['precision'] = arguments[current_index];
precision = false;
} else if( format.charAt( i + 1 ) == 'v' ) {
vector_delimiter = arguments[current_index];
} else {
flags['width'] = arguments[current_index];
}
++index;
if( !fixed ) {
current_index++;
}
relative = false;
}
} else {
if( current_char == '%' ) {
in_operator = true;
continue;
} else {
result += current_char;
continue;
}
}
}
return result;
}  
sprintf.format = function sprintfFormat( type, value, flags ) {  
// Similar to how perl printf works
if( value == undefined ) {
if( type == 's' ) {
return '';
} else {
return '0';
}
}  
var result;
var prefix = '';
var fill = '';
var fillchar = ' ';
switch( type ) {
case '%':
result = '%';
break;
case 'c':
result = String.fromCharCode( parseInt( value ) );
break;
case 's':
result = value.toString;
break;
case 'd':
result = parseInt( value ).toString;
break;
case 'u':
result = Math.abs( parseInt( value ) ).toString; // it's not correct, but JS lacks unsigned ints
break;
case 'o':
result = (new Number( Math.abs( parseInt( value ) ) ) ).toString(8);
break;
case 'x':
result = (new Number( Math.abs( parseInt( value ) ) ) ).toString(16);
break;
case 'b':
result = (new Number( Math.abs( parseInt( value ) ) ) ).toString(2);
break;
case 'e':
var digits = flags['precision'] ? flags['precision'] : 6;
result = (new Number( value ) ).toExponential( digits ).toString;
break;
case 'f':
var digits = flags['precision'] ? flags['precision'] : 6;
result = (new Number( value ) ).toFixed( digits ).toString;
case 'g':
var digits = flags['precision'] ? flags['precision'] : 6;
result = (new Number( value ) ).toPrecision( digits ).toString;
break;
case 'X':
result = (new Number( Math.abs( parseInt( value ) ) ) ).toString(16).toUpperCase;
break;
case 'E':
var digits = flags['precision'] ? flags['precision'] : 6;
result = (new Number( value ) ).toExponential( digits ).toString.toUpperCase;
break;
case 'G':
var digits = flags['precision'] ? flags['precision'] : 6;
result = (new Number( value ) ).toPrecision( digits ).toString.toUpperCase;
break;
}  
if(flags['+'] && parseFloat( value ) > 0 && ['d','e','f','g','E','G'].indexOf(type) != -1 ) {
prefix = '+';
}  
if(flags[' '] && parseFloat( value ) > 0 && ['d','e','f','g','E','G'].indexOf(type) != -1 ) {
prefix = ' ';
}  
if( flags['#'] && parseInt( value ) != 0 ) {
switch(type) {
case 'o':
prefix = '0';
break;
case 'x':
case 'X':
prefix = '0x';
break;
case 'b':
prefix = '0b';
break;
}
}  
if( flags['0'] && !flags['-'] ) {
fillchar = '0';
}  
if( flags['width'] && flags['width'] > ( result.length + prefix.length ) ) {
var tofill = flags['width'] - result.length - prefix.length;
for( var i = 0; i < tofill; ++i ) {
fill += fillchar;
}
}  
if( flags['-'] && !flags['0'] ) {
result += fill;
} else {
result = fill + result;
}  
return prefix + result;
}  
Bytes = function ( value ) {
if( typeof(value) == 'string' ) {
var res = /(\d+) ?(\w?)(i?)B?/.exec( value );
var number = res[1];
var mag = res[2];
var si = res[3];  
if( ! number ) {
this.number = 0;
return;
}  
if( !si ) {
this.value = number * Math.pow( 10, Bytes.magnitudes[mag] * 3 );
} else {
this.value = number * Math.pow( 2, Bytes.magnitudes[mag] * 10 );
}
} else {
this.value = value;
}
}  
Bytes.magnitudes = {
'': 0,
'K': 1,
'M': 2,
'G': 3,
'T': 4,
'P': 5,
'E': 6,
'Z': 7,
'Y': 8
}
Bytes.rmagnitudes = {
0: '',
1: 'K',
2: 'M',
3: 'G',
4: 'T',
5: 'P',
6: 'E',
7: 'Z',
8: 'Y'
}  
Bytes.prototype.valueOf = function {
return this.value;
}  
Bytes.prototype.toString = function( magnitude ) {
var tmp = this.value;
if( magnitude ) {
var si = /i/.test(magnitude);
var mag = magnitude.replace( /.*?(\w)i?B?.*/g, '$1' );
if( si ) {
tmp /= Math.pow( 2, Bytes.magnitudes[mag] * 10 );
} else {
tmp /= Math.pow( 10, Bytes.magnitudes[mag] * 3 );
}
if( parseInt( tmp ) != tmp ) {
tmp = (new Number( tmp ) ).toPrecision( 4 );
}
return tmp + ' ' + mag + (si?'i':'') + 'B';
} else {
// si per default
var current = 0;
while( tmp >= 1024 ) {
tmp /= 1024;
++current;
}
tmp = this.value / Math.pow( 2, current * 10 );
if( parseInt( tmp ) != tmp ) {
tmp = (new Number( tmp ) ).toPrecision( 4 );
}
return tmp + ' ' + Bytes.rmagnitudes[current] + ( current > 0 ? 'iB' : 'B' );
}  
}
String.prototype.ltrim = function stringPrototypeLtrim( chars ) {
chars = chars || "\\s*";
return this.replace( new RegExp("^[" + chars + "]+", "g"), "" );
}  
String.prototype.rtrim = function stringPrototypeRtrim( chars ) {
chars = chars || "\\s*";
return this.replace( new RegExp("[" + chars + "]+$", "g"), "" );
}
String.prototype.trim = function stringPrototypeTrim( chars ) {
return this.rtrim(chars).ltrim(chars);
}  
String.prototype.splitWeightedByKeys = function stringPrototypeSplitWeightedByKeys( start, end, skip ) {
if( start.length != end.length ) {
throw 'start marker and end marker must be of the same length';
}
var level = 0;
var initial = null;
var result = [];
if( !( skip instanceof Array ) ) {
if( typeof( skip ) == 'undefined' ) {
skip = [];
} else if( typeof( skip ) == 'string' ) {
skip = [ skip ];
} else {
throw "non-applicable skip parameter";
}
}
for( var i = 0; i < this.length; ++i ) {
for( var j = 0; j < skip.length; ++j ) {
if( this.substr( i, skip[j].length ) == skip[j] ) {
i += skip[j].length - 1;
continue;
}
}
if( this.substr( i, start.length ) == start ) {
if( initial == null ) {
initial = i;
}
++level;
i += start.length - 1;
} else if( this.substr( i, end.length ) == end ) {
--level;
i += end.length - 1;
}
if( level == 0 && initial != null ) {
result.push( this.substring( initial, i + 1 ) );
initial = null;
}
}  
return result;
}  
Array.prototype.uniq = function arrayPrototypeUniq {
var result = [];
for( var i = 0; i < this.length; ++i ) {
var current = this[i];
if( result.indexOf( current ) == -1 ) {
result.push( current );
}
}
return result;
}  
Array.prototype.dups = function arrayPrototypeUniq {
var uniques = [];
var result = [];
for( var i = 0; i < this.length; ++i ) {
var current = this[i];
if( uniques.indexOf( current ) == -1 ) {
uniques.push( current );
} else {
result.push( current );
}
}
return result;
}  
Array.prototype.chunk = function arrayChunk( size ) {
if( typeof( size ) != 'number' || size <= 0 ) { // pretty impossible to do anything :)
return [ this ]; // we return an array consisting of this array.
}
var result = [];
var current;
for(var i = 0; i < this.length; ++i ) {
if( i % size == 0 ) { // when 'i' is 0, this is always true, so we start by creating one.
current = [];
result.push( current );
}
current.push( this[i] );
}
return result;
}  
Unbinder = function unbinder( string ) {
if( typeof( string ) != 'string' ) {
throw "not a string";
}
this.content = string;
this.counter = 0;
this.history = {};
this.prefix = '%UNIQ::' + Math.random + '::';
this.postfix = '::UNIQ%';
}  
Unbinder.prototype = {
unbind: function UnbinderUnbind( prefix, postfix ) {
var re = new RegExp( prefix + '(.*?)' + postfix, 'g' );
this.content = this.content.replace( re, Unbinder.getCallback( this ) );
},
rebind: function UnbinderRebind {
var content = this.content;
content.self = this;
for( var current in this.history )
if( this.history.hasOwnProperty( current ) )
content = content.replace( current, this.history[current] );
return content;
},
prefix: null, // %UNIQ::0.5955981644938324::
postfix: null, // ::UNIQ%
content: null, // string
counter: null, // 0++
history: null // {}
};  
Unbinder.getCallback = function UnbinderGetCallback(self) {
return function UnbinderCallback( match , a , b ) {
var current = self.prefix + self.counter + self.postfix;
self.history[current] = match;
++self.counter;
return current;
};
};