new function() {
 var Public = {
 'browser': function() { return Private.browser;},
 'version': {
 'number': function() { return Private.version.number; },
 'string': function() { return Private.version.string; }
 },
'OS': function() { return Private.OS; },

 // A boolean value indicating whether or not the given browser was
 // detected.
 'aol': function() { return Private.aol; },
 'camino': function() { return Private.camino; },
 'firefox': function() { return Private.firefox;},
'flock': function() { return Private.flock; },
 'icab': function() { return Private.icab;},
 'konqueror': function() { return Private.konqueror; },
 'mozilla': function() { return Private.mozilla;},
 'msie': function() { return Private.msie;},
'netscape': function() { return Private.netscape; },
'opera': function() { return Private.opera; },
 'safari': function() { return Private.safari; },
'linux': function() { return Private.linux; },
 'mac': function() { return Private.mac; },
 'win': function() { return Private.win; }
 };
 $.browser = Public;
 var Private = {
 'browser': 'Unknown',
 'version': {
 'number': undefined,
 'string': 'Unknown'
 },
'OS': 'Unknown',
 'aol': false,
 'camino': false,
 'firefox': false,
'flock': false,
 'icab': false,
 'konqueror': false,
 'mozilla': false,
 'msie': false,
'netscape': false,
'opera': false,
 'safari': false,
'linux': false,
 'mac': false,
 'win': false
 };
 for( var i = 0,
 ua = navigator.userAgent,
 ve = navigator.vendor, 
 data = [
 {
 'name': 'Safari',
 'browser': function() { return /Apple/.test(ve) }
 },
 {
 'name': 'Opera',
 'browser': function() {
 return window.opera != undefined
 }
 },
 {
 'name': 'iCab',
 'browser': function() { return /iCab/.test(ve) }
 },
 {
 'name': 'Konqueror',
 'browser': function() { return /KDE/.test(ve) }
 },
 {
 'identifier': 'aol',
 'name': 'AOL Explorer',
 'browser': function() {
 return /America Online Browser/.test(ua)
 },
 'version': function() {
 return ua.match(/rev(\d+(?:\.\d+)+)/)
 }
 },
 {
 'name': 'Flock',
 'browser': function() { return /Flock/.test(ua) }
 },
 {
 'name': 'Camino',
 'browser': function() { return /Camino/.test(ve) }
 },
 {
 'name': 'Firefox',
 'browser': function() { return /Firefox/.test(ua) }
 },
 {
 'name': 'Netscape',
 'browser': function() { return /Netscape/.test(ua) }
 },
 { // Internet Explorer <http://www.microsoft.com/windows/ie/>
// <http://www.microsoft.com/mac/ie/>
 'identifier': 'msie',
 'name': 'Internet Explorer',
 'browser': function() { return /MSIE/.test(ua) },
 'version': function() {
 return ua.match(
/MSIE (\d+(?:\.\d+)+(?:b\d*)?)/
 )
 }
 },
 { // Mozilla <http://www.mozilla.org/products/mozilla1.x/>
 'name': 'Mozilla',
 'browser': function() {
 return /Gecko|Mozilla/.test(ua)
 },
 'version': function() {
 return ua.match(/rv:(\d+(?:\.\d+)+)/)
 }
 }
 ];
i < data.length;
i++
 ) {
 if( data[i].browser() ) { // we have a match
var identifier = data[i].identifier ? data[i].identifier
: data[i].name.toLowerCase();

// Make a note that this browser was detected.
Private[ identifier ] = true;

// $.browser.browser() will now return the correct browser.
Private.browser = data[i].name;

var result;
if( data[i].version != undefined && (result = data[i].version()) ) {
 // Use the explicitly set test for browser version.
 Private.version.string = result[1];
 Private.version.number = parseFloat( result[1] );
} else {
 var re = new RegExp(
 data[i].name + '(?:\\s|\\/)(\\d+(?:\\.\\d+)+(?:(?:a|b)\\d*)?)'
 );

 result = ua.match(re);
 if( result != undefined ) {
 Private.version.string = result[1];
 Private.version.number = parseFloat( result[1] );
 }
}
break;
 }
 };
 for( var i = 0,// counter
 pl = navigator.platform, // the navigator's platform string
 data = [ // OS data and tests
 { 
 'identifier': 'win',
 'name': 'Windows',
 'OS': function() { return /Win/.test(pl) }
 },
 { // Apple Mac OS <http://www.apple.com/macos/>
 'name': 'Mac',
 'OS': function() { return /Mac/.test(pl) }
 },
 { // Linux <http://www.linux.org/>
 'name': 'Linux',
 'OS': function() { return /Linux/.test(pl) }
 }
 ];
 i < data.length;
 i++
 ) {
 if( data[i].OS() ) { // we have a match
var identifier = data[i].identifier ? data[i].identifier
: data[i].name.toLowerCase();
Private[ identifier ] = true;
Private.OS = data[i].name;
break;
 }
 };
}();
