new function() { 
var Public = {
'auto': function( bool ) {
return bool != undefined ? Private.auto = bool
 : Private.auto;
},
'init': function() {
return Private.init();
},
'bind': function( callback ) {
return Private.bind( callback );
},
  'unbind': function( callback ) {
return Private.unbind( callback );
},
 'trigger': function( force, args ) {
return Private.trigger( force, args );
},
  'active': function() {
return Private.active;
},
'delay': function( milliseconds ) {
return milliseconds ? Private.delay = milliseconds
: Private.delay;
},
'start': function() {
return Private.start();
},
'stop': function() {
return Private.stop();
},
 'current': function() {
return Private.current;
},
'previous': function() {
return Private.previous;
}
};
$.jqem = Public;
var Private = {
'$em': $( document.createElement('i') ),
 'active': false,
 'canExp': undefined,
'current': undefined,
  'delay': 100,  // milliseconds
'iid': undefined,
'previous': undefined,
'auto': true,
'init': init,
'bind': bind,
 'unbind': unbind,
'trigger': trigger,
 'update': function() {
Private.trigger( false );
return '1em';
},
  'start': start,
'stop': stop
};
$(document).ready(function() {
if( Private.auto ) init();
});
function init() {
$('body').prepend(
Private.$em.css({
'display': 'block',
  'left': '-1em',
  'position': 'absolute',
'visibility': 'hidden',
 'width': '1em'
})
);
Private.canExp = ( Private.$em.style != undefined
&& Private.$em.style.setExpression != undefined );
Private.start();
};
function bind( callback ) {
Private.$em.bind( 'emchange', callback );
};
function unbind( callback ) {
Private.$em.unbind( 'emchange', callback );
};
function trigger( force, args ) {
if( force == undefined ) force = false;

if( force || Private.$em.width() != Private.current ) {
Private.previous = Private.current;
Private.current  = Private.$em.width();
$.event.trigger( 'emchange', args );
}
};
function start() {
if( Private.active ) return;
Private.current = Private.previous = Private.$em.width();
if( Private.canExp ) {
Private.$em.style.setExpression( 'width', '$.jqem.update();' );
} else {
Private.iid = window.setInterval( Private.update, Private.delay );
}
Private.active = true;
};
function stop() {
if( !Private.active ) return;
if( Private.canExp ) {
Private.$em.style.removeExpression('width');
} else {
window.removeInterval( Private.iid );
}
};
}();
