--- /dev/null
+/*
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * <a href="http://www.owasp.org/index.php/ESAPI">http://www.owasp.org/index.php/ESAPI</a>.
+ *
+ * Copyright (c) 2008 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ */
+
+
+// Utility and Core API Methods
+var $namespace = function(name, separator, container){
+ var ns = name.split(separator || '.'),
+ o = container || window,
+ i,
+ len;
+ for(i = 0, len = ns.length; i < len; i++){
+ o = o[ns[i]] = o[ns[i]] || {};
+ }
+ return o;
+};
+
+var $type = function( oVar, oType ) {
+ if ( !oVar instanceof oType ) {
+ throw new SyntaxError();
+ }
+};
+
+if (!$) {
+ var $ = function( sElementID ) {
+ return document.getElementById( sElementID );
+ };
+}
+
+if (!Array.prototype.each) {
+ Array.prototype.each = function(fIterator) {
+ if (typeof fIterator != 'function') {
+ throw 'Illegal Argument for Array.each';
+ }
+
+ for (var i = 0; i < this.length; i ++) {
+ fIterator(this[i]);
+ }
+ };
+}
+
+if (!Array.prototype.contains) {
+ Array.prototype.contains = function(srch) {
+ var found = false;
+ this.each(function(e) {
+ if ( ( srch.equals && srch.equals(e) ) || e == srch) {
+ found = true;
+ return;
+ }
+ });
+ return found;
+ };
+}
+
+if (!Array.prototype.containsKey) {
+ Array.prototype.containsKey = function(srch) {
+ for ( var key in this ) {
+ if ( key.toLowerCase() == srch.toLowerCase() ) {
+ return true;
+ }
+ }
+ return false;
+ };
+}
+
+if (!Array.prototype.getCaseInsensitive) {
+ Array.prototype.getCaseInsensitive = function(key) {
+ for (var k in this) {
+ if (k.toLowerCase() == key.toLowerCase()) {
+ return this[k];
+ }
+ }
+ return null;
+ };
+}
+
+if (!String.prototype.charCodeAt) {
+ String.prototype.charCodeAt = function( idx ) {
+ var c = this.charAt(idx);
+ for ( var i=0;i<65536;i++) {
+ var s = String.fromCharCode(i);
+ if ( s == c ) { return i; }
+ }
+ return 0;
+ };
+}
+
+if (!String.prototype.endsWith) {
+ String.prototype.endsWith = function( test ) {
+ return this.substr( ( this.length - test.length ), test.length ) == test;
+ };
+}
+
+// Declare Core Exceptions
+if ( !Exception ) {
+ var Exception = function( sMsg, oException ) {
+ this.cause = oException;
+ this.errorMessage = sMsg;
+ };
+
+ Exception.prototype = Error.prototype;
+
+ Exception.prototype.getCause = function() { return this.cause; };
+
+ Exception.prototype.getMessage = function() { return this.message; };
+
+ /**
+ * This method creates the stacktrace for the Exception only when it is called the first time and
+ * caches it for access after that. Since building a stacktrace is a fairly expensive process, we
+ * only want to do it if it is called.
+ */
+ Exception.prototype.getStackTrace = function() {
+ if ( this.callstack ) {
+ return this.callstack;
+ }
+
+ if ( this.stack ) { // Mozilla
+ var lines = stack.split("\n");
+ for ( var i=0, len=lines.length; i<len; i ++ ) {
+ if ( lines[i].match( /^\s*[A-Za-z0-9\=+\$]+\(/ ) ) {
+ this.callstack.push(lines[i]);
+ }
+ }
+ this.callstack.shift();
+ return this.callstack;
+ }
+ else if ( window.opera && this.message ) { // Opera
+ var lines = this.message.split('\n');
+ for ( var i=0, len=lines.length; i<len; i++ ) {
+ if ( lines[i].match( /^\s*[A-Za-z0-9\=+\$]+\(/ ) ) {
+ var entry = lines[i];
+ if ( lines[i+1] ) {
+ entry += " at " + lines[i+1];
+ i++;
+ }
+ this.callstack.push(entry);
+ }
+ }
+ this.callstack.shift();
+ return this.callstack;
+ }
+ else { // IE and Safari
+ var currentFunction = arguments.callee.caller;
+ while ( currentFunction ) {
+ var fn = currentFunction.toString();
+ var fname = fn.substring(fn.indexOf("function")+8,fn.indexOf("(")) || "anonymous";
+ this.callstack.push(fname);
+ currentFunction = currentFunction.caller;
+ }
+ return this.callstack;
+ }
+ };
+
+ Exception.prototype.printStackTrace = function( writer ) {
+ var out = this.getMessage() + "|||" + this.getStackTrace().join( "|||" );
+
+ if ( this.cause ) {
+ if ( this.cause.printStackTrace ) {
+ out += "||||||Caused by " + this.cause.printStackTrace().replace( "\n", "|||" );
+ }
+ }
+
+ if ( !writer ) {
+ return writer.replace( "|||", "\n" );
+ } else if ( writer.value ) {
+ writer.value = out.replace( "|||", "\n" );
+ } else if ( writer.writeln ) {
+ writer.writeln( out.replace( "|||", "\n" ) );
+ } else if ( writer.innerHTML ) {
+ writer.innerHTML = out.replace( "|||", "<br/>" );
+ } else if ( writer.innerText ) {
+ writer.innerText = out.replace( "|||", "<br/>" );
+ } else if ( writer.append ) {
+ writer.append( out.replace( "|||", "\n" ) );
+ } else if ( writer instanceof Function ) {
+ writer(out.replace( "|||", "\n" ) );
+ }
+ };
+}
+
+if ( !RuntimeException ) {
+ var RuntimeException = Exception;
+}
+
+if ( !IllegalArgumentException ) {
+ var IllegalArgumentException = Exception;
+}
+
+if ( !DateFormat ) {
+ // Based on http://jacwright.com/projects/javascript/date_format
+ var DateFormat = function( sFmt ) {
+
+ var fmt = sFmt;
+
+ var replaceChars = {
+ longMonths: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ],
+ shortMonths: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ],
+ longDays: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
+ shortDays: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ],
+
+ // Day
+ d: function(date) { return (date.getDate() < 10 ? '0' : '') + date.getDate(); },
+ D: function(date) { return replaceChars.shortDays[date.getDay()]; },
+ j: function(date) { return date.getDate(); },
+ l: function(date) { return replaceChars.longDays[date.getDay()]; },
+ N: function(date) { return date.getDay() + 1; },
+ S: function(date) { return (date.getDate() % 10 == 1 && date.getDate() != 11 ? 'st' : (date.getDate() % 10 == 2 && date.getDate() != 12 ? 'nd' : (date.getDate() % 10 == 3 && date.getDate() != 13 ? 'rd' : 'th'))); },
+ w: function(date) { return date.getDay(); },
+ z: function(date) { return "Not Yet Supported"; },
+ // Week
+ W: function(date) { return "Not Yet Supported"; },
+ // Month
+ F: function(date) { return replaceChars.longMonths[date.getMonth()]; },
+ m: function(date) { return (date.getMonth() < 9 ? '0' : '') + (date.getMonth() + 1); },
+ M: function(date) { return replaceChars.shortMonths[date.getMonth()]; },
+ n: function(date) { return date.getMonth() + 1; },
+ t: function(date) { return "Not Yet Supported"; },
+ // Year
+ L: function(date) { return (((date.getFullYear()%4==0)&&(date.getFullYear()%100 != 0)) || (date.getFullYear()%400==0)) ? '1' : '0'; },
+ o: function(date) { return "Not Supported"; },
+ Y: function(date) { return date.getFullYear(); },
+ y: function(date) { return ('' + date.getFullYear()).substr(2); },
+ // Time
+ a: function(date) { return date.getHours() < 12 ? 'am' : 'pm'; },
+ A: function(date) { return date.getHours() < 12 ? 'AM' : 'PM'; },
+ B: function(date) { return "Not Yet Supported"; },
+ g: function(date) { return date.getHours() % 12 || 12; },
+ G: function(date) { return date.getHours(); },
+ h: function(date) { return ((date.getHours() % 12 || 12) < 10 ? '0' : '') + (date.getHours() % 12 || 12); },
+ H: function(date) { return (date.getHours() < 10 ? '0' : '') + date.getHours(); },
+ i: function(date) { return (date.getMinutes() < 10 ? '0' : '') + date.getMinutes(); },
+ s: function(date) { return (date.getSeconds() < 10 ? '0' : '') + date.getSeconds(); },
+ // Timezone
+ e: function(date) { return "Not Yet Supported"; },
+ I: function(date) { return "Not Supported"; },
+ O: function(date) { return (-date.getTimezoneOffset() < 0 ? '-' : '+') + (Math.abs(date.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(date.getTimezoneOffset() / 60)) + '00'; },
+ P: function(date) { return (-date.getTimezoneOffset() < 0 ? '-' : '+') + (Math.abs(date.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(date.getTimezoneOffset() / 60)) + ':' + (Math.abs(date.getTimezoneOffset() % 60) < 10 ? '0' : '') + (Math.abs(date.getTimezoneOffset() % 60)); },
+ T: function(date) { var m = date.getMonth(); date.setMonth(0); var result = date.toTimeString().replace(/^.+ \(?([^\)]+)\)?$/, '$1'); date.setMonth(m); return result;},
+ Z: function(date) { return -date.getTimezoneOffset() * 60; },
+ // Full Date/Time
+ c: function(date) { return date.format("Y-m-d") + "T" + date.format("H:i:sP"); },
+ r: function(date) { return date.toString(); },
+ U: function(date) { return date.getTime() / 1000; }
+ };
+
+
+ return {
+ format: function(oDate) {
+ var out = '';
+ for(var i=0;i<fmt.length;i++) {
+ var c = fmt.charAt(i);
+ if ( replaceChars[c] ) {
+ out += replaceChars[c].call(oDate);
+ } else {
+ out += c;
+ }
+ }
+ return out;
+ }
+ };
+ };
+
+ DateFormat.getDateInstance = function() {
+ return new DateFormat("M/d/y h:i a");
+ };
+}
+
+$namespace('org.owasp.esapi');
+
+org.owasp.esapi.ESAPI = function( oProperties ) {
+ var _properties = oProperties;
+
+ if ( !_properties ) throw new RuntimeException("Configuration Error - Unable to load $ESAPI_Properties Object");
+
+ var _encoder = null;
+ var _validator = null;
+ var _logFactory = null;
+ var _resourceBundle = null;
+ var _httputilities = null;
+
+ return {
+ properties: _properties,
+
+ encoder: function() {
+ if (!_encoder) {
+ if (!_properties.encoder.Implementation) throw new RuntimeException('Configuration Error - $ESAPI.properties.encoder.Implementation object not found.');
+ _encoder = new _properties.encoder.Implementation();
+ }
+ return _encoder;
+ },
+
+ logFactory: function() {
+ if ( !_logFactory ) {
+ if (!_properties.logging.Implementation) throw new RuntimeException('Configuration Error - $ESAPI.properties.logging.Implementation object not found.');
+ _logFactory = new _properties.logging.Implementation();
+ }
+ return _logFactory;
+ },
+
+ logger: function(sModuleName) {
+ return this.logFactory().getLogger(sModuleName);
+ },
+
+ locale: function() {
+ return org.owasp.esapi.i18n.Locale.getLocale( _properties.localization.DefaultLocale );
+ },
+
+ resourceBundle: function() {
+ if (!_resourceBundle) {
+ if(!_properties.localization.StandardResourceBundle) throw new RuntimeException("Configuration Error - $ESAPI.properties.localization.StandardResourceBundle not found.");
+ _resourceBundle = new org.owasp.esapi.i18n.ObjectResourceBundle( _properties.localization.StandardResourceBundle );
+ }
+ return _resourceBundle;
+ },
+
+ validator: function() {
+ if (!_validator) {
+ if (!_properties.validation.Implementation) throw new RuntimeException('Configuration Error - $ESAPI.properties.validation.Implementation object not found.');
+ _validator = new _properties.validation.Implementation();
+ }
+ return _validator;
+ },
+
+ httpUtilities: function() {
+ if (!_httputilities) _httputilities = new org.owasp.esapi.HTTPUtilities();
+ return _httputilities;
+ }
+ };
+};
+
+var $ESAPI = null;
+
+org.owasp.esapi.ESAPI.initialize = function() {
+ $ESAPI = new org.owasp.esapi.ESAPI( Base.esapi.properties );
+};
+
+$namespace('org.owasp.esapi');
+
+org.owasp.esapi.Encoder = function() {
+
+}
+
+$namespace('org.owasp.esapi');
+
+org.owasp.esapi.EncoderConstants = {
+ CHAR_LOWERS: [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ],
+ CHAR_UPPERS: [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ],
+ CHAR_DIGITS: [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ],
+ CHAR_SPECIALS: [ '!', '$', '*', '+', '-', '.', '=', '?', '@', '^', '_', '|', '~' ],
+ CHAR_LETTERS: [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ],
+ CHAR_ALNUM: [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ]
+};
+
+$namespace('org.owasp.esapi');
+
+org.owasp.esapi.EnterpriseSecurityException = function(sUserMessage, sLogMessage, oException) {
+ var _logMessage = sLogMessage;
+ var _super = new Exception(sUserMessage, oException);
+
+ return {
+ getMessage: _super.getMessage,
+ getUserMessage: _super.getMessage,
+ getLogMessage: function() {
+ return _logMessage;
+ },
+ getStackTrace: _super.getStackTrace,
+ printStackTrace: _super.printStackTrace
+ };
+};
+
+$namespace('org.owasp.esapi');
+
+org.owasp.esapi.HTTPUtilities = function() {
+ var log = $ESAPI.logger("HTTPUtilities");
+ var resourceBundle = $ESAPI.resourceBundle();
+ var EventType = org.owasp.esapi.Logger.EventType;
+
+ return {
+ addCookie: function( oCookie ) {
+ $type(oCookie,org.owasp.esapi.net.Cookie);
+
+ if ( window.top.location.protocol != 'http:' || window.top.location.protocol != 'https:' )
+ throw new RuntimeException(resourceBundle.getString( "HTTPUtilities.Cookie.Protocol", {"protocol":window.top.location.protocol}));
+
+ var name = oCookie.getName(),
+ value = oCookie.getValue(),
+ maxAge = oCookie.getMaxAge(),
+ domain = oCookie.getDomain(),
+ path = oCookie.getPath(),
+ secure = oCookie.getSecure();
+
+ var validationErrors = new org.owasp.esapi.ValidationErrorList();
+ var cookieName = $ESAPI.validator().getValidInput("cookie name", name, "HttpCookieName", 50, false, validationErrors );
+ var cookieValue = $ESAPI.validator().getValidInput("cookie value", value, "HttpCookieValue", 5000, false, validationErrors );
+
+ if (validationErrors.size() == 0) {
+ var header = name+'='+escape(value);
+ header += maxAge?";expires=" + ( new Date( ( new Date() ).getTime() + ( 1000 * maxAge ) ).toGMTString() ) : "";
+ header += path?";path="+path:"";
+ header += domain?";domain="+domain:"";
+ header += secure||$ESAPI.properties.httputilities.cookies.ForceSecure?";secure":"";
+ document.cookie=header;
+ }
+ else
+ {
+ log.warning(EventType.SECURITY_FAILURE, resourceBundle.getString("HTTPUtilities.Cookie.UnsafeData", { 'name':name, 'value':value } ) );
+ }
+ },
+
+ /**
+ * Returns a {@link org.owasp.esapi.net.Cookie} containing the name and value of the requested cookie.
+ *
+ * IMPORTANT: The value of the cookie is not sanitized at this level. It is the responsibility of the calling
+ * code to sanitize the value for proper output encoding prior to using it.
+ *
+ * @param sName {String} The name of the cookie to retrieve
+ * @return {org.owasp.esapi.net.Cookie}
+ */
+ getCookie: function(sName) {
+ var cookieJar = document.cookie.split("; ");
+ for(var i=0,len=cookieJar.length;i<len;i++) {
+ var cookie = cookieJar[i].split("=");
+ if (cookie[0] == escape(sName)) {
+ return new org.owasp.esapi.net.Cookie( sName, cookie[1]?unescape(cookie[1]):'' );
+ }
+ }
+ return null;
+ },
+
+ /**
+ * Will attempt to kill any cookies associated with the current request (domain,path,secure). If a cookie cannot
+ * be deleted, a RuntimeException will be thrown.
+ *
+ * @throws RuntimeException if one of the cookies cannot be deleted.
+ */
+ killAllCookies: function() {
+ var cookieJar = document.cookie.split("; ");
+ for(var i=0,len=cookieJar.length;i<len;i++) {
+ var cookie = cookieJar[i].split("=");
+ var name = unescape(cookie[0]);
+ // RuntimeException will bubble through if the cookie cannot be deleted
+ if (!this.killCookie(name)) {
+ // Something is wrong - cookieJar contains a cookie that is inaccesible using getCookie
+ throw new RuntimeException(resourceBundle.getString("HTTPUtilities.Cookie.CantKill", {"name":name}));
+ }
+ }
+ },
+
+ /**
+ * Will kill a single cookie. If that cookie cannot be deleted a RuntimeException will be thrown
+ * @param sName {String} The name of the cookie
+ */
+ killCookie: function(sName) {
+ var c = this.getCookie(sName);
+ if ( c ) {
+ c.setMaxAge( -10 );
+ this.addCookie(c);
+ if (this.getCookie(sName)) {
+ throw new RuntimeException(resourceBundle.getString("HTTPUtilities.Cookie.CantKill", {"name":sName}));
+ }
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * This only works for GET parameters and is meerly a convenience method for accessing that information if need be
+ * @param sName {String} The name of the parameter to retrieve
+ */
+ getRequestParameter: function( sName ) {
+ var url = window.top.location.search.substring(1);
+ var pIndex = url.indexOf(sName);
+ if (pIndex<0) return null;
+ pIndex=pIndex+sName.length;
+ var lastIndex=url.indexOf("&",pIndex);
+ if (lastIndex<0) lastIndex=url.length;
+ return unescape(url.substring(pIndex,lastIndex));
+ }
+ };
+};
+
+$namespace('org.owasp.esapi');
+
+org.owasp.esapi.IntrusionException = function(sUserMessage, sLogMessage, oCause) {
+ var _super = new org.owasp.esapi.EnterpriseSecurityException(sUserMessage, sLogMessage, oCause);
+
+ return {
+ getMessage: _super.getMessage,
+ getUserMessage: _super.getMessage,
+ getLogMessage: _super.getLogMessage,
+ getStackTrace: _super.getStackTrace,
+ printStackTrace: _super.printStackTrace
+ };
+};
+
+$namespace('org.owasp.esapi');
+
+org.owasp.esapi.LogFactory = function() {
+ return {
+ getLogger: false
+ };
+}
+
+$namespace('org.owasp.esapi');
+
+org.owasp.esapi.Logger = function() {
+ return {
+ setLevel: false,
+ fatal: false,
+ error: false,
+ isErrorEnabled: false,
+ warning: false,
+ isWarningEnabled: false,
+ info: false,
+ isInfoEnabled: false,
+ debug: false,
+ isDebugEnabled: false,
+ trace: false,
+ isTraceEnabled: false
+ };
+};
+
+org.owasp.esapi.Logger.EventType = function( sName, bNewSuccess ) {
+ var type = sName;
+ var success = bNewSuccess;
+
+ return {
+ isSuccess: function() {
+ return success;
+ },
+
+ toString: function() {
+ return type;
+ }
+ };
+};
+
+with(org.owasp.esapi.Logger) {
+
+ EventType.SECURITY_SUCCESS = new EventType( "SECURITY SUCCESS", true );
+ EventType.SECURITY_FAILURE = new EventType( "SECURITY FAILURE", false );
+ EventType.EVENT_SUCCESS = new EventType( "EVENT SUCCESS", true );
+ EventType.EVENT_FAILURE = new EventType( "EVENT FAILURE", false );
+
+ OFF = Number.MAX_VALUE;
+ FATAL = 1000;
+ ERROR = 800;
+ WARNING = 600;
+ INFO = 400;
+ DEBUG = 200;
+ TRACE = 100;
+ ALL = Number.MIN_VALUE;
+}
+
+$namespace('org.owasp.esapi');
+
+org.owasp.esapi.PreparedString = function(sTemplate, oCodec, sParameterCharacter) {
+ // Private Scope
+ var parts = [];
+ var parameters = [];
+
+ function split(s) {
+ var idx = 0, pcount = 0;
+ for (var i = 0; i < s.length; i ++) {
+ if (s.charAt(i) == sParameterCharacter) {
+ pcount ++;
+ parts.push(s.substr(idx, i));
+ idx = i + 1;
+ }
+ }
+ parts.push(s.substr(idx));
+ parameters = new Array(pcount);
+ }
+
+ ;
+
+ if (!sParameterCharacter) {
+ sParameterCharacter = '?';
+ }
+
+ split(sTemplate);
+
+ return {
+ set: function(iIndex, sValue, codec) {
+ if (iIndex < 1 || iIndex > parameters.length) {
+ throw new IllegalArgumentException("Attempt to set parameter: " + iIndex + " on a PreparedString with only " + parameters.length + " placeholders");
+ }
+ if (!codec) {
+ codec = oCodec;
+ }
+ parameters[iIndex - 1] = codec.encode([], sValue);
+ },
+
+ toString: function() {
+ for (var ix = 0; ix < parameters.length; ix ++) {
+ if (parameters[ix] == null) {
+ throw new RuntimeException("Attempt to render PreparedString without setting parameter " + (ix + 1));
+ }
+ }
+ var out = '', i = 0;
+ for (var p = 0; p < parts.length; p ++) {
+ out += parts[p];
+ if (i < parameters.length) {
+ out += parameters[i++];
+ }
+ }
+ return out;
+ }
+ };
+};
+
+
+$namespace('org.owasp.esapi');
+
+org.owasp.esapi.ValidationErrorList = function() {
+ var errorList = Array();
+
+ return {
+ addError: function( sContext, oValidationException ) {
+ if ( sContext == null ) throw new RuntimeException( "Context cannot be null: " + oValidationException.getLogMessage(), oValidationException );
+ if ( oValidationException == null ) throw new RuntimeException( "Context (" + sContext + ") - Error cannot be null" );
+ if ( errorList[sContext] ) throw new RuntimeException( "Context (" + sContext + ") already exists. must be unique." );
+ errorList[sContext] = oValidationException;
+ },
+
+ errors: function() {
+ return errorList;
+ },
+
+ isEmpty: function() {
+ return errorList.length == 0;
+ },
+
+ size: function() {
+ return errorList.length;
+ }
+ };
+};
+
+
+$namespace('org.owasp.esapi');
+
+org.owasp.esapi.ValidationRule = function() {
+ return {
+ getValid: false,
+ setAllowNull: false,
+ getTypeName: false,
+ setTypeName: false,
+ setEncoder: false,
+ assertValid: false,
+ getSafe: false,
+ isValid: false,
+ whitelist: false
+ };
+};
+
+
+$namespace('org.owasp.esapi');
+
+org.owasp.esapi.Validator = function() {
+ return {
+ addRule: false,
+ getRule: false,
+ getValidInput: false,
+ isValidDate: false,
+ getValidDate: false,
+ isValidSafeHTML: false,
+ getValidSafeHTML: false,
+ isValidCreditCard: false,
+ getValidCreditCard: false,
+ isValidFilename: false,
+ getValidFilename: false,
+ isValidNumber: false,
+ getValidNumber: false,
+ isValidPrintable: false,
+ getValidPrintable: false
+ };
+};
+
+
+$namespace('org.owasp.esapi.codecs.Base64');
+
+org.owasp.esapi.codecs.Base64 = {
+ _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
+
+ encode: function(sInput) {
+ if (!sInput) {
+ return null;
+ }
+
+ var out = '';
+ var ch1,ch2,ch3,enc1,enc2,enc3,enc4;
+ var i = 0;
+
+ var input = org.owasp.esapi.codecs.UTF8.encode(sInput);
+
+ while (i < input.length) {
+ ch1 = input.charCodeAt(i++);
+ ch2 = input.charCodeAt(i++);
+ ch3 = input.charCodeAt(i++);
+
+ enc1 = ch1 >> 2;
+ enc2 = ((ch1 & 3) << 4) | (ch2 >> 4);
+ enc3 = ((ch2 & 15) << 2) | (ch3 >> 6);
+ enc4 = ch3 & 63;
+
+ if (isNaN(ch2)) {
+ enc3 = enc4 = 64;
+ }
+ else if (isNaN(ch3)) {
+ enc4 = 64;
+ }
+
+ out += this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
+ }
+
+ return out;
+ },
+
+ decode: function(sInput) {
+ if (!sInput) {
+ return null;
+ }
+
+ var out = '';
+ var ch1, ch2, ch3, enc1, enc2, enc3, enc4;
+ var i = 0;
+
+ var input = sInput.replace(/[^A-Za-z0-9\+\/\=]/g, "");
+
+ while (i < input.length) {
+ enc1 = this._keyStr.indexOf(input.charAt(i++));
+ enc2 = this._keyStr.indexOf(input.charAt(i++));
+ enc3 = this._keyStr.indexOf(input.charAt(i++));
+ enc4 = this._keyStr.indexOf(input.charAt(i++));
+
+ ch1 = (enc1 << 2) | (enc2 >> 4);
+ ch2 = ((enc2 & 15) << 4) | (enc3 >> 2);
+ ch3 = ((enc3 & 3) << 6) | enc4;
+
+ out += String.fromCharCode(ch1);
+ if (enc3 != 64) {
+ out += String.fromCharCode(ch2);
+ }
+ if (enc4 != 64) {
+ out += String.fromCharCode(ch3);
+ }
+ }
+
+ out = org.owasp.esapi.codecs.UTF8.decode(out);
+ return out;
+ }
+};
+
+
+$namespace('org.owasp.esapi.codecs');
+
+org.owasp.esapi.codecs.CSSCodec = function() {
+ var _super = new org.owasp.esapi.codecs.Codec();
+
+ return {
+ encode: _super.encode,
+
+ decode: _super.decode,
+
+ encodeCharacter: function(aImmune, c) {
+ if (aImmune.contains(c)) {
+ return c;
+ }
+
+ var hex = org.owasp.esapi.codecs.Codec.getHexForNonAlphanumeric(c);
+ if (hex == null) {
+ return c;
+ }
+
+ return "\\" + hex + " ";
+ },
+
+ decodeCharacter: function(oPushbackString) {
+ oPushbackString.mark();
+ var first = oPushbackString.next();
+ if (first == null) {
+ oPushbackString.reset();
+ return null;
+ }
+
+ if (first != '\\') {
+ oPushbackString.reset();
+ return null;
+ }
+
+ var second = oPushbackString.next();
+ if (second == null) {
+ oPushbackString.reset();
+ return null;
+ }
+
+ if (oPushbackString.isHexDigit(second)) {
+ var out = second;
+ for (var i = 0; i < 6; i ++) {
+ var c = oPushbackString.next();
+ if (c == null || c.charCodeAt(0) == 0x20) {
+ break;
+ }
+ if (oPushbackString.isHexDigit(c)) {
+ out += c;
+ } else {
+ input.pushback(c);
+ break;
+ }
+ }
+
+ try {
+ var n = parseInt(out, 16);
+ return String.fromCharCode(n);
+ } catch (e) {
+ oPushbackString.reset();
+ return null;
+ }
+ }
+
+ return second;
+ }
+ };
+};
+
+
+$namespace('org.owasp.esapi.codecs');
+
+org.owasp.esapi.codecs.Codec = function() {
+ return {
+ /**
+ * Encode a String so that it can be safely used in a specific context.
+ *
+ * @param aImmune
+ * array of immune characters
+ * @param sInput
+ * the String to encode
+ * @return the encoded String
+ */
+ encode: function(aImmune, sInput) {
+ var out = '';
+ for (var i = 0; i < sInput.length; i ++) {
+ var c = sInput.charAt(i);
+ out += this.encodeCharacter(aImmune, c);
+ }
+ return out;
+ },
+
+ /**
+ * Default implementation that should be overridden in specific codecs.
+ *
+ * @param aImmune
+ * array of immune characters
+ * @param c
+ * the Character to encode
+ * @return
+ * the encoded Character
+ */
+ encodeCharacter: function(aImmune, c) {
+ return c;
+ },
+
+ /**
+ * Decode a String that was encoded using the encode method in this Class
+ *
+ * @param sInput
+ * the String to decode
+ * @return
+ * the decoded String
+ */
+ decode: function(sInput) {
+ var out = '';
+ var pbs = new org.owasp.esapi.codecs.PushbackString(sInput);
+ while (pbs.hasNext()) {
+ var c = this.decodeCharacter(pbs);
+ if (c != null) {
+ out += c;
+ } else {
+ out += pbs.next();
+ }
+ }
+ return out;
+ },
+
+ /**
+ * Returns the decoded version of the next character from the input string and advances the
+ * current character in the PushbackString. If the current character is not encoded, this
+ * method MUST reset the PushbackString.
+ *
+ * @param oPushbackString the Character to decode
+ * @return the decoded Character
+ */
+ decodeCharacter: function(oPushbackString) {
+ return oPushbackString.next();
+ }
+ };
+};
+
+org.owasp.esapi.codecs.Codec.getHexForNonAlphanumeric = function(c) {
+ if (c.charCodeAt(0) < 256) {
+ return org.owasp.esapi.codecs.Codec.hex[c.charCodeAt(0)];
+ }
+ return c.charCodeAt(0).toString(16);
+};
+
+org.owasp.esapi.codecs.Codec.hex = [];
+for ( var c = 0; c < 0xFF; c ++ ) {
+ if ( c >= 0x30 && c <= 0x39 || c>= 0x41 && c <= 0x5A || c >= 0x61 && c <= 0x7A ) {
+ org.owasp.esapi.codecs.Codec.hex[c] = null;
+ } else {
+ org.owasp.esapi.codecs.Codec.hex[c] = c.toString(16);
+ }
+};
+
+var entityToCharacterMap = [];
+entityToCharacterMap["""] = "34"; /* 34 : quotation mark */
+entityToCharacterMap["&"] = "38"; /* 38 : ampersand */
+entityToCharacterMap["<"] = "60"; /* 60 : less-than sign */
+entityToCharacterMap[">"] = "62"; /* 62 : greater-than sign */
+entityToCharacterMap[" "] = "160"; /* 160 : no-break space */
+entityToCharacterMap["¡"] = "161"; /* 161 : inverted exclamation mark */
+entityToCharacterMap["¢"] = "162"; /* 162 : cent sign */
+entityToCharacterMap["£"] = "163"; /* 163 : pound sign */
+entityToCharacterMap["¤"] = "164"; /* 164 : currency sign */
+entityToCharacterMap["¥"] = "165"; /* 165 : yen sign */
+entityToCharacterMap["¦"] = "166"; /* 166 : broken bar */
+entityToCharacterMap["§"] = "167"; /* 167 : section sign */
+entityToCharacterMap["¨"] = "168"; /* 168 : diaeresis */
+entityToCharacterMap["©"] = "169"; /* 169 : copyright sign */
+entityToCharacterMap["ª"] = "170"; /* 170 : feminine ordinal indicator */
+entityToCharacterMap["«"] = "171"; /* 171 : left-pointing double angle quotation mark */
+entityToCharacterMap["¬"] = "172"; /* 172 : not sign */
+entityToCharacterMap["­"] = "173"; /* 173 : soft hyphen */
+entityToCharacterMap["®"] = "174"; /* 174 : registered sign */
+entityToCharacterMap["¯"] = "175"; /* 175 : macron */
+entityToCharacterMap["°"] = "176"; /* 176 : degree sign */
+entityToCharacterMap["±"] = "177"; /* 177 : plus-minus sign */
+entityToCharacterMap["²"] = "178"; /* 178 : superscript two */
+entityToCharacterMap["³"] = "179"; /* 179 : superscript three */
+entityToCharacterMap["´"] = "180"; /* 180 : acute accent */
+entityToCharacterMap["µ"] = "181"; /* 181 : micro sign */
+entityToCharacterMap["¶"] = "182"; /* 182 : pilcrow sign */
+entityToCharacterMap["·"] = "183"; /* 183 : middle dot */
+entityToCharacterMap["¸"] = "184"; /* 184 : cedilla */
+entityToCharacterMap["¹"] = "185"; /* 185 : superscript one */
+entityToCharacterMap["º"] = "186"; /* 186 : masculine ordinal indicator */
+entityToCharacterMap["»"] = "187"; /* 187 : right-pointing double angle quotation mark */
+entityToCharacterMap["¼"] = "188"; /* 188 : vulgar fraction one quarter */
+entityToCharacterMap["½"] = "189"; /* 189 : vulgar fraction one half */
+entityToCharacterMap["¾"] = "190"; /* 190 : vulgar fraction three quarters */
+entityToCharacterMap["¿"] = "191"; /* 191 : inverted question mark */
+entityToCharacterMap["À"] = "192"; /* 192 : Latin capital letter a with grave */
+entityToCharacterMap["Á"] = "193"; /* 193 : Latin capital letter a with acute */
+entityToCharacterMap["Â"] = "194"; /* 194 : Latin capital letter a with circumflex */
+entityToCharacterMap["Ã"] = "195"; /* 195 : Latin capital letter a with tilde */
+entityToCharacterMap["Ä"] = "196"; /* 196 : Latin capital letter a with diaeresis */
+entityToCharacterMap["Å"] = "197"; /* 197 : Latin capital letter a with ring above */
+entityToCharacterMap["Æ"] = "198"; /* 198 : Latin capital letter ae */
+entityToCharacterMap["Ç"] = "199"; /* 199 : Latin capital letter c with cedilla */
+entityToCharacterMap["È"] = "200"; /* 200 : Latin capital letter e with grave */
+entityToCharacterMap["É"] = "201"; /* 201 : Latin capital letter e with acute */
+entityToCharacterMap["Ê"] = "202"; /* 202 : Latin capital letter e with circumflex */
+entityToCharacterMap["Ë"] = "203"; /* 203 : Latin capital letter e with diaeresis */
+entityToCharacterMap["Ì"] = "204"; /* 204 : Latin capital letter i with grave */
+entityToCharacterMap["Í"] = "205"; /* 205 : Latin capital letter i with acute */
+entityToCharacterMap["Î"] = "206"; /* 206 : Latin capital letter i with circumflex */
+entityToCharacterMap["Ï"] = "207"; /* 207 : Latin capital letter i with diaeresis */
+entityToCharacterMap["Ð"] = "208"; /* 208 : Latin capital letter eth */
+entityToCharacterMap["Ñ"] = "209"; /* 209 : Latin capital letter n with tilde */
+entityToCharacterMap["Ò"] = "210"; /* 210 : Latin capital letter o with grave */
+entityToCharacterMap["Ó"] = "211"; /* 211 : Latin capital letter o with acute */
+entityToCharacterMap["Ô"] = "212"; /* 212 : Latin capital letter o with circumflex */
+entityToCharacterMap["Õ"] = "213"; /* 213 : Latin capital letter o with tilde */
+entityToCharacterMap["Ö"] = "214"; /* 214 : Latin capital letter o with diaeresis */
+entityToCharacterMap["×"] = "215"; /* 215 : multiplication sign */
+entityToCharacterMap["Ø"] = "216"; /* 216 : Latin capital letter o with stroke */
+entityToCharacterMap["Ù"] = "217"; /* 217 : Latin capital letter u with grave */
+entityToCharacterMap["Ú"] = "218"; /* 218 : Latin capital letter u with acute */
+entityToCharacterMap["Û"] = "219"; /* 219 : Latin capital letter u with circumflex */
+entityToCharacterMap["Ü"] = "220"; /* 220 : Latin capital letter u with diaeresis */
+entityToCharacterMap["Ý"] = "221"; /* 221 : Latin capital letter y with acute */
+entityToCharacterMap["Þ"] = "222"; /* 222 : Latin capital letter thorn */
+entityToCharacterMap["ß"] = "223"; /* 223 : Latin small letter sharp s, German Eszett */
+entityToCharacterMap["à"] = "224"; /* 224 : Latin small letter a with grave */
+entityToCharacterMap["á"] = "225"; /* 225 : Latin small letter a with acute */
+entityToCharacterMap["â"] = "226"; /* 226 : Latin small letter a with circumflex */
+entityToCharacterMap["ã"] = "227"; /* 227 : Latin small letter a with tilde */
+entityToCharacterMap["ä"] = "228"; /* 228 : Latin small letter a with diaeresis */
+entityToCharacterMap["å"] = "229"; /* 229 : Latin small letter a with ring above */
+entityToCharacterMap["æ"] = "230"; /* 230 : Latin lowercase ligature ae */
+entityToCharacterMap["ç"] = "231"; /* 231 : Latin small letter c with cedilla */
+entityToCharacterMap["è"] = "232"; /* 232 : Latin small letter e with grave */
+entityToCharacterMap["é"] = "233"; /* 233 : Latin small letter e with acute */
+entityToCharacterMap["ê"] = "234"; /* 234 : Latin small letter e with circumflex */
+entityToCharacterMap["ë"] = "235"; /* 235 : Latin small letter e with diaeresis */
+entityToCharacterMap["ì"] = "236"; /* 236 : Latin small letter i with grave */
+entityToCharacterMap["í"] = "237"; /* 237 : Latin small letter i with acute */
+entityToCharacterMap["î"] = "238"; /* 238 : Latin small letter i with circumflex */
+entityToCharacterMap["ï"] = "239"; /* 239 : Latin small letter i with diaeresis */
+entityToCharacterMap["ð"] = "240"; /* 240 : Latin small letter eth */
+entityToCharacterMap["ñ"] = "241"; /* 241 : Latin small letter n with tilde */
+entityToCharacterMap["ò"] = "242"; /* 242 : Latin small letter o with grave */
+entityToCharacterMap["ó"] = "243"; /* 243 : Latin small letter o with acute */
+entityToCharacterMap["ô"] = "244"; /* 244 : Latin small letter o with circumflex */
+entityToCharacterMap["õ"] = "245"; /* 245 : Latin small letter o with tilde */
+entityToCharacterMap["ö"] = "246"; /* 246 : Latin small letter o with diaeresis */
+entityToCharacterMap["÷"] = "247"; /* 247 : division sign */
+entityToCharacterMap["ø"] = "248"; /* 248 : Latin small letter o with stroke */
+entityToCharacterMap["ù"] = "249"; /* 249 : Latin small letter u with grave */
+entityToCharacterMap["ú"] = "250"; /* 250 : Latin small letter u with acute */
+entityToCharacterMap["û"] = "251"; /* 251 : Latin small letter u with circumflex */
+entityToCharacterMap["ü"] = "252"; /* 252 : Latin small letter u with diaeresis */
+entityToCharacterMap["ý"] = "253"; /* 253 : Latin small letter y with acute */
+entityToCharacterMap["þ"] = "254"; /* 254 : Latin small letter thorn */
+entityToCharacterMap["ÿ"] = "255"; /* 255 : Latin small letter y with diaeresis */
+entityToCharacterMap["&OElig"] = "338"; /* 338 : Latin capital ligature oe */
+entityToCharacterMap["&oelig"] = "339"; /* 339 : Latin small ligature oe */
+entityToCharacterMap["&Scaron"] = "352"; /* 352 : Latin capital letter s with caron */
+entityToCharacterMap["&scaron"] = "353"; /* 353 : Latin small letter s with caron */
+entityToCharacterMap["&Yuml"] = "376"; /* 376 : Latin capital letter y with diaeresis */
+entityToCharacterMap["&fnof"] = "402"; /* 402 : Latin small letter f with hook */
+entityToCharacterMap["&circ"] = "710"; /* 710 : modifier letter circumflex accent */
+entityToCharacterMap["&tilde"] = "732"; /* 732 : small tilde */
+entityToCharacterMap["&Alpha"] = "913"; /* 913 : Greek capital letter alpha */
+entityToCharacterMap["&Beta"] = "914"; /* 914 : Greek capital letter beta */
+entityToCharacterMap["&Gamma"] = "915"; /* 915 : Greek capital letter gamma */
+entityToCharacterMap["&Delta"] = "916"; /* 916 : Greek capital letter delta */
+entityToCharacterMap["&Epsilon"] = "917"; /* 917 : Greek capital letter epsilon */
+entityToCharacterMap["&Zeta"] = "918"; /* 918 : Greek capital letter zeta */
+entityToCharacterMap["&Eta"] = "919"; /* 919 : Greek capital letter eta */
+entityToCharacterMap["&Theta"] = "920"; /* 920 : Greek capital letter theta */
+entityToCharacterMap["&Iota"] = "921"; /* 921 : Greek capital letter iota */
+entityToCharacterMap["&Kappa"] = "922"; /* 922 : Greek capital letter kappa */
+entityToCharacterMap["&Lambda"] = "923"; /* 923 : Greek capital letter lambda */
+entityToCharacterMap["&Mu"] = "924"; /* 924 : Greek capital letter mu */
+entityToCharacterMap["&Nu"] = "925"; /* 925 : Greek capital letter nu */
+entityToCharacterMap["&Xi"] = "926"; /* 926 : Greek capital letter xi */
+entityToCharacterMap["&Omicron"] = "927"; /* 927 : Greek capital letter omicron */
+entityToCharacterMap["&Pi"] = "928"; /* 928 : Greek capital letter pi */
+entityToCharacterMap["&Rho"] = "929"; /* 929 : Greek capital letter rho */
+entityToCharacterMap["&Sigma"] = "931"; /* 931 : Greek capital letter sigma */
+entityToCharacterMap["&Tau"] = "932"; /* 932 : Greek capital letter tau */
+entityToCharacterMap["&Upsilon"] = "933"; /* 933 : Greek capital letter upsilon */
+entityToCharacterMap["&Phi"] = "934"; /* 934 : Greek capital letter phi */
+entityToCharacterMap["&Chi"] = "935"; /* 935 : Greek capital letter chi */
+entityToCharacterMap["&Psi"] = "936"; /* 936 : Greek capital letter psi */
+entityToCharacterMap["&Omega"] = "937"; /* 937 : Greek capital letter omega */
+entityToCharacterMap["&alpha"] = "945"; /* 945 : Greek small letter alpha */
+entityToCharacterMap["&beta"] = "946"; /* 946 : Greek small letter beta */
+entityToCharacterMap["&gamma"] = "947"; /* 947 : Greek small letter gamma */
+entityToCharacterMap["&delta"] = "948"; /* 948 : Greek small letter delta */
+entityToCharacterMap["&epsilon"] = "949"; /* 949 : Greek small letter epsilon */
+entityToCharacterMap["&zeta"] = "950"; /* 950 : Greek small letter zeta */
+entityToCharacterMap["&eta"] = "951"; /* 951 : Greek small letter eta */
+entityToCharacterMap["&theta"] = "952"; /* 952 : Greek small letter theta */
+entityToCharacterMap["&iota"] = "953"; /* 953 : Greek small letter iota */
+entityToCharacterMap["&kappa"] = "954"; /* 954 : Greek small letter kappa */
+entityToCharacterMap["&lambda"] = "955"; /* 955 : Greek small letter lambda */
+entityToCharacterMap["&mu"] = "956"; /* 956 : Greek small letter mu */
+entityToCharacterMap["&nu"] = "957"; /* 957 : Greek small letter nu */
+entityToCharacterMap["&xi"] = "958"; /* 958 : Greek small letter xi */
+entityToCharacterMap["&omicron"] = "959"; /* 959 : Greek small letter omicron */
+entityToCharacterMap["&pi"] = "960"; /* 960 : Greek small letter pi */
+entityToCharacterMap["&rho"] = "961"; /* 961 : Greek small letter rho */
+entityToCharacterMap["&sigmaf"] = "962"; /* 962 : Greek small letter final sigma */
+entityToCharacterMap["&sigma"] = "963"; /* 963 : Greek small letter sigma */
+entityToCharacterMap["&tau"] = "964"; /* 964 : Greek small letter tau */
+entityToCharacterMap["&upsilon"] = "965"; /* 965 : Greek small letter upsilon */
+entityToCharacterMap["&phi"] = "966"; /* 966 : Greek small letter phi */
+entityToCharacterMap["&chi"] = "967"; /* 967 : Greek small letter chi */
+entityToCharacterMap["&psi"] = "968"; /* 968 : Greek small letter psi */
+entityToCharacterMap["&omega"] = "969"; /* 969 : Greek small letter omega */
+entityToCharacterMap["&thetasym"] = "977"; /* 977 : Greek theta symbol */
+entityToCharacterMap["&upsih"] = "978"; /* 978 : Greek upsilon with hook symbol */
+entityToCharacterMap["&piv"] = "982"; /* 982 : Greek pi symbol */
+entityToCharacterMap["&ensp"] = "8194"; /* 8194 : en space */
+entityToCharacterMap["&emsp"] = "8195"; /* 8195 : em space */
+entityToCharacterMap["&thinsp"] = "8201"; /* 8201 : thin space */
+entityToCharacterMap["&zwnj"] = "8204"; /* 8204 : zero width non-joiner */
+entityToCharacterMap["&zwj"] = "8205"; /* 8205 : zero width joiner */
+entityToCharacterMap["&lrm"] = "8206"; /* 8206 : left-to-right mark */
+entityToCharacterMap["&rlm"] = "8207"; /* 8207 : right-to-left mark */
+entityToCharacterMap["&ndash"] = "8211"; /* 8211 : en dash */
+entityToCharacterMap["&mdash"] = "8212"; /* 8212 : em dash */
+entityToCharacterMap["&lsquo"] = "8216"; /* 8216 : left single quotation mark */
+entityToCharacterMap["&rsquo"] = "8217"; /* 8217 : right single quotation mark */
+entityToCharacterMap["&sbquo"] = "8218"; /* 8218 : single low-9 quotation mark */
+entityToCharacterMap["&ldquo"] = "8220"; /* 8220 : left double quotation mark */
+entityToCharacterMap["&rdquo"] = "8221"; /* 8221 : right double quotation mark */
+entityToCharacterMap["&bdquo"] = "8222"; /* 8222 : double low-9 quotation mark */
+entityToCharacterMap["&dagger"] = "8224"; /* 8224 : dagger */
+entityToCharacterMap["&Dagger"] = "8225"; /* 8225 : double dagger */
+entityToCharacterMap["&bull"] = "8226"; /* 8226 : bullet */
+entityToCharacterMap["&hellip"] = "8230"; /* 8230 : horizontal ellipsis */
+entityToCharacterMap["&permil"] = "8240"; /* 8240 : per mille sign */
+entityToCharacterMap["&prime"] = "8242"; /* 8242 : prime */
+entityToCharacterMap["&Prime"] = "8243"; /* 8243 : double prime */
+entityToCharacterMap["&lsaquo"] = "8249"; /* 8249 : single left-pointing angle quotation mark */
+entityToCharacterMap["&rsaquo"] = "8250"; /* 8250 : single right-pointing angle quotation mark */
+entityToCharacterMap["&oline"] = "8254"; /* 8254 : overline */
+entityToCharacterMap["&frasl"] = "8260"; /* 8260 : fraction slash */
+entityToCharacterMap["&euro"] = "8364"; /* 8364 : euro sign */
+entityToCharacterMap["&image"] = "8365"; /* 8465 : black-letter capital i */
+entityToCharacterMap["&weierp"] = "8472"; /* 8472 : script capital p, Weierstrass p */
+entityToCharacterMap["&real"] = "8476"; /* 8476 : black-letter capital r */
+entityToCharacterMap["&trade"] = "8482"; /* 8482 : trademark sign */
+entityToCharacterMap["&alefsym"] = "8501"; /* 8501 : alef symbol */
+entityToCharacterMap["&larr"] = "8592"; /* 8592 : leftwards arrow */
+entityToCharacterMap["&uarr"] = "8593"; /* 8593 : upwards arrow */
+entityToCharacterMap["&rarr"] = "8594"; /* 8594 : rightwards arrow */
+entityToCharacterMap["&darr"] = "8595"; /* 8595 : downwards arrow */
+entityToCharacterMap["&harr"] = "8596"; /* 8596 : left right arrow */
+entityToCharacterMap["&crarr"] = "8629"; /* 8629 : downwards arrow with corner leftwards */
+entityToCharacterMap["&lArr"] = "8656"; /* 8656 : leftwards double arrow */
+entityToCharacterMap["&uArr"] = "8657"; /* 8657 : upwards double arrow */
+entityToCharacterMap["&rArr"] = "8658"; /* 8658 : rightwards double arrow */
+entityToCharacterMap["&dArr"] = "8659"; /* 8659 : downwards double arrow */
+entityToCharacterMap["&hArr"] = "8660"; /* 8660 : left right double arrow */
+entityToCharacterMap["&forall"] = "8704"; /* 8704 : for all */
+entityToCharacterMap["&part"] = "8706"; /* 8706 : partial differential */
+entityToCharacterMap["&exist"] = "8707"; /* 8707 : there exists */
+entityToCharacterMap["&empty"] = "8709"; /* 8709 : empty set */
+entityToCharacterMap["&nabla"] = "8711"; /* 8711 : nabla */
+entityToCharacterMap["&isin"] = "8712"; /* 8712 : element of */
+entityToCharacterMap["¬in"] = "8713"; /* 8713 : not an element of */
+entityToCharacterMap["&ni"] = "8715"; /* 8715 : contains as member */
+entityToCharacterMap["&prod"] = "8719"; /* 8719 : n-ary product */
+entityToCharacterMap["&sum"] = "8721"; /* 8721 : n-ary summation */
+entityToCharacterMap["&minus"] = "8722"; /* 8722 : minus sign */
+entityToCharacterMap["&lowast"] = "8727"; /* 8727 : asterisk operator */
+entityToCharacterMap["&radic"] = "8730"; /* 8730 : square root */
+entityToCharacterMap["&prop"] = "8733"; /* 8733 : proportional to */
+entityToCharacterMap["&infin"] = "8734"; /* 8734 : infinity */
+entityToCharacterMap["&ang"] = "8736"; /* 8736 : angle */
+entityToCharacterMap["&and"] = "8743"; /* 8743 : logical and */
+entityToCharacterMap["&or"] = "8744"; /* 8744 : logical or */
+entityToCharacterMap["&cap"] = "8745"; /* 8745 : intersection */
+entityToCharacterMap["&cup"] = "8746"; /* 8746 : union */
+entityToCharacterMap["&int"] = "8747"; /* 8747 : integral */
+entityToCharacterMap["&there4"] = "8756"; /* 8756 : therefore */
+entityToCharacterMap["&sim"] = "8764"; /* 8764 : tilde operator */
+entityToCharacterMap["&cong"] = "8773"; /* 8773 : congruent to */
+entityToCharacterMap["&asymp"] = "8776"; /* 8776 : almost equal to */
+entityToCharacterMap["&ne"] = "8800"; /* 8800 : not equal to */
+entityToCharacterMap["&equiv"] = "8801"; /* 8801 : identical to, equivalent to */
+entityToCharacterMap["&le"] = "8804"; /* 8804 : less-than or equal to */
+entityToCharacterMap["&ge"] = "8805"; /* 8805 : greater-than or equal to */
+entityToCharacterMap["&sub"] = "8834"; /* 8834 : subset of */
+entityToCharacterMap["&sup"] = "8835"; /* 8835 : superset of */
+entityToCharacterMap["&nsub"] = "8836"; /* 8836 : not a subset of */
+entityToCharacterMap["&sube"] = "8838"; /* 8838 : subset of or equal to */
+entityToCharacterMap["&supe"] = "8839"; /* 8839 : superset of or equal to */
+entityToCharacterMap["&oplus"] = "8853"; /* 8853 : circled plus */
+entityToCharacterMap["&otimes"] = "8855"; /* 8855 : circled times */
+entityToCharacterMap["&perp"] = "8869"; /* 8869 : up tack */
+entityToCharacterMap["&sdot"] = "8901"; /* 8901 : dot operator */
+entityToCharacterMap["&lceil"] = "8968"; /* 8968 : left ceiling */
+entityToCharacterMap["&rceil"] = "8969"; /* 8969 : right ceiling */
+entityToCharacterMap["&lfloor"] = "8970"; /* 8970 : left floor */
+entityToCharacterMap["&rfloor"] = "8971"; /* 8971 : right floor */
+entityToCharacterMap["&lang"] = "9001"; /* 9001 : left-pointing angle bracket */
+entityToCharacterMap["&rang"] = "9002"; /* 9002 : right-pointing angle bracket */
+entityToCharacterMap["&loz"] = "9674"; /* 9674 : lozenge */
+entityToCharacterMap["&spades"] = "9824"; /* 9824 : black spade suit */
+entityToCharacterMap["&clubs"] = "9827"; /* 9827 : black club suit */
+entityToCharacterMap["&hearts"] = "9829"; /* 9829 : black heart suit */
+entityToCharacterMap["&diams"] = "9830"; /* 9830 : black diamond suit */
+
+var characterToEntityMap = [];
+
+for ( var entity in entityToCharacterMap ) {
+ characterToEntityMap[entityToCharacterMap[entity]] = entity;
+}
+
+$namespace('org.owasp.esapi.codecs');
+
+org.owasp.esapi.codecs.HTMLEntityCodec = function() {
+ var _super = new org.owasp.esapi.codecs.Codec();
+
+ var getNumericEntity = function(input) {
+ var first = input.peek();
+ if (first == null) {
+ return null;
+ }
+
+ if (first == 'x' || first == 'X') {
+ input.next();
+ return parseHex(input);
+ }
+ return parseNumber(input);
+ };
+
+ var parseNumber = function(input) {
+ var out = '';
+ while (input.hasNext()) {
+ var c = input.peek();
+ if (c.match(/[0-9]/)) {
+ out += c;
+ input.next();
+ } else if (c == ';') {
+ input.next();
+ break;
+ } else {
+ break;
+ }
+ }
+
+ try {
+ return parseInt(out);
+ } catch (e) {
+ return null;
+ }
+ };
+
+ var parseHex = function(input) {
+ var out = '';
+ while (input.hasNext()) {
+ var c = input.peek();
+ if (c.match(/[0-9A-Fa-f]/)) {
+ out += c;
+ input.next();
+ } else if (c == ';') {
+ input.next();
+ break;
+ } else {
+ break;
+ }
+ }
+ try {
+ return parseInt(out, 16);
+ } catch (e) {
+ return null;
+ }
+ };
+
+ var getNamedEntity = function(input) {
+ var entity = '';
+ while (input.hasNext()) {
+ var c = input.peek();
+ if (c.match(/[A-Za-z]/)) {
+ entity += c;
+ input.next();
+ if (entityToCharacterMap.containsKey('&' + entity)) {
+ if (input.peek(';')) input.next();
+ break;
+ }
+ } else if (c == ';') {
+ input.next();
+ } else {
+ break;
+ }
+ }
+
+ return String.fromCharCode(entityToCharacterMap.getCaseInsensitive('&' + entity));
+ };
+
+ return {
+ encode: _super.encode,
+
+ decode: _super.decode,
+
+ encodeCharacter: function(aImmune, c) {
+ if (aImmune.contains(c)) {
+ return c;
+ }
+
+ var hex = org.owasp.esapi.codecs.Codec.getHexForNonAlphanumeric(c);
+ if (hex == null) {
+ return c;
+ }
+
+ var cc = c.charCodeAt(0);
+ if (( cc <= 0x1f && c != '\t' && c != '\n' && c != '\r' ) || ( cc >= 0x7f && cc <= 0x9f ) || c == ' ') {
+ return " ";
+ }
+
+ var entityName = characterToEntityMap[cc];
+ if (entityName != null) {
+ return entityName + ";";
+ }
+
+ return "&#x" + hex + ";";
+ },
+
+ decodeCharacter: function(oPushbackString) {
+ //noinspection UnnecessaryLocalVariableJS
+ var input = oPushbackString;
+ input.mark();
+ var first = input.next();
+ if (first == null || first != '&') {
+ input.reset();
+ return null;
+ }
+
+ var second = input.next();
+ if (second == null) {
+ input.reset();
+ return null;
+ }
+
+ if (second == '#') {
+ var c = getNumericEntity(input);
+ if (c != null) {
+ return c;
+ }
+ } else if (second.match(/[A-Za-z]/)) {
+ input.pushback(second);
+ c = getNamedEntity(input);
+ if (c != null) {
+ return c;
+ }
+ }
+ input.reset();
+ return null;
+ }
+ };
+};
+
+
+$namespace('org.owasp.esapi.codecs');
+
+org.owasp.esapi.codecs.JavascriptCodec = function() {
+ var _super = new org.owasp.esapi.codecs.Codec();
+
+ return {
+ encode: function(aImmune, sInput) {
+ var out = '';
+ for (var idx = 0; idx < sInput.length; idx ++) {
+ var ch = sInput.charAt(idx);
+ if (aImmune.contains(ch)) {
+ out += ch;
+ }
+ else {
+ var hex = org.owasp.esapi.codecs.Codec.getHexForNonAlphanumeric(ch);
+ if (hex == null) {
+ out += ch;
+ }
+ else {
+ var tmp = ch.charCodeAt(0).toString(16);
+ if (ch.charCodeAt(0) < 256) {
+ var pad = "00".substr(tmp.length);
+ out += "\\x" + pad + tmp.toUpperCase();
+ }
+ else {
+ pad = "0000".substr(tmp.length);
+ out += "\\u" + pad + tmp.toUpperCase();
+ }
+ }
+ }
+ }
+ return out;
+ },
+
+ decode: _super.decode,
+
+ decodeCharacter: function(oPushbackString) {
+ oPushbackString.mark();
+ var first = oPushbackString.next();
+ if (first == null) {
+ oPushbackString.reset();
+ return null;
+ }
+
+ if (first != '\\') {
+ oPushbackString.reset();
+ return null;
+ }
+
+ var second = oPushbackString.next();
+ if (second == null) {
+ oPushbackString.reset();
+ return null;
+ }
+
+ // \0 collides with the octal decoder and is non-standard
+ // if ( second.charValue() == '0' ) {
+ // return Character.valueOf( (char)0x00 );
+ if (second == 'b') {
+ return 0x08;
+ } else if (second == 't') {
+ return 0x09;
+ } else if (second == 'n') {
+ return 0x0a;
+ } else if (second == 'v') {
+ return 0x0b;
+ } else if (second == 'f') {
+ return 0x0c;
+ } else if (second == 'r') {
+ return 0x0d;
+ } else if (second == '\"') {
+ return 0x22;
+ } else if (second == '\'') {
+ return 0x27;
+ } else if (second == '\\') {
+ return 0x5c;
+ } else if (second.toLowerCase() == 'x') {
+ out = '';
+ for (var i = 0; i < 2; i++) {
+ var c = oPushbackString.nextHex();
+ if (c != null) {
+ out += c;
+ } else {
+ input.reset();
+ return null;
+ }
+ }
+ try {
+ n = parseInt(out, 16);
+ return String.fromCharCode(n);
+ } catch (e) {
+ oPushbackString.reset();
+ return null;
+ }
+ } else if (second.toLowerCase() == 'u') {
+ out = '';
+ for (i = 0; i < 4; i++) {
+ c = oPushbackString.nextHex();
+ if (c != null) {
+ out += c;
+ } else {
+ input.reset();
+ return null;
+ }
+ }
+ try {
+ var n = parseInt(out, 16);
+ return String.fromCharCode(n);
+ } catch (e) {
+ oPushbackString.reset();
+ return null;
+ }
+ } else if (oPushbackString.isOctalDigit(second)) {
+ var out = second;
+ var c2 = oPushbackString.next();
+ if (!oPushbackString.isOctalDigit(c2)) {
+ oPushbackString.pushback(c2);
+ } else {
+ out += c2;
+ var c3 = oPushbackString.next();
+ if (!oPushbackString.isOctalDigit(c3)) {
+ oPushbackString.pushback(c3);
+ } else {
+ out += c3;
+ }
+ }
+
+ try {
+ n = parseInt(out, 8);
+ return String.fromCharCode(n);
+ } catch (e) {
+ oPushbackString.reset();
+ return null;
+ }
+ }
+ return second;
+ }
+ };
+};
+
+
+$namespace('org.owasp.esapi.codecs');
+
+org.owasp.esapi.codecs.PercentCodec = function() {
+ var _super = new org.owasp.esapi.codecs.Codec();
+
+ var ALPHA_NUMERIC_STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ var RFC_NON_ALPHANUMERIC_UNRESERVED_STR = "-._~";
+ var ENCODED_NON_ALPHA_NUMERIC_UNRESERVED = true;
+ var UNENCODED_STR = ALPHA_NUMERIC_STR + (ENCODED_NON_ALPHA_NUMERIC_UNRESERVED ? "" : RFC_NON_ALPHANUMERIC_UNRESERVED_STR);
+
+ var getTwoUpperBytes = function(b) {
+ var out = '';
+ if (b < -128 || b > 127) {
+ throw new IllegalArgumentException("b is not a byte (was " + b + ")");
+ }
+ b &= 0xFF;
+ if (b < 0x10) {
+ out += '0';
+ }
+ return out + b.toString(16).toUpperCase();
+ };
+
+ return {
+ encode: _super.encode,
+
+ decode: _super.decode,
+
+ encodeCharacter: function(aImmune, c) {
+ if (UNENCODED_STR.indexOf(c) > -1) {
+ return c;
+ }
+
+ var bytes = org.owasp.esapi.codecs.UTF8.encode(c);
+ var out = '';
+ for (var b = 0; b < bytes.length; b++) {
+ out += '%' + getTwoUpperBytes(bytes.charCodeAt(b));
+ }
+ return out;
+ },
+
+ decodeCharacter: function(oPushbackString) {
+ oPushbackString.mark();
+ var first = oPushbackString.next();
+ if (first == null || first != '%') {
+ oPushbackString.reset();
+ return null;
+ }
+
+ var out = '';
+ for (var i = 0; i < 2; i++) {
+ var c = oPushbackString.nextHex();
+ if (c != null) {
+ out += c;
+ }
+ }
+ if (out.length == 2) {
+ try {
+ var n = parseInt(out, 16);
+ return String.fromCharCode(n);
+ } catch (e) {
+ }
+ }
+ oPushbackString.reset();
+ return null;
+ }
+ };
+};
+
+
+$namespace('org.owasp.esapi.codecs');
+
+org.owasp.esapi.codecs.PushbackString = function(sInput) {
+ var _input = sInput,
+ _pushback = '',
+ _temp = '',
+ _index = 0,
+ _mark = 0;
+
+ return {
+ pushback: function(c) {
+ _pushback = c;
+ },
+
+ index: function() {
+ return _index;
+ },
+
+ hasNext: function() {
+ if (_pushback != null) return true;
+ return !(_input == null || _input.length == 0 || _index >= _input.length);
+
+ },
+
+ next: function() {
+ if (_pushback != null) {
+ var save = _pushback;
+ _pushback = null;
+ return save;
+ }
+ if (_input == null || _input.length == 0 || _index >= _input.length) {
+ return null;
+ }
+ return _input.charAt(_index++);
+ },
+
+ nextHex: function() {
+ var c = this.next();
+ if (this.isHexDigit(c)) return c;
+ return null;
+ },
+
+ nextOctal: function() {
+ var c = this.next();
+ if (this.isOctalDigit(c)) return c;
+ return null;
+ },
+
+ isHexDigit: function(c) {
+ return c != null && ( ( c >= '0' && c <= '9' ) || ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) );
+ },
+
+ isOctalDigit: function(c) {
+ return c != null && ( c >= '0' && c <= '7' );
+ },
+
+ peek: function(c) {
+ if (!c) {
+ if (_pushback != null) return _pushback;
+ if (_input == null || _input.length == 0 || _index >= _input.length) return null;
+ return _input.charAt(_index);
+ } else {
+ if (_pushback != null && _pushback == c) return true;
+ if (_input == null || _input.length == 0 || _index >= _input.length) return false;
+ return _input.charAt(_index) == c;
+ }
+ },
+
+ mark: function() {
+ _temp = _pushback;
+ _mark = _index;
+ },
+
+ reset: function() {
+ _pushback = _temp;
+ _index = _mark;
+ },
+
+ remainder: function() {
+ var out = _input.substr(_index);
+ if (_pushback != null) {
+ out = _pushback + out;
+ }
+ return out;
+ }
+ };
+};
+
+
+$namespace('org.owasp.esapi.codecs');
+
+org.owasp.esapi.codecs.UTF8 = {
+ encode: function(sInput) {
+ var input = sInput.replace(/\r\n/g, "\n");
+ var utftext = '';
+
+ for (var n = 0; n < input.length; n ++) {
+ var c = input.charCodeAt(n);
+
+ if (c < 128) {
+ utftext += String.fromCharCode(c);
+ }
+ else if (( c > 127) && (c < 2048)) {
+ utftext += String.fromCharCode((c >> 6) | 192);
+ utftext += String.fromCharCode((c & 63) | 128);
+ }
+ else {
+ utftext += String.fromCharCode((c >> 12) | 224);
+ utftext += String.fromCharCode(((c >> 6) & 63) | 128);
+ utftext += String.fromCharCode((c & 63) | 128);
+ }
+ }
+
+ return utftext;
+ }
+ ,
+
+ decode: function(sInput) {
+ var out = '';
+ var i = c = c1 = c2 = 0;
+
+ while (i < sInput.length) {
+ c = sInput.charCodeAt(i);
+
+ if (c < 128) {
+ out += String.fromCharCode(c);
+ i ++;
+ }
+ else if ((c > 191) && (c < 224)) {
+ c2 = sInput.charCodeAt(i + 1);
+ out += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
+ i += 2;
+ }
+ else {
+ c2 = utftext.charCodeAt(i + 1);
+ c3 = utftext.charCodeAt(i + 2);
+ string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
+ i += 3;
+ }
+ }
+
+ return out;
+ }
+};
+
+
+$namespace('org.owasp.esapi.i18n');
+
+org.owasp.esapi.i18n.ArrayResourceBundle = function( sName, oLocale, aMessages, oParent ) {
+ with(org.owasp.esapi.i18n) var _super = new ResourceBundle( sName, oLocale, oParent );
+
+ var messages = aMessages;
+
+ return {
+ getParent: _super.getParent,
+ getLocale: _super.getLocale,
+ getName: _super.getName,
+ getString: _super.getString,
+ getMessage: function(sKey) {
+ return messages[sKey];
+ }
+ };
+};
+
+
+$namespace('org.owasp.esapi.i18n');
+
+org.owasp.esapi.i18n.Locale = function( sLanguage, sCountry, sVariant ) {
+ var language = sLanguage, country = sCountry, variant = sVariant;
+
+ return {
+ getLanguage: function() { return language; },
+ getCountry: function() { return country; },
+ getVariant: function() { return variant; },
+ toString: function() { return language + ( country ? "-" + country + ( variant ? "-" + variant : "" ) : "" ); }
+ };
+};
+
+org.owasp.esapi.i18n.Locale.US = new org.owasp.esapi.i18n.Locale("en","US");
+org.owasp.esapi.i18n.Locale.GB = new org.owasp.esapi.i18n.Locale("en","GB");
+
+org.owasp.esapi.i18n.Locale.getLocale = function(sLocale) {
+ var l = sLocale.split("-");
+ return new org.owasp.esapi.i18n.Locale( l[0], (l.length>1?l[1]:""), (l.length>2?l.length[2]:""));
+};
+
+org.owasp.esapi.i18n.Locale.getDefault = function() {
+ var l = (navigator['language']?navigator['language']:(navigator['userLanguage']?navigator['userLanguage']:'en-US')).split("-");
+ return new org.owasp.esapi.i18n.Locale( l[0], (l.length>1?l[1]:""), (l.length>2?l.length[2]:""));
+};
+
+
+$namespace('org.owasp.esapi.i18n');
+
+org.owasp.esapi.i18n.ObjectResourceBundle = function( oResource, oParent ) {
+ var _super = new org.owasp.esapi.i18n.ResourceBundle( oResource.name, org.owasp.esapi.i18n.Locale.getLocale(oResource.locale), oParent );
+
+ var messages = oResource.messages;
+
+ return {
+ getParent: _super.getParent,
+ getLocale: _super.getLocale,
+ getName: _super.getName,
+ getString: _super.getString,
+ getMessage: function(sKey) {
+ return messages[sKey];
+ }
+ };
+};
+
+
+$namespace('org.owasp.esapi.i18n');
+
+org.owasp.esapi.i18n.ResourceBundle = function( sName, oLocale, oParentResourceBundle ) {
+ var parent = oParentResourceBundle;
+ var locale = oLocale;
+ var name = sName;
+
+ if ( !name ) throw new SyntaxError("Name required for implementations of org.owasp.esapi.i18n.ResourceBundle");
+ if ( !locale ) throw new SyntaxError("Locale required for implementations of org.owasp.esapi.i18n.ResourceBundle");
+
+ return {
+ getParent: function() { return parent; },
+ getLocale: function() { return locale; },
+ getName: function() { return name; },
+ getMessage: function(sKey) { return sKey; },
+ getString: function( sKey, oContextMap ) {
+ if ( arguments.length < 1 ) {
+ throw new IllegalArgumentException("No key passed to getString");
+ }
+
+ var msg = this.getMessage(sKey);
+ if ( !msg ) {
+ if ( parent ) {
+ return parent.getString( sKey, oContextMap );
+ } else {
+ return sKey;
+ }
+ }
+
+ if ( !msg.match( /\{([A-Za-z]+)\}/ ) || !oContextMap ) {
+ return msg;
+ }
+
+ var out = '', lastIndex = 0;
+ while (true) {
+ var nextVarIdx = msg.indexOf( "{", lastIndex );
+ var endIndex = msg.indexOf( "}", nextVarIdx );
+
+ if ( nextVarIdx < 0 ) {
+ out += msg.substr( lastIndex, msg.length-lastIndex );
+ break;
+ }
+
+ if ( nextVarIdx >= 0 && endIndex < -1 ) {
+ throw new SyntaxError("Invalid Message - Unclosed Context Reference: " + msg );
+ }
+
+ out += msg.substring( lastIndex, nextVarIdx );
+ var contextKey = msg.substring( nextVarIdx+1, endIndex );
+ if ( oContextMap[contextKey] ) {
+ out += oContextMap[contextKey];
+ } else {
+ out += msg.substring( nextVarIdx, endIndex+1 );
+ }
+
+ lastIndex = endIndex + 1;
+ }
+
+ return out;
+ }
+ };
+};
+
+org.owasp.esapi.i18n.ResourceBundle.getResourceBundle = function(sResource, oLocale) {
+ var classname = sResource + "_" + oLocale.toString().replace("-","_");
+
+ with( org.owasp.esapi.i18n ) {
+ if ( ResourceBundle[classname] instanceof Object ) {
+ return ResourceBundle[classname];
+ } else {
+ return new ResourceBundle[classname]();
+ }
+ }
+};
+
+$namespace('org.owasp.esapi.net');
+
+/**
+ * Constructs a cookie with a specified name and value.
+ * <p/>
+ * The name must conform to RFC 2109. That means it can contain only ASCII alphanumeric characters and cannot contain
+ * commas, semicolons, or white space or begin with a $ character. The cookie's name cannot be changed after creation.
+ * <p/>
+ * The value can be anything the server chooses to send. Its value is probably of interest only to the server. The
+ * cookie's value can be changed after creation with the setValue method.
+ * <p/>
+ * By default, cookies are created according to the Netscape cookie specification. The version can be changed with the
+ * {@link #setVersion} method.
+ *
+ * @constructor
+ * @param sName {String} a <code>String</code> specifying the name of the cookie
+ * @param sValue {String} a <code>String</code> specifying the value of the cookie
+ * @throws IllegalArgumentException
+ * if the cookie name contains illegal characters (for example, a comma, space, or semicolon) or it is one of
+ * the tokens reserved for use by the cookie protocol
+ */
+org.owasp.esapi.net.Cookie = function( sName, sValue ) {
+ var name; // NAME= ... "$Name" style is reserved
+ var value; // value of NAME
+
+ var comment; // ;Comment=VALUE ... describes the cookies use
+ var domain; // ;Domain=VALUE ... domain that sees the cookie
+ var maxAge; // ;Max-Age=VALUE ... cookies auto-expire
+ var path; // ;Path=VALUE ... URLs that see the cookie
+ var secure; // ;Secure ... e.g. use SSL
+ var version; // ;Version=1 ... means RFC-2109++ style
+
+ var _resourceBundle = $ESAPI.resourceBundle();
+
+ var tSpecials = ",; ";
+
+ var isToken = function(sValue) {
+ for(var i=0,len=sValue.length;i<len;i++) {
+ var cc = sValue.charCodeAt(i),c=sValue.charAt(i);
+ if (cc<0x20||cc>=0x7F||tSpecials.indexOf(c)!=-1) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ if ( !isToken(sName)
+ || sName.toLowerCase() == 'comment'
+ || sName.toLowerCase() == 'discard'
+ || sName.toLowerCase() == 'domain'
+ || sName.toLowerCase() == 'expires'
+ || sName.toLowerCase() == 'max-age'
+ || sName.toLowerCase() == 'path'
+ || sName.toLowerCase() == 'secure'
+ || sName.toLowerCase() == 'version'
+ || sName.charAt(0) == '$' ) {
+ var errMsg = _resourceBundle.getString( "Cookie.Name", { 'name':sName } );
+ throw new IllegalArgumentException(errMsg);
+ }
+
+ name = sName;
+ value = sValue;
+
+ return {
+ setComment: function(purpose) { comment = purpose; },
+ getComment: function() { return comment; },
+ setDomain: function(sDomain) { domain = sDomain.toLowerCase(); },
+ getDomain: function() { return domain; },
+ setMaxAge: function(nExpirey) { maxAge = nExpirey; },
+ getMaxAge: function() { return maxAge; },
+ setPath: function(sPath) { path = sPath; },
+ getPath: function() { return path; },
+ setSecure: function(bSecure) { secure = bSecure; },
+ getSecure: function() { return secure; },
+ getName: function() { return name; },
+ setValue: function(sValue) { value = sValue; },
+ getValue: function() { return value; },
+ setVersion: function(nVersion) {
+ if(nVersion<0||nVersion>1)throw new IllegalArgumentException(_resourceBundle.getString("Cookie.Version", { 'version':nVersion } ) );
+ version = nVersion;
+ },
+ getVersion: function() { return version; }
+ };
+};
+
+$namespace('org.owasp.esapi.reference.encoding');
+
+org.owasp.esapi.reference.encoding.DefaultEncoder = function(aCodecs) {
+ var _codecs = [],
+ _htmlCodec = new org.owasp.esapi.codecs.HTMLEntityCodec(),
+ _javascriptCodec = new org.owasp.esapi.codecs.JavascriptCodec(),
+ _cssCodec = new org.owasp.esapi.codecs.CSSCodec(),
+ _percentCodec = new org.owasp.esapi.codecs.PercentCodec();
+
+ if (!aCodecs) {
+ _codecs.push(_htmlCodec);
+ _codecs.push(_javascriptCodec);
+ _codecs.push(_cssCodec);
+ _codecs.push(_percentCodec);
+ } else {
+ _codecs = aCodecs;
+ }
+
+ var IMMUNE_HTML = new Array(',', '.', '-', '_', ' ');
+ var IMMUNE_HTMLATTR = new Array(',', '.', '-', '_');
+ var IMMUNE_CSS = new Array();
+ var IMMUNE_JAVASCRIPT = new Array(',', '.', '_');
+
+ return {
+ cananicalize: function(sInput, bStrict) {
+ if (!sInput) {
+ return null;
+ }
+ var working = sInput, codecFound = null, mixedCount = 1, foundCount = 0, clean = false;
+ while (!clean) {
+ clean = true;
+
+ _codecs.each(function(codec) {
+ var old = working;
+ working = codec.decode(working);
+
+ if (old != working) {
+ if (codecFound != null && codecFound != codec) {
+ mixedCount ++;
+ }
+ codecFound = codec;
+ if (clean) {
+ foundCount ++;
+ }
+ clean = false;
+ }
+ });
+ }
+
+ if (foundCount >= 2 && mixedCount > 1) {
+ if (bStrict) {
+ throw new org.owasp.esapi.IntrusionException("Input validation failure", "Multiple (" + foundCount + "x) and mixed encoding (" + mixedCount + "x) detected in " + sInput);
+ }
+ }
+ else if (foundCount >= 2) {
+ if (bStrict) {
+ throw new org.owasp.esapi.IntrusionException("Input validation failure", "Multiple (" + foundCount + "x) encoding detected in " + sInput);
+ }
+ }
+ else if (mixedCount > 1) {
+ if (bStrict) {
+ throw new org.owasp.esapi.IntrusionException("Input validation failure", "Mixed (" + mixedCount + "x) encoding detected in " + sInput);
+ }
+ }
+ return working;
+ },
+
+ normalize: function(sInput) {
+ return sInput.replace(/[^\x00-\x7F]/g, '');
+ },
+
+ encodeForHTML: function(sInput) {
+ return !sInput ? null : _htmlCodec.encode(IMMUNE_HTML, sInput);
+ },
+
+ decodeForHTML: function(sInput) {
+ return !sInput ? null : _htmlCodec.decode(sInput);
+ },
+
+ encodeForHTMLAttribute: function(sInput) {
+ return !sInput ? null : _htmlCodec.encode(IMMUNE_HTMLATTR, sInput);
+ },
+
+ encodeForCSS: function(sInput) {
+ return !sInput ? null : _cssCodec.encode(IMMUNE_CSS, sInput);
+ },
+
+ encodeForJavaScript: function(sInput) {
+ return !sInput ? null : _javascriptCodec.encode(IMMUNE_JAVASCRIPT, sInput);
+ },
+
+ encodeForJavascript: this.encodeForJavaScript,
+
+ encodeForURL: function(sInput) {
+ return !sInput ? null : escape(sInput);
+ },
+
+ decodeFromURL: function(sInput) {
+ return !sInput ? null : unescape(sInput);
+ },
+
+ encodeForBase64: function(sInput) {
+ return !sInput ? null : org.owasp.esapi.codecs.Base64.encode(sInput);
+ },
+
+ decodeFromBase64: function(sInput) {
+ return !sInput ? null : org.owasp.esapi.codecs.Base64.decode(sInput);
+ }
+ };
+};
+
+
+$namespace('org.owasp.esapi.reference.logging');
+
+org.owasp.esapi.reference.logging.Log4JSLogFactory = function() {
+ var loggersMap = Array();
+
+ var Log4JSLogger = function( sModuleName ) {
+ var jsLogger = null;
+ var moduleName = sModuleName?sModuleName:null;
+ var Level = Log4js.Level;
+
+ var logUrl = false, logApplicationName = false, encodingRequired = false, encodingFunction = $ESAPI.encoder().encodeForHTML;
+
+ jsLogger = Log4js.getLogger( moduleName );
+
+ var convertESAPILevel = function( nLevel ) {
+ var Logger = org.owasp.esapi.Logger;
+ switch (nLevel) {
+ case Logger.OFF: return Log4js.Level.OFF;
+ case Logger.FATAL: return Log4js.Level.FATAL;
+ case Logger.ERROR: return Log4js.Level.ERROR;
+ case Logger.WARNING: return Log4js.Level.WARN;
+ case Logger.INFO: return Log4js.Level.INFO;
+ case Logger.DEBUG: return Log4js.Level.DEBUG;
+ case Logger.TRACE: return Log4js.Level.TRACE;
+ case Logger.ALL: return Log4js.Level.ALL;
+ }
+ };
+
+ return {
+ setLevel: function( nLevel ) {
+ try {
+ jsLogger.setLevel( convertESAPILevel( nLevel ) );
+ } catch (e) {
+ this.error( org.owasp.esapi.Logger.SECURITY_FAILURE, "", e );
+ }
+ },
+
+ trace: function( oEventType, sMessage, oException ) {
+ this.log( Level.TRACE, oEventType, sMessage, oException );
+ },
+
+ debug: function( oEventType, sMessage, oException ) {
+ this.log( Level.DEBUG, oEventType, sMessage, oException );
+ },
+
+ info: function( oEventType, sMessage, oException ) {
+ this.log( Level.INFO, oEventType, sMessage, oException );
+ },
+
+ warning: function( oEventType, sMessage, oException ) {
+ this.log( Level.WARN, oEventType, sMessage, oException );
+ },
+
+ error: function( oEventType, sMessage, oException ) {
+ this.log( Level.ERROR, oEventType, sMessage, oException );
+ },
+
+ fatal: function( oEventType, sMessage, oException ) {
+ this.log( Level.FATAL, oEventType, sMessage, oException );
+ },
+
+ log: function( oLevel, oEventType, sMessage, oException ) {
+ switch(oLevel) {
+ case Level.TRACE: if ( !jsLogger.isTraceEnabled() ) { return; } break;
+ case Level.DEBUG: if ( !jsLogger.isDebugEnabled() ) { return; } break;
+ case Level.INFO: if ( !jsLogger.isInfoEnabled() ) { return; } break;
+ case Level.WARNING: if ( !jsLogger.isWarnEnabled() ) { return; } break;
+ case Level.ERROR: if ( !jsLogger.isErrorEnabled() ) { return; } break;
+ case Level.FATAL: if ( !jsLogger.isFatalEnabled() ) { return; } break;
+ }
+
+ if ( !sMessage ) {
+ sMessage = "";
+ }
+
+ sMessage = '[' + oEventType.toString() + '] - ' + sMessage;
+
+ var clean = sMessage.replace("\n","_").replace("\r","_");
+ if ( encodingRequired ) {
+ clean = encodingFunction(clean);
+ if ( clean != sMessage) {
+ clean += " [Encoded]";
+ }
+ }
+
+ var appInfo = ( logUrl ? window.location.href : "" ) +
+ ( logApplicationName ? "/" + $ESAPI.properties.application.Name : "" );
+
+ jsLogger.log( oLevel, ( appInfo != "" ? "[" + appInfo + "] " : "" ) + clean, oException );
+ },
+
+ addAppender: function( oAppender ) {
+ jsLogger.addAppender( oAppender );
+ },
+
+ isLogUrl: function() { return logUrl; },
+ setLogUrl: function(b) { logUrl = b; },
+ isLogApplicationName: function() { return logApplicationName; },
+ setLogApplicationName: function(b) { logApplicationName = b; },
+ isEncodingRequired: function() { return encodingRequired; },
+ setEncodingRequired: function(b) { encodingRequired = b; },
+ setEncodingFunction: function(f) { encodingFunction = f; },
+ isDebugEnabled: function() { return jsLogger.isDebugEnabled(); },
+ isErrorEnabled: function() { return jsLogger.isErrorEnabled(); },
+ isFatalEnabled: function() { return jsLogger.isFatalEnabled(); },
+ isInfoEnabled: function() { return jsLogger.isInfoEnabled(); },
+ isTraceEnabled: function() { return jsLogger.isTraceEnabled(); },
+ isWarningEnabled: function() { return jsLogger.isWarnEnabled(); }
+ };
+ };
+
+ var getLoggerConfig = function( moduleName ) {
+ var logConfig = $ESAPI.properties.logging;
+ if ( logConfig[moduleName] ) {
+ logConfig = logConfig[moduleName];
+ }
+ return logConfig;
+ };
+
+ return {
+ getLogger: function ( moduleName ) {
+ var key = ( typeof moduleName == 'string' ) ? moduleName : moduleName.constructor.toString();
+ var logger = loggersMap[key];
+ if ( !logger ) {
+ logger = new Log4JSLogger(key);
+
+ var logConfig = getLoggerConfig(moduleName);
+
+ logger.setLevel( logConfig.Level );
+ logger.setLogUrl( logConfig.LogUrl );
+ logger.setLogApplicationName( logConfig.LogApplicationName );
+ logger.setEncodingRequired( logConfig.EncodingRequired );
+
+ if ( logConfig.EncodingFunction ) {
+ logger.setEncodingFunction( logConfig.EncodingFunction );
+ }
+
+ logConfig.Appenders.each(function(e){
+ if ( logConfig.Layout ) {
+ e.setLayout( logConfig.Layout );
+ }
+ logger.addAppender(e);
+ });
+
+ loggersMap[key] = logger;
+ }
+ return logger;
+ }
+ };
+};
+
+
+$namespace('org.owasp.esapi.reference.validation');
+
+org.owasp.esapi.reference.validation.BaseValidationRule = function( sTypeName, oEncoder, oLocale ) {
+ var log = $ESAPI.logger( "Validation" );
+ var EventType = org.owasp.esapi.Logger.EventType;
+
+ var typename = sTypeName;
+ var encoder = oEncoder?oEncoder:$ESAPI.encoder();
+ var allowNull = false;
+
+ var ResourceBundle = org.owasp.esapi.i18n.ResourceBundle;
+
+ var locale = oLocale?oLocale:$ESAPI.locale();
+ var resourceBundle;
+
+ if ( $ESAPI.properties.validation.ResourceBundle ) {
+ resourceBundle = ResourceBundle.getResourceBundle( $ESAPI.properties.validation.ResourceBundle, locale );
+ }
+
+ if ( !resourceBundle ) {
+ resourceBundle = $ESAPI.resourceBundle();
+ log.info( EventType.EVENT_FAILURE, "No Validation ResourceBundle - Defaulting to " + resourceBundle.getName() + "(" + resourceBundle.getLocale().toString() + ")" );
+ }
+
+ log.info( EventType.EVENT_SUCCESS, "Validation Rule Initialized with ResourceBundle: " + resourceBundle.getName() );
+
+ return {
+ setAllowNull: function(b) { allowNull = b; },
+
+ isAllowNull: function() { return allowNull; },
+
+ getTypeName: function() { return typename; },
+
+ setTypeName: function(s) { typename = s; },
+
+ setEncoder: function(oEncoder) { encoder = oEncoder; },
+
+ getEncoder: function() { return encoder; },
+
+ assertValid: function( sContext, sInput ) {
+ this.getValid( sContext, sInput );
+ },
+
+ getValid: function( sContext, sInput, oValidationErrorList ) {
+ var valid = null;
+ try {
+ valid = this.getValidInput( sContext, sInput );
+ } catch (oValidationException) {
+ return this.sanitize( sContext, sInput );
+ }
+ return valid;
+ },
+
+ getValidInput: function( sContext, sInput ) {
+ return sInput;
+ },
+
+ getSafe: function( sContext, sInput ) {
+ var valid = null;
+ try {
+ valid = this.getValidInput( sContext, sInput );
+ } catch (oValidationException) {
+ return this.sanitize( sContext, sInput );
+ }
+ return valid;
+ },
+
+ /**
+ * The method is similar to ValidationRuile.getSafe except that it returns a
+ * harmless object that <b>may or may not have any similarity to the original
+ * input (in some cases you may not care)</b>. In most cases this should be the
+ * same as the getSafe method only instead of throwing an exception, return
+ * some default value.
+ *
+ * @param context
+ * @param input
+ * @return a parsed version of the input or a default value.
+ */
+ sanitize: function( sContext, sInput ) {
+ return sInput;
+ },
+
+ isValid: function( sContext, sInput ) {
+ var valid = false;
+ try {
+ this.getValidInput( sContext, sInput );
+ valid = true;
+ } catch (oValidationException) {
+ return false;
+ }
+ return valid;
+ },
+
+ /**
+ * Removes characters that aren't in the whitelist from the input String.
+ * O(input.length) whitelist performance
+ * @param input String to be sanitized
+ * @param whitelist allowed characters
+ * @return input stripped of all chars that aren't in the whitelist
+ */
+ whitelist: function( sInput, aWhitelist ) {
+ var stripped = '';
+ for ( var i=0;i<sInput.length;i++ ) {
+ var c = sInput.charAt(i);
+ if ( aWhitelist.contains(c) ) {
+ stripped += c;
+ }
+ }
+ return stripped;
+ },
+
+ getUserMessage: function( sContext, sDefault, oContextValues ) {
+ return this.getMessage( sContext+".Usr", sDefault+".Usr", oContextValues );
+ },
+
+ getLogMessage: function( sContext, sDefault, oContextValues ) {
+ return this.getMessage( sContext+".Log", sDefault+".Log", oContextValues );
+ },
+
+ getMessage: function( sContext, sDefault, oContextValues ) {
+ return resourceBundle.getString( sContext, oContextValues ) ? resourceBundle.getString( sContext, oContextValues ) : resourceBundle.getString( sDefault, oContextValues );
+ },
+
+ validationException: function( sContext, sDefault, sValidation, oContextValues ) {
+ throw new org.owasp.esapi.reference.validation.ValidationException(
+ this.getUserMessage( sContext+"."+sValidation, sDefault+"."+sValidation, oContextValues ),
+ this.getLogMessage( sContext+"."+sValidation, sDefault+"."+sValidation, oContextValues ),
+ sContext
+ );
+ }
+ };
+};
+
+
+$namespace('org.owasp.esapi.reference.validation');
+
+org.owasp.esapi.reference.validation.CreditCardValidationRule = function( sTypeName, oEncoder, oLocale ) {
+ var _super = new org.owasp.esapi.reference.validation.BaseValidationRule( sTypeName, oEncoder, oLocale );
+ var _validationType = "CreditCard";
+
+ var maxCardLength = 19;
+ var ccrule;
+
+ var readDefaultCreditCardRule = function() {
+ var p = new RegExp( $ESAPI.properties.validation.CreditCard );
+ var ccr = new org.owasp.esapi.reference.validation.StringValidationRule( "ccrule", _super.getEncoder(), oLocale, p );
+ ccr.setMaxLength( maxCardLength );
+ ccr.setAllowNull( false );
+ return ccr;
+ };
+
+ ccRule = readDefaultCreditCardRule();
+
+ var validCreditCardFormat = function( ccNum ) {
+ var digitsonly = '';
+ var c;
+ for (var i=0;o<ccNum.length;i++) {
+ c = ccNum.charAt(i);
+ if ( c.match( /[0-9]/ ) ) digitsonly += c;
+ }
+
+ var sum = 0, digit = 0, addend = 0, timesTwo = false;
+
+ for (var j=digitsonly.length-1; j>=0; j--) {
+ digit = parseInt(digitsonly.substring(j,i+1));
+ if ( timesTwo ) {
+ addend = digit * 2;
+ if ( addend > 9 ) addend -= 9;
+ } else {
+ addend = digit;
+ }
+ sum += addend;
+ timesTwo = !timesTwo;
+ }
+ return sum % 10 == 0;
+ };
+
+ return {
+ getMaxCardLength: function() { return maxCardLength; },
+
+ setMaxCardLength: function(n) { maxCardLength = n; },
+
+ setAllowNull: _super.setAllowNull,
+
+ isAllowNull: _super.isAllowNull,
+
+ getTypeName: _super.getTypeName,
+
+ setTypeName: _super.setTypeName,
+
+ setEncoder: _super.setEncoder,
+
+ getEncoder: _super.getEncoder,
+
+ assertValid: _super.assertValid,
+
+ getValid: _super.getValid,
+
+ getValidInput: function( sContext, sInput ) {
+ if ( !sInput || sInput.trim() == '' ) {
+ if ( this.isAllowNull() ) {
+ return null;
+ }
+ _super.validationException( sContext, _validationType, "Required", { "context":sContext, "input":sInput } );
+ }
+
+ var canonical = ccrule.getValid( sContext, sInput );
+
+ if ( !validCreditCardFormat(canonical) ) {
+ _super.validationException( sContext, _validationType, "Invalid", { "context":sContext, "input":sInput } );
+ }
+
+ return canonical;
+ },
+
+ getSafe: _super.getSafe,
+
+ sanitize: function( sContext, sInput ) {
+ return this.whitelist( sInput, org.owasp.esapi.EncoderConstants.CHAR_DIGITS );
+ },
+
+ isValid: _super.isValid,
+
+ whitelist: _super.whitelist
+ };
+};
+
+
+$namespace('org.owasp.esapi.reference.validation');
+
+org.owasp.esapi.reference.validation.DateValidationRule = function( sTypeName, oEncoder, oLocale ) {
+ var _super = new org.owasp.esapi.reference.validation.BaseValidationRule( sTypeName, oEncoder, oLocale );
+ var _validationTarget = "Date";
+
+ var format = DateFormat.getDateInstance();
+
+ var safelyParse = function(sContext,sInput) {
+ if ( !sContext || sContext.trim() == '' ) {
+ if ( _super.isAllowNull() ) {
+ return null;
+ }
+ _super.validationException( sContext, _validationTarget, "Required", { "context":sContext, "input":sInput, "format":format } );
+ }
+
+ var canonical = _super.getEncoder().cananicalize(sInput);
+
+ try {
+ return format.parse(canonical);
+ } catch (e) {
+ _super.validationException( sContext, _validationTarget, "Invalid", { "context":sContext, "input":sInput, "format":format } );
+ }
+ };
+
+ return {
+ setDateFormat: function(fmt) {
+ if ( !fmt ) {
+ throw new IllegalArgumentException("DateValidationRule.setDateFormat requires a non-null DateFormat");
+ }
+ format = fmt;
+ },
+
+ setAllowNull: _super.setAllowNull,
+
+ isAllowNull: _super.isAllowNull,
+
+ getTypeName: _super.getTypeName,
+
+ setTypeName: _super.setTypeName,
+
+ setEncoder: _super.setEncoder,
+
+ getEncoder: _super.getEncoder,
+
+ assertValid: _super.assertValid,
+
+ getValid: _super.getValid,
+
+ getValidInput: function( sContext, sInput ) {
+ return safelyParse(sContext,sInput);
+ },
+
+ getSafe: _super.getSafe,
+
+ sanitize: function( sContext, sInput ) {
+ var date = new Date(0);
+ try {
+ date = safelyParse(sContext,sInput);
+ } catch (e) { }
+ return date;
+ },
+
+ isValid: _super.isValid,
+
+ whitelist: _super.whitelist
+ };
+};
+
+
+$namespace('org.owasp.esapi.reference.validation');
+
+org.owasp.esapi.reference.validation.DefaultValidator = function( oEncoder, oLocale ) {
+ var rules = Array();
+ var encoder = oEncoder?oEncoder:$ESAPI.encoder();
+ var locale = oLocale?oLocale:org.owasp.esapi.i18n.Locale.getDefault();
+
+ var p = org.owasp.esapi.reference.validation;
+
+ return {
+ addRule: function( oValidationRule ) {
+ rules[oValidationRule.getName()] = oValidationRule;
+ },
+
+ getRule: function( sName ) {
+ return rules[sName];
+ },
+
+ isValidInput: function( sContext, sInput, sType, nMaxLength, bAllowNull ) {
+ try {
+ this.getValidInput( sContext, sInput, sType, nMaxLength, bAllowNull );
+ return true;
+ } catch (e) {
+ return false;
+ }
+ },
+
+ getValidInput: function( sContext, sInput, sType, nMaxLength, bAllowNull, oValidationErrorList ) {
+ var rvr = new org.owasp.esapi.reference.validation.StringValidationRule( sType, encoder, locale );
+ var p = new RegExp($ESAPI.properties.validation[sType]);
+ if ( p && p instanceof RegExp ) {
+ rvr.addWhitelistPattern( p );
+ } else {
+ throw new IllegalArgumentException("Invalid Type: " + sType + " not found.");
+ }
+ rvr.setMaxLength( nMaxLength );
+ rvr.setAllowNull( bAllowNull );
+
+ try {
+ return rvr.getValid(sContext,sInput);
+ } catch (e) {
+ if ( e instanceof p.ValidationErrorList && oValidationErrorList ) {
+ oValidationErrorList.addError( sContext, e );
+ }
+ throw e;
+ }
+ },
+
+ isValidDate: function( sContext, sInput, oDateFormat, bAllowNull ) {
+ try {
+ this.getValidDate( sContext, sInput, oDateFormat, bAllowNull );
+ return true;
+ } catch (e) {
+ return false;
+ }
+ },
+
+ getValidDate: function( sContext, sInput, oDateFormat, bAllowNull, oValidationErrorList ) {
+ var dvr = new p.DateValidationRule( sContext, encoder, locale );
+ dvr.setAllowNull( bAllowNull );
+ dvr.setDateFormat(oDateFormat);
+ try {
+ return dvr.getValid( sContext, sInput );
+ } catch (e) {
+ if ( e instanceof p.ValidationErrorList && oValidationErrorList ) {
+ oValidationErrorList.addError( sContext, e );
+ }
+ throw e;
+ }
+ },
+
+ getValidCreditCard: function( sContext, sInput, bAllowNull, oValidationErrorList ) {
+ var ccr = new p.CreditCardValidationRule( sContext, encoder, locale );
+ ccr.setAllowNull(bAllowNull);
+
+ try {
+ return ccr.getValid(sContext,sInput);
+ } catch (e) {
+ if ( e instanceof p.ValidationErrorList && oValidationErrorList ) {
+ oValidationErrorList.addError( sContext, e );
+ }
+ throw e;
+ }
+ },
+
+ isValidCreditCard: function( sContext, sInput, bAllowNull ) {
+ try {
+ this.getValidCreditCard( sContext,sInput,bAllowNull );
+ return true;
+ } catch (e) {
+ return false;
+ }
+ },
+
+ getValidNumber: function( sContext, sInput, bAllowNull, nMinValue, nMaxValue, oValidationErrorList ) {
+ var nvr = new p.NumberValidationRule( sContext, encoder, locale, nMinValue, nMaxValue );
+ nvr.setAllowNull(bAllowNull);
+
+ try {
+ return nvr.getValid(sContext, sInput);
+ } catch(e) {
+ if ( e instanceof p.ValidationErrorList && oValidationErrorList ) {
+ oValidationErrorList.addError( sContext, e );
+ }
+ throw e;
+ }
+ },
+
+ isValidNumber: function( sContext, sInput, bAllowNull, nMinValue, nMaxValue ) {
+ try {
+ this.getValidNumber(sContext,sInput,bAllowNull,nMinValue,nMaxValue);
+ return true;
+ } catch (e) {
+ return false;
+ }
+ },
+
+ getValidInteger: function( sContext, sInput, bAllowNull, nMinValue, nMaxValue, oValidationErrorList ) {
+ var nvr = new p.IntegerValidationRule( sContext, encoder, locale, nMinValue, nMaxValue );
+ nvr.setAllowNull(bAllowNull);
+
+ try {
+ return nvr.getValid(sContext, sInput);
+ } catch(e) {
+ if ( e instanceof p.ValidationErrorList && oValidationErrorList ) {
+ oValidationErrorList.addError( sContext, e );
+ }
+ throw e;
+ }
+ },
+
+ isValidInteger: function( sContext, sInput, bAllowNull, nMinValue, nMaxValue ) {
+ try {
+ this.getValidInteger(sContext,sInput,bAllowNull,nMinValue,nMaxValue);
+ return true;
+ } catch (e) {
+ return false;
+ }
+ }
+ };
+};
+
+
+$namespace('org.owasp.esapi.reference.validation');
+
+org.owasp.esapi.reference.validation.IntegerValidationRule = function( sTypeName, oEncoder, oLocale, nMinValue, nMaxValue ) {
+ var _super = new org.owasp.esapi.reference.validation.BaseValidationRule( sTypeName, oEncoder, oLocale );
+ var _validationTarget = "Integer";
+
+ var minValue = nMinValue?nMinValue:Number.MIN_VALUE;
+ var maxValue = nMaxValue?nMaxValue:Number.MAX_VALUE;
+
+ if ( minValue >= maxValue ) {
+ throw new IllegalArgumentException( "minValue must be less than maxValue" );
+ }
+
+ var safelyParse = function(sContext,sInput) {
+ if ( !sInput || sInput.trim() == '' ) {
+ if ( _super.allowNull() ) {
+ return null;
+ }
+ _super.validationException( sContext, _validationTarget, "Required", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } );
+ }
+
+ var canonical = _super.getEncoder().cananicalize(sInput);
+
+ var n = parseInt(canonical);
+ if ( n == 'NaN' ) {
+ _super.validationException( sContext, _validationTarget, "NaN", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } );
+ }
+ if ( n < minValue ) {
+ _super.validationException( sContext, _validationTarget, "MinValue", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } );
+ }
+ if ( n > maxValue ) {
+ _super.validationException( sContext, _validationTarget, "MaxValue", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } );
+ }
+ return n;
+ };
+
+ return {
+ setMinValue: function(n) { minValue = n; },
+
+ getMinValue: function() { return minValue; },
+
+ setMaxValue: function(n) { maxValue = n; },
+
+ getMaxValue: function() { return maxValue; },
+
+ setAllowNull: _super.setAllowNull,
+
+ isAllowNull: _super.isAllowNull,
+
+ getTypeName: _super.getTypeName,
+
+ setTypeName: _super.setTypeName,
+
+ setEncoder: _super.setEncoder,
+
+ getEncoder: _super.getEncoder,
+
+ assertValid: _super.assertValid,
+
+ getValid: _super.getValid,
+
+ getValidInput: function( sContext, sInput ) {
+ return safelyParse(sContext,sInput);
+ },
+
+ getSafe: _super.getSafe,
+
+ sanitize: function( sContext, sInput ) {
+ var n = 0;
+ try {
+ n = safelyParse(sContext,sInput);
+ } catch (e) { }
+ return n;
+ },
+
+ isValid: _super.isValid,
+
+ whitelist: _super.whitelist
+ };
+};
+
+
+$namespace('org.owasp.esapi.reference.validation');
+
+org.owasp.esapi.reference.validation.NumberValidationRule = function( sTypeName, oEncoder, oLocale, fMinValue, fMaxValue ) {
+ var _super = new org.owasp.esapi.reference.validation.BaseValidationRule( sTypeName, oEncoder, oLocale );
+ var _validationTarget = 'Number';
+
+ var minValue = fMinValue?fMinValue:Number.MIN_VALUE;
+ var maxValue = fMaxValue?fMaxValue:Number.MAX_VALUE;
+
+ if ( minValue >= maxValue ) throw new IllegalArgumentException("MinValue must be less that MaxValue");
+
+ var safelyParse = function( sContext, sInput ) {
+ if ( !sInput || sInput.trim() == '' ) {
+ if ( _super.isAllowNull() ) {
+ return null;
+ }
+ _super.validationException( sContext, _validationTarget, "Required", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } );
+ }
+
+ var canonical = _super.getEncoder().cananicalize( sInput );
+
+ var f = 0.0;
+ try {
+ f = parseFloat( canonical );
+ } catch (e) {
+ _super.validationException( sContext, _validationTarget, "Invalid", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } );
+ }
+
+ if ( f == 'NaN' ) {
+ _super.validationException( sContext, _validationTarget, "NaN", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } );
+ }
+ if ( f < minValue ) {
+ _super.validationException( sContext, _validationTarget, "MinValue", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } );
+ }
+ if ( f > maxValue ) {
+ _super.validationException( sContext, _validationTarget, "MaxValue", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } );
+ }
+ return f;
+ };
+
+ return {
+ setMinValue: function(n) { minValue = n; },
+
+ getMinValue: function() { return minValue; },
+
+ setMaxValue: function(n) { maxValue = n; },
+
+ getMaxValue: function() { return maxValue; },
+
+ setAllowNull: _super.setAllowNull,
+
+ isAllowNull: _super.isAllowNull,
+
+ getTypeName: _super.getTypeName,
+
+ setTypeName: _super.setTypeName,
+
+ setEncoder: _super.setEncoder,
+
+ getEncoder: _super.getEncoder,
+
+ assertValid: _super.assertValid,
+
+ getValid: _super.getValid,
+
+ getValidInput: function( sContext, sInput ) {
+ return safelyParse(sContext,sInput);
+ },
+
+ getSafe: _super.getSafe,
+
+ sanitize: function( sContext, sInput ) {
+ var n = 0;
+ try {
+ n = safelyParse(sContext,sInput);
+ } catch (e) { }
+ return n;
+ },
+
+ isValid: _super.isValid,
+
+ whitelist: _super.whitelist
+ };
+};
+
+
+$namespace('org.owasp.esapi.reference.validation');
+
+org.owasp.esapi.reference.validation.StringValidationRule = function( sTypeName, oEncoder, oLocale, sWhiteListPattern ) {
+ var _super = new org.owasp.esapi.reference.validation.BaseValidationRule( sTypeName, oEncoder, oLocale );
+ var _validationTarget = 'String';
+
+ var whitelistPatterns = Array();
+ var blacklistPatterns = Array();
+ var minLength = 0;
+ var maxLength = Number.MAX_VALUE;
+ var validateInputAndCanonical = true;
+
+ if ( sWhiteListPattern ) {
+ if ( sWhiteListPattern instanceof String ) {
+ whitelistPatterns.push( new RegExp(sWhiteListPattern) );
+ } else if ( sWhiteListPattern instanceof RegExp ) {
+ whitelistPatterns.push( sWhiteListPattern );
+ } else {
+ throw new IllegalArgumentException("sWhiteListPattern must be a string containing RegExp or a RegExp Object");
+ }
+ }
+
+ var checkWhitelist = function( sContext, sInput, sOrig ) {
+ whitelistPatterns.each(function(p){
+ if ( sInput.match(p) ) {
+ _super.validationException( sContext, _validationTarget, "Whitelist", { "context":sContext, "input":sInput, "orig":sOrig, "pattern":p.toString(), "minLength":minLength, "maxLength":maxLength, "validateInputAndCanonical":validateInputAndCanonical } );
+ }
+ });
+ };
+
+ var checkBlacklist = function( sContext, sInput, sOrig ) {
+ blacklistPatterns.each(function(p){
+ if ( sInput.match(p) ) {
+ _super.validationException( sContext, _validationTarget, "Blacklist", { "context":sContext, "input":sInput, "orig":sOrig, "pattern":p.toString(), "minLength":minLength, "maxLength":maxLength, "validateInputAndCanonical":validateInputAndCanonical } );
+ }
+ });
+ };
+
+ var checkLength = function( sContext, sInput, sOrig ) {
+ if ( sInput.length < minLength ) {
+ _super.validationException( sContext, _validationTarget, "MinLength", { "context":sContext, "input":sInput, "orig":sOrig, "minLength":minLength, "maxLength":maxLength, "validateInputAndCanonical":validateInputAndCanonical } );
+ }
+ if ( sInput.length > maxLength ) {
+ _super.validationException( sContext, _validationTarget, "MaxLength", { "context":sContext, "input":sInput, "orig":sOrig, "minLength":minLength, "maxLength":maxLength, "validateInputAndCanonical":validateInputAndCanonical } );
+ }
+ return sInput;
+ };
+
+ var checkEmpty = function( sContext, sInput, sOrig ) {
+ if ( !sInput || sInput.trim() == '' ) {
+ if ( _super.isAllowNull() ) {
+ return null;
+ }
+ _super.validationException( sContext, _validationTarget, "Required", { "context":sContext, "input":sInput, "orig":sOrig, "minLength":minLength, "maxLength":maxLength, "validateInputAndCanonical":validateInputAndCanonical } );
+ }
+ };
+
+ return {
+ addWhitelistPattern: function(p) {
+ if ( p instanceof String ) {
+ whitelistPatterns.push( new RegExp(p) );
+ } else if ( p instanceof RegExp ) {
+ whitelistPatterns.push(p);
+ } else {
+ throw new IllegalArgumentException("p must be a string containing RegExp or a RegExp Object");
+ }
+ },
+
+ addBlacklistPattern: function(p) {
+ if ( p instanceof String ) {
+ blacklistPatterns.push( new RegExp(p) );
+ } else if ( p instanceof RegExp ) {
+ blacklistPatterns.push(p);
+ } else {
+ throw new IllegalArgumentException("p must be a string containing RegExp or a RegExp Object");
+ }
+ },
+
+ setMinLength: function(n) { minLength = n; },
+
+ getMinLength: function() { return minLength; },
+
+ setMaxLength: function(n) { maxLength = n; },
+
+ getMaxLength: function() { return maxLength; },
+
+ setValidateInputAndCanonical: function(b) { validateInputAndCanonical = b; },
+
+ isValidateInputAndCanonical: function() { return validateInputAndCanonical; },
+
+ setAllowNull: _super.setAllowNull,
+
+ isAllowNull: _super.isAllowNull,
+
+ getTypeName: _super.getTypeName,
+
+ setTypeName: _super.setTypeName,
+
+ setEncoder: _super.setEncoder,
+
+ getEncoder: _super.getEncoder,
+
+ assertValid: _super.assertValid,
+
+ getValid: _super.getValid,
+
+ getValidInput: function( sContext, sInput ) {
+ var canonical = null;
+
+ if ( checkEmpty( sContext, sInput ) == null ) {
+ return null;
+ }
+
+ if ( validateInputAndCanonical ) {
+ checkLength(sContext, sInput);
+ checkWhitelist(sContext,sInput);
+ checkBlacklist(sContext,sInput);
+ }
+
+ canonical = this.getEncoder().cananicalize(sInput);
+
+ if ( checkEmpty( sContext, canonical, sInput ) == null ) {
+ return null;
+ }
+
+ checkLength( sContext, canonical, sInput );
+ checkWhitelist( sContext, canonical, sInput );
+ checkBlacklist( sContext, canonical, sInput );
+
+ return canonical;
+ },
+
+ getSafe: _super.getSafe,
+
+ sanitize: function( sContext, sInput ) {
+ return this.whitelist( sInput, org.owasp.esapi.EncoderConstants.CHAR_ALNUM );
+ },
+
+ isValid: _super.isValid,
+
+ whitelist: _super.whitelist
+ };
+};
+
+
+$namespace('org.owasp.esapi.reference.validation');
+
+org.owasp.esapi.reference.validation.ValidationException = function( sUserMessage, sLogMessage ) {
+ var oException, sContext;
+ if ( arguments[2] && arguments[2] instanceof Exception ) {
+ oException = arguments[2];
+ if ( arguments[3] && arguments[3] instanceof String ) {
+ sContext = arguments[3];
+ }
+ } else if ( arguments[2] && arguments[2] instanceof String ) {
+ sContext = arguments[2];
+ }
+
+ var _super = new org.owasp.esapi.EnterpriseSecurityException( sUserMessage, sLogMessage, oException );
+
+ return {
+ setContext: function(s) { sContext = s; },
+ getContext: function() { return sContext; },
+ getMessage: _super.getMessage,
+ getUserMessage: _super.getMessage,
+ getLogMessage: _super.getLogMessage,
+ getStackTrace: _super.getStackTrace,
+ printStackTrace: _super.printStackTrace
+ };
+};
-var _GET = parseGet();\r
-var _openedWindows = {};\r
-\r
-function getWmode() {\r
- if (_GET['wmode'] != undefined) {\r
- return _GET['wmode'];\r
- }\r
-\r
- var ua = navigator.userAgent;\r
- if (ua.search(/mac/i) > -1 && ua.search(/opera/i) > -1) {\r
- return 'normal';\r
- } else {\r
- return 'direct';\r
- }\r
-}\r
-\r
-function getLocation() {\r
- return window.location.toString();\r
-}\r
-\r
-function getPath() {\r
- var l = window.location;\r
-\r
- var res = l.toString();\r
- var origin = l.protocol + '//' + l.host\r
- return res.replace(origin, '');\r
-}\r
-\r
-function getFlashvars(junk, fv) {\r
- var res = {};\r
- if (fv != undefined) {\r
- res = fv;\r
- }\r
-\r
- res = parseGet(res);\r
-\r
- res['junk'] = junk;\r
- return res;\r
-}\r
-\r
-function parseGet(res) {\r
- if (res == undefined) {\r
- res = {};\r
- }\r
- var couples = window.location.search.substr(1).split('&');\r
- var couple = new Array();\r
- for (var i = 0; i < couples.length; i++) {\r
- couple = couples[i].split('=');\r
- res[couple[0]] = couple[1];\r
- }\r
- return res;\r
-}\r
-\r
-function getLang() {\r
- if (_GET.lang == undefined || _GET.lang == null || _GET.lang == '') {\r
- return FB_DEFAULT_LANG;\r
- }\r
- return _GET.lang;\r
-}\r
-\r
-function mailto(adresse) {\r
- window.location = 'mailto:' + adresse;\r
-}\r
-function getBookmarks(id) {\r
- return getCookie('fb_bookmarks_' + id);\r
-}\r
-function setBookmarks(data, id) {\r
- date = new Date;\r
- date.setFullYear(date.getFullYear() + 10);\r
- setCookie('fb_bookmarks_' + id, data, date, '/');\r
-}\r
-\r
-function popupFS(page) {\r
- if (page == undefined) {\r
- page = 0;\r
- }\r
- var date = new Date().getTime();\r
- window.open('index.html#/' + page, 'fbpopupfs_' + date, 'width=' + screen.width + ',height=' + screen.height + ',resizable=yes');\r
-}\r
-\r
-function popupFocus(url, target) {\r
- var openedw;\r
- if (target.substr(0, 1) == '_') {\r
- openedw = window.open(url, target, 'width=' + screen.width + ',height=' + screen.height + ',resizable=yes');\r
- } else {\r
- if (_openedWindows[target] != undefined && _openedWindows[target] != null) {\r
- openedw = _openedWindows[target];\r
- openedw.location = url;\r
- } else {\r
- openedw = window.open(url, target, 'width=' + screen.width + ',height=' + screen.height + ',resizable=yes');\r
- _openedWindows[target] = openedw;\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- openedw.focus();\r
-}\r
-\r
-function getCookieVal(offset)\r
-{\r
- var endstr = document.cookie.indexOf(";", offset);\r
- if (endstr == -1) {\r
- endstr = document.cookie.length;\r
- }\r
- return unescape(document.cookie.substring(offset, endstr));\r
-}\r
-function getCookie(nom)\r
-{\r
- var arg = nom + "=";\r
- var alen = arg.length;\r
- var clen = document.cookie.length;\r
- var i = 0;\r
- while (i < clen) {\r
- var j = i + alen;\r
- if (document.cookie.substring(i, j) == arg) {\r
- return getCookieVal(j);\r
- }\r
- i = document.cookie.indexOf(" ", i) + 1;\r
- if (i == 0) {\r
- break;\r
- }\r
- }\r
- return null;\r
-}\r
-function setCookie(nom, valeur)\r
-{\r
- date = new Date;\r
- date.setFullYear(date.getFullYear() + 10);\r
-\r
- var argv = setCookie.arguments;\r
- var argc = setCookie.arguments.length;\r
- var expires = (argc > 2) ? argv[2] : date;\r
- var path = (argc > 3) ? argv[3] : '/';\r
- var domain = (argc > 4) ? argv[4] : null;\r
- var secure = (argc > 5) ? argv[5] : false;\r
- document.cookie = nom + "=" + escape(valeur) +\r
- ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +\r
- ((path == null) ? "" : ("; path=/")) +\r
- ((domain == null) ? "" : ("; domain=" + domain)) +\r
- ((secure == true) ? "; secure" : "");\r
-}\r
-function addThis(x) {\r
- addthis_offset_left = parseFloat(x);\r
- addthis_open(document.getElementById('addThisBt'), '', '[URL]', '[TITLE]');\r
-}\r
-function handleWheel(delta) {\r
- try {\r
- fb(delta);\r
- document.getElementById('fluidbook').mouseWheel(delta);\r
- } catch (e) {\r
-\r
- }\r
-}\r
-\r
-function isMobile() {\r
- var devices = ['iphone', 'ipad', 'ipod', 'droid', 'blackberry', 'mobile', 'htc', 'samsung', 'nokia', 'archos', 'galaxy', 'motorola', 'pad', 'slate', 'symbian', 'phone', 'nintendo', 'playstation', 'touch', 'webos', 'ericsson', 'metro'];\r
- return _isMobile(devices);\r
-}\r
-\r
-function isBadMobile() {\r
- var devices = ['kindle'];\r
- return _isMobile(devices);\r
-}\r
-\r
-function _isMobile(devices) {\r
- var ua = navigator.userAgent;\r
- var pattern;\r
-\r
- for (i = 0; i < devices.length; i++) {\r
- pattern = new RegExp(devices[i], 'i');\r
- if (ua.search(pattern) > -1) {\r
- return true;\r
- }\r
- }\r
- return false;\r
-}\r
-\r
-function redirectPDF() {\r
- window.location = 'data/document.pdf';\r
-}\r
-\r
-function redirectMobile() {\r
- var page = '';\r
- var get = parseGet();\r
- console.log(get);\r
- var html = 'index.html';\r
- if (get['widget'] != undefined && get['widget'] == '1') {\r
- html = 'widget.html';\r
- page = '?widget=1&';\r
- if (get['background'] != undefined) {\r
- page += "background=" + get['background'];\r
- }\r
- }\r
- var pageNr = 0;\r
- if (get.page != undefined) {\r
- pageNr = parseInt(get.page);\r
- }\r
- if (window.location.hash != '') {\r
- var e = window.location.hash.split('/');\r
- var pnr = parseInt(e[1]);\r
- if (!isNaN(pnr)) {\r
- pageNr = pnr;\r
- }\r
- }\r
-\r
-\r
- if (page == '' && pageNr > 0) {\r
- page = '#/page/' + pageNr;\r
- }\r
-\r
- window.location = 'm/' + html + page;\r
-}\r
-\r
-function fb(e) {\r
- try {\r
- console.log(e);\r
- } catch (err) {\r
-\r
- }\r
-}\r
-\r
-\r
-function wheel(event) {\r
- var delta = 0;\r
- if (!event) /* For IE. */\r
- event = window.event;\r
- if (event.wheelDelta) { /* IE/Opera. */\r
- delta = event.wheelDelta / 120;\r
- /** In Opera 9, delta differs in sign as compared to IE.\r
- */\r
- if (window.opera)\r
- delta = -delta;\r
- } else if (event.detail) { /** Mozilla case. */\r
- /** In Mozilla, sign of delta is different than in IE.\r
- * Also, delta is multiple of 3.\r
- */\r
- delta = -event.detail / 3;\r
- }\r
- /** If delta is nonzero, handle it.\r
- * Basically, delta is now positive if wheel was scrolled up,\r
- * and negative, if wheel was scrolled down.\r
- */\r
- if (delta) {\r
- handleWheel(delta);\r
- }\r
- /** Prevent default actions caused by mouse wheel.\r
- * That might be ugly, but we handle scrolls somehow\r
- * anyway, so don't bother here..\r
- */\r
- if (event.preventDefault) {\r
- event.preventDefault();\r
- }\r
- event.returnValue = false;\r
-}\r
-\r
-function ready() {\r
- document.body.style.backgroundColor = '#' + getBackgroundColor();\r
-}\r
-\r
-function getBackgroundColor() {\r
- if (_GET['background'] != undefined) {\r
- return _GET['background'];\r
- } else {\r
- return backgroundColor;\r
- }\r
-}\r
-\r
-/** Initialization code.\r
- * If you use your own event management code, change it as required.\r
- */\r
-if (window.addEventListener) {\r
- /** DOMMouseScroll is for mozilla. */\r
- window.addEventListener('DOMMouseScroll', wheel, false);\r
-}\r
-/** IE/Opera. */\r
-window.onmousewheel = document.onmousewheel = wheel;\r
-\r
-window.onkeydown = key;\r
-window.onkeypress = key;\r
-window.onkeydown = key;\r
-\r
-function key(e) {\r
- if (e.ctrlKey && (e.keyCode == 80 || e.keyCode == 112)) {\r
- return false;\r
- }\r
-\r
- return true;\r
+// Initialize the api
+org.owasp.esapi.ESAPI.initialize();
+
+var _GET = parseGet();
+var _openedWindows = {};
+
+function getWmode() {
+ if (_GET['wmode'] != undefined) {
+ return _GET['wmode'];
+ }
+
+ var ua = navigator.userAgent;
+ if (ua.search(/mac/i) > -1 && ua.search(/opera/i) > -1) {
+ return 'normal';
+ } else {
+ return 'direct';
+ }
+}
+
+function getLocation() {
+ return window.location.toString();
+}
+
+function getPath() {
+ var l = window.location;
+
+ var res = l.toString();
+ var origin = l.protocol + '//' + l.host
+ return res.replace(origin, '');
+}
+
+function getFlashvars(junk, fv) {
+ var res = {};
+ if (fv != undefined) {
+ res = fv;
+ }
+
+ res = parseGet(res);
+ res['junk'] = $ESAPI.encoder().encodeForJavaScript(junk);
+ return res;
+}
+
+function parseGet(res) {
+ if (res == undefined) {
+ res = {};
+ }
+ var couples = window.location.search.substr(1).split('&');
+ var couple = new Array();
+ for (var i = 0; i < couples.length; i++) {
+ couple = couples[i].split('=');
+ res[couple[0]] = $ESAPI.httpUtilities().getRequestParameter(couple[0]);
+ }
+ return res;
+}
+
+function getLang() {
+ if (_GET.lang == undefined || _GET.lang == null || _GET.lang == '') {
+ return FB_DEFAULT_LANG;
+ }
+ return _GET.lang;
+}
+
+function mailto(adresse) {
+ window.location = 'mailto:' + adresse;
+}
+function getBookmarks(id) {
+ return getCookie('fb_bookmarks_' + id);
+}
+function setBookmarks(data, id) {
+ date = new Date;
+ date.setFullYear(date.getFullYear() + 10);
+ setCookie('fb_bookmarks_' + id, data, date, '/');
+}
+
+function popupFS(page) {
+ if (page == undefined) {
+ page = 0;
+ }
+ var date = new Date().getTime();
+ window.open('index.html#/' + page, 'fbpopupfs_' + date, 'width=' + screen.width + ',height=' + screen.height + ',resizable=yes');
+}
+
+function popupFocus(url, target) {
+ var openedw;
+ if (target.substr(0, 1) == '_') {
+ openedw = window.open(url, target, 'width=' + screen.width + ',height=' + screen.height + ',resizable=yes');
+ } else {
+ if (_openedWindows[target] != undefined && _openedWindows[target] != null) {
+ openedw = _openedWindows[target];
+ openedw.location = url;
+ } else {
+ openedw = window.open(url, target, 'width=' + screen.width + ',height=' + screen.height + ',resizable=yes');
+ _openedWindows[target] = openedw;
+ }
+ }
+
+
+
+
+ openedw.focus();
+}
+
+function getCookieVal(offset)
+{
+ var endstr = document.cookie.indexOf(";", offset);
+ if (endstr == -1) {
+ endstr = document.cookie.length;
+ }
+ return unescape(document.cookie.substring(offset, endstr));
+}
+function getCookie(nom)
+{
+ return $ESAPI.httpUtilities().getCookie(nom);
+
+ /*var arg = nom + "=";
+ var alen = arg.length;
+ var clen = document.cookie.length;
+ var i = 0;
+ while (i < clen) {
+ var j = i + alen;
+ if (document.cookie.substring(i, j) == arg) {
+ return getCookieVal(j);
+ }
+ i = document.cookie.indexOf(" ", i) + 1;
+ if (i == 0) {
+ break;
+ }
+ }
+ return null;*/
+}
+function setCookie(nom, valeur)
+{
+ var cookie = new org.owasp.esapi.net.Cookie(nom, valeur);
+ cookie.setMaxAge(10 * 365 * 24 * 3600);
+ return $ESAPI.httpUtilities().addCookie(cookie);
+
+
+ /*date = new Date;
+ date.setFullYear(date.getFullYear() + 10);
+
+ var argv = setCookie.arguments;
+ var argc = setCookie.arguments.length;
+ var expires = (argc > 2) ? argv[2] : date;
+ var path = (argc > 3) ? argv[3] : '/';
+ var domain = (argc > 4) ? argv[4] : null;
+ var secure = (argc > 5) ? argv[5] : false;
+ document.cookie = nom + "=" + escape(valeur) +
+ ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
+ ((path == null) ? "" : ("; path=/")) +
+ ((domain == null) ? "" : ("; domain=" + domain)) +
+ ((secure == true) ? "; secure" : "");*/
+}
+function addThis(x) {
+ addthis_offset_left = parseFloat(x);
+ addthis_open(document.getElementById('addThisBt'), '', '[URL]', '[TITLE]');
+}
+function handleWheel(delta) {
+ try {
+ fb(delta);
+ document.getElementById('fluidbook').mouseWheel(delta);
+ } catch (e) {
+
+ }
+}
+
+function isMobile() {
+ var devices = ['iphone', 'ipad', 'ipod', 'droid', 'blackberry', 'mobile', 'htc', 'samsung', 'nokia', 'archos', 'galaxy', 'motorola', 'pad', 'slate', 'symbian', 'phone', 'nintendo', 'playstation', 'touch', 'webos', 'ericsson', 'metro'];
+ return _isMobile(devices);
+}
+
+function isBadMobile() {
+ var devices = ['kindle'];
+ return _isMobile(devices);
+}
+
+function _isMobile(devices) {
+ var ua = navigator.userAgent;
+ var pattern;
+
+ for (i = 0; i < devices.length; i++) {
+ pattern = new RegExp(devices[i], 'i');
+ if (ua.search(pattern) > -1) {
+ return true;
+ }
+ }
+ return false;
+}
+
+function redirectPDF() {
+ window.location = 'data/document.pdf';
+}
+
+function redirectMobile() {
+ var page = '';
+ var get = parseGet();
+ console.log(get);
+ var html = 'index.html';
+ if (get['widget'] != undefined && get['widget'] == '1') {
+ html = 'widget.html';
+ page = '?widget=1&';
+ if (get['background'] != undefined) {
+ page += "background=" + get['background'];
+ }
+ }
+ var pageNr = 0;
+ if (get.page != undefined) {
+ pageNr = parseInt(get.page);
+ }
+ if (window.location.hash != '') {
+ var e = window.location.hash.split('/');
+ var pnr = parseInt(e[1]);
+ if (!isNaN(pnr)) {
+ pageNr = pnr;
+ }
+ }
+
+
+ if (page == '' && pageNr > 0) {
+ page = '#/page/' + pageNr;
+ }
+
+ window.location = 'm/' + html + page;
+}
+
+function fb(e) {
+ try {
+ console.log(e);
+ } catch (err) {
+
+ }
+}
+
+
+function wheel(event) {
+ var delta = 0;
+ if (!event) /* For IE. */
+ event = window.event;
+ if (event.wheelDelta) { /* IE/Opera. */
+ delta = event.wheelDelta / 120;
+ /** In Opera 9, delta differs in sign as compared to IE.
+ */
+ if (window.opera)
+ delta = -delta;
+ } else if (event.detail) { /** Mozilla case. */
+ /** In Mozilla, sign of delta is different than in IE.
+ * Also, delta is multiple of 3.
+ */
+ delta = -event.detail / 3;
+ }
+ /** If delta is nonzero, handle it.
+ * Basically, delta is now positive if wheel was scrolled up,
+ * and negative, if wheel was scrolled down.
+ */
+ if (delta) {
+ handleWheel(delta);
+ }
+ /** Prevent default actions caused by mouse wheel.
+ * That might be ugly, but we handle scrolls somehow
+ * anyway, so don't bother here..
+ */
+ if (event.preventDefault) {
+ event.preventDefault();
+ }
+ event.returnValue = false;
+}
+
+function ready() {
+ document.body.style.backgroundColor = '#' + getBackgroundColor();
+}
+
+function getBackgroundColor() {
+ if (_GET['background'] != undefined) {
+ return _GET['background'];
+ } else {
+ return backgroundColor;
+ }
+}
+
+/** Initialization code.
+ * If you use your own event management code, change it as required.
+ */
+if (window.addEventListener) {
+ /** DOMMouseScroll is for mozilla. */
+ window.addEventListener('DOMMouseScroll', wheel, false);
+}
+/** IE/Opera. */
+window.onmousewheel = document.onmousewheel = wheel;
+
+window.onkeydown = key;
+window.onkeypress = key;
+window.onkeydown = key;
+
+function key(e) {
+ if (e.ctrlKey && (e.keyCode == 80 || e.keyCode == 112)) {
+ return false;
+ }
+
+ return true;
}
\ No newline at end of file
--- /dev/null
+var Log4js={version:"1.0",applicationStartDate:new Date(),loggers:{},getLogger:function(categoryName){if(!(typeof categoryName=="string")){categoryName="[default]";}if(!Log4js.loggers[categoryName]){Log4js.loggers[categoryName]=new Log4js.Logger(categoryName);}return Log4js.loggers[categoryName];},getDefaultLogger:function(){return Log4js.getLogger("[default]");},attachEvent:function(element,name,observer){if(element.addEventListener){element.addEventListener(name,observer,false);}else if(element.attachEvent){element.attachEvent('on'+name,observer);}}};Log4js.extend=function(destination,source){for(property in source){destination[property]=source[property];}return destination;}Log4js.bind=function(fn,object){return function(){return fn.apply(object,arguments);};};Log4js.Level=function(level,levelStr){this.level=level;this.levelStr=levelStr;};Log4js.Level.prototype={toLevel:function(sArg,defaultLevel){if(sArg===null){return defaultLevel;}if(typeof sArg=="string"){var s=sArg.toUpperCase();if(s=="ALL"){return Log4js.Level.ALL;}if(s=="DEBUG"){return Log4js.Level.DEBUG;}if(s=="INFO"){return Log4js.Level.INFO;}if(s=="WARN"){return Log4js.Level.WARN;}if(s=="ERROR"){return Log4js.Level.ERROR;}if(s=="FATAL"){return Log4js.Level.FATAL;}if(s=="OFF"){return Log4js.Level.OFF;}if(s=="TRACE"){return Log4js.Level.TRACE;}return defaultLevel;}else if(typeof sArg=="number"){switch(sArg){case ALL_INT:return Log4js.Level.ALL;case DEBUG_INT:return Log4js.Level.DEBUG;case INFO_INT:return Log4js.Level.INFO;case WARN_INT:return Log4js.Level.WARN;case ERROR_INT:return Log4js.Level.ERROR;case FATAL_INT:return Log4js.Level.FATAL;case OFF_INT:return Log4js.Level.OFF;case TRACE_INT:return Log4js.Level.TRACE;default:return defaultLevel;}}else{return defaultLevel;}},toString:function(){return this.levelStr;},valueOf:function(){return this.level;}};Log4js.Level.OFF_INT=Number.MAX_VALUE;Log4js.Level.FATAL_INT=50000;Log4js.Level.ERROR_INT=40000;Log4js.Level.WARN_INT=30000;Log4js.Level.INFO_INT=20000;Log4js.Level.DEBUG_INT=10000;Log4js.Level.TRACE_INT=5000;Log4js.Level.ALL_INT=Number.MIN_VALUE;Log4js.Level.OFF=new Log4js.Level(Log4js.Level.OFF_INT,"OFF");Log4js.Level.FATAL=new Log4js.Level(Log4js.Level.FATAL_INT,"FATAL");Log4js.Level.ERROR=new Log4js.Level(Log4js.Level.ERROR_INT,"ERROR");Log4js.Level.WARN=new Log4js.Level(Log4js.Level.WARN_INT,"WARN");Log4js.Level.INFO=new Log4js.Level(Log4js.Level.INFO_INT,"INFO");Log4js.Level.DEBUG=new Log4js.Level(Log4js.Level.DEBUG_INT,"DEBUG");Log4js.Level.TRACE=new Log4js.Level(Log4js.Level.TRACE_INT,"TRACE");Log4js.Level.ALL=new Log4js.Level(Log4js.Level.ALL_INT,"ALL");Log4js.CustomEvent=function(){this.listeners=[];};Log4js.CustomEvent.prototype={addListener:function(method){this.listeners.push(method);},removeListener:function(method){var foundIndexes=this.findListenerIndexes(method);for(var i=0;i<foundIndexes.length;i++){this.listeners.splice(foundIndexes[i],1);}},dispatch:function(handler){for(var i=0;i<this.listeners.length;i++){try{this.listeners[i](handler);}catch(e){log4jsLogger.warn("Could not run the listener "+this.listeners[i]+". \n"+e);}}},findListenerIndexes:function(method){var indexes=[];for(var i=0;i<this.listeners.length;i++){if(this.listeners[i]==method){indexes.push(i);}}return indexes;}};Log4js.LoggingEvent=function(categoryName,level,message,exception,logger){this.startTime=new Date();this.categoryName=categoryName;this.message=message;this.exception=exception;this.level=level;this.logger=logger;};Log4js.LoggingEvent.prototype={getFormattedTimestamp:function(){if(this.logger){return this.logger.getFormattedTimestamp(this.startTime);}else{return this.startTime.toGMTString();}}};Log4js.Logger=function(name){this.loggingEvents=[];this.appenders=[];this.category=name||"";this.level=Log4js.Level.FATAL;this.dateformat=Log4js.DateFormatter.DEFAULT_DATE_FORMAT;this.dateformatter=new Log4js.DateFormatter();this.onlog=new Log4js.CustomEvent();this.onclear=new Log4js.CustomEvent();this.appenders.push(new Log4js.Appender(this));try{window.onerror=this.windowError.bind(this);}catch(e){}};Log4js.Logger.prototype={addAppender:function(appender){if(appender instanceof Log4js.Appender){appender.setLogger(this);this.appenders.push(appender);}else{throw "Not instance of an Appender: "+appender;}},setAppenders:function(appenders){for(var i=0;i<this.appenders.length;i++){this.appenders[i].doClear();}this.appenders=appenders;for(var j=0;j<this.appenders.length;j++){this.appenders[j].setLogger(this);}},setLevel:function(level){this.level=level;},log:function(logLevel,message,exception){var loggingEvent=new Log4js.LoggingEvent(this.category,logLevel,message,exception,this);this.loggingEvents.push(loggingEvent);this.onlog.dispatch(loggingEvent);},clear:function(){try{this.loggingEvents=[];this.onclear.dispatch();}catch(e){}},isTraceEnabled:function(){if(this.level.valueOf()<=Log4js.Level.TRACE.valueOf()){return true;}return false;},trace:function(message){if(this.isTraceEnabled()){this.log(Log4js.Level.TRACE,message,null);}},isDebugEnabled:function(){if(this.level.valueOf()<=Log4js.Level.DEBUG.valueOf()){return true;}return false;},debug:function(message){if(this.isDebugEnabled()){this.log(Log4js.Level.DEBUG,message,null);}},debug:function(message,throwable){if(this.isDebugEnabled()){this.log(Log4js.Level.DEBUG,message,throwable);}},isInfoEnabled:function(){if(this.level.valueOf()<=Log4js.Level.INFO.valueOf()){return true;}return false;},info:function(message){if(this.isInfoEnabled()){this.log(Log4js.Level.INFO,message,null);}},info:function(message,throwable){if(this.isInfoEnabled()){this.log(Log4js.Level.INFO,message,throwable);}},isWarnEnabled:function(){if(this.level.valueOf()<=Log4js.Level.WARN.valueOf()){return true;}return false;},warn:function(message){if(this.isWarnEnabled()){this.log(Log4js.Level.WARN,message,null);}},warn:function(message,throwable){if(this.isWarnEnabled()){this.log(Log4js.Level.WARN,message,throwable);}},isErrorEnabled:function(){if(this.level.valueOf()<=Log4js.Level.ERROR.valueOf()){return true;}return false;},error:function(message){if(this.isErrorEnabled()){this.log(Log4js.Level.ERROR,message,null);}},error:function(message,throwable){if(this.isErrorEnabled()){this.log(Log4js.Level.ERROR,message,throwable);}},isFatalEnabled:function(){if(this.level.valueOf()<=Log4js.Level.FATAL.valueOf()){return true;}return false;},fatal:function(message){if(this.isFatalEnabled()){this.log(Log4js.Level.FATAL,message,null);}},fatal:function(message,throwable){if(this.isFatalEnabled()){this.log(Log4js.Level.FATAL,message,throwable);}},windowError:function(msg,url,line){var message="Error in ("+(url||window.location)+") on line "+line+" with message ("+msg+")";this.log(Log4js.Level.FATAL,message,null);},setDateFormat:function(format){this.dateformat=format;},getFormattedTimestamp:function(date){return this.dateformatter.formatDate(date,this.dateformat);}};Log4js.Appender=function(){this.logger=null;};Log4js.Appender.prototype={doAppend:function(loggingEvent){return;},doClear:function(){return;},setLayout:function(layout){this.layout=layout;},setLogger:function(logger){logger.onlog.addListener(Log4js.bind(this.doAppend,this));logger.onclear.addListener(Log4js.bind(this.doClear,this));this.logger=logger;}};Log4js.Layout=function(){return;};Log4js.Layout.prototype={format:function(loggingEvent){return "";},getContentType:function(){return "text/plain";},getHeader:function(){return null;},getFooter:function(){return null;},getSeparator:function(){return "";}};Log4js.ConsoleAppender=function(isInline){this.layout=new Log4js.PatternLayout(Log4js.PatternLayout.TTCC_CONVERSION_PATTERN);this.inline=isInline;this.accesskey="d";this.tagPattern=null;this.commandHistory=[];this.commandIndex=0;this.popupBlocker=false;this.outputElement=null;this.docReference=null;this.winReference=null;if(this.inline){Log4js.attachEvent(window,'load',Log4js.bind(this.initialize,this));}};Log4js.ConsoleAppender.prototype=Log4js.extend(new Log4js.Appender(),{setAccessKey:function(key){this.accesskey=key;},initialize:function(){if(!this.inline){var doc=null;var win=null;window.top.consoleWindow=window.open("",this.logger.category,"left=0,top=0,width=700,height=700,scrollbars=no,status=no,resizable=yes;toolbar=no");window.top.consoleWindow.opener=self;win=window.top.consoleWindow;if(!win){this.popupBlocker=true;alert("Popup window manager blocking the Log4js popup window to bedisplayed.\n\n"+"Please disabled this to properly see logged events.");}else{doc=win.document;doc.open();doc.write("<!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN ");doc.write(" http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd>\n\n");doc.write("<html><head><title>Log4js - "+this.logger.category+"</title>\n");doc.write("</head><body style=\"background-color:darkgray\"></body>\n");win.blur();win.focus();}this.docReference=doc;this.winReference=win;}else{this.docReference=document;this.winReference=window;}this.outputCount=0;this.tagPattern=".*";this.logElement=this.docReference.createElement('div');this.docReference.body.appendChild(this.logElement);this.logElement.style.display='none';this.logElement.style.position="absolute";this.logElement.style.left='0px';this.logElement.style.width='100%';this.logElement.style.textAlign="left";this.logElement.style.fontFamily="lucida console";this.logElement.style.fontSize="100%";this.logElement.style.backgroundColor='darkgray';this.logElement.style.opacity=0.9;this.logElement.style.zIndex=2000;this.toolbarElement=this.docReference.createElement('div');this.logElement.appendChild(this.toolbarElement);this.toolbarElement.style.padding="0 0 0 2px";this.buttonsContainerElement=this.docReference.createElement('span');this.toolbarElement.appendChild(this.buttonsContainerElement);if(this.inline){var closeButton=this.docReference.createElement('button');closeButton.style.cssFloat="right";closeButton.style.styleFloat="right";closeButton.style.color="black";closeButton.innerHTML="close";closeButton.onclick=Log4js.bind(this.toggle,this);this.buttonsContainerElement.appendChild(closeButton);}var clearButton=this.docReference.createElement('button');clearButton.style.cssFloat="right";clearButton.style.styleFloat="right";clearButton.style.color="black";clearButton.innerHTML="clear";clearButton.onclick=Log4js.bind(this.logger.clear,this.logger);this.buttonsContainerElement.appendChild(clearButton);this.tagFilterContainerElement=this.docReference.createElement('span');this.toolbarElement.appendChild(this.tagFilterContainerElement);this.tagFilterContainerElement.style.cssFloat='left';this.tagFilterContainerElement.appendChild(this.docReference.createTextNode("Log4js - "+this.logger.category));this.tagFilterContainerElement.appendChild(this.docReference.createTextNode(" | Level Filter: "));this.tagFilterElement=this.docReference.createElement('input');this.tagFilterContainerElement.appendChild(this.tagFilterElement);this.tagFilterElement.style.width='200px';this.tagFilterElement.value=this.tagPattern;this.tagFilterElement.setAttribute('autocomplete','off');Log4js.attachEvent(this.tagFilterElement,'keyup',Log4js.bind(this.updateTags,this));Log4js.attachEvent(this.tagFilterElement,'click',Log4js.bind(function(){this.tagFilterElement.select();},this));this.outputElement=this.docReference.createElement('div');this.logElement.appendChild(this.outputElement);this.outputElement.style.overflow="auto";this.outputElement.style.clear="both";this.outputElement.style.height=(this.inline)?("200px"):("650px");this.outputElement.style.width="100%";this.outputElement.style.backgroundColor='black';this.inputContainerElement=this.docReference.createElement('div');this.inputContainerElement.style.width="100%";this.logElement.appendChild(this.inputContainerElement);this.inputElement=this.docReference.createElement('input');this.inputContainerElement.appendChild(this.inputElement);this.inputElement.style.width='100%';this.inputElement.style.borderWidth='0px';this.inputElement.style.margin='0px';this.inputElement.style.padding='0px';this.inputElement.value='Type command here';this.inputElement.setAttribute('autocomplete','off');Log4js.attachEvent(this.inputElement,'keyup',Log4js.bind(this.handleInput,this));Log4js.attachEvent(this.inputElement,'click',Log4js.bind(function(){this.inputElement.select();},this));if(this.inline){window.setInterval(Log4js.bind(this.repositionWindow,this),500);this.repositionWindow();var accessElement=this.docReference.createElement('button');accessElement.style.position="absolute";accessElement.style.top="-100px";accessElement.accessKey=this.accesskey;accessElement.onclick=Log4js.bind(this.toggle,this);this.docReference.body.appendChild(accessElement);}else{this.show();}},toggle:function(){if(this.logElement.style.display=='none'){this.show();return true;}else{this.hide();return false;}},show:function(){this.logElement.style.display='';this.outputElement.scrollTop=this.outputElement.scrollHeight;this.inputElement.select();},hide:function(){this.logElement.style.display='none';},output:function(message,style){var shouldScroll=(this.outputElement.scrollTop+(2*this.outputElement.clientHeight))>=this.outputElement.scrollHeight;this.outputCount++;style=(style?style+=';':'');style+='padding:1px;margin:0 0 5px 0';if(this.outputCount%2===0){style+=";background-color:#101010";}message=message||"undefined";message=message.toString();this.outputElement.innerHTML+="<pre style='"+style+"'>"+message+"</pre>";if(shouldScroll){this.outputElement.scrollTop=this.outputElement.scrollHeight;}},updateTags:function(){var pattern=this.tagFilterElement.value;if(this.tagPattern==pattern){return;}try{new RegExp(pattern);}catch(e){return;}this.tagPattern=pattern;this.outputElement.innerHTML="";this.outputCount=0;for(var i=0;i<this.logger.loggingEvents.length;i++){this.doAppend(this.logger.loggingEvents[i]);}},repositionWindow:function(){var offset=window.pageYOffset||this.docReference.documentElement.scrollTop||this.docReference.body.scrollTop;var pageHeight=self.innerHeight||this.docReference.documentElement.clientHeight||this.docReference.body.clientHeight;this.logElement.style.top=(offset+pageHeight-this.logElement.offsetHeight)+"px";},doAppend:function(loggingEvent){if(this.popupBlocker){return;}if((!this.inline)&&(!this.winReference||this.winReference.closed)){this.initialize();}if(this.tagPattern!==null&&loggingEvent.level.toString().search(new RegExp(this.tagPattern,'igm'))==-1){return;}var style='';if(loggingEvent.level.toString().search(/ERROR/)!=-1){style+='color:red';}else if(loggingEvent.level.toString().search(/FATAL/)!=-1){style+='color:red';}else if(loggingEvent.level.toString().search(/WARN/)!=-1){style+='color:orange';}else if(loggingEvent.level.toString().search(/DEBUG/)!=-1){style+='color:green';}else if(loggingEvent.level.toString().search(/INFO/)!=-1){style+='color:white';}else{style+='color:yellow';}this.output(this.layout.format(loggingEvent),style);},doClear:function(){this.outputElement.innerHTML="";},handleInput:function(e){if(e.keyCode==13){var command=this.inputElement.value;switch(command){case "clear":this.logger.clear();break;default:var consoleOutput="";try{consoleOutput=eval(this.inputElement.value);}catch(e){this.logger.error("Problem parsing input <"+command+">"+e.message);break;}this.logger.trace(consoleOutput);break;}if(this.inputElement.value!==""&&this.inputElement.value!==this.commandHistory[0]){this.commandHistory.unshift(this.inputElement.value);}this.commandIndex=0;this.inputElement.value="";}else if(e.keyCode==38&&this.commandHistory.length>0){this.inputElement.value=this.commandHistory[this.commandIndex];if(this.commandIndex<this.commandHistory.length-1){this.commandIndex+=1;}}else if(e.keyCode==40&&this.commandHistory.length>0){if(this.commandIndex>0){this.commandIndex-=1;}this.inputElement.value=this.commandHistory[this.commandIndex];}else{this.commandIndex=0;}},toString:function(){return "Log4js.ConsoleAppender[inline="+this.inline+"]";}});Log4js.MetatagAppender=function(){this.currentLine=0;};Log4js.MetatagAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){var now=new Date();var lines=loggingEvent.message.split("\n");var headTag=document.getElementsByTagName("head")[0];for(var i=1;i<=lines.length;i++){var value=lines[i-1];if(i==1){value=loggingEvent.level.toString()+": "+value;}else{value="> "+value;}var metaTag=document.createElement("meta");metaTag.setAttribute("name","X-log4js:"+this.currentLine);metaTag.setAttribute("content",value);headTag.appendChild(metaTag);this.currentLine+=1;}},toString:function(){return "Log4js.MetatagAppender";}});Log4js.AjaxAppender=function(loggingUrl){this.isInProgress=false;this.loggingUrl=loggingUrl||"logging.log4js";this.threshold=1;this.timeout=2000;this.loggingEventMap=new Log4js.FifoBuffer();this.layout=new Log4js.XMLLayout();this.httpRequest=null;};Log4js.AjaxAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){log4jsLogger.trace("> AjaxAppender.append");if(this.loggingEventMap.length()<=this.threshold||this.isInProgress===true){this.loggingEventMap.push(loggingEvent);}if(this.loggingEventMap.length()>=this.threshold&&this.isInProgress===false){this.send();}log4jsLogger.trace("< AjaxAppender.append");},doClear:function(){log4jsLogger.trace("> AjaxAppender.doClear");if(this.loggingEventMap.length()>0){this.send();}log4jsLogger.trace("< AjaxAppender.doClear");},setThreshold:function(threshold){log4jsLogger.trace("> AjaxAppender.setThreshold: "+threshold);this.threshold=threshold;log4jsLogger.trace("< AjaxAppender.setThreshold");},setTimeout:function(milliseconds){this.timeout=milliseconds;},send:function(){if(this.loggingEventMap.length()>0){log4jsLogger.trace("> AjaxAppender.send");this.isInProgress=true;var a=[];for(var i=0;i<this.loggingEventMap.length()&&i<this.threshold;i++){a.push(this.layout.format(this.loggingEventMap.pull()));}var content=this.layout.getHeader();content+=a.join(this.layout.getSeparator());content+=this.layout.getFooter();var appender=this;if(this.httpRequest===null){this.httpRequest=this.getXmlHttpRequest();}this.httpRequest.onreadystatechange=function(){appender.onReadyStateChanged.call(appender);};this.httpRequest.open("POST",this.loggingUrl,true);this.httpRequest.setRequestHeader("Content-type",this.layout.getContentType());this.httpRequest.setRequestHeader("REFERER",location.href);this.httpRequest.setRequestHeader("Content-length",content.length);this.httpRequest.setRequestHeader("Connection","close");this.httpRequest.send(content);appender=this;try{window.setTimeout(function(){log4jsLogger.trace("> AjaxAppender.timeout");appender.httpRequest.onreadystatechange=function(){return;};appender.httpRequest.abort();appender.isInProgress=false;if(appender.loggingEventMap.length()>0){appender.send();}log4jsLogger.trace("< AjaxAppender.timeout");},this.timeout);}catch(e){log4jsLogger.fatal(e);}log4jsLogger.trace("> AjaxAppender.send");}},onReadyStateChanged:function(){log4jsLogger.trace("> AjaxAppender.onReadyStateChanged");var req=this.httpRequest;if(this.httpRequest.readyState!=4){log4jsLogger.trace("< AjaxAppender.onReadyStateChanged: readyState "+req.readyState+" != 4");return;}var success=((typeof req.status==="undefined")||req.status===0||(req.status>=200&&req.status<300));if(success){log4jsLogger.trace(" AjaxAppender.onReadyStateChanged: success");this.isInProgress=false;}else{var msg=" AjaxAppender.onReadyStateChanged: XMLHttpRequest request to URL "+this.loggingUrl+" returned status code "+this.httpRequest.status;log4jsLogger.error(msg);}log4jsLogger.trace("< AjaxAppender.onReadyStateChanged: readyState == 4");},getXmlHttpRequest:function(){log4jsLogger.trace("> AjaxAppender.getXmlHttpRequest");var httpRequest=false;try{if(window.XMLHttpRequest){httpRequest=new XMLHttpRequest();if(httpRequest.overrideMimeType){httpRequest.overrideMimeType(this.layout.getContentType());}}else if(window.ActiveXObject){try{httpRequest=new ActiveXObject("Msxml2.XMLHTTP");}catch(e){httpRequest=new ActiveXObject("Microsoft.XMLHTTP");}}}catch(e){httpRequest=false;}if(!httpRequest){log4jsLogger.fatal("Unfortunatelly your browser does not support AjaxAppender for log4js!");}log4jsLogger.trace("< AjaxAppender.getXmlHttpRequest");return httpRequest;},toString:function(){return "Log4js.AjaxAppender[loggingUrl="+this.loggingUrl+", threshold="+this.threshold+"]";}});Log4js.FileAppender=function(file){this.layout=new Log4js.SimpleLayout();this.isIE='undefined';this.file=file||"log4js.log";try{this.fso=new ActiveXObject("Scripting.FileSystemObject");this.isIE=true;}catch(e){try{netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");this.fso=Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);this.isIE=false;}catch(e){log4jsLogger.error(e);}}};Log4js.FileAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){try{var fileHandle=null;if(this.isIE==='undefined'){log4jsLogger.error("Unsupported ")}else if(this.isIE){fileHandle=this.fso.OpenTextFile(this.file,8,true);fileHandle.WriteLine(this.layout.format(loggingEvent));fileHandle.close();}else{netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");this.fso.initWithPath(this.file);if(!this.fso.exists()){this.fso.create(0x00,0600);}fileHandle=Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);fileHandle.init(this.fso,0x04|0x08|0x10,064,0);var line=this.layout.format(loggingEvent);fileHandle.write(line,line.length);fileHandle.close();}}catch(e){log4jsLogger.error(e);}},doClear:function(){try{if(this.isIE){var fileHandle=this.fso.GetFile(this.file);fileHandle.Delete();}else{netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");this.fso.initWithPath(this.file);if(this.fso.exists()){this.fso.remove(false);}}}catch(e){log4jsLogger.error(e);}},toString:function(){return "Log4js.FileAppender[file="+this.file+"]";}});Log4js.WindowsEventAppender=function(){this.layout=new Log4js.SimpleLayout();try{this.shell=new ActiveXObject("WScript.Shell");}catch(e){log4jsLogger.error(e);}};Log4js.WindowsEventAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){var winLevel=4;switch(loggingEvent.level){case Log4js.Level.FATAL:winLevel=1;break;case Log4js.Level.ERROR:winLevel=1;break;case Log4js.Level.WARN:winLevel=2;break;default:winLevel=4;break;}try{this.shell.LogEvent(winLevel,this.level.format(loggingEvent));}catch(e){log4jsLogger.error(e);}},toString:function(){return "Log4js.WindowsEventAppender";}});Log4js.JSAlertAppender=function(){this.layout=new Log4js.SimpleLayout();};Log4js.JSAlertAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){alert(this.layout.getHeader()+this.layout.format(loggingEvent)+this.layout.getFooter());},toString:function(){return "Log4js.JSAlertAppender";}});Log4js.MozillaJSConsoleAppender=function(){this.layout=new Log4js.SimpleLayout();try{netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");this.jsConsole=Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);this.scriptError=Components.classes["@mozilla.org/scripterror;1"].createInstance(Components.interfaces.nsIScriptError);}catch(e){log4jsLogger.error(e);}};Log4js.MozillaJSConsoleAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){try{netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");this.scriptError.init(this.layout.format(loggingEvent),null,null,null,null,this.getFlag(loggingEvent),loggingEvent.categoryName);this.jsConsole.logMessage(this.scriptError);}catch(e){log4jsLogger.error(e);}},toString:function(){return "Log4js.MozillaJSConsoleAppender";},getFlag:function(loggingEvent){var retval;switch(loggingEvent.level){case Log4js.Level.FATAL:retval=2;break;case Log4js.Level.ERROR:retval=0;break;case Log4js.Level.WARN:retval=1;break;default:retval=1;break;}return retval;}});Log4js.OperaJSConsoleAppender=function(){this.layout=new Log4js.SimpleLayout();};Log4js.OperaJSConsoleAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){opera.postError(this.layout.format(loggingEvent));},toString:function(){return "Log4js.OperaJSConsoleAppender";}});Log4js.SafariJSConsoleAppender=function(){this.layout=new Log4js.SimpleLayout();};Log4js.SafariJSConsoleAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){window.console.log(this.layout.format(loggingEvent));},toString:function(){return "Log4js.SafariJSConsoleAppender";}});Log4js.BrowserConsoleAppender=function(){this.consoleDelegate=null;if(window.console){this.consoleDelegate=new Log4js.SafariJSConsoleAppender();}else if(window.opera){this.consoleDelegate=new Log4js.OperaJSConsoleAppender();}else if(netscape){this.consoleDelegate=new Log4js.MozJSConsoleAppender();}else{log4jsLogger.error("Unsupported Browser");}};Log4js.BrowserConsoleAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){this.consoleDelegate.doAppend(loggingEvent);},doClear:function(){this.consoleDelegate.doClear();},setLayout:function(layout){this.consoleDelegate.setLayout(layout);},toString:function(){return "Log4js.BrowserConsoleAppender: "+this.consoleDelegate.toString();}});Log4js.SimpleLayout=function(){this.LINE_SEP="\n";this.LINE_SEP_LEN=1;};Log4js.SimpleLayout.prototype=Log4js.extend(new Log4js.Layout(),{format:function(loggingEvent){return loggingEvent.level.toString()+" - "+loggingEvent.message+this.LINE_SEP;},getContentType:function(){return "text/plain";},getHeader:function(){return "";},getFooter:function(){return "";}});Log4js.BasicLayout=function(){this.LINE_SEP="\n";};Log4js.BasicLayout.prototype=Log4js.extend(new Log4js.Layout(),{format:function(loggingEvent){return loggingEvent.categoryName+"~"+loggingEvent.startTime.toLocaleString()+" ["+loggingEvent.level.toString()+"] "+loggingEvent.message+this.LINE_SEP;},getContentType:function(){return "text/plain";},getHeader:function(){return "";},getFooter:function(){return "";}});Log4js.HtmlLayout=function(){return;};Log4js.HtmlLayout.prototype=Log4js.extend(new Log4js.Layout(),{format:function(loggingEvent){return "<div style=\""+this.getStyle(loggingEvent)+"\">"+loggingEvent.getFormattedTimestamp()+" - "+loggingEvent.level.toString()+" - "+loggingEvent.message+"</div>\n";},getContentType:function(){return "text/html";},getHeader:function(){return "<html><head><title>log4js</head><body>";},getFooter:function(){return "</body></html>";},getStyle:function(loggingEvent){var style;if(loggingEvent.level.toString().search(/ERROR/)!=-1){style='color:red';}else if(loggingEvent.level.toString().search(/FATAL/)!=-1){style='color:red';}else if(loggingEvent.level.toString().search(/WARN/)!=-1){style='color:orange';}else if(loggingEvent.level.toString().search(/DEBUG/)!=-1){style='color:green';}else if(loggingEvent.level.toString().search(/INFO/)!=-1){style='color:white';}else{style='color:yellow';}return style;}});Log4js.XMLLayout=function(){return;};Log4js.XMLLayout.prototype=Log4js.extend(new Log4js.Layout(),{format:function(loggingEvent){var useragent="unknown";try{useragent=navigator.userAgent;}catch(e){useragent="unknown";}var referer="unknown";try{referer=location.href;}catch(e){referer="unknown";}var content="<log4js:event logger=\"";content+=loggingEvent.categoryName+"\" level=\"";content+=loggingEvent.level.toString()+"\" useragent=\"";content+=useragent+"\" referer=\"";content+=referer.replace(/&/g,"&")+"\" timestamp=\"";content+=loggingEvent.getFormattedTimestamp()+"\">\n";content+="\t<log4js:message><![CDATA["+this.escapeCdata(loggingEvent.message)+"]]></log4js:message>\n";if(loggingEvent.exception){content+=this.formatException(loggingEvent.exception);}content+="</log4js:event>\n";return content;},getContentType:function(){return "text/xml";},getHeader:function(){return "<log4js:eventSet version=\""+Log4js.version+"\" xmlns:log4js=\"http://log4js.berlios.de/2007/log4js/\">\n";},getFooter:function(){return "</log4js:eventSet>\n";},getSeparator:function(){return "\n";},formatException:function(ex){if(ex){var exStr="\t<log4js:throwable>";if(ex.message){exStr+="\t\t<log4js:message><![CDATA["+this.escapeCdata(ex.message)+"]]></log4js:message>\n";}if(ex.description){exStr+="\t\t<log4js:description><![CDATA["+this.escapeCdata(ex.description)+"]]></log4js:description>\n";}exStr+="\t\t<log4js:stacktrace>";exStr+="\t\t\t<log4js:location fileName=\""+ex.fileName+"\" lineNumber=\""+ex.lineNumber+"\" />";exStr+="\t\t</log4js:stacktrace>";exStr="\t</log4js:throwable>";return exStr;}return null;},escapeCdata:function(str){return str.replace(/\]\]>/,"]]>]]><![CDATA[");}});Log4js.JSONLayout=function(){this.df=new Log4js.DateFormatter();};Log4js.JSONLayout.prototype=Log4js.extend(new Log4js.Layout(),{format:function(loggingEvent){var useragent="unknown";try{useragent=navigator.userAgent;}catch(e){useragent="unknown";}var referer="unknown";try{referer=location.href;}catch(e){referer="unknown";}var jsonString="{\n \"LoggingEvent\": {\n";jsonString+="\t\"logger\": \""+loggingEvent.categoryName+"\",\n";jsonString+="\t\"level\": \""+loggingEvent.level.toString()+"\",\n";jsonString+="\t\"message\": \""+loggingEvent.message+"\",\n";jsonString+="\t\"referer\": \""+referer+"\",\n";jsonString+="\t\"useragent\": \""+useragent+"\",\n";jsonString+="\t\"timestamp\": \""+this.df.formatDate(loggingEvent.startTime,"yyyy-MM-ddThh:mm:ssZ")+"\",\n";jsonString+="\t\"exception\": \""+loggingEvent.exception+"\"\n";jsonString+="}}";return jsonString;},getContentType:function(){return "text/json";},getHeader:function(){return "{\"Log4js\": [\n";},getFooter:function(){return "\n]}";},getSeparator:function(){return ",\n";}});Log4js.PatternLayout=function(pattern){if(pattern){this.pattern=pattern;}else{this.pattern=Log4js.PatternLayout.DEFAULT_CONVERSION_PATTERN;}};Log4js.PatternLayout.TTCC_CONVERSION_PATTERN="%r %p %c - %m%n";Log4js.PatternLayout.DEFAULT_CONVERSION_PATTERN="%m%n";Log4js.PatternLayout.ISO8601_DATEFORMAT="yyyy-MM-dd HH:mm:ss,SSS";Log4js.PatternLayout.DATETIME_DATEFORMAT="dd MMM YYYY HH:mm:ss,SSS";Log4js.PatternLayout.ABSOLUTETIME_DATEFORMAT="HH:mm:ss,SSS";Log4js.PatternLayout.prototype=Log4js.extend(new Log4js.Layout(),{getContentType:function(){return "text/plain";},getHeader:function(){return null;},getFooter:function(){return null;},format:function(loggingEvent){var regex= /%(-?[0-9]+)?(\.?[0-9]+)?([cdmnpr%])(\{([^\}]+)\})?|([^%]+)/;var formattedString="";var result;var searchString=this.pattern;while((result=regex.exec(searchString))){var matchedString=result[0];var padding=result[1];var truncation=result[2];var conversionCharacter=result[3];var specifier=result[5];var text=result[6];if(text){formattedString+=""+text;}else{var replacement="";switch(conversionCharacter){case "c":var loggerName=loggingEvent.categoryName;if(specifier){var precision=parseInt(specifier,10);var loggerNameBits=loggingEvent.categoryName.split(".");if(precision>=loggerNameBits.length){replacement=loggerName;}else{replacement=loggerNameBits.slice(loggerNameBits.length-precision).join(".");}}else{replacement=loggerName;}break;case "d":var dateFormat=Log4js.PatternLayout.ISO8601_DATEFORMAT;if(specifier){dateFormat=specifier;if(dateFormat=="ISO8601"){dateFormat=Log4js.PatternLayout.ISO8601_DATEFORMAT;}else if(dateFormat=="ABSOLUTE"){dateFormat=Log4js.PatternLayout.ABSOLUTETIME_DATEFORMAT;}else if(dateFormat=="DATE"){dateFormat=Log4js.PatternLayout.DATETIME_DATEFORMAT;}}replacement=(new Log4js.SimpleDateFormat(dateFormat)).format(loggingEvent.startTime);break;case "m":replacement=loggingEvent.message;break;case "n":replacement="\n";break;case "p":replacement=loggingEvent.level.toString();break;case "r":replacement=""+loggingEvent.startTime.toLocaleTimeString();break;case "%":replacement="%";break;default:replacement=matchedString;break;}var len;if(truncation){len=parseInt(truncation.substr(1),10);replacement=replacement.substring(0,len);}if(padding){if(padding.charAt(0)=="-"){len=parseInt(padding.substr(1),10);while(replacement.length<len){replacement+=" ";}}else{len=parseInt(padding,10);while(replacement.length<len){replacement=" "+replacement;}}}formattedString+=replacement;}searchString=searchString.substr(result.index+result[0].length);}return formattedString;}});if(!Array.prototype.push){Array.prototype.push=function(){var startLength=this.length;for(var i=0;i<arguments.length;i++){this[startLength+i]=arguments[i];}return this.length;};}Log4js.FifoBuffer=function(){this.array=new Array();};Log4js.FifoBuffer.prototype={push:function(obj){this.array[this.array.length]=obj;return this.array.length;},pull:function(){if(this.array.length>0){var firstItem=this.array[0];for(var i=0;i<this.array.length-1;i++){this.array[i]=this.array[i+1];}this.array.length=this.array.length-1;return firstItem;}return null;},length:function(){return this.array.length;}};Log4js.DateFormatter=function(){return;};Log4js.DateFormatter.DEFAULT_DATE_FORMAT="yyyy-MM-ddThh:mm:ssO";Log4js.DateFormatter.prototype={formatDate:function(vDate,vFormat){var vDay=this.addZero(vDate.getDate());var vMonth=this.addZero(vDate.getMonth()+1);var vYearLong=this.addZero(vDate.getFullYear());var vYearShort=this.addZero(vDate.getFullYear().toString().substring(3,4));var vYear=(vFormat.indexOf("yyyy")>-1?vYearLong:vYearShort);var vHour=this.addZero(vDate.getHours());var vMinute=this.addZero(vDate.getMinutes());var vSecond=this.addZero(vDate.getSeconds());var vTimeZone=this.O(vDate);var vDateString=vFormat.replace(/dd/g,vDay).replace(/MM/g,vMonth).replace(/y{1,4}/g,vYear);vDateString=vDateString.replace(/hh/g,vHour).replace(/mm/g,vMinute).replace(/ss/g,vSecond);vDateString=vDateString.replace(/O/g,vTimeZone);return vDateString;},addZero:function(vNumber){return((vNumber<10)?"0":"")+vNumber;},O:function(date){var os=Math.abs(date.getTimezoneOffset());var h=String(Math.floor(os/60));var m=String(os%60);h.length==1?h="0"+h:1;m.length==1?m="0"+m:1;return date.getTimezoneOffset()<0?"+"+h+m:"-"+h+m;}};var log4jsLogger=Log4js.getLogger("Log4js");log4jsLogger.addAppender(new Log4js.ConsoleAppender());log4jsLogger.setLevel(Log4js.Level.ALL);\r
--- /dev/null
+/*\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/*jsl:option explicit*/\r
+\r
+/**\r
+ * @fileoverview log4js is a library to log in JavaScript in similar manner \r
+ * than in log4j for Java. The API should be nearly the same.\r
+ * \r
+ * This file contains all log4js code and is the only file required for logging.\r
+ * \r
+ * <h3>Example:</h3>\r
+ * <pre>\r
+ * var log = new Log4js.getLogger("some-category-name"); //create logger instance\r
+ * log.setLevel(Log4js.Level.TRACE); //set the Level\r
+ * log.addAppender(new ConsoleAppender(log, false)); // console that launches in new window\r
+ \r
+ * // if multiple appenders are set all will log\r
+ * log.addAppender(new ConsoleAppender(log, true)); // console that is in-line in the page\r
+ * log.addAppender(new FileAppender("C:\\somefile.log")); // file appender logs to C:\\somefile.log\r
+ * \r
+ * ...\r
+ * \r
+ * //call the log\r
+ * log.trace("trace me" );\r
+ * </pre>\r
+ *\r
+ * @version 0.3\r
+ * @author Stephan Strittmatter - http://jroller.com/page/stritti\r
+ * @author Seth Chisamore - http://www.chisamore.com\r
+ * @since 2005-05-20\r
+ * Website: http://log4js.berlios.de\r
+ */\r
+var Log4js = {\r
+ \r
+ /** \r
+ * Current version of log4js. \r
+ * @static\r
+ * @final\r
+ */\r
+ version: "1.0",\r
+\r
+ /** \r
+ * Date of logger initialized.\r
+ * @static\r
+ * @final\r
+ */\r
+ applicationStartDate: new Date(),\r
+ \r
+ /** \r
+ * Hashtable of loggers.\r
+ * @static\r
+ * @final\r
+ * @private \r
+ */\r
+ loggers: {},\r
+ \r
+ /**\r
+ * Get a logger instance. Instance is cached on categoryName level.\r
+ * @param {String} categoryName name of category to log to.\r
+ * @return {Logger} instance of logger for the category\r
+ * @static\r
+ */\r
+ getLogger: function(categoryName) {\r
+ \r
+ // Use default logger if categoryName is not specified or invalid\r
+ if (!(typeof categoryName == "string")) {\r
+ categoryName = "[default]";\r
+ }\r
+\r
+ if (!Log4js.loggers[categoryName]) {\r
+ // Create the logger for this name if it doesn't already exist\r
+ Log4js.loggers[categoryName] = new Log4js.Logger(categoryName);\r
+ }\r
+ \r
+ return Log4js.loggers[categoryName];\r
+ },\r
+ \r
+ /**\r
+ * Get the default logger instance.\r
+ * @return {Logger} instance of default logger\r
+ * @static\r
+ */\r
+ getDefaultLogger: function() {\r
+ return Log4js.getLogger("[default]"); \r
+ },\r
+ \r
+ /**\r
+ * Atatch an observer function to an elements event browser independent.\r
+ * \r
+ * @param element element to attach event\r
+ * @param name name of event\r
+ * @param observer observer method to be called\r
+ * @private\r
+ */\r
+ attachEvent: function (element, name, observer) {\r
+ if (element.addEventListener) { //DOM event model\r
+ element.addEventListener(name, observer, false);\r
+ } else if (element.attachEvent) { //M$ event model\r
+ element.attachEvent('on' + name, observer);\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Load a JS-script dynamically.\r
+ * @param {String} src\r
+ */\r
+/* $import: function (src) {\r
+ var documentScripts = document.getElementsByTagName("script");\r
+ \r
+ for (index = 0; index < documentScripts.length; ++index)\r
+ {\r
+ var documentScript = documentScripts[index];\r
+ if (documentScript.src == src) {\r
+ return false;\r
+ }\r
+ }\r
+ \r
+ var script = document.createElement('script');\r
+ script.type = 'text/javascript';\r
+ script.src = src;\r
+ document.getElementsByTagName('head')[0].appendChild(script); \r
+ \r
+ return true;\r
+ }\r
+ */\r
+};\r
+\r
+/**\r
+ * Internal object extension (OO) methods.\r
+ * \r
+ * @private\r
+ * @ignore\r
+ */\r
+Log4js.extend = function(destination, source) {\r
+ for (property in source) {\r
+ destination[property] = source[property];\r
+ }\r
+ return destination;\r
+}\r
+ \r
+/**\r
+ * Functions taken from Prototype library, \r
+ * didn't want to require for just few functions.\r
+ * More info at {@link http://prototype.conio.net/}\r
+ * @private\r
+ */ \r
+Log4js.bind = function(fn, object) {\r
+ return function() {\r
+ return fn.apply(object, arguments);\r
+ };\r
+};\r
+\r
+/**\r
+ * Log4js.Level Enumeration. Do not use directly. Use static objects instead.\r
+ * @constructor\r
+ * @param {Number} level number of level\r
+ * @param {String} levelString String representation of level\r
+ * @private\r
+ */\r
+Log4js.Level = function(level, levelStr) {\r
+ this.level = level;\r
+ this.levelStr = levelStr;\r
+};\r
+\r
+Log4js.Level.prototype = {\r
+ /** \r
+ * converts given String to corresponding Level\r
+ * @param {String} sArg String value of Level\r
+ * @param {Log4js.Level} defaultLevel default Level, if no String representation\r
+ * @return Level object\r
+ * @type Log4js.Level\r
+ */\r
+ toLevel: function(sArg, defaultLevel) { \r
+ \r
+ if(sArg === null) {\r
+ return defaultLevel;\r
+ }\r
+ \r
+ if(typeof sArg == "string") { \r
+ var s = sArg.toUpperCase();\r
+ if(s == "ALL") {return Log4js.Level.ALL;}\r
+ if(s == "DEBUG") {return Log4js.Level.DEBUG;}\r
+ if(s == "INFO") {return Log4js.Level.INFO;}\r
+ if(s == "WARN") {return Log4js.Level.WARN;}\r
+ if(s == "ERROR") {return Log4js.Level.ERROR;}\r
+ if(s == "FATAL") {return Log4js.Level.FATAL;}\r
+ if(s == "OFF") {return Log4js.Level.OFF;}\r
+ if(s == "TRACE") {return Log4js.Level.TRACE;}\r
+ return defaultLevel;\r
+ } else if(typeof sArg == "number") {\r
+ switch(sArg) {\r
+ case ALL_INT: return Log4js.Level.ALL;\r
+ case DEBUG_INT: return Log4js.Level.DEBUG;\r
+ case INFO_INT: return Log4js.Level.INFO;\r
+ case WARN_INT: return Log4js.Level.WARN;\r
+ case ERROR_INT: return Log4js.Level.ERROR;\r
+ case FATAL_INT: return Log4js.Level.FATAL;\r
+ case OFF_INT: return Log4js.Level.OFF;\r
+ case TRACE_INT: return Log4js.Level.TRACE;\r
+ default: return defaultLevel;\r
+ }\r
+ } else {\r
+ return defaultLevel; \r
+ }\r
+ }, \r
+ /** \r
+ * @return converted Level to String\r
+ * @type String\r
+ */ \r
+ toString: function() {\r
+ return this.levelStr; \r
+ },\r
+ /** \r
+ * @return internal Number value of Level\r
+ * @type Number\r
+ */ \r
+ valueOf: function() {\r
+ return this.level;\r
+ }\r
+};\r
+\r
+// Static variables\r
+/** \r
+ * @private\r
+ */\r
+Log4js.Level.OFF_INT = Number.MAX_VALUE;\r
+/** \r
+ * @private\r
+ */\r
+Log4js.Level.FATAL_INT = 50000;\r
+/** \r
+ * @private\r
+ */\r
+Log4js.Level.ERROR_INT = 40000;\r
+/** \r
+ * @private\r
+ */\r
+Log4js.Level.WARN_INT = 30000;\r
+/** \r
+ * @private\r
+ */\r
+Log4js.Level.INFO_INT = 20000;\r
+/** \r
+ * @private\r
+ */\r
+Log4js.Level.DEBUG_INT = 10000;\r
+/** \r
+ * @private\r
+ */\r
+Log4js.Level.TRACE_INT = 5000;\r
+/** \r
+ * @private\r
+ */\r
+Log4js.Level.ALL_INT = Number.MIN_VALUE;\r
+\r
+/** \r
+ * Logging Level OFF - all disabled\r
+ * @type Log4js.Level\r
+ * @static\r
+ */\r
+Log4js.Level.OFF = new Log4js.Level(Log4js.Level.OFF_INT, "OFF");\r
+/** \r
+ * Logging Level Fatal\r
+ * @type Log4js.Level\r
+ * @static\r
+ */\r
+Log4js.Level.FATAL = new Log4js.Level(Log4js.Level.FATAL_INT, "FATAL");\r
+/** \r
+ * Logging Level Error\r
+ * @type Log4js.Level\r
+ * @static\r
+ */\r
+Log4js.Level.ERROR = new Log4js.Level(Log4js.Level.ERROR_INT, "ERROR"); \r
+/** \r
+ * Logging Level Warn\r
+ * @type Log4js.Level\r
+ * @static\r
+ */\r
+Log4js.Level.WARN = new Log4js.Level(Log4js.Level.WARN_INT, "WARN"); \r
+/** \r
+ * Logging Level Info\r
+ * @type Log4js.Level\r
+ * @static\r
+ */\r
+Log4js.Level.INFO = new Log4js.Level(Log4js.Level.INFO_INT, "INFO"); \r
+/** \r
+ * Logging Level Debug\r
+ * @type Log4js.Level\r
+ * @static\r
+ */\r
+Log4js.Level.DEBUG = new Log4js.Level(Log4js.Level.DEBUG_INT, "DEBUG"); \r
+/** \r
+ * Logging Level Trace\r
+ * @type Log4js.Level\r
+ * @static\r
+ */\r
+Log4js.Level.TRACE = new Log4js.Level(Log4js.Level.TRACE_INT, "TRACE"); \r
+/** \r
+ * Logging Level All - All traces are enabled\r
+ * @type Log4js.Level\r
+ * @static\r
+ */\r
+Log4js.Level.ALL = new Log4js.Level(Log4js.Level.ALL_INT, "ALL"); \r
+\r
+/**\r
+ * Log4js CustomEvent\r
+ * @constructor\r
+ * @author Corey Johnson - original code in Lumberjack (http://gleepglop.com/javascripts/logger/)\r
+ * @author Seth Chisamore - adapted for Log4js\r
+ * @private\r
+ */\r
+Log4js.CustomEvent = function() {\r
+ this.listeners = [];\r
+};\r
+\r
+Log4js.CustomEvent.prototype = {\r
+ \r
+ /**\r
+ * @param method method to be added\r
+ */ \r
+ addListener : function(method) {\r
+ this.listeners.push(method);\r
+ },\r
+\r
+ /**\r
+ * @param method method to be removed\r
+ */ \r
+ removeListener : function(method) {\r
+ var foundIndexes = this.findListenerIndexes(method);\r
+\r
+ for(var i = 0; i < foundIndexes.length; i++) {\r
+ this.listeners.splice(foundIndexes[i], 1);\r
+ }\r
+ },\r
+\r
+ /**\r
+ * @param handler\r
+ */ \r
+ dispatch : function(handler) {\r
+ for(var i = 0; i < this.listeners.length; i++) {\r
+ try {\r
+ this.listeners[i](handler);\r
+ }\r
+ catch (e) {\r
+ log4jsLogger.warn("Could not run the listener " + this.listeners[i] + ". \n" + e);\r
+ }\r
+ }\r
+ },\r
+\r
+ /**\r
+ * @private\r
+ * @param method\r
+ */\r
+ findListenerIndexes : function(method) {\r
+ var indexes = [];\r
+ for(var i = 0; i < this.listeners.length; i++) { \r
+ if (this.listeners[i] == method) {\r
+ indexes.push(i);\r
+ }\r
+ }\r
+\r
+ return indexes;\r
+ }\r
+};\r
+\r
+/**\r
+ * Models a logging event.\r
+ * @constructor\r
+ * @param {String} categoryName name of category\r
+ * @param {Log4js.Level} level level of message\r
+ * @param {String} message message to log\r
+ * @param {Log4js.Logger} logger the associated logger\r
+ * @author Seth Chisamore\r
+ */\r
+Log4js.LoggingEvent = function(categoryName, level, message, exception, logger) {\r
+ /**\r
+ * the timestamp of the Logging Event\r
+ * @type Date\r
+ * @private\r
+ */\r
+ this.startTime = new Date();\r
+ /**\r
+ * category of event\r
+ * @type String\r
+ * @private\r
+ */\r
+ this.categoryName = categoryName;\r
+ /**\r
+ * the logging message\r
+ * @type String\r
+ * @private\r
+ */\r
+ this.message = message;\r
+ /**\r
+ * the logging exception\r
+ * @type Exception\r
+ * @private\r
+ */\r
+ this.exception = exception;\r
+ /**\r
+ * level of log\r
+ * @type Log4js.Level\r
+ * @private\r
+ */\r
+ this.level = level;\r
+ /**\r
+ * reference to logger\r
+ * @type Log4js.Logger\r
+ * @private\r
+ */\r
+ this.logger = logger;\r
+};\r
+\r
+Log4js.LoggingEvent.prototype = { \r
+ /**\r
+ * get the timestamp formatted as String.\r
+ * @return {String} formatted timestamp\r
+ * @see Log4js#setDateFormat()\r
+ */\r
+ getFormattedTimestamp: function() {\r
+ if(this.logger) {\r
+ return this.logger.getFormattedTimestamp(this.startTime);\r
+ } else {\r
+ return this.startTime.toGMTString();\r
+ }\r
+ }\r
+};\r
+\r
+/**\r
+ * Logger to log messages to the defined appender.</p>\r
+ * Default appender is Appender, which is ignoring all messages. Please\r
+ * use setAppender() to set a specific appender (e.g. WindowAppender).\r
+ * use {@see Log4js#getLogger(String)} to get an instance.\r
+ * @constructor\r
+ * @param name name of category to log to\r
+ * @author Stephan Strittmatter\r
+ */\r
+Log4js.Logger = function(name) {\r
+ this.loggingEvents = [];\r
+ this.appenders = [];\r
+ /** category of logger */\r
+ this.category = name || "";\r
+ /** level to be logged */\r
+ this.level = Log4js.Level.FATAL;\r
+ \r
+ this.dateformat = Log4js.DateFormatter.DEFAULT_DATE_FORMAT;\r
+ this.dateformatter = new Log4js.DateFormatter();\r
+ \r
+ this.onlog = new Log4js.CustomEvent();\r
+ this.onclear = new Log4js.CustomEvent();\r
+ \r
+ /** appender to write in */\r
+ this.appenders.push(new Log4js.Appender(this));\r
+ \r
+ // if multiple log objects are instantiated this will only log to the log \r
+ // object that is declared last can't seem to get the attachEvent method to \r
+ // work correctly\r
+ try {\r
+ window.onerror = this.windowError.bind(this);\r
+ } catch (e) {\r
+ //log4jsLogger.fatal(e);\r
+ }\r
+};\r
+\r
+Log4js.Logger.prototype = {\r
+\r
+ /**\r
+ * add additional appender. DefaultAppender always is there.\r
+ * @param appender additional wanted appender\r
+ */\r
+ addAppender: function(appender) {\r
+ if (appender instanceof Log4js.Appender) {\r
+ appender.setLogger(this);\r
+ this.appenders.push(appender); \r
+ } else {\r
+ throw "Not instance of an Appender: " + appender;\r
+ }\r
+ },\r
+\r
+ /**\r
+ * set Array of appenders. Previous Appenders are cleared and removed.\r
+ * @param {Array} appenders Array of Appenders\r
+ */\r
+ setAppenders: function(appenders) {\r
+ //clear first all existing appenders\r
+ for(var i = 0; i < this.appenders.length; i++) {\r
+ this.appenders[i].doClear();\r
+ }\r
+ \r
+ this.appenders = appenders;\r
+ \r
+ for(var j = 0; j < this.appenders.length; j++) {\r
+ this.appenders[j].setLogger(this);\r
+ }\r
+ },\r
+ \r
+ /**\r
+ * Set the Loglevel default is LogLEvel.TRACE\r
+ * @param level wanted logging level\r
+ */\r
+ setLevel: function(level) {\r
+ this.level = level;\r
+ },\r
+ \r
+ /** \r
+ * main log method logging to all available appenders \r
+ * @private\r
+ */\r
+ log: function(logLevel, message, exception) {\r
+ var loggingEvent = new Log4js.LoggingEvent(this.category, logLevel, \r
+ message, exception, this);\r
+ this.loggingEvents.push(loggingEvent);\r
+ this.onlog.dispatch(loggingEvent);\r
+ },\r
+ \r
+ /** clear logging */\r
+ clear : function () {\r
+ try{\r
+ this.loggingEvents = [];\r
+ this.onclear.dispatch();\r
+ } catch(e){}\r
+ },\r
+ /** checks if Level Trace is enabled */\r
+ isTraceEnabled: function() {\r
+ if (this.level.valueOf() <= Log4js.Level.TRACE.valueOf()) {\r
+ return true;\r
+ }\r
+ return false;\r
+ },\r
+ /** \r
+ * Trace messages \r
+ * @param message {Object} message to be logged\r
+ */\r
+ trace: function(message) {\r
+ if (this.isTraceEnabled()) {\r
+ this.log(Log4js.Level.TRACE, message, null);\r
+ }\r
+ },\r
+ /** checks if Level Debug is enabled */\r
+ isDebugEnabled: function() {\r
+ if (this.level.valueOf() <= Log4js.Level.DEBUG.valueOf()) {\r
+ return true;\r
+ }\r
+ return false;\r
+ },\r
+ /** \r
+ * Debug messages \r
+ * @param message {Object} message to be logged\r
+ */\r
+ debug: function(message) {\r
+ if (this.isDebugEnabled()) {\r
+ this.log(Log4js.Level.DEBUG, message, null);\r
+ }\r
+ },\r
+ /**\r
+ * Debug messages \r
+ * @param {Object} message message to be logged\r
+ * @param {Throwable} throwable \r
+ */\r
+ debug: function(message, throwable) {\r
+ if (this.isDebugEnabled()) {\r
+ this.log(Log4js.Level.DEBUG, message, throwable);\r
+ }\r
+ }, \r
+ /** checks if Level Info is enabled */\r
+ isInfoEnabled: function() {\r
+ if (this.level.valueOf() <= Log4js.Level.INFO.valueOf()) {\r
+ return true;\r
+ }\r
+ return false;\r
+ },\r
+ /** \r
+ * logging info messages \r
+ * @param {Object} message message to be logged\r
+ */\r
+ info: function(message) {\r
+ if (this.isInfoEnabled()) {\r
+ this.log(Log4js.Level.INFO, message, null);\r
+ }\r
+ },\r
+ /** \r
+ * logging info messages \r
+ * @param {Object} message message to be logged\r
+ * @param {Throwable} throwable \r
+ */\r
+ info: function(message, throwable) {\r
+ if (this.isInfoEnabled()) {\r
+ this.log(Log4js.Level.INFO, message, throwable);\r
+ }\r
+ },\r
+ /** checks if Level Warn is enabled */\r
+ isWarnEnabled: function() {\r
+ if (this.level.valueOf() <= Log4js.Level.WARN.valueOf()) {\r
+ return true;\r
+ }\r
+ return false;\r
+ },\r
+\r
+ /** logging warn messages */\r
+ warn: function(message) {\r
+ if (this.isWarnEnabled()) {\r
+ this.log(Log4js.Level.WARN, message, null);\r
+ }\r
+ },\r
+ /** logging warn messages */\r
+ warn: function(message, throwable) {\r
+ if (this.isWarnEnabled()) {\r
+ this.log(Log4js.Level.WARN, message, throwable);\r
+ }\r
+ },\r
+ /** checks if Level Error is enabled */\r
+ isErrorEnabled: function() {\r
+ if (this.level.valueOf() <= Log4js.Level.ERROR.valueOf()) {\r
+ return true;\r
+ }\r
+ return false;\r
+ },\r
+ /** logging error messages */\r
+ error: function(message) {\r
+ if (this.isErrorEnabled()) {\r
+ this.log(Log4js.Level.ERROR, message, null);\r
+ }\r
+ },\r
+ /** logging error messages */\r
+ error: function(message, throwable) {\r
+ if (this.isErrorEnabled()) {\r
+ this.log(Log4js.Level.ERROR, message, throwable);\r
+ }\r
+ },\r
+ /** checks if Level Fatal is enabled */\r
+ isFatalEnabled: function() {\r
+ if (this.level.valueOf() <= Log4js.Level.FATAL.valueOf()) {\r
+ return true;\r
+ }\r
+ return false;\r
+ },\r
+ /** logging fatal messages */\r
+ fatal: function(message) {\r
+ if (this.isFatalEnabled()) {\r
+ this.log(Log4js.Level.FATAL, message, null);\r
+ }\r
+ },\r
+ /** logging fatal messages */\r
+ fatal: function(message, throwable) {\r
+ if (this.isFatalEnabled()) {\r
+ this.log(Log4js.Level.FATAL, message, throwable);\r
+ }\r
+ }, \r
+ /** \r
+ * Capture main window errors and log as fatal.\r
+ * @private\r
+ */\r
+ windowError: function(msg, url, line){\r
+ var message = "Error in (" + (url || window.location) + ") on line "+ line +" with message (" + msg + ")";\r
+ this.log(Log4js.Level.FATAL, message, null); \r
+ },\r
+ \r
+ /**\r
+ * Set the date format of logger. Following switches are supported:\r
+ * <ul>\r
+ * <li>yyyy - The year</li>\r
+ * <li>MM - the month</li>\r
+ * <li>dd - the day of month<li>\r
+ * <li>hh - the hour<li>\r
+ * <li>mm - minutes</li>\r
+ * <li>O - timezone offset</li>\r
+ * </ul>\r
+ * @param {String} format format String for the date\r
+ * @see #getTimestamp\r
+ */\r
+ setDateFormat: function(format) {\r
+ this.dateformat = format;\r
+ },\r
+ \r
+ /**\r
+ * Generates a timestamp using the format set in {Log4js.setDateFormat}.\r
+ * @param {Date} date the date to format\r
+ * @see #setDateFormat\r
+ * @return A formatted timestamp with the current date and time.\r
+ */\r
+ getFormattedTimestamp: function(date) {\r
+ return this.dateformatter.formatDate(date, this.dateformat);\r
+ }\r
+};\r
+\r
+/**\r
+ * Abstract base class for other appenders. \r
+ * It is doing nothing.\r
+ *\r
+ * @constructor\r
+ * @param {Log4js.Logger} logger log4js instance this appender is attached to\r
+ * @author Stephan Strittmatter\r
+ */\r
+Log4js.Appender = function () {\r
+ /**\r
+ * Reference to calling logger\r
+ * @type Log4js.Logger\r
+ * @private\r
+ */\r
+ this.logger = null;\r
+};\r
+\r
+Log4js.Appender.prototype = {\r
+ /** \r
+ * appends the given loggingEvent appender specific\r
+ * @param {Log4js.LoggingEvent} loggingEvent loggingEvent to append\r
+ */\r
+ doAppend: function(loggingEvent) {\r
+ return;\r
+ },\r
+ /** \r
+ * clears the Appender\r
+ */\r
+ doClear: function() {\r
+ return;\r
+ },\r
+ \r
+ /**\r
+ * Set the Layout for this appender.\r
+ * @param {Log4js.Layout} layout Layout for formatting loggingEvent\r
+ */\r
+ setLayout: function(layout){\r
+ this.layout = layout;\r
+ },\r
+ /**\r
+ * Set reference to the logger.\r
+ * @param {Log4js.Logger} the invoking logger\r
+ */\r
+ setLogger: function(logger){\r
+ // add listener to the logger methods\r
+ logger.onlog.addListener(Log4js.bind(this.doAppend, this));\r
+ logger.onclear.addListener(Log4js.bind(this.doClear, this));\r
+ \r
+ this.logger = logger;\r
+ }\r
+};\r
+\r
+/**\r
+ * Interface for Layouts.\r
+ * Use this Layout as "interface" for other Layouts. It is doing nothing.\r
+ *\r
+ * @constructor\r
+ * @author Stephan Strittmatter\r
+ */\r
+Log4js.Layout = function(){return;};\r
+Log4js.Layout.prototype = {\r
+ /** \r
+ * Implement this method to create your own layout format.\r
+ * @param {Log4js.LoggingEvent} loggingEvent loggingEvent to format\r
+ * @return formatted String\r
+ * @type String\r
+ */\r
+ format: function(loggingEvent) {\r
+ return "";\r
+ },\r
+ /** \r
+ * Returns the content type output by this layout. \r
+ * @return The base class returns "text/plain".\r
+ * @type String\r
+ */\r
+ getContentType: function() {\r
+ return "text/plain";\r
+ },\r
+ /** \r
+ * @return Returns the header for the layout format. The base class returns null.\r
+ * @type String\r
+ */\r
+ getHeader: function() {\r
+ return null;\r
+ },\r
+ /** \r
+ * @return Returns the footer for the layout format. The base class returns null.\r
+ * @type String\r
+ */\r
+ getFooter: function() {\r
+ return null;\r
+ },\r
+ \r
+ /**\r
+ * @return Separator between events\r
+ * @type String\r
+ */\r
+ getSeparator: function() {\r
+ return "";\r
+ }\r
+};\r
+\r
+/**\r
+ * Console Appender writes the logs to a console. If "inline" is\r
+ * set to "false" the console launches in another window otherwise\r
+ * the window is inline on the page and toggled on and off with "Alt-D".\r
+ * Note: At FireFox &gb; 2.0 the keystroke is little different now: "SHIFT+ALT+D".\r
+ *\r
+ * @constructor\r
+ * @extends Log4js.Appender\r
+ * @param {boolean} isInline boolean value that indicates whether the console be placed inline, default is to launch in new window\r
+ *\r
+ * @author Corey Johnson - original console code in Lumberjack (http://gleepglop.com/javascripts/logger/)\r
+ * @author Seth Chisamore - adapted for use as a log4js appender\r
+ */\r
+Log4js.ConsoleAppender = function(isInline) {\r
+ \r
+ /**\r
+ * @type Log4js.Layout\r
+ * @private\r
+ */\r
+ this.layout = new Log4js.PatternLayout(Log4js.PatternLayout.TTCC_CONVERSION_PATTERN);\r
+ /**\r
+ * @type boolean\r
+ * @private\r
+ */\r
+ this.inline = isInline;\r
+\r
+ /**\r
+ * @type String\r
+ * @private\r
+ */\r
+ this.accesskey = "d";\r
+ \r
+ /**\r
+ * @private\r
+ */\r
+ this.tagPattern = null;\r
+ \r
+ this.commandHistory = [];\r
+ this.commandIndex = 0;\r
+ \r
+ /**\r
+ * true if popup is blocked.\r
+ */\r
+ this.popupBlocker = false;\r
+ \r
+ /**\r
+ * current output div-element.\r
+ */\r
+ this.outputElement = null;\r
+ \r
+ this.docReference = null;\r
+ this.winReference = null; \r
+ \r
+ if(this.inline) {\r
+ Log4js.attachEvent(window, 'load', Log4js.bind(this.initialize, this));\r
+ }\r
+};\r
+\r
+Log4js.ConsoleAppender.prototype = Log4js.extend(new Log4js.Appender(), { \r
+\r
+ /**\r
+ * Set the access key to show/hide the inline console (default "e;d"e;)\r
+ * @param key access key to show/hide the inline console\r
+ */ \r
+ setAccessKey : function(key) {\r
+ this.accesskey = key;\r
+ },\r
+ \r
+ /**\r
+ * @private\r
+ */\r
+ initialize : function() {\r
+ \r
+ if(!this.inline) {\r
+ var doc = null; \r
+ var win = null;\r
+ window.top.consoleWindow = window.open("", this.logger.category, \r
+ "left=0,top=0,width=700,height=700,scrollbars=no,status=no,resizable=yes;toolbar=no");\r
+ window.top.consoleWindow.opener = self;\r
+ win = window.top.consoleWindow;\r
+ \r
+ if (!win) { \r
+ this.popupBlocker=true; \r
+ alert("Popup window manager blocking the Log4js popup window to bedisplayed.\n\n" \r
+ + "Please disabled this to properly see logged events."); \r
+ } else { \r
+\r
+ doc = win.document;\r
+ doc.open();\r
+ doc.write("<!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN ");\r
+ doc.write(" http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd>\n\n");\r
+ doc.write("<html><head><title>Log4js - " + this.logger.category + "</title>\n");\r
+ doc.write("</head><body style=\"background-color:darkgray\"></body>\n");\r
+ win.blur();\r
+ win.focus();\r
+ }\r
+ \r
+ this.docReference = doc;\r
+ this.winReference = win;\r
+ } else {\r
+ this.docReference = document;\r
+ this.winReference = window; \r
+ }\r
+ \r
+ this.outputCount = 0;\r
+ this.tagPattern = ".*";\r
+ \r
+ // I hate writing javascript in HTML... but what's a better alternative\r
+ this.logElement = this.docReference.createElement('div');\r
+ this.docReference.body.appendChild(this.logElement);\r
+ this.logElement.style.display = 'none';\r
+ \r
+ this.logElement.style.position = "absolute";\r
+ this.logElement.style.left = '0px';\r
+ this.logElement.style.width = '100%';\r
+ \r
+ this.logElement.style.textAlign = "left";\r
+ this.logElement.style.fontFamily = "lucida console";\r
+ this.logElement.style.fontSize = "100%";\r
+ this.logElement.style.backgroundColor = 'darkgray'; \r
+ this.logElement.style.opacity = 0.9;\r
+ this.logElement.style.zIndex = 2000; \r
+ \r
+ // Add toolbarElement\r
+ this.toolbarElement = this.docReference.createElement('div');\r
+ this.logElement.appendChild(this.toolbarElement); \r
+ this.toolbarElement.style.padding = "0 0 0 2px";\r
+ \r
+ // Add buttons \r
+ this.buttonsContainerElement = this.docReference.createElement('span');\r
+ this.toolbarElement.appendChild(this.buttonsContainerElement); \r
+ \r
+ if(this.inline) {\r
+ var closeButton = this.docReference.createElement('button');\r
+ closeButton.style.cssFloat = "right";\r
+ closeButton.style.styleFloat = "right"; // IE dom bug...doesn't understand cssFloat\r
+ closeButton.style.color = "black";\r
+ closeButton.innerHTML = "close";\r
+ closeButton.onclick = Log4js.bind(this.toggle, this);\r
+ this.buttonsContainerElement.appendChild(closeButton);\r
+ }\r
+ \r
+ var clearButton = this.docReference.createElement('button');\r
+ clearButton.style.cssFloat = "right";\r
+ clearButton.style.styleFloat = "right"; // IE dom bug...doesn't understand cssFloat\r
+ clearButton.style.color = "black";\r
+ clearButton.innerHTML = "clear";\r
+ clearButton.onclick = Log4js.bind(this.logger.clear, this.logger);\r
+ this.buttonsContainerElement.appendChild(clearButton);\r
+ \r
+\r
+ //Add CategoryName and Level Filter\r
+ this.tagFilterContainerElement = this.docReference.createElement('span');\r
+ this.toolbarElement.appendChild(this.tagFilterContainerElement);\r
+ this.tagFilterContainerElement.style.cssFloat = 'left';\r
+ \r
+ this.tagFilterContainerElement.appendChild(this.docReference.createTextNode("Log4js - " + this.logger.category));\r
+ this.tagFilterContainerElement.appendChild(this.docReference.createTextNode(" | Level Filter: "));\r
+ \r
+ this.tagFilterElement = this.docReference.createElement('input');\r
+ this.tagFilterContainerElement.appendChild(this.tagFilterElement);\r
+ this.tagFilterElement.style.width = '200px'; \r
+ this.tagFilterElement.value = this.tagPattern; \r
+ this.tagFilterElement.setAttribute('autocomplete', 'off'); // So Firefox doesn't flip out\r
+ \r
+ Log4js.attachEvent(this.tagFilterElement, 'keyup', Log4js.bind(this.updateTags, this));\r
+ Log4js.attachEvent(this.tagFilterElement, 'click', Log4js.bind( function() {this.tagFilterElement.select();}, this));\r
+ \r
+ // Add outputElement\r
+ this.outputElement = this.docReference.createElement('div');\r
+ this.logElement.appendChild(this.outputElement); \r
+ this.outputElement.style.overflow = "auto"; \r
+ this.outputElement.style.clear = "both";\r
+ this.outputElement.style.height = (this.inline) ? ("200px"):("650px");\r
+ this.outputElement.style.width = "100%";\r
+ this.outputElement.style.backgroundColor = 'black'; \r
+ \r
+ this.inputContainerElement = this.docReference.createElement('div');\r
+ this.inputContainerElement.style.width = "100%";\r
+ this.logElement.appendChild(this.inputContainerElement); \r
+ \r
+ this.inputElement = this.docReference.createElement('input');\r
+ this.inputContainerElement.appendChild(this.inputElement); \r
+ this.inputElement.style.width = '100%';\r
+ this.inputElement.style.borderWidth = '0px'; // Inputs with 100% width always seem to be too large (I HATE THEM) they only work if the border, margin and padding are 0\r
+ this.inputElement.style.margin = '0px';\r
+ this.inputElement.style.padding = '0px';\r
+ this.inputElement.value = 'Type command here'; \r
+ this.inputElement.setAttribute('autocomplete', 'off'); // So Firefox doesn't flip out\r
+ \r
+ Log4js.attachEvent(this.inputElement, 'keyup', Log4js.bind(this.handleInput, this));\r
+ Log4js.attachEvent(this.inputElement, 'click', Log4js.bind( function() {this.inputElement.select();}, this));\r
+ \r
+ if(this.inline){\r
+ window.setInterval(Log4js.bind(this.repositionWindow, this), 500);\r
+ this.repositionWindow(); \r
+ // Allow acess key link \r
+ var accessElement = this.docReference.createElement('button');\r
+ accessElement.style.position = "absolute";\r
+ accessElement.style.top = "-100px";\r
+ accessElement.accessKey = this.accesskey;\r
+ accessElement.onclick = Log4js.bind(this.toggle, this);\r
+ this.docReference.body.appendChild(accessElement);\r
+ } else {\r
+ this.show();\r
+ }\r
+ },\r
+ /**\r
+ * shows/hide an element\r
+ * @private\r
+ * @return true if shown\r
+ */\r
+ toggle : function() {\r
+ if (this.logElement.style.display == 'none') {\r
+ this.show();\r
+ return true;\r
+ } else {\r
+ this.hide();\r
+ return false;\r
+ }\r
+ }, \r
+ /**\r
+ * @private\r
+ */\r
+ show : function() {\r
+ this.logElement.style.display = '';\r
+ this.outputElement.scrollTop = this.outputElement.scrollHeight; // Scroll to bottom when toggled\r
+ this.inputElement.select();\r
+ }, \r
+ /**\r
+ * @private\r
+ */ \r
+ hide : function() {\r
+ this.logElement.style.display = 'none';\r
+ }, \r
+ /**\r
+ * @private\r
+ * @param message\r
+ * @style\r
+ */ \r
+ output : function(message, style) {\r
+\r
+ // If we are at the bottom of the window, then keep scrolling with the output \r
+ var shouldScroll = (this.outputElement.scrollTop + (2 * this.outputElement.clientHeight)) >= this.outputElement.scrollHeight;\r
+ \r
+ this.outputCount++;\r
+ style = (style ? style += ';' : ''); \r
+ style += 'padding:1px;margin:0 0 5px 0'; \r
+ \r
+ if (this.outputCount % 2 === 0) {\r
+ style += ";background-color:#101010";\r
+ }\r
+ \r
+ message = message || "undefined";\r
+ message = message.toString();\r
+ \r
+ this.outputElement.innerHTML += "<pre style='" + style + "'>" + message + "</pre>";\r
+ \r
+ if (shouldScroll) { \r
+ this.outputElement.scrollTop = this.outputElement.scrollHeight;\r
+ }\r
+ },\r
+ \r
+ /**\r
+ * @private\r
+ */\r
+ updateTags : function() {\r
+ \r
+ var pattern = this.tagFilterElement.value;\r
+ \r
+ if (this.tagPattern == pattern) {\r
+ return;\r
+ }\r
+ \r
+ try {\r
+ new RegExp(pattern);\r
+ } catch (e) {\r
+ return;\r
+ }\r
+ \r
+ this.tagPattern = pattern;\r
+\r
+ this.outputElement.innerHTML = "";\r
+ \r
+ // Go through each log entry again\r
+ this.outputCount = 0;\r
+ for (var i = 0; i < this.logger.loggingEvents.length; i++) {\r
+ this.doAppend(this.logger.loggingEvents[i]);\r
+ } \r
+ },\r
+\r
+ /**\r
+ * @private\r
+ */ \r
+ repositionWindow : function() {\r
+ var offset = window.pageYOffset || this.docReference.documentElement.scrollTop || this.docReference.body.scrollTop;\r
+ var pageHeight = self.innerHeight || this.docReference.documentElement.clientHeight || this.docReference.body.clientHeight;\r
+ this.logElement.style.top = (offset + pageHeight - this.logElement.offsetHeight) + "px";\r
+ },\r
+\r
+ /**\r
+ * @param loggingEvent event to be logged\r
+ * @see Log4js.Appender#doAppend\r
+ */\r
+ doAppend : function(loggingEvent) {\r
+ \r
+ if(this.popupBlocker) {\r
+ //popup blocked, we return in this case\r
+ return;\r
+ }\r
+ \r
+ if ((!this.inline) && (!this.winReference || this.winReference.closed)) {\r
+ this.initialize();\r
+ }\r
+ \r
+ if (this.tagPattern !== null && \r
+ loggingEvent.level.toString().search(new RegExp(this.tagPattern, 'igm')) == -1) {\r
+ return;\r
+ }\r
+ \r
+ var style = '';\r
+ \r
+ if (loggingEvent.level.toString().search(/ERROR/) != -1) { \r
+ style += 'color:red';\r
+ } else if (loggingEvent.level.toString().search(/FATAL/) != -1) { \r
+ style += 'color:red';\r
+ } else if (loggingEvent.level.toString().search(/WARN/) != -1) { \r
+ style += 'color:orange';\r
+ } else if (loggingEvent.level.toString().search(/DEBUG/) != -1) {\r
+ style += 'color:green';\r
+ } else if (loggingEvent.level.toString().search(/INFO/) != -1) {\r
+ style += 'color:white';\r
+ } else {\r
+ style += 'color:yellow';\r
+ }\r
+ \r
+ this.output(this.layout.format(loggingEvent), style); \r
+ },\r
+\r
+ /**\r
+ * @see Log4js.Appender#doClear\r
+ */\r
+ doClear : function() {\r
+ this.outputElement.innerHTML = "";\r
+ },\r
+ /**\r
+ * @private\r
+ * @param e\r
+ */\r
+ handleInput : function(e) {\r
+ if (e.keyCode == 13 ) { \r
+ var command = this.inputElement.value;\r
+ \r
+ switch(command) {\r
+ case "clear":\r
+ this.logger.clear(); \r
+ break;\r
+ \r
+ default: \r
+ var consoleOutput = "";\r
+ \r
+ try {\r
+ consoleOutput = eval(this.inputElement.value);\r
+ } catch (e) { \r
+ this.logger.error("Problem parsing input <" + command + ">" + e.message);\r
+ break;\r
+ }\r
+ \r
+ this.logger.trace(consoleOutput);\r
+ break;\r
+ } \r
+ \r
+ if (this.inputElement.value !== "" && this.inputElement.value !== this.commandHistory[0]) {\r
+ this.commandHistory.unshift(this.inputElement.value);\r
+ }\r
+ \r
+ this.commandIndex = 0;\r
+ this.inputElement.value = ""; \r
+ } else if (e.keyCode == 38 && this.commandHistory.length > 0) {\r
+ this.inputElement.value = this.commandHistory[this.commandIndex];\r
+\r
+ if (this.commandIndex < this.commandHistory.length - 1) {\r
+ this.commandIndex += 1;\r
+ }\r
+ } else if (e.keyCode == 40 && this.commandHistory.length > 0) {\r
+ if (this.commandIndex > 0) { \r
+ this.commandIndex -= 1;\r
+ } \r
+\r
+ this.inputElement.value = this.commandHistory[this.commandIndex];\r
+ } else {\r
+ this.commandIndex = 0;\r
+ }\r
+ },\r
+ \r
+ /** \r
+ * toString\r
+ */\r
+ toString: function() {\r
+ return "Log4js.ConsoleAppender[inline=" + this.inline + "]"; \r
+ }\r
+}); \r
+\r
+/**\r
+ * Metatag Appender writing the logs to meta tags\r
+ *\r
+ * @extends Log4js.Appender\r
+ * @constructor\r
+ * @param logger log4js instance this appender is attached to\r
+ * @author Stephan Strittmatter\r
+ */\r
+Log4js.MetatagAppender = function() {\r
+ this.currentLine = 0;\r
+};\r
+Log4js.MetatagAppender.prototype = Log4js.extend(new Log4js.Appender(), { \r
+ /**\r
+ * @param loggingEvent event to be logged\r
+ * @see Log4js.Appender#doAppend\r
+ */\r
+ doAppend: function(loggingEvent) {\r
+ var now = new Date();\r
+ var lines = loggingEvent.message.split("\n");\r
+ var headTag = document.getElementsByTagName("head")[0];\r
+\r
+ for (var i = 1; i <= lines.length; i++) {\r
+ var value = lines[i - 1];\r
+ if (i == 1) {\r
+ value = loggingEvent.level.toString() + ": " + value;\r
+ } else {\r
+ value = "> " + value;\r
+ }\r
+\r
+ var metaTag = document.createElement("meta");\r
+ metaTag.setAttribute("name", "X-log4js:" + this.currentLine);\r
+ metaTag.setAttribute("content", value);\r
+ headTag.appendChild(metaTag);\r
+ this.currentLine += 1;\r
+ }\r
+ },\r
+\r
+ /** \r
+ * toString\r
+ */\r
+ toString: function() {\r
+ return "Log4js.MetatagAppender"; \r
+ }\r
+});\r
+\r
+/**\r
+ * AJAX Appender sending {@link Log4js.LoggingEvent}s asynchron via \r
+ * <code>XMLHttpRequest</code> to server.<br />\r
+ * The {@link Log4js.LoggingEvent} is POSTed as response content and is \r
+ * formatted by the accociated layout. Default layout is {@link Log4js.XMLLayout}. \r
+ * The <code>threshold</code> defines when the logs \r
+ * should be send to the server. By default every event is sent on its\r
+ * own (threshold=1). If it is set to 10, then the events are send in groups of\r
+ * 10 events.\r
+ *\r
+ * @extends Log4js.Appender \r
+ * @constructor\r
+ * @param {Log4js.Logger} logger log4js instance this appender is attached to\r
+ * @param {String} loggingUrl url where appender will post log messages to\r
+ * @author Stephan Strittmatter\r
+ */\r
+Log4js.AjaxAppender = function(loggingUrl) {\r
+\r
+ /**\r
+ * is still esnding data to server\r
+ * @type boolean\r
+ * @private\r
+ */\r
+ this.isInProgress = false;\r
+ \r
+ /**\r
+ * @type String\r
+ * @private\r
+ */\r
+ this.loggingUrl = loggingUrl || "logging.log4js";\r
+ \r
+ /**\r
+ * @type Integer\r
+ * @private\r
+ */\r
+ this.threshold = 1;\r
+ \r
+ /**\r
+ * timeout when request is aborted.\r
+ * @private\r
+ */\r
+ this.timeout = 2000;\r
+ \r
+ /**\r
+ * List of LoggingEvents which should be send after threshold is reached.\r
+ * @type Map\r
+ * @private\r
+ */\r
+ this.loggingEventMap = new Log4js.FifoBuffer();\r
+\r
+ /**\r
+ * @type Log4js.Layout\r
+ * @private\r
+ */\r
+ this.layout = new Log4js.XMLLayout();\r
+ /**\r
+ * @type XMLHttpRequest\r
+ * @private\r
+ */ \r
+ this.httpRequest = null;\r
+};\r
+\r
+Log4js.AjaxAppender.prototype = Log4js.extend(new Log4js.Appender(), { \r
+ /**\r
+ * sends the logs to the server\r
+ * @param loggingEvent event to be logged\r
+ * @see Log4js.Appender#doAppend\r
+ */\r
+ doAppend: function(loggingEvent) {\r
+ log4jsLogger.trace("> AjaxAppender.append");\r
+ \r
+ if (this.loggingEventMap.length() <= this.threshold || this.isInProgress === true) {\r
+ this.loggingEventMap.push(loggingEvent);\r
+ }\r
+ \r
+ if(this.loggingEventMap.length() >= this.threshold && this.isInProgress === false) {\r
+ //if threshold is reached send the events and reset current threshold\r
+ this.send();\r
+ }\r
+ \r
+ log4jsLogger.trace("< AjaxAppender.append");\r
+ },\r
+ \r
+ /** @see Appender#doClear */\r
+ doClear: function() {\r
+ log4jsLogger.trace("> AjaxAppender.doClear" );\r
+ if(this.loggingEventMap.length() > 0) {\r
+ this.send();\r
+ }\r
+ log4jsLogger.trace("< AjaxAppender.doClear" );\r
+ },\r
+ \r
+ /**\r
+ * Set the threshold when logs have to be send. Default threshold is 1.\r
+ * @praram {int} threshold new threshold\r
+ */\r
+ setThreshold: function(threshold) {\r
+ log4jsLogger.trace("> AjaxAppender.setThreshold: " + threshold );\r
+ this.threshold = threshold;\r
+ log4jsLogger.trace("< AjaxAppender.setThreshold" );\r
+ },\r
+ \r
+ /**\r
+ * Set the timeout in milli seconds until sending request is aborted.\r
+ * Default is 2000 ms.\r
+ * @param {int} milliseconds the new timeout\r
+ */\r
+ setTimeout: function(milliseconds) {\r
+ this.timeout = milliseconds;\r
+ },\r
+ \r
+ /**\r
+ * send the request.\r
+ */\r
+ send: function() {\r
+ if(this.loggingEventMap.length() >0) {\r
+ \r
+ log4jsLogger.trace("> AjaxAppender.send");\r
+ \r
+ \r
+ this.isInProgress = true;\r
+ var a = [];\r
+ \r
+ for(var i = 0; i < this.loggingEventMap.length() && i < this.threshold; i++) {\r
+ a.push(this.layout.format(this.loggingEventMap.pull()));\r
+ } \r
+ \r
+ var content = this.layout.getHeader(); \r
+ content += a.join(this.layout.getSeparator());\r
+ content += this.layout.getFooter();\r
+ \r
+ var appender = this;\r
+ if(this.httpRequest === null){\r
+ this.httpRequest = this.getXmlHttpRequest();\r
+ }\r
+ this.httpRequest.onreadystatechange = function() {\r
+ appender.onReadyStateChanged.call(appender);\r
+ };\r
+ \r
+ this.httpRequest.open("POST", this.loggingUrl, true);\r
+ // set the request headers.\r
+ //this.httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");\r
+ this.httpRequest.setRequestHeader("Content-type", this.layout.getContentType());\r
+ //REFERER will be the top-level\r
+ // URI which may differ from the location of the error if\r
+ // it occurs in an included .js file\r
+ this.httpRequest.setRequestHeader("REFERER", location.href);\r
+ this.httpRequest.setRequestHeader("Content-length", content.length);\r
+ this.httpRequest.setRequestHeader("Connection", "close");\r
+ this.httpRequest.send( content );\r
+ \r
+ appender = this;\r
+ \r
+ try {\r
+ window.setTimeout(function(){\r
+ log4jsLogger.trace("> AjaxAppender.timeout");\r
+ appender.httpRequest.onreadystatechange = function(){return;};\r
+ appender.httpRequest.abort();\r
+ //this.httpRequest = null;\r
+ appender.isInProgress = false;\r
+ \r
+ if(appender.loggingEventMap.length() > 0) {\r
+ appender.send();\r
+ }\r
+ log4jsLogger.trace("< AjaxAppender.timeout");\r
+ }, this.timeout);\r
+ } catch (e) {\r
+ log4jsLogger.fatal(e);\r
+ }\r
+ log4jsLogger.trace("> AjaxAppender.send");\r
+ }\r
+ },\r
+ \r
+ /**\r
+ * @private\r
+ */\r
+ onReadyStateChanged: function() {\r
+ log4jsLogger.trace("> AjaxAppender.onReadyStateChanged");\r
+ var req = this.httpRequest;\r
+ if (this.httpRequest.readyState != 4) { \r
+ log4jsLogger.trace("< AjaxAppender.onReadyStateChanged: readyState " + req.readyState + " != 4");\r
+ return; \r
+ }\r
+ \r
+ var success = ((typeof req.status === "undefined") || req.status === 0 || (req.status >= 200 && req.status < 300));\r
+ \r
+ if (success) {\r
+ log4jsLogger.trace(" AjaxAppender.onReadyStateChanged: success");\r
+\r
+ //ready sending data\r
+ this.isInProgress = false;\r
+\r
+ } else {\r
+ var msg = " AjaxAppender.onReadyStateChanged: XMLHttpRequest request to URL " + this.loggingUrl + " returned status code " + this.httpRequest.status;\r
+ log4jsLogger.error(msg);\r
+ }\r
+ \r
+ log4jsLogger.trace("< AjaxAppender.onReadyStateChanged: readyState == 4"); \r
+ },\r
+ /**\r
+ * Get the XMLHttpRequest object independent of browser.\r
+ * @private\r
+ */\r
+ getXmlHttpRequest: function() {\r
+ log4jsLogger.trace("> AjaxAppender.getXmlHttpRequest");\r
+ \r
+ var httpRequest = false;\r
+\r
+ try { \r
+ if (window.XMLHttpRequest) { // Mozilla, Safari, IE7...\r
+ httpRequest = new XMLHttpRequest();\r
+ if (httpRequest.overrideMimeType) {\r
+ httpRequest.overrideMimeType(this.layout.getContentType());\r
+ }\r
+ } else if (window.ActiveXObject) { // IE\r
+ try {\r
+ httpRequest = new ActiveXObject("Msxml2.XMLHTTP");\r
+ } catch (e) {\r
+ httpRequest = new ActiveXObject("Microsoft.XMLHTTP");\r
+ }\r
+ }\r
+ } catch (e) {\r
+ httpRequest = false;\r
+ }\r
+ \r
+ if (!httpRequest) {\r
+ log4jsLogger.fatal("Unfortunatelly your browser does not support AjaxAppender for log4js!");\r
+ }\r
+ \r
+ log4jsLogger.trace("< AjaxAppender.getXmlHttpRequest");\r
+ return httpRequest;\r
+ },\r
+ \r
+ /** \r
+ * toString\r
+ */\r
+ toString: function() {\r
+ return "Log4js.AjaxAppender[loggingUrl=" + this.loggingUrl + ", threshold=" + this.threshold + "]"; \r
+ }\r
+});\r
+\r
+/**\r
+ * File Appender writing the logs to a text file.\r
+ * PLEASE NOTE - Only works in IE and Mozilla \r
+ * use ActiveX to write file on IE\r
+ * use XPCom components to write file on Mozilla\r
+ * \r
+ * @extends Log4js.Appender \r
+ * @constructor\r
+ * @param logger log4js instance this appender is attached to\r
+ * @param file file log messages will be written to\r
+ * @author Seth Chisamore\r
+ * @author Nicolas Justin njustin@idealx.com\r
+ * @author Gregory Kokanosky gkokanosky@idealx.com\r
+ */\r
+Log4js.FileAppender = function(file) {\r
+\r
+ this.layout = new Log4js.SimpleLayout();\r
+ this.isIE = 'undefined';\r
+ \r
+ this.file = file || "log4js.log"; \r
+ \r
+ try{\r
+ this.fso = new ActiveXObject("Scripting.FileSystemObject");\r
+ this.isIE = true;\r
+ } catch(e){\r
+ try {\r
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\r
+ this.fso = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);\r
+ this.isIE = false; //mozilla & co\r
+ } catch (e) {\r
+ log4jsLogger.error(e);\r
+ }\r
+ }\r
+};\r
+\r
+Log4js.FileAppender.prototype = Log4js.extend(new Log4js.Appender(), { \r
+ /**\r
+ * @param loggingEvent event to be logged\r
+ * @see Log4js.Appender#doAppend\r
+ */\r
+ doAppend: function(loggingEvent) {\r
+ try {\r
+ var fileHandle = null;\r
+ \r
+ if( this.isIE === 'undefined') {\r
+ log4jsLogger.error("Unsupported ")\r
+ }\r
+ else if( this.isIE ){\r
+ // try opening existing file, create if needed\r
+ fileHandle = this.fso.OpenTextFile(this.file, 8, true); \r
+ // write out our data\r
+ fileHandle.WriteLine(this.layout.format(loggingEvent));\r
+ fileHandle.close(); \r
+ } else {\r
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\r
+ this.fso.initWithPath(this.file);\r
+ if(!this.fso.exists()) {\r
+ //create file if needed\r
+ this.fso.create(0x00, 0600);\r
+ }\r
+ \r
+ fileHandle = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);\r
+ fileHandle.init( this.fso, 0x04 | 0x08 | 0x10, 064, 0);\r
+ var line = this.layout.format(loggingEvent);\r
+ fileHandle.write(line, line.length); //write data\r
+ fileHandle.close();\r
+ }\r
+ } catch (e) {\r
+ log4jsLogger.error(e);\r
+ }\r
+ },\r
+ /*\r
+ * @see Log4js.Appender#doClear\r
+ */\r
+ doClear: function() {\r
+ try {\r
+ if( this.isIE ){\r
+ var fileHandle = this.fso.GetFile(this.file);\r
+ fileHandle.Delete();\r
+ } else {\r
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\r
+ this.fso.initWithPath(this.file);\r
+ if(this.fso.exists()) {\r
+ this.fso.remove(false);\r
+ }\r
+ }\r
+ } catch (e) {\r
+ log4jsLogger.error(e);\r
+ }\r
+ },\r
+ \r
+ /** \r
+ * toString\r
+ */\r
+ toString: function() {\r
+ return "Log4js.FileAppender[file=" + this.file + "]"; \r
+ }\r
+});\r
+\r
+/**\r
+ * Windows Event Appender writes the logs to the Windows Event log.\r
+ * PLEASE NOTE - Only works in IE..uses ActiveX to write to Windows Event log\r
+ *\r
+ * @extends Log4js.Appender \r
+ * @constructor\r
+ * @param logger log4js instance this appender is attached to\r
+ * @author Seth Chisamore\r
+ */\r
+Log4js.WindowsEventAppender = function() {\r
+ \r
+ this.layout = new Log4js.SimpleLayout();\r
+ \r
+ try {\r
+ this.shell = new ActiveXObject("WScript.Shell");\r
+ } catch(e) {\r
+ log4jsLogger.error(e);\r
+ }\r
+};\r
+\r
+Log4js.WindowsEventAppender.prototype = Log4js.extend(new Log4js.Appender(), { \r
+ /**\r
+ * @param loggingEvent event to be logged\r
+ * @see Log4js.Appender#doAppend\r
+ */\r
+ doAppend: function(loggingEvent) {\r
+ var winLevel = 4;\r
+ \r
+ // Map log level to windows event log level.\r
+ // Windows events: - SUCCESS: 0, ERROR: 1, WARNING: 2, INFORMATION: 4, AUDIT_SUCCESS: 8, AUDIT_FAILURE: 16\r
+ switch (loggingEvent.level) { \r
+ case Log4js.Level.FATAL:\r
+ winLevel = 1;\r
+ break;\r
+ case Log4js.Level.ERROR:\r
+ winLevel = 1;\r
+ break;\r
+ case Log4js.Level.WARN:\r
+ winLevel = 2;\r
+ break;\r
+ default:\r
+ winLevel = 4;\r
+ break;\r
+ }\r
+ \r
+ try {\r
+ this.shell.LogEvent(winLevel, this.level.format(loggingEvent));\r
+ } catch(e) {\r
+ log4jsLogger.error(e);\r
+ }\r
+ },\r
+ \r
+ /** \r
+ * toString\r
+ */\r
+ toString: function() {\r
+ return "Log4js.WindowsEventAppender"; \r
+ } \r
+});\r
+\r
+/**\r
+ * JS Alert Appender writes the logs to the JavaScript alert dialog box\r
+ * @constructor\r
+ * @extends Log4js.Appender \r
+ * @param logger log4js instance this appender is attached to\r
+ * @author Sébastien LECACHEUR\r
+ */\r
+Log4js.JSAlertAppender = function() {\r
+\r
+ this.layout = new Log4js.SimpleLayout();\r
+};\r
+\r
+Log4js.JSAlertAppender.prototype = Log4js.extend(new Log4js.Appender(), { \r
+ /** \r
+ * @see Log4js.Appender#doAppend\r
+ */\r
+ doAppend: function(loggingEvent) {\r
+ alert(this.layout.getHeader() + this.layout.format(loggingEvent) + this.layout.getFooter());\r
+ },\r
+ \r
+ /** \r
+ * toString\r
+ */\r
+ toString: function() {\r
+ return "Log4js.JSAlertAppender"; \r
+ } \r
+});\r
+\r
+/**\r
+ * Appender writes the logs to the JavaScript console of Mozilla browser\r
+ * More infos: http://kb.mozillazine.org/index.php?title=JavaScript_Console&redirect=no\r
+ * PLEASE NOTE - Only works in Mozilla browser\r
+ * @constructor\r
+ * @extends Log4js.Appender \r
+ * @param logger log4js instance this appender is attached to\r
+ * @author Stephan Strittmatter\r
+ */\r
+Log4js.MozillaJSConsoleAppender = function() {\r
+ this.layout = new Log4js.SimpleLayout();\r
+ try {\r
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\r
+ this.jsConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);\r
+ this.scriptError = Components.classes["@mozilla.org/scripterror;1"].createInstance(Components.interfaces.nsIScriptError);\r
+ } catch (e) {\r
+ log4jsLogger.error(e);\r
+ }\r
+};\r
+\r
+Log4js.MozillaJSConsoleAppender.prototype = Log4js.extend(new Log4js.Appender(), { \r
+ /** \r
+ * @see Log4js.Appender#doAppend\r
+ */\r
+ doAppend: function(loggingEvent) {\r
+ try {\r
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\r
+ this.scriptError.init(this.layout.format(loggingEvent), null, null, null, null, this.getFlag(loggingEvent), loggingEvent.categoryName);\r
+ this.jsConsole.logMessage(this.scriptError);\r
+ } catch (e) {\r
+ log4jsLogger.error(e);\r
+ }\r
+ },\r
+ \r
+ /** \r
+ * toString\r
+ */\r
+ toString: function() {\r
+ return "Log4js.MozillaJSConsoleAppender"; \r
+ },\r
+ \r
+ /**\r
+ * Map Log4js.Level to jsConsole Flags:\r
+ * <ul>\r
+ * <li>nsIScriptError.errorFlag (0) = Level.Error</li>\r
+ * <li>nsIScriptError.warningFlag (1)= Log4js.Level.WARN</li>\r
+ * <li>nsIScriptError.exceptionFlag (2) = Log4js.Level.FATAL</li>\r
+ * <li>nsIScriptError.strictFlag (4) = unused</li>\r
+ * </ul>\r
+ * @private\r
+ */ \r
+ getFlag: function(loggingEvent)\r
+ {\r
+ var retval;\r
+ switch (loggingEvent.level) { \r
+ case Log4js.Level.FATAL:\r
+ retval = 2;//nsIScriptError.exceptionFlag = 2\r
+ break;\r
+ case Log4js.Level.ERROR:\r
+ retval = 0;//nsIScriptError.errorFlag\r
+ break;\r
+ case Log4js.Level.WARN:\r
+ retval = 1;//nsIScriptError.warningFlag = 1\r
+ break;\r
+ default:\r
+ retval = 1;//nsIScriptError.warningFlag = 1\r
+ break;\r
+ }\r
+ \r
+ return retval; \r
+ }\r
+});\r
+\r
+/**\r
+ * Appender writes the logs to the JavaScript console of Opera browser\r
+ * PLEASE NOTE - Only works in Opera browser\r
+ * @constructor\r
+ * @extends Log4js.Appender \r
+ * @param logger log4js instance this appender is attached to\r
+ * @author Stephan Strittmatter\r
+ */\r
+Log4js.OperaJSConsoleAppender = function() {\r
+ this.layout = new Log4js.SimpleLayout();\r
+};\r
+\r
+Log4js.OperaJSConsoleAppender.prototype = Log4js.extend(new Log4js.Appender(), { \r
+ /** \r
+ * @see Log4js.Appender#doAppend\r
+ */\r
+ doAppend: function(loggingEvent) {\r
+ opera.postError(this.layout.format(loggingEvent));\r
+ },\r
+ \r
+ /** \r
+ * toString\r
+ */\r
+ toString: function() {\r
+ return "Log4js.OperaJSConsoleAppender"; \r
+ }\r
+});\r
+\r
+/**\r
+ * Appender writes the logs to the JavaScript console of Safari browser\r
+ * PLEASE NOTE - Only works in Safari browser\r
+ * @constructor\r
+ * @extends Log4js.Appender \r
+ * @param logger log4js instance this appender is attached to\r
+ * @author Stephan Strittmatter\r
+ */\r
+Log4js.SafariJSConsoleAppender = function() {\r
+ this.layout = new Log4js.SimpleLayout();\r
+};\r
+\r
+Log4js.SafariJSConsoleAppender.prototype = Log4js.extend(new Log4js.Appender(), { \r
+ /** \r
+ * @see Log4js.Appender#doAppend\r
+ */\r
+ doAppend: function(loggingEvent) {\r
+ window.console.log(this.layout.format(loggingEvent));\r
+ },\r
+ \r
+ /** \r
+ * toString\r
+ */\r
+ toString: function() {\r
+ return "Log4js.SafariJSConsoleAppender"; \r
+ }\r
+});\r
+\r
+/**\r
+ * JavaScript Console Appender which is browser independent.\r
+ * It checks internally for the current browser and adds delegate to\r
+ * specific JavaScript Console Appender of the browser.\r
+ * \r
+ * @author Stephan Strittmatter\r
+ * @since 1.0\r
+ */\r
+Log4js.BrowserConsoleAppender = function() {\r
+ /**\r
+ * Delegate for browser specific implementation\r
+ * @type Log4js.Appender\r
+ * @private\r
+ */\r
+ this.consoleDelegate = null;\r
+ \r
+ if (window.console) {\r
+ this.consoleDelegate = new Log4js.SafariJSConsoleAppender(); \r
+ }\r
+ else if (window.opera) {\r
+ this.consoleDelegate = new Log4js.OperaJSConsoleAppender(); \r
+ }\r
+ else if(netscape) {\r
+ this.consoleDelegate = new Log4js.MozJSConsoleAppender(); \r
+ }\r
+ else {\r
+ //@todo\r
+ log4jsLogger.error("Unsupported Browser");\r
+ }\r
+};\r
+\r
+Log4js.BrowserConsoleAppender.prototype = Log4js.extend(new Log4js.Appender(), { \r
+ /** \r
+ * @see Log4js.Appender#doAppend\r
+ */\r
+ doAppend: function(loggingEvent) {\r
+ this.consoleDelegate.doAppend(loggingEvent);\r
+ },\r
+ /** \r
+ * @see Log4js.Appender#doClear\r
+ */\r
+ doClear: function() {\r
+ this.consoleDelegate.doClear();\r
+ },\r
+ /**\r
+ * @see Log4js.Appender#setLayout\r
+ */\r
+ setLayout: function(layout){\r
+ this.consoleDelegate.setLayout(layout);\r
+ },\r
+ \r
+ /** \r
+ * toString\r
+ */\r
+ toString: function() {\r
+ return "Log4js.BrowserConsoleAppender: " + this.consoleDelegate.toString(); \r
+ }\r
+});\r
+\r
+/**\r
+ * SimpleLayout consists of the level of the log statement, followed by " - " \r
+ * and then the log message itself. For example,\r
+ * <code>DEBUG - Hello world</code>\r
+ *\r
+ * @constructor\r
+ * @extends Log4js.Layout\r
+ * @extends Layout\r
+ * @author Stephan Strittmatter\r
+ */\r
+Log4js.SimpleLayout = function() {\r
+ this.LINE_SEP = "\n";\r
+ this.LINE_SEP_LEN = 1;\r
+};\r
+\r
+Log4js.SimpleLayout.prototype = Log4js.extend(new Log4js.Layout(), {\r
+ /** \r
+ * Implement this method to create your own layout format.\r
+ * @param {Log4js.LoggingEvent} loggingEvent loggingEvent to format\r
+ * @return formatted String\r
+ * @type String\r
+ */\r
+ format: function(loggingEvent) {\r
+ return loggingEvent.level.toString() + " - " + loggingEvent.message + this.LINE_SEP;\r
+ },\r
+ /** \r
+ * Returns the content type output by this layout. \r
+ * @return The base class returns "text/plain".\r
+ * @type String\r
+ */\r
+ getContentType: function() {\r
+ return "text/plain";\r
+ },\r
+ /** \r
+ * @return Returns the header for the layout format. The base class returns null.\r
+ * @type String\r
+ */\r
+ getHeader: function() {\r
+ return "";\r
+ },\r
+ /** \r
+ * @return Returns the footer for the layout format. The base class returns null.\r
+ * @type String\r
+ */\r
+ getFooter: function() {\r
+ return "";\r
+ }\r
+});\r
+ \r
+/**\r
+ * BasicLayout is a simple layout for storing the loggs. The loggs are stored\r
+ * in following format:\r
+ * <pre>\r
+ * categoryName~startTime [logLevel] message\n\r
+ * </pre>\r
+ *\r
+ * @constructor\r
+ * @extends Log4js.Layout\r
+ * @author Stephan Strittmatter\r
+ */\r
+Log4js.BasicLayout = function() {\r
+ this.LINE_SEP = "\n";\r
+};\r
+\r
+Log4js.BasicLayout.prototype = Log4js.extend(new Log4js.Layout(), {\r
+ /** \r
+ * Implement this method to create your own layout format.\r
+ * @param {Log4js.LoggingEvent} loggingEvent loggingEvent to format\r
+ * @return formatted String\r
+ * @type String\r
+ */\r
+ format: function(loggingEvent) {\r
+ return loggingEvent.categoryName + "~" + loggingEvent.startTime.toLocaleString() + " [" + loggingEvent.level.toString() + "] " + loggingEvent.message + this.LINE_SEP;\r
+ },\r
+ /** \r
+ * Returns the content type output by this layout. \r
+ * @return The base class returns "text/plain".\r
+ * @type String\r
+ */\r
+ getContentType: function() {\r
+ return "text/plain";\r
+ },\r
+ /** \r
+ * @return Returns the header for the layout format. The base class returns null.\r
+ * @type String\r
+ */\r
+ getHeader: function() {\r
+ return "";\r
+ },\r
+ /** \r
+ * @return Returns the footer for the layout format. The base class returns null.\r
+ * @type String\r
+ */\r
+ getFooter: function() {\r
+ return "";\r
+ }\r
+});\r
+\r
+/**\r
+ * HtmlLayout write the logs in Html format.\r
+ *\r
+ * @constructor\r
+ * @extends Log4js.Layout\r
+ * @author Stephan Strittmatter\r
+ */\r
+Log4js.HtmlLayout = function() {return;};\r
+\r
+Log4js.HtmlLayout.prototype = Log4js.extend(new Log4js.Layout(), {\r
+ /** \r
+ * Implement this method to create your own layout format.\r
+ * @param {Log4js.LoggingEvent} loggingEvent loggingEvent to format\r
+ * @return formatted String\r
+ * @type String\r
+ */\r
+ format: function(loggingEvent) {\r
+ return "<div style=\"" + this.getStyle(loggingEvent) + "\">" + loggingEvent.getFormattedTimestamp() + " - " + loggingEvent.level.toString() + " - " + loggingEvent.message + "</div>\n";\r
+ },\r
+ /** \r
+ * Returns the content type output by this layout. \r
+ * @return The base class returns "text/html".\r
+ * @type String\r
+ */\r
+ getContentType: function() {\r
+ return "text/html";\r
+ },\r
+ /** \r
+ * @return Returns the header for the layout format. The base class returns null.\r
+ * @type String\r
+ */\r
+ getHeader: function() {\r
+ return "<html><head><title>log4js</head><body>";\r
+ },\r
+ /** \r
+ * @return Returns the footer for the layout format. The base class returns null.\r
+ * @type String\r
+ */\r
+ getFooter: function() {\r
+ return "</body></html>";\r
+ },\r
+ \r
+ getStyle: function(loggingEvent)\r
+ {\r
+ var style;\r
+ if (loggingEvent.level.toString().search(/ERROR/) != -1) { \r
+ style = 'color:red';\r
+ } else if (loggingEvent.level.toString().search(/FATAL/) != -1) { \r
+ style = 'color:red';\r
+ } else if (loggingEvent.level.toString().search(/WARN/) != -1) { \r
+ style = 'color:orange';\r
+ } else if (loggingEvent.level.toString().search(/DEBUG/) != -1) {\r
+ style = 'color:green';\r
+ } else if (loggingEvent.level.toString().search(/INFO/) != -1) {\r
+ style = 'color:white';\r
+ } else {\r
+ style = 'color:yellow';\r
+ } \r
+ return style;\r
+ }\r
+});\r
+\r
+/**\r
+ * XMLLayout write the logs in XML format.\r
+ * Layout is simmilar to log4j's XMLLayout:\r
+ * <pre>\r
+ * <log4js:event category="category" level="Level" client="Client" referer="ref" timestam="Date">\r
+ * <log4js:message>Logged message</log4js:message>\r
+ * </log4js:event>\r
+ * </pre>\r
+ * @constructor\r
+ * @extends Layout\r
+ * @author Stephan Strittmatter\r
+ */\r
+Log4js.XMLLayout = function(){return;};\r
+Log4js.XMLLayout.prototype = Log4js.extend(new Log4js.Layout(), {\r
+ /** \r
+ * Implement this method to create your own layout format.\r
+ * @param {Log4js.LoggingEvent} loggingEvent loggingEvent to format\r
+ * @return formatted String\r
+ * @type String\r
+ */\r
+ format: function(loggingEvent) {\r
+ var useragent = "unknown";\r
+ try {\r
+ useragent = navigator.userAgent;\r
+ } catch(e){\r
+ useragent = "unknown";\r
+ }\r
+ \r
+ var referer = "unknown";\r
+ try {\r
+ referer = location.href;\r
+ } catch(e){\r
+ referer = "unknown";\r
+ }\r
+ \r
+ var content = "<log4js:event logger=\"";\r
+ content += loggingEvent.categoryName + "\" level=\"";\r
+ content += loggingEvent.level.toString() + "\" useragent=\"";\r
+ content += useragent + "\" referer=\"";\r
+ content += referer.replace(/&/g, "&") + "\" timestamp=\"";\r
+ content += loggingEvent.getFormattedTimestamp() + "\">\n";\r
+ content += "\t<log4js:message><![CDATA[" + this.escapeCdata(loggingEvent.message) + "]]></log4js:message>\n"; \r
+ \r
+ if (loggingEvent.exception) {\r
+ content += this.formatException(loggingEvent.exception) ;\r
+ }\r
+ content += "</log4js:event>\n";\r
+ \r
+ return content;\r
+ },\r
+ /** \r
+ * Returns the content type output by this layout. \r
+ * @return The base class returns "text/xml".\r
+ * @type String\r
+ */\r
+ getContentType: function() {\r
+ return "text/xml";\r
+ },\r
+ /** \r
+ * @return Returns the header for the layout format. The base class returns null.\r
+ * @type String\r
+ */\r
+ getHeader: function() {\r
+ return "<log4js:eventSet version=\"" + Log4js.version + \r
+ "\" xmlns:log4js=\"http://log4js.berlios.de/2007/log4js/\">\n";\r
+ },\r
+ /** \r
+ * @return Returns the footer for the layout format. The base class returns null.\r
+ * @type String\r
+ */\r
+ getFooter: function() {\r
+ return "</log4js:eventSet>\n";\r
+ },\r
+ \r
+ getSeparator: function() {\r
+ return "\n";\r
+ },\r
+ \r
+ /**\r
+ * better readable formatted Exceptions.\r
+ * @param ex {Exception} the exception to be formatted.\r
+ * @return {String} the formatted String representation of the exception.\r
+ * @private\r
+ */\r
+ formatException: function(ex) {\r
+ if (ex) {\r
+ var exStr = "\t<log4js:throwable>"; \r
+ if (ex.message) {\r
+ exStr += "\t\t<log4js:message><![CDATA[" + this.escapeCdata(ex.message) + "]]></log4js:message>\n"; \r
+ } \r
+ if (ex.description) {\r
+ exStr += "\t\t<log4js:description><![CDATA[" + this.escapeCdata(ex.description) + "]]></log4js:description>\n"; \r
+ }\r
+ \r
+ exStr += "\t\t<log4js:stacktrace>";\r
+ exStr += "\t\t\t<log4js:location fileName=\""+ex.fileName+"\" lineNumber=\""+ex.lineNumber+"\" />";\r
+ exStr += "\t\t</log4js:stacktrace>";\r
+ exStr = "\t</log4js:throwable>";\r
+ return exStr;\r
+ }\r
+ return null;\r
+ },\r
+ /**\r
+ * Escape Cdata messages\r
+ * @param str {String} message to escape\r
+ * @return {String} the escaped message\r
+ * @private\r
+ */\r
+ escapeCdata: function(str) {\r
+ return str.replace(/\]\]>/, "]]>]]><![CDATA[");\r
+ }\r
+});\r
+\r
+/**\r
+ * JSONLayout write the logs in JSON format.\r
+ * JSON library is required to use this Layout. See also {@link http://www.json.org}\r
+ * @constructor\r
+ * @extends Log4js.Layout\r
+ * @author Stephan Strittmatter\r
+ */\r
+Log4js.JSONLayout = function() {\r
+ this.df = new Log4js.DateFormatter();\r
+};\r
+Log4js.JSONLayout.prototype = Log4js.extend(new Log4js.Layout(), {\r
+ /** \r
+ * Implement this method to create your own layout format.\r
+ * @param {Log4js.LoggingEvent} loggingEvent loggingEvent to format\r
+ * @return formatted String\r
+ * @type String\r
+ */\r
+ format: function(loggingEvent) {\r
+ \r
+ var useragent = "unknown";\r
+ try {\r
+ useragent = navigator.userAgent;\r
+ } catch(e){\r
+ useragent = "unknown";\r
+ }\r
+ \r
+ var referer = "unknown";\r
+ try {\r
+ referer = location.href;\r
+ } catch(e){\r
+ referer = "unknown";\r
+ }\r
+ \r
+ var jsonString = "{\n \"LoggingEvent\": {\n";\r
+ \r
+ jsonString += "\t\"logger\": \"" + loggingEvent.categoryName + "\",\n";\r
+ jsonString += "\t\"level\": \"" + loggingEvent.level.toString() + "\",\n";\r
+ jsonString += "\t\"message\": \"" + loggingEvent.message + "\",\n"; \r
+ jsonString += "\t\"referer\": \"" + referer + "\",\n"; \r
+ jsonString += "\t\"useragent\": \"" + useragent + "\",\n"; \r
+ jsonString += "\t\"timestamp\": \"" + this.df.formatDate(loggingEvent.startTime, "yyyy-MM-ddThh:mm:ssZ") + "\",\n";\r
+ jsonString += "\t\"exception\": \"" + loggingEvent.exception + "\"\n"; \r
+ jsonString += "}}"; \r
+ \r
+ return jsonString;\r
+ },\r
+ /** \r
+ * Returns the content type output by this layout. \r
+ * @return The base class returns "text/xml".\r
+ * @type String\r
+ */\r
+ getContentType: function() {\r
+ return "text/json";\r
+ },\r
+ /** \r
+ * @return Returns the header for the layout format. The base class returns null.\r
+ * @type String\r
+ */\r
+ getHeader: function() {\r
+ return "{\"Log4js\": [\n";\r
+ },\r
+ /** \r
+ * @return Returns the footer for the layout format. The base class returns null.\r
+ * @type String\r
+ */\r
+ getFooter: function() {\r
+ return "\n]}";\r
+ },\r
+ \r
+ getSeparator: function() {\r
+ return ",\n";\r
+ }\r
+});\r
+\r
+/** \r
+ * PatternLayout \r
+ */\r
+Log4js.PatternLayout = function(pattern) {\r
+ if (pattern) {\r
+ this.pattern = pattern;\r
+ } else {\r
+ this.pattern = Log4js.PatternLayout.DEFAULT_CONVERSION_PATTERN;\r
+ }\r
+};\r
+\r
+Log4js.PatternLayout.TTCC_CONVERSION_PATTERN = "%r %p %c - %m%n";\r
+Log4js.PatternLayout.DEFAULT_CONVERSION_PATTERN = "%m%n";\r
+Log4js.PatternLayout.ISO8601_DATEFORMAT = "yyyy-MM-dd HH:mm:ss,SSS";\r
+Log4js.PatternLayout.DATETIME_DATEFORMAT = "dd MMM YYYY HH:mm:ss,SSS";\r
+Log4js.PatternLayout.ABSOLUTETIME_DATEFORMAT = "HH:mm:ss,SSS";\r
+\r
+Log4js.PatternLayout.prototype = Log4js.extend(new Log4js.Layout(), {\r
+ /** \r
+ * Returns the content type output by this layout. \r
+ * @return "text/plain".\r
+ * @type String\r
+ */\r
+ getContentType: function() {\r
+ return "text/plain";\r
+ },\r
+ /** \r
+ * @return Returns the header for the layout format.\r
+ * @type String\r
+ */\r
+ getHeader: function() {\r
+ return null;\r
+ },\r
+ /** \r
+ * @return Returns the footer for the layout format.\r
+ * @type String\r
+ */\r
+ getFooter: function() {\r
+ return null;\r
+ },\r
+ \r
+ format: function(loggingEvent) {\r
+ var regex = /%(-?[0-9]+)?(\.?[0-9]+)?([cdmnpr%])(\{([^\}]+)\})?|([^%]+)/;\r
+ var formattedString = "";\r
+ var result;\r
+ var searchString = this.pattern;\r
+\r
+ // Cannot use regex global flag since it doesn't work in IE5\r
+ while ((result = regex.exec(searchString))) {\r
+ var matchedString = result[0];\r
+ var padding = result[1];\r
+ var truncation = result[2];\r
+ var conversionCharacter = result[3];\r
+ var specifier = result[5];\r
+ var text = result[6];\r
+\r
+ // Check if the pattern matched was just normal text\r
+ if (text) {\r
+ formattedString += "" + text;\r
+ } else {\r
+ // Create a raw replacement string based on the conversion\r
+ // character and specifier\r
+ var replacement = "";\r
+ switch(conversionCharacter) {\r
+ case "c":\r
+ var loggerName = loggingEvent.categoryName;\r
+ if (specifier) {\r
+ var precision = parseInt(specifier, 10);\r
+ var loggerNameBits = loggingEvent.categoryName.split(".");\r
+ if (precision >= loggerNameBits.length) {\r
+ replacement = loggerName;\r
+ } else {\r
+ replacement = loggerNameBits.slice(loggerNameBits.length - precision).join(".");\r
+ }\r
+ } else {\r
+ replacement = loggerName;\r
+ }\r
+ break;\r
+ case "d":\r
+ var dateFormat = Log4js.PatternLayout.ISO8601_DATEFORMAT;\r
+ if (specifier) {\r
+ dateFormat = specifier;\r
+ // Pick up special cases\r
+ if (dateFormat == "ISO8601") {\r
+ dateFormat = Log4js.PatternLayout.ISO8601_DATEFORMAT;\r
+ } else if (dateFormat == "ABSOLUTE") {\r
+ dateFormat = Log4js.PatternLayout.ABSOLUTETIME_DATEFORMAT;\r
+ } else if (dateFormat == "DATE") {\r
+ dateFormat = Log4js.PatternLayout.DATETIME_DATEFORMAT;\r
+ }\r
+ }\r
+ // Format the date\r
+ replacement = (new Log4js.SimpleDateFormat(dateFormat)).format(loggingEvent.startTime);\r
+ break;\r
+ case "m":\r
+ replacement = loggingEvent.message;\r
+ break;\r
+ case "n":\r
+ replacement = "\n";\r
+ break;\r
+ case "p":\r
+ replacement = loggingEvent.level.toString();\r
+ break;\r
+ case "r":\r
+ replacement = "" + loggingEvent.startTime.toLocaleTimeString(); //TODO: .getDifference(Log4js.applicationStartDate);\r
+ break;\r
+ case "%":\r
+ replacement = "%";\r
+ break;\r
+ default:\r
+ replacement = matchedString;\r
+ break;\r
+ }\r
+ // Format the replacement according to any padding or\r
+ // truncation specified\r
+\r
+ var len;\r
+\r
+ // First, truncation\r
+ if (truncation) {\r
+ len = parseInt(truncation.substr(1), 10);\r
+ replacement = replacement.substring(0, len);\r
+ }\r
+ // Next, padding\r
+ if (padding) {\r
+ if (padding.charAt(0) == "-") {\r
+ len = parseInt(padding.substr(1), 10);\r
+ // Right pad with spaces\r
+ while (replacement.length < len) {\r
+ replacement += " ";\r
+ }\r
+ } else {\r
+ len = parseInt(padding, 10);\r
+ // Left pad with spaces\r
+ while (replacement.length < len) {\r
+ replacement = " " + replacement;\r
+ }\r
+ }\r
+ }\r
+ formattedString += replacement;\r
+ }\r
+ searchString = searchString.substr(result.index + result[0].length);\r
+ }\r
+ return formattedString;\r
+ }\r
+});\r
+\r
+/**\r
+ * @private\r
+ * @ignore\r
+ */\r
+if (!Array.prototype.push) {\r
+ /**\r
+ * Functions taken from Prototype library, didn't want to require for just few \r
+ * functions.\r
+ * More info at {@link http://\r
+ * prototype.conio.net/}\r
+ * @private\r
+ */\r
+ Array.prototype.push = function() {\r
+ var startLength = this.length;\r
+ for (var i = 0; i < arguments.length; i++) {\r
+ this[startLength + i] = arguments[i];\r
+ }\r
+ return this.length;\r
+ };\r
+}\r
+\r
+/**\r
+ * FIFO buffer\r
+ * @private\r
+ */\r
+Log4js.FifoBuffer = function()\r
+{\r
+ this.array = new Array();\r
+};\r
+\r
+Log4js.FifoBuffer.prototype = {\r
+\r
+ /**\r
+ * @param {Object} obj any object added to buffer\r
+ */\r
+ push : function(obj) {\r
+ this.array[this.array.length] = obj;\r
+ return this.array.length;\r
+ },\r
+ \r
+ /**\r
+ * @return first putted in Object\r
+ */\r
+ pull : function() {\r
+ if (this.array.length > 0) {\r
+ var firstItem = this.array[0];\r
+ for (var i = 0; i < this.array.length - 1; i++) {\r
+ this.array[i] = this.array[i + 1];\r
+ }\r
+ this.array.length = this.array.length - 1;\r
+ return firstItem;\r
+ }\r
+ return null;\r
+ },\r
+ \r
+ length : function() {\r
+ return this.array.length;\r
+ }\r
+};\r
+\r
+\r
+\r
+/**\r
+ * Date Formatter\r
+ * addZero() and formatDate() are courtesy of Mike Golding:\r
+ * http://www.mikezilla.com/exp0015.html\r
+ * @private\r
+ */ \r
+Log4js.DateFormatter = function() {\r
+ return;\r
+};\r
+/**\r
+ * default format of date (ISO-8601)\r
+ * @static\r
+ * @final\r
+ */\r
+Log4js.DateFormatter.DEFAULT_DATE_FORMAT = "yyyy-MM-ddThh:mm:ssO";\r
+\r
+\r
+Log4js.DateFormatter.prototype = {\r
+ /**\r
+ * Formats the given date by the given pattern.<br />\r
+ * Following switches are supported:\r
+ * <ul>\r
+ * <li>yyyy: The year</li>\r
+ * <li>MM: the month</li>\r
+ * <li>dd: the day of month<li>\r
+ * <li>hh: the hour<li>\r
+ * <li>mm: minutes</li>\r
+ * <li>O: timezone offset</li>\r
+ * </ul>\r
+ * @param {Date} vDate the date to format\r
+ * @param {String} vFormat the format pattern\r
+ * @return {String} formatted date string\r
+ * @static\r
+ */\r
+ formatDate : function(vDate, vFormat) {\r
+ var vDay = this.addZero(vDate.getDate());\r
+ var vMonth = this.addZero(vDate.getMonth()+1);\r
+ var vYearLong = this.addZero(vDate.getFullYear());\r
+ var vYearShort = this.addZero(vDate.getFullYear().toString().substring(3,4));\r
+ var vYear = (vFormat.indexOf("yyyy")>-1?vYearLong:vYearShort);\r
+ var vHour = this.addZero(vDate.getHours());\r
+ var vMinute = this.addZero(vDate.getMinutes());\r
+ var vSecond = this.addZero(vDate.getSeconds());\r
+ var vTimeZone = this.O(vDate);\r
+ var vDateString = vFormat.replace(/dd/g, vDay).replace(/MM/g, vMonth).replace(/y{1,4}/g, vYear);\r
+ vDateString = vDateString.replace(/hh/g, vHour).replace(/mm/g, vMinute).replace(/ss/g, vSecond);\r
+ vDateString = vDateString.replace(/O/g, vTimeZone);\r
+ return vDateString;\r
+ },\r
+ \r
+ /**\r
+ * @private\r
+ * @static\r
+ */\r
+ addZero : function(vNumber) {\r
+ return ((vNumber < 10) ? "0" : "") + vNumber;\r
+ },\r
+ \r
+ /**\r
+ * Formates the TimeOffest\r
+ * Thanks to http://www.svendtofte.com/code/date_format/\r
+ * @private\r
+ */\r
+ O : function (date) {\r
+ // Difference to Greenwich time (GMT) in hours\r
+ var os = Math.abs(date.getTimezoneOffset());\r
+ var h = String(Math.floor(os/60));\r
+ var m = String(os%60);\r
+ h.length == 1? h = "0"+h:1;\r
+ m.length == 1? m = "0"+m:1;\r
+ return date.getTimezoneOffset() < 0 ? "+"+h+m : "-"+h+m;\r
+ }\r
+};\r
+\r
+\r
+/**\r
+ * internal Logger to be used\r
+ * @private\r
+ */\r
+var log4jsLogger = Log4js.getLogger("Log4js");\r
+log4jsLogger.addAppender(new Log4js.ConsoleAppender());\r
+log4jsLogger.setLevel(Log4js.Level.ALL);
\ No newline at end of file
--- /dev/null
+/*
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * <a href="http://www.owasp.org/index.php/ESAPI">http://www.owasp.org/index.php/ESAPI</a>.
+ *
+ * Copyright (c) 2008 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ */
+
+$namespace('Base.esapi.properties');
+
+Base.esapi.properties = {
+ application: {
+ // Change this value to reflect your application, or override it in an application scoped configuration.
+ Name: 'ESAPI4JS Base Application'
+ },
+
+ httputilities: {
+ cookies: {
+ ForceSecure: true
+ }
+ },
+
+ logging: {
+ Implementation: org.owasp.esapi.reference.logging.Log4JSLogFactory,
+ Level: org.owasp.esapi.Logger.ERROR,
+ // For a console that pops up in a seperate window
+ // Appenders: [ new ConsoleAppender(true) ],
+ // To log to a logging service on the server
+ // Appenders: [ new AjaxAppender( '/log/' ) ],
+ // Default to log nowhere
+ Appenders: [ ],
+ LogUrl: false,
+ LogApplicationName: false,
+ EncodingRequired: true
+ },
+
+ encoder: {
+ Implementation: org.owasp.esapi.reference.encoding.DefaultEncoder,
+ AllowMultipleEncoding: false
+ },
+
+ localization: {
+ StandardResourceBundle: ESAPI_Standard_en_US,
+ DefaultLocale: 'en-US'
+ },
+
+ validation: {
+ Implementation: org.owasp.esapi.reference.validation.DefaultValidator,
+ AccountName: '^[a-zA-Z0-9]{3,20}$',
+ SafeString: '[a-zA-Z0-9\\-_+]*',
+ Email: '^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$',
+ IPAddress: '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$',
+ URL: '^(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\:\\\'\\/\\\\\\+=&%\\$#_]*)?$',
+ CreditCard: '^(\\d{4}[- ]?){3}\\d{4}$',
+ SSN: '^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$',
+ HttpScheme: '^(http|https)$',
+ HttpServerName: '^[a-zA-Z0-9_.\\-]*$',
+ HttpParameterName: '^[a-zA-Z0-9_]{1,32}$',
+ HttpParameterValue: '^[a-zA-Z0-9.\\-\\/+=_ ]*$',
+ HttpCookieName: '^[a-zA-Z0-9\\-_]{1,32}$',
+ HttpCookieValue: '^[a-zA-Z0-9\\-\\/+=_ ]*$'
+ }
+};
\ No newline at end of file
-/**\r * SWFAddress 2.4: Deep linking for Flash and Ajax <http://www.asual.com/swfaddress/>\r *\r * SWFAddress is (c) 2006-2009 Rostislav Hristov and contributors\r * This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>\r *\r */\r\rif (typeof asual == "undefined") var asual = {};\rif (typeof asual.util == "undefined") asual.util = {};\r\rasual.util.Browser = new function() {\r \r var _agent = navigator.userAgent.toLowerCase(),\r _safari = /webkit/.test(_agent),\r _opera = /opera/.test(_agent),\r _msie = /msie/.test(_agent) && !/opera/.test(_agent),\r _mozilla = /mozilla/.test(_agent) && !/(compatible|webkit)/.test(_agent),\r _version = parseFloat(_msie ? _agent.substr(_agent.indexOf('msie') + 4) : \r (_agent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [0,'0'])[1]);\r\r this.toString = function() {\r return '[class Browser]';\r };\r\r this.getVersion = function() {\r return _version;\r };\r\r this.isMSIE = function() {\r return _msie;\r };\r\r this.isSafari = function() {\r return _safari;\r };\r\r this.isOpera = function() {\r return _opera;\r };\r\r this.isMozilla = function() {\r return _mozilla;\r };\r};\r\rasual.util.Events = new function() {\r\r var DOM_LOADED = 'DOMContentLoaded', \r STOP = 'onstop',\r _w = window,\r _d = document,\r _cache = [],\r _util = asual.util,\r _browser = _util.Browser,\r _msie = _browser.isMSIE(),\r _safari = _browser.isSafari();\r\r this.toString = function() {\r return '[class Events]';\r };\r\r this.addListener = function(obj, type, listener) {\r _cache.push({o: obj, t: type, l: listener});\r if (!(type == DOM_LOADED && (_msie || _safari))) {\r if (obj.addEventListener)\r obj.addEventListener(type, listener, false);\r else if (obj.attachEvent)\r obj.attachEvent('on' + type, listener);\r }\r };\r\r this.removeListener = function(obj, type, listener) {\r for (var i = 0, e; e = _cache[i]; i++) {\r if (e.o == obj && e.t == type && e.l == listener) {\r _cache.splice(i, 1);\r break;\r }\r }\r if (!(type == DOM_LOADED && (_msie || _safari))) {\r if (obj.removeEventListener)\r obj.removeEventListener(type, listener, false);\r else if (obj.detachEvent)\r obj.detachEvent('on' + type, listener);\r }\r };\r\r var _unload = function() {\r for (var i = 0, evt; evt = _cache[i]; i++) {\r if (evt.t != DOM_LOADED)\r _util.Events.removeListener(evt.o, evt.t, evt.l);\r }\r };\r\r var _unloadFix = function() {\r if (_d.readyState == 'interactive') {\r function stop() {\r _d.detachEvent(STOP, stop);\r _unload();\r };\r _d.attachEvent(STOP, stop);\r _w.setTimeout(function() {\r _d.detachEvent(STOP, stop);\r }, 0);\r }\r };\r\r if (_msie || _safari) {\r (function (){\r try {\r if ((_msie && _d.body) || !/loaded|complete/.test(_d.readyState))\r _d.documentElement.doScroll('left');\r } catch(e) {\r return setTimeout(arguments.callee, 0);\r }\r for (var i = 0, e; e = _cache[i]; i++)\r if (e.t == DOM_LOADED) e.l.call(null);\r })();\r }\r\r if (_msie)\r _w.attachEvent('onbeforeunload', _unloadFix);\r\r this.addListener(_w, 'unload', _unload);\r};\r\rasual.util.Functions = new function() {\r\r this.toString = function() {\r return '[class Functions]';\r };\r\r this.bind = function(method, object, param) {\r for (var i = 2, p, arr = []; p = arguments[i]; i++)\r arr.push(p);\r return function() {\r return method.apply(object, arr);\r }\r };\r};\r\rvar SWFAddressEvent = function(type) {\r\r this.toString = function() {\r return '[object SWFAddressEvent]';\r };\r\r this.type = type;\r\r this.target = [SWFAddress][0];\r\r this.value = SWFAddress.getValue();\r\r this.path = SWFAddress.getPath();\r\r this.pathNames = SWFAddress.getPathNames();\r\r this.parameters = {};\r\r var _parameterNames = SWFAddress.getParameterNames();\r for (var i = 0, l = _parameterNames.length; i < l; i++)\r this.parameters[_parameterNames[i]] = SWFAddress.getParameter(_parameterNames[i]);\r\r this.parameterNames = _parameterNames;\r\r};\r\rSWFAddressEvent.INIT = 'init';\r\rSWFAddressEvent.CHANGE = 'change';\r\rSWFAddressEvent.INTERNAL_CHANGE = 'internalChange';\r\rSWFAddressEvent.EXTERNAL_CHANGE = 'externalChange';\r\rvar SWFAddress = new function() {\r\r var _getHash = function() {\r var index = _l.href.indexOf('#');\r return index != -1 ? _ec(_dc(_l.href.substr(index + 1))) : '';\r };\r\r var _getWindow = function() {\r return window;\r };\r\r var _strictCheck = function(value, force) {\r if (_opts.strict)\r value = force ? (value.substr(0, 1) != '/' ? '/' + value : value) : (value == '' ? '/' : value);\r return value;\r };\r\r var _ieLocal = function(value, direction) {\r return (_msie && _l.protocol == 'file:') ? \r (direction ? _value.replace(/\?/, '%3F') : _value.replace(/%253F/, '?')) : value;\r };\r\r var _searchScript = function(el) {\r if (el.childNodes) {\r for (var i = 0, l = el.childNodes.length, s; i < l; i++) {\r if (el.childNodes[i].src)\r _url = String(el.childNodes[i].src);\r if (s = _searchScript(el.childNodes[i]))\r return s;\r }\r }\r };\r\r var _titleCheck = function() {\r if (_d.title != _title && _d.title.indexOf('#') != -1)\r _d.title = _title;\r };\r\r var _listen = function() {\r if (!_silent) {\r var hash = _getHash();\r var diff = !(_value == hash);\r if (_safari && _version < 523) {\r if (_length != _h.length) {\r _length = _h.length;\r if (typeof _stack[_length - 1] != UNDEFINED)\r _value = _stack[_length - 1];\r _update.call(this, false);\r }\r } else if (_msie && diff) {\r if (_version < 7)\r _l.reload();\r else\r this.setValue(hash);\r } else if (diff) {\r _value = hash;\r _update.call(this, false);\r }\r if (_msie)\r _titleCheck.call(this);\r }\r };\r\r var _bodyClick = function(e) {\r if (_popup.length > 0) {\r var popup = window.open(_popup[0], _popup[1], eval(_popup[2]));\r if (typeof _popup[3] != UNDEFINED)\r eval(_popup[3]);\r }\r _popup = [];\r };\r\r var _swfChange = function() {\r for (var i = 0, id, obj, value = SWFAddress.getValue(), setter = 'setSWFAddressValue'; id = _ids[i]; i++) {\r obj = document.getElementById(id);\r if (obj) {\r if (obj.parentNode && typeof obj.parentNode.so != UNDEFINED) {\r obj.parentNode.so.call(setter, value);\r } else {\r if (!(obj && typeof obj[setter] != UNDEFINED)) {\r var objects = obj.getElementsByTagName('object');\r var embeds = obj.getElementsByTagName('embed');\r obj = ((objects[0] && typeof objects[0][setter] != UNDEFINED) ? \r objects[0] : ((embeds[0] && typeof embeds[0][setter] != UNDEFINED) ? \r embeds[0] : null));\r }\r if (obj)\r obj[setter](value);\r } \r } else if (obj = document[id]) {\r if (typeof obj[setter] != UNDEFINED)\r obj[setter](value);\r }\r }\r };\r\r var _jsDispatch = function(type) {\r this.dispatchEvent(new SWFAddressEvent(type));\r type = type.substr(0, 1).toUpperCase() + type.substr(1);\r if(typeof this['on' + type] == FUNCTION)\r this['on' + type]();\r };\r\r var _jsInit = function() {\r if (_util.Browser.isSafari())\r _d.body.addEventListener('click', _bodyClick);\r _jsDispatch.call(this, 'init');\r };\r\r var _jsChange = function() {\r _swfChange();\r _jsDispatch.call(this, 'change');\r };\r\r var _update = function(internal) {\r _jsChange.call(this);\r if (internal) {\r _jsDispatch.call(this, 'internalChange');\r } else {\r _jsDispatch.call(this, 'externalChange');\r }\r _st(_functions.bind(_track, this), 10);\r };\r\r var _track = function() {\r var value = (_l.pathname + (/\/$/.test(_l.pathname) ? '' : '/') + this.getValue()).replace(/\/\//, '/').replace(/^\/$/, '');\r var fn = _t[_opts.tracker];\r if (typeof fn == FUNCTION)\r fn(value);\r else if (typeof _t.pageTracker != UNDEFINED && typeof _t.pageTracker._trackPageview == FUNCTION)\r _t.pageTracker._trackPageview(value);\r else if (typeof _t.urchinTracker == FUNCTION) \r _t.urchinTracker(value);\r };\r\r var _htmlWrite = function() {\r var doc = _frame.contentWindow.document;\r doc.open();\r doc.write('<html><head><title>' + _d.title + '</title><script>var ' + ID + ' = "' + _getHash() + '";</script></head></html>');\r doc.close();\r };\r\r var _htmlLoad = function() {\r var win = _frame.contentWindow;\r var src = win.location.href;\r _value = (typeof win[ID] != UNDEFINED ? win[ID] : '');\r if (_value != _getHash()) {\r _update.call(SWFAddress, false);\r _l.hash = _ieLocal(_value, TRUE);\r }\r };\r\r var _load = function() {\r if (!_loaded) {\r _loaded = TRUE;\r if (_msie && _version < 8) {\r var frameset = _d.getElementsByTagName('frameset')[0];\r _frame = _d.createElement((frameset ? '' : 'i') + 'frame');\r if (frameset) {\r frameset.insertAdjacentElement('beforeEnd', _frame);\r frameset[frameset.cols ? 'cols' : 'rows'] += ',0';\r _frame.src = 'javascript:false';\r _frame.noResize = true;\r _frame.frameBorder = _frame.frameSpacing = 0;\r } else {\r _frame.src = 'javascript:false';\r _frame.style.display = 'none';\r _d.body.insertAdjacentElement('afterBegin', _frame);\r }\r _st(function() {\r _events.addListener(_frame, 'load', _htmlLoad); \r if (typeof _frame.contentWindow[ID] == UNDEFINED) \r _htmlWrite();\r }, 50);\r } else if (_safari) {\r if (_version < 418) {\r _d.body.innerHTML += '<form id="' + ID + '" style="position:absolute;top:-9999px;" method="get"></form>';\r _form = _d.getElementById(ID);\r }\r if (typeof _l[ID] == UNDEFINED) _l[ID] = {};\r if (typeof _l[ID][_l.pathname] != UNDEFINED) _stack = _l[ID][_l.pathname].split(',');\r }\r\r _st(_functions.bind(function() {\r _jsInit.call(this);\r _jsChange.call(this);\r _track.call(this);\r }, this), 1);\r\r if (_msie && _version >= 8) {\r _d.body.onhashchange = _functions.bind(_listen, this);\r _si(_functions.bind(_titleCheck, this), 50);\r } else {\r _si(_functions.bind(_listen, this), 50);\r }\r }\r };\r\r var ID = 'swfaddress',\r FUNCTION = 'function',\r UNDEFINED = 'undefined',\r TRUE = true,\r FALSE = false,\r _util = asual.util,\r _browser = _util.Browser, \r _events = _util.Events,\r _functions = _util.Functions,\r _version = _browser.getVersion(),\r _msie = _browser.isMSIE(),\r _mozilla = _browser.isMozilla(),\r _opera = _browser.isOpera(),\r _safari = _browser.isSafari(),\r _supported = FALSE,\r _t = _getWindow(),\r _d = _t.document,\r _h = _t.history, \r _l = _t.location,\r _si = setInterval,\r _st = setTimeout, \r _dc = decodeURI,\r _ec = encodeURI,\r _frame,\r _form,\r _url,\r _title = _d.title, \r _length = _h.length, \r _silent = FALSE,\r _loaded = FALSE,\r _justset = TRUE,\r _juststart = TRUE,\r _ref = this,\r _stack = [], \r _ids = [],\r _popup = [],\r _listeners = {},\r _value = _getHash(),\r _opts = {history: TRUE, strict: TRUE}; \r\r if (_msie && _d.documentMode && _d.documentMode != _version)\r _version = _d.documentMode != 8 ? 7 : 8;\r\r _supported = \r (_mozilla && _version >= 1) || \r (_msie && _version >= 6) ||\r (_opera && _version >= 9.5) ||\r (_safari && _version >= 312);\r\r if (_supported) {\r\r if (_opera) \r history.navigationMode = 'compatible';\r\r for (var i = 1; i < _length; i++)\r _stack.push('');\r\r _stack.push(_getHash());\r\r if (_msie && _l.hash != _getHash())\r _l.hash = '#' + _ieLocal(_getHash(), TRUE);\r\r _searchScript(document);\r var _qi = _url ? _url.indexOf('?') : -1;\r if (_qi != -1) {\r var param, params = _url.substr(_qi + 1).split('&');\r for (var i = 0, p; p = params[i]; i++) {\r param = p.split('=');\r if (/^(history|strict)$/.test(param[0])) {\r _opts[param[0]] = (isNaN(param[1]) ? /^(true|yes)$/i.test(param[1]) : (parseInt(param[1]) != 0));\r }\r if (/^tracker$/.test(param[0]))\r _opts[param[0]] = param[1];\r }\r }\r\r if (_msie)\r _titleCheck.call(this);\r\r if (window == _t)\r _events.addListener(document, 'DOMContentLoaded', _functions.bind(_load, this));\r _events.addListener(_t, 'load', _functions.bind(_load, this));\r\r } else if ((!_supported && _l.href.indexOf('#') != -1) || \r (_safari && _version < 418 && _l.href.indexOf('#') != -1 && _l.search != '')){\r _d.open();\r _d.write('<html><head><meta http-equiv="refresh" content="0;url=' + \r _l.href.substr(0, _l.href.indexOf('#')) + '" /></head></html>');\r _d.close();\r } else {\r _track();\r }\r\r this.toString = function() {\r return '[class SWFAddress]';\r };\r\r this.back = function() {\r _h.back();\r };\r\r this.forward = function() {\r _h.forward();\r };\r\r this.up = function() {\r var path = this.getPath();\r this.setValue(path.substr(0, path.lastIndexOf('/', path.length - 2) + (path.substr(path.length - 1) == '/' ? 1 : 0)));\r };\r\r this.go = function(delta) {\r _h.go(delta);\r };\r\r this.href = function(url, target) {\r target = typeof target != UNDEFINED ? target : '_self'; \r if (target == '_self')\r self.location.href = url; \r else if (target == '_top')\r _l.href = url; \r else if (target == '_blank')\r window.open(url); \r else\r _t.frames[target].location.href = url; \r };\r\r this.popup = function(url, name, options, handler) {\r try {\r var popup = window.open(url, name, eval(options));\r if (typeof handler != UNDEFINED)\r eval(handler);\r } catch (ex) {}\r _popup = arguments;\r };\r\r this.getIds = function() {\r return _ids;\r };\r\r this.getId = function(index) {\r return _ids[0];\r };\r\r this.setId = function(id) {\r _ids[0] = id;\r };\r\r this.addId = function(id) {\r this.removeId(id);\r _ids.push(id);\r };\r\r this.removeId = function(id) {\r for (var i = 0; i < _ids.length; i++) {\r if (id == _ids[i]) {\r _ids.splice(i, 1);\r break;\r }\r }\r };\r\r this.addEventListener = function(type, listener) {\r if (typeof _listeners[type] == UNDEFINED)\r _listeners[type] = [];\r _listeners[type].push(listener);\r };\r\r this.removeEventListener = function(type, listener) {\r if (typeof _listeners[type] != UNDEFINED) {\r for (var i = 0, l; l = _listeners[type][i]; i++)\r if (l == listener) break;\r _listeners[type].splice(i, 1);\r }\r };\r\r this.dispatchEvent = function(event) {\r if (this.hasEventListener(event.type)) {\r event.target = this;\r for (var i = 0, l; l = _listeners[event.type][i]; i++)\r l(event);\r return TRUE; \r }\r return FALSE;\r };\r\r this.hasEventListener = function(type) {\r return (typeof _listeners[type] != UNDEFINED && _listeners[type].length > 0);\r };\r\r this.getBaseURL = function() {\r var url = _l.href;\r if (url.indexOf('#') != -1)\r url = url.substr(0, url.indexOf('#'));\r if (url.substr(url.length - 1) == '/')\r url = url.substr(0, url.length - 1);\r return url;\r };\r\r this.getStrict = function() {\r return _opts.strict;\r };\r\r this.setStrict = function(strict) {\r _opts.strict = strict;\r };\r\r this.getHistory = function() {\r return _opts.history;\r };\r\r this.setHistory = function(history) {\r _opts.history = history;\r };\r\r this.getTracker = function() {\r return _opts.tracker;\r };\r\r this.setTracker = function(tracker) {\r _opts.tracker = tracker;\r };\r\r this.getTitle = function() {\r return _d.title;\r };\r\r this.setTitle = function(title) {\r if (!_supported) return null;\r if (typeof title == UNDEFINED) return;\r if (title == 'null') title = '';\r title = _dc(title);\r _st(function() {\r _title = _d.title = title;\r if (_juststart && _frame && _frame.contentWindow && _frame.contentWindow.document) {\r _frame.contentWindow.document.title = title;\r _juststart = FALSE;\r }\r if (!_justset && _mozilla)\r _l.replace(_l.href.indexOf('#') != -1 ? _l.href : _l.href + '#');\r _justset = FALSE;\r }, 10);\r };\r\r this.getStatus = function() {\r return _t.status;\r };\r\r this.setStatus = function(status) {\r if (!_supported) return null;\r if (typeof status == UNDEFINED) return;\r if (status == 'null') status = '';\r status = _dc(status);\r if (!_safari) {\r status = _strictCheck((status != 'null') ? status : '', TRUE);\r if (status == '/') status = '';\r if (!(/http(s)?:\/\//.test(status))) {\r var index = _l.href.indexOf('#');\r status = (index == -1 ? _l.href : _l.href.substr(0, index)) + '#' + status;\r }\r _t.status = status;\r }\r };\r\r this.resetStatus = function() {\r _t.status = '';\r };\r\r this.getValue = function() {\r if (!_supported) return null;\r return _dc(_strictCheck(_ieLocal(_value, FALSE), FALSE));\r };\r\r this.setValue = function(value) {\r if (!_supported) return null;\r if (typeof value == UNDEFINED) return;\r if (value == 'null') value = '';\r value = _ec(_dc(_strictCheck(value, TRUE)));\r if (value == '/') value = '';\r if (_value == value) return;\r _justset = TRUE;\r _value = value;\r _silent = TRUE;\r _update.call(SWFAddress, true);\r _stack[_h.length] = _value;\r if (_safari) {\r if (_opts.history) {\r _l[ID][_l.pathname] = _stack.toString();\r _length = _h.length + 1;\r if (_version < 418) {\r if (_l.search == '') {\r _form.action = '#' + _value;\r _form.submit();\r }\r } else if (_version < 523 || _value == '') {\r var evt = _d.createEvent('MouseEvents');\r evt.initEvent('click', TRUE, TRUE);\r var anchor = _d.createElement('a');\r anchor.href = '#' + _value;\r anchor.dispatchEvent(evt); \r } else {\r _l.hash = '#' + _value;\r }\r } else {\r _l.replace('#' + _value);\r }\r } else if (_value != _getHash()) {\r if (_opts.history)\r _l.hash = '#' + _dc(_ieLocal(_value, TRUE));\r else\r _l.replace('#' + _dc(_value));\r }\r if ((_msie && _version < 8) && _opts.history) {\r _st(_htmlWrite, 50);\r }\r if (_safari)\r _st(function(){ _silent = FALSE; }, 1);\r else\r _silent = FALSE;\r };\r\r this.getPath = function() {\r var value = this.getValue();\r if (value.indexOf('?') != -1) {\r return value.split('?')[0];\r } else if (value.indexOf('#') != -1) {\r return value.split('#')[0];\r } else {\r return value; \r } \r };\r\r this.getPathNames = function() {\r var path = this.getPath(), names = path.split('/');\r if (path.substr(0, 1) == '/' || path.length == 0)\r names.splice(0, 1);\r if (path.substr(path.length - 1, 1) == '/')\r names.splice(names.length - 1, 1);\r return names;\r };\r\r this.getQueryString = function() {\r var value = this.getValue(), index = value.indexOf('?');\r if (index != -1 && index < value.length) \r return value.substr(index + 1);\r };\r\r this.getParameter = function(param) {\r var value = this.getValue();\r var index = value.indexOf('?');\r if (index != -1) {\r value = value.substr(index + 1);\r var p, params = value.split('&'), i = params.length, r = [];\r while(i--) {\r p = params[i].split('=');\r if (p[0] == param)\r r.push(p[1]);\r }\r if (r.length != 0)\r return r.length != 1 ? r : r[0];\r }\r };\r\r this.getParameterNames = function() {\r var value = this.getValue();\r var index = value.indexOf('?');\r var names = [];\r if (index != -1) {\r value = value.substr(index + 1);\r if (value != '' && value.indexOf('=') != -1) {\r var params = value.split('&'), i = 0;\r while(i < params.length) {\r names.push(params[i].split('=')[0]);\r i++;\r }\r }\r }\r return names;\r };\r\r this.onInit = null;\r\r this.onChange = null;\r\r this.onInternalChange = null;\r\r this.onExternalChange = null;\r\r (function() {\r\r var _args;\r\r if (typeof FlashObject != UNDEFINED) SWFObject = FlashObject;\r if (typeof SWFObject != UNDEFINED && SWFObject.prototype && SWFObject.prototype.write) {\r var _s1 = SWFObject.prototype.write;\r SWFObject.prototype.write = function() {\r _args = arguments;\r if (this.getAttribute('version').major < 8) {\r this.addVariable('$swfaddress', SWFAddress.getValue());\r ((typeof _args[0] == 'string') ? \r document.getElementById(_args[0]) : _args[0]).so = this;\r }\r var success;\r if (success = _s1.apply(this, _args))\r _ref.addId(this.getAttribute('id'));\r return success;\r }\r } \r\r if (typeof swfobject != UNDEFINED) {\r var _s2r = swfobject.registerObject;\r swfobject.registerObject = function() {\r _args = arguments;\r _s2r.apply(this, _args);\r _ref.addId(_args[0]);\r }\r var _s2c = swfobject.createSWF;\r swfobject.createSWF = function() {\r _args = arguments;\r var swf = _s2c.apply(this, _args);\r if (swf)\r _ref.addId(_args[0].id);\r return swf;\r }\r var _s2e = swfobject.embedSWF;\r swfobject.embedSWF = function() {\r _args = arguments;\r if (typeof _args[8] == UNDEFINED)\r _args[8] = {};\r if (typeof _args[8].id == UNDEFINED)\r _args[8].id = _args[1];\r _s2e.apply(this, _args);\r _ref.addId(_args[8].id);\r }\r }\r\r if (typeof UFO != UNDEFINED) {\r var _u = UFO.create;\r UFO.create = function() {\r _args = arguments;\r _u.apply(this, _args);\r _ref.addId(_args[0].id);\r }\r }\r\r if (typeof AC_FL_RunContent != UNDEFINED) {\r var _a = AC_FL_RunContent;\r AC_FL_RunContent = function() {\r _args = arguments; \r _a.apply(this, _args);\r for (var i = 0, l = _args.length; i < l; i++)\r if (_args[i]== 'id') _ref.addId(_args[i+1]);\r }\r }\r\r })();\r};\r
\ No newline at end of file
+/**
+ * SWFAddress 2.4: Deep linking for Flash and Ajax <http://www.asual.com/swfaddress/>
+ *
+ * SWFAddress is (c) 2006-2009 Rostislav Hristov and contributors
+ * This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
+ *
+ */
+
+if (typeof asual == "undefined")
+ var asual = {};
+if (typeof asual.util == "undefined")
+ asual.util = {};
+
+asual.util.Browser = new function() {
+
+ var _agent = navigator.userAgent.toLowerCase(),
+ _safari = /webkit/.test(_agent),
+ _opera = /opera/.test(_agent),
+ _msie = /msie/.test(_agent) && !/opera/.test(_agent),
+ _mozilla = /mozilla/.test(_agent) && !/(compatible|webkit)/.test(_agent),
+ _version = parseFloat(_msie ? _agent.substr(_agent.indexOf('msie') + 4) :
+ (_agent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [0, '0'])[1]);
+
+ this.toString = function() {
+ return '[class Browser]';
+ };
+
+ this.getVersion = function() {
+ return _version;
+ };
+
+ this.isMSIE = function() {
+ return _msie;
+ };
+
+ this.isSafari = function() {
+ return _safari;
+ };
+
+ this.isOpera = function() {
+ return _opera;
+ };
+
+ this.isMozilla = function() {
+ return _mozilla;
+ };
+};
+
+asual.util.Events = new function() {
+
+ var DOM_LOADED = 'DOMContentLoaded',
+ STOP = 'onstop',
+ _w = window,
+ _d = document,
+ _cache = [],
+ _util = asual.util,
+ _browser = _util.Browser,
+ _msie = _browser.isMSIE(),
+ _safari = _browser.isSafari();
+
+ this.toString = function() {
+ return '[class Events]';
+ };
+
+ this.addListener = function(obj, type, listener) {
+ _cache.push({o: obj, t: type, l: listener});
+ if (!(type == DOM_LOADED && (_msie || _safari))) {
+ if (obj.addEventListener)
+ obj.addEventListener(type, listener, false);
+ else if (obj.attachEvent)
+ obj.attachEvent('on' + type, listener);
+ }
+ };
+
+ this.removeListener = function(obj, type, listener) {
+ for (var i = 0, e; e = _cache[i]; i++) {
+ if (e.o == obj && e.t == type && e.l == listener) {
+ _cache.splice(i, 1);
+ break;
+ }
+ }
+ if (!(type == DOM_LOADED && (_msie || _safari))) {
+ if (obj.removeEventListener)
+ obj.removeEventListener(type, listener, false);
+ else if (obj.detachEvent)
+ obj.detachEvent('on' + type, listener);
+ }
+ };
+
+ var _unload = function() {
+ for (var i = 0, evt; evt = _cache[i]; i++) {
+ if (evt.t != DOM_LOADED)
+ _util.Events.removeListener(evt.o, evt.t, evt.l);
+ }
+ };
+
+ var _unloadFix = function() {
+ if (_d.readyState == 'interactive') {
+ function stop() {
+ _d.detachEvent(STOP, stop);
+ _unload();
+ }
+ ;
+ _d.attachEvent(STOP, stop);
+ _w.setTimeout(function() {
+ _d.detachEvent(STOP, stop);
+ }, 0);
+ }
+ };
+
+ if (_msie || _safari) {
+ (function() {
+ try {
+ if ((_msie && _d.body) || !/loaded|complete/.test(_d.readyState))
+ _d.documentElement.doScroll('left');
+ } catch (e) {
+ return setTimeout(arguments.callee, 0);
+ }
+ for (var i = 0, e; e = _cache[i]; i++)
+ if (e.t == DOM_LOADED)
+ e.l.call(null);
+ })();
+ }
+
+ if (_msie)
+ _w.attachEvent('onbeforeunload', _unloadFix);
+
+ this.addListener(_w, 'unload', _unload);
+};
+
+asual.util.Functions = new function() {
+
+ this.toString = function() {
+ return '[class Functions]';
+ };
+
+ this.bind = function(method, object, param) {
+ for (var i = 2, p, arr = []; p = arguments[i]; i++)
+ arr.push(p);
+ return function() {
+ return method.apply(object, arr);
+ }
+ };
+};
+
+var SWFAddressEvent = function(type) {
+
+ this.toString = function() {
+ return '[object SWFAddressEvent]';
+ };
+
+ this.type = type;
+
+ this.target = [SWFAddress][0];
+
+ this.value = SWFAddress.getValue();
+
+ this.path = SWFAddress.getPath();
+
+ this.pathNames = SWFAddress.getPathNames();
+
+ this.parameters = {};
+
+ var _parameterNames = SWFAddress.getParameterNames();
+ for (var i = 0, l = _parameterNames.length; i < l; i++)
+ this.parameters[_parameterNames[i]] = SWFAddress.getParameter(_parameterNames[i]);
+
+ this.parameterNames = _parameterNames;
+
+};
+
+SWFAddressEvent.INIT = 'init';
+
+SWFAddressEvent.CHANGE = 'change';
+
+SWFAddressEvent.INTERNAL_CHANGE = 'internalChange';
+
+SWFAddressEvent.EXTERNAL_CHANGE = 'externalChange';
+
+var SWFAddress = new function() {
+
+ var _getHash = function() {
+ var index = _l.href.indexOf('#');
+ return index != -1 ? _ec(_dc(_l.href.substr(index + 1))) : '';
+ };
+
+ var _getWindow = function() {
+ return window;
+ };
+
+ var _strictCheck = function(value, force) {
+ if (_opts.strict)
+ value = force ? (value.substr(0, 1) != '/' ? '/' + value : value) : (value == '' ? '/' : value);
+ return value;
+ };
+
+ var _ieLocal = function(value, direction) {
+ return (_msie && _l.protocol == 'file:') ?
+ (direction ? _value.replace(/\?/, '%3F') : _value.replace(/%253F/, '?')) : value;
+ };
+
+ var _searchScript = function(el) {
+ if (el.childNodes) {
+ for (var i = 0, l = el.childNodes.length, s; i < l; i++) {
+ if (el.childNodes[i].src)
+ _url = String(el.childNodes[i].src);
+ if (s = _searchScript(el.childNodes[i]))
+ return s;
+ }
+ }
+ };
+
+ var _titleCheck = function() {
+ if (_d.title != _title && _d.title.indexOf('#') != -1)
+ _d.title = _title;
+ };
+
+ var _listen = function() {
+ if (!_silent) {
+ var hash = _getHash();
+ var diff = !(_value == hash);
+ if (_safari && _version < 523) {
+ if (_length != _h.length) {
+ _length = _h.length;
+ if (typeof _stack[_length - 1] != UNDEFINED)
+ _value = _stack[_length - 1];
+ _update.call(this, false);
+ }
+ } else if (_msie && diff) {
+ if (_version < 7)
+ _l.reload();
+ else
+ this.setValue(hash);
+ } else if (diff) {
+ _value = hash;
+ _update.call(this, false);
+ }
+ if (_msie)
+ _titleCheck.call(this);
+ }
+ };
+
+ var _bodyClick = function(e) {
+ if (_popup.length > 0) {
+ var popup = window.open(_popup[0], _popup[1], eval(_popup[2]));
+ if (typeof _popup[3] != UNDEFINED)
+ eval(_popup[3]);
+ }
+ _popup = [];
+ };
+
+ var _swfChange = function() {
+ for (var i = 0, id, obj, value = SWFAddress.getValue(), setter = 'setSWFAddressValue'; id = _ids[i]; i++) {
+ obj = document.getElementById(id);
+ if (obj) {
+ if (obj.parentNode && typeof obj.parentNode.so != UNDEFINED) {
+ obj.parentNode.so.call(setter, value);
+ } else {
+ if (!(obj && typeof obj[setter] != UNDEFINED)) {
+ var objects = obj.getElementsByTagName('object');
+ var embeds = obj.getElementsByTagName('embed');
+ obj = ((objects[0] && typeof objects[0][setter] != UNDEFINED) ?
+ objects[0] : ((embeds[0] && typeof embeds[0][setter] != UNDEFINED) ?
+ embeds[0] : null));
+ }
+ if (obj)
+ obj[setter](value);
+ }
+ } else if (obj = document[id]) {
+ if (typeof obj[setter] != UNDEFINED)
+ obj[setter](value);
+ }
+ }
+ };
+
+ var _jsDispatch = function(type) {
+ this.dispatchEvent(new SWFAddressEvent(type));
+ type = type.substr(0, 1).toUpperCase() + type.substr(1);
+ if (typeof this['on' + type] == FUNCTION)
+ this['on' + type]();
+ };
+
+ var _jsInit = function() {
+ if (_util.Browser.isSafari())
+ _d.body.addEventListener('click', _bodyClick);
+ _jsDispatch.call(this, 'init');
+ };
+
+ var _jsChange = function() {
+ _swfChange();
+ _jsDispatch.call(this, 'change');
+ };
+
+ var _update = function(internal) {
+ _jsChange.call(this);
+ if (internal) {
+ _jsDispatch.call(this, 'internalChange');
+ } else {
+ _jsDispatch.call(this, 'externalChange');
+ }
+ _st(_functions.bind(_track, this), 10);
+ };
+
+ var _track = function() {
+ var value = (_l.pathname + (/\/$/.test(_l.pathname) ? '' : '/') + this.getValue()).replace(/\/\//, '/').replace(/^\/$/, '');
+ var fn = _t[_opts.tracker];
+ if (typeof fn == FUNCTION)
+ fn(value);
+ else if (typeof _t.pageTracker != UNDEFINED && typeof _t.pageTracker._trackPageview == FUNCTION)
+ _t.pageTracker._trackPageview(value);
+ else if (typeof _t.urchinTracker == FUNCTION)
+ _t.urchinTracker(value);
+ };
+
+ var _htmlWrite = function() {
+ var doc = _frame.contentWindow.document;
+ doc.open();
+ doc.write('<html><head><title>' + _d.title + '</title><script>var ' + ID + ' = "' + _getHash() + '";</script></head></html>');
+ doc.close();
+ };
+
+ var _htmlLoad = function() {
+ var win = _frame.contentWindow;
+ var src = win.location.href;
+ _value = (typeof win[ID] != UNDEFINED ? win[ID] : '');
+ if (_value != _getHash()) {
+ _update.call(SWFAddress, false);
+ _l.hash = _ieLocal(_value, TRUE);
+ }
+ };
+
+ var _load = function() {
+ if (!_loaded) {
+ _loaded = TRUE;
+ if (_msie && _version < 8) {
+ var frameset = _d.getElementsByTagName('frameset')[0];
+ _frame = _d.createElement((frameset ? '' : 'i') + 'frame');
+ if (frameset) {
+ frameset.insertAdjacentElement('beforeEnd', _frame);
+ frameset[frameset.cols ? 'cols' : 'rows'] += ',0';
+ _frame.src = 'javascript:false';
+ _frame.noResize = true;
+ _frame.frameBorder = _frame.frameSpacing = 0;
+ } else {
+ _frame.src = 'javascript:false';
+ _frame.style.display = 'none';
+ _d.body.insertAdjacentElement('afterBegin', _frame);
+ }
+ _st(function() {
+ _events.addListener(_frame, 'load', _htmlLoad);
+ if (typeof _frame.contentWindow[ID] == UNDEFINED)
+ _htmlWrite();
+ }, 50);
+ } else if (_safari) {
+ if (_version < 418) {
+ _d.body.innerHTML += '<form id="' + ID + '" style="position:absolute;top:-9999px;" method="get"></form>';
+ _form = _d.getElementById(ID);
+ }
+ if (typeof _l[ID] == UNDEFINED)
+ _l[ID] = {};
+ if (typeof _l[ID][_l.pathname] != UNDEFINED)
+ _stack = _l[ID][_l.pathname].split(',');
+ }
+
+ _st(_functions.bind(function() {
+ _jsInit.call(this);
+ _jsChange.call(this);
+ _track.call(this);
+ }, this), 1);
+
+ if (_msie && _version >= 8) {
+ _d.body.onhashchange = _functions.bind(_listen, this);
+ _si(_functions.bind(_titleCheck, this), 50);
+ } else {
+ _si(_functions.bind(_listen, this), 50);
+ }
+ }
+ };
+
+ var ID = 'swfaddress',
+ FUNCTION = 'function',
+ UNDEFINED = 'undefined',
+ TRUE = true,
+ FALSE = false,
+ _util = asual.util,
+ _browser = _util.Browser,
+ _events = _util.Events,
+ _functions = _util.Functions,
+ _version = _browser.getVersion(),
+ _msie = _browser.isMSIE(),
+ _mozilla = _browser.isMozilla(),
+ _opera = _browser.isOpera(),
+ _safari = _browser.isSafari(),
+ _supported = FALSE,
+ _t = _getWindow(),
+ _d = _t.document,
+ _h = _t.history,
+ _l = _t.location,
+ _si = setInterval,
+ _st = setTimeout,
+ _dc = decodeURI,
+ _ec = encodeURI,
+ _frame,
+ _form,
+ _url,
+ _title = _d.title,
+ _length = _h.length,
+ _silent = FALSE,
+ _loaded = FALSE,
+ _justset = TRUE,
+ _juststart = TRUE,
+ _ref = this,
+ _stack = [],
+ _ids = [],
+ _popup = [],
+ _listeners = {},
+ _value = _getHash(),
+ _opts = {history: TRUE, strict: TRUE};
+
+ if (_msie && _d.documentMode && _d.documentMode != _version)
+ _version = _d.documentMode != 8 ? 7 : 8;
+
+ _supported =
+ (_mozilla && _version >= 1) ||
+ (_msie && _version >= 6) ||
+ (_opera && _version >= 9.5) ||
+ (_safari && _version >= 312);
+
+ if (_supported) {
+
+ if (_opera)
+ history.navigationMode = 'compatible';
+
+ for (var i = 1; i < _length; i++)
+ _stack.push('');
+
+ _stack.push(_getHash());
+
+ if (_msie && _l.hash != _getHash())
+ _l.hash = '#' + _ieLocal(_getHash(), TRUE);
+
+ _searchScript(document);
+ var _qi = _url ? _url.indexOf('?') : -1;
+ if (_qi != -1) {
+ var param, params = _url.substr(_qi + 1).split('&');
+ for (var i = 0, p; p = params[i]; i++) {
+ param = p.split('=');
+ if (/^(history|strict)$/.test(param[0])) {
+ _opts[param[0]] = (isNaN(param[1]) ? /^(true|yes)$/i.test(param[1]) : (parseInt(param[1]) != 0));
+ }
+ if (/^tracker$/.test(param[0]))
+ _opts[param[0]] = param[1];
+ }
+ }
+
+ if (_msie)
+ _titleCheck.call(this);
+
+ if (window == _t)
+ _events.addListener(document, 'DOMContentLoaded', _functions.bind(_load, this));
+ _events.addListener(_t, 'load', _functions.bind(_load, this));
+
+ } /*else if ((!_supported && _l.href.indexOf('#') != -1) ||
+ (_safari && _version < 418 && _l.href.indexOf('#') != -1 && _l.search != '')){
+ _d.open();
+ _d.write('<html><head><meta http-equiv="refresh" content="0;url=' +
+ _l.href.substr(0, _l.href.indexOf('#')) + '" /></head></html>');
+ _d.close();
+ } */ else {
+ _track();
+ }
+
+ this.toString = function() {
+ return '[class SWFAddress]';
+ };
+
+ this.back = function() {
+ _h.back();
+ };
+
+ this.forward = function() {
+ _h.forward();
+ };
+
+ this.up = function() {
+ var path = this.getPath();
+ this.setValue(path.substr(0, path.lastIndexOf('/', path.length - 2) + (path.substr(path.length - 1) == '/' ? 1 : 0)));
+ };
+
+ this.go = function(delta) {
+ _h.go(delta);
+ };
+
+ this.href = function(url, target) {
+ target = typeof target != UNDEFINED ? target : '_self';
+ if (target == '_self')
+ self.location.href = url;
+ else if (target == '_top')
+ _l.href = url;
+ else if (target == '_blank')
+ window.open(url);
+ else
+ _t.frames[target].location.href = url;
+ };
+
+ this.popup = function(url, name, options, handler) {
+ try {
+ var popup = window.open(url, name, eval(options));
+ if (typeof handler != UNDEFINED)
+ eval(handler);
+ } catch (ex) {
+ }
+ _popup = arguments;
+ };
+
+ this.getIds = function() {
+ return _ids;
+ };
+
+ this.getId = function(index) {
+ return _ids[0];
+ };
+
+ this.setId = function(id) {
+ _ids[0] = id;
+ };
+
+ this.addId = function(id) {
+ this.removeId(id);
+ _ids.push(id);
+ };
+
+ this.removeId = function(id) {
+ for (var i = 0; i < _ids.length; i++) {
+ if (id == _ids[i]) {
+ _ids.splice(i, 1);
+ break;
+ }
+ }
+ };
+
+ this.addEventListener = function(type, listener) {
+ if (typeof _listeners[type] == UNDEFINED)
+ _listeners[type] = [];
+ _listeners[type].push(listener);
+ };
+
+ this.removeEventListener = function(type, listener) {
+ if (typeof _listeners[type] != UNDEFINED) {
+ for (var i = 0, l; l = _listeners[type][i]; i++)
+ if (l == listener)
+ break;
+ _listeners[type].splice(i, 1);
+ }
+ };
+
+ this.dispatchEvent = function(event) {
+ if (this.hasEventListener(event.type)) {
+ event.target = this;
+ for (var i = 0, l; l = _listeners[event.type][i]; i++)
+ l(event);
+ return TRUE;
+ }
+ return FALSE;
+ };
+
+ this.hasEventListener = function(type) {
+ return (typeof _listeners[type] != UNDEFINED && _listeners[type].length > 0);
+ };
+
+ this.getBaseURL = function() {
+ var url = _l.href;
+ if (url.indexOf('#') != -1)
+ url = url.substr(0, url.indexOf('#'));
+ if (url.substr(url.length - 1) == '/')
+ url = url.substr(0, url.length - 1);
+ return url;
+ };
+
+ this.getStrict = function() {
+ return _opts.strict;
+ };
+
+ this.setStrict = function(strict) {
+ _opts.strict = strict;
+ };
+
+ this.getHistory = function() {
+ return _opts.history;
+ };
+
+ this.setHistory = function(history) {
+ _opts.history = history;
+ };
+
+ this.getTracker = function() {
+ return _opts.tracker;
+ };
+
+ this.setTracker = function(tracker) {
+ _opts.tracker = tracker;
+ };
+
+ this.getTitle = function() {
+ return _d.title;
+ };
+
+ this.setTitle = function(title) {
+ if (!_supported)
+ return null;
+ if (typeof title == UNDEFINED)
+ return;
+ if (title == 'null')
+ title = '';
+ title = _dc(title);
+ _st(function() {
+ _title = _d.title = title;
+ if (_juststart && _frame && _frame.contentWindow && _frame.contentWindow.document) {
+ _frame.contentWindow.document.title = title;
+ _juststart = FALSE;
+ }
+ if (!_justset && _mozilla)
+ _l.replace(_l.href.indexOf('#') != -1 ? _l.href : _l.href + '#');
+ _justset = FALSE;
+ }, 10);
+ };
+
+ this.getStatus = function() {
+ return _t.status;
+ };
+
+ this.setStatus = function(status) {
+ if (!_supported)
+ return null;
+ if (typeof status == UNDEFINED)
+ return;
+ if (status == 'null')
+ status = '';
+ status = _dc(status);
+ if (!_safari) {
+ status = _strictCheck((status != 'null') ? status : '', TRUE);
+ if (status == '/')
+ status = '';
+ if (!(/http(s)?:\/\//.test(status))) {
+ var index = _l.href.indexOf('#');
+ status = (index == -1 ? _l.href : _l.href.substr(0, index)) + '#' + status;
+ }
+ _t.status = status;
+ }
+ };
+
+ this.resetStatus = function() {
+ _t.status = '';
+ };
+
+ this.getValue = function() {
+ if (!_supported)
+ return null;
+ return _dc(_strictCheck(_ieLocal(_value, FALSE), FALSE));
+ };
+
+ this.setValue = function(value) {
+ if (!_supported)
+ return null;
+ if (typeof value == UNDEFINED)
+ return;
+ if (value == 'null')
+ value = '';
+ value = _ec(_dc(_strictCheck(value, TRUE)));
+ if (value == '/')
+ value = '';
+ if (_value == value)
+ return;
+ _justset = TRUE;
+ _value = value;
+ _silent = TRUE;
+ _update.call(SWFAddress, true);
+ _stack[_h.length] = _value;
+ if (_safari) {
+ if (_opts.history) {
+ _l[ID][_l.pathname] = _stack.toString();
+ _length = _h.length + 1;
+ if (_version < 418) {
+ if (_l.search == '') {
+ _form.action = '#' + _value;
+ _form.submit();
+ }
+ } else if (_version < 523 || _value == '') {
+ var evt = _d.createEvent('MouseEvents');
+ evt.initEvent('click', TRUE, TRUE);
+ var anchor = _d.createElement('a');
+ anchor.href = '#' + _value;
+ anchor.dispatchEvent(evt);
+ } else {
+ _l.hash = '#' + _value;
+ }
+ } else {
+ _l.replace('#' + _value);
+ }
+ } else if (_value != _getHash()) {
+ if (_opts.history)
+ _l.hash = '#' + _dc(_ieLocal(_value, TRUE));
+ else
+ _l.replace('#' + _dc(_value));
+ }
+ if ((_msie && _version < 8) && _opts.history) {
+ _st(_htmlWrite, 50);
+ }
+ if (_safari)
+ _st(function() {
+ _silent = FALSE;
+ }, 1);
+ else
+ _silent = FALSE;
+ };
+
+ this.getPath = function() {
+ var value = this.getValue();
+ if (value.indexOf('?') != -1) {
+ return value.split('?')[0];
+ } else if (value.indexOf('#') != -1) {
+ return value.split('#')[0];
+ } else {
+ return value;
+ }
+ };
+
+ this.getPathNames = function() {
+ var path = this.getPath(), names = path.split('/');
+ if (path.substr(0, 1) == '/' || path.length == 0)
+ names.splice(0, 1);
+ if (path.substr(path.length - 1, 1) == '/')
+ names.splice(names.length - 1, 1);
+ return names;
+ };
+
+ this.getQueryString = function() {
+ var value = this.getValue(), index = value.indexOf('?');
+ if (index != -1 && index < value.length)
+ return value.substr(index + 1);
+ };
+
+ this.getParameter = function(param) {
+ var value = this.getValue();
+ var index = value.indexOf('?');
+ if (index != -1) {
+ value = value.substr(index + 1);
+ var p, params = value.split('&'), i = params.length, r = [];
+ while (i--) {
+ p = params[i].split('=');
+ if (p[0] == param)
+ r.push(p[1]);
+ }
+ if (r.length != 0)
+ return r.length != 1 ? r : r[0];
+ }
+ };
+
+ this.getParameterNames = function() {
+ var value = this.getValue();
+ var index = value.indexOf('?');
+ var names = [];
+ if (index != -1) {
+ value = value.substr(index + 1);
+ if (value != '' && value.indexOf('=') != -1) {
+ var params = value.split('&'), i = 0;
+ while (i < params.length) {
+ names.push(params[i].split('=')[0]);
+ i++;
+ }
+ }
+ }
+ return names;
+ };
+
+ this.onInit = null;
+
+ this.onChange = null;
+
+ this.onInternalChange = null;
+
+ this.onExternalChange = null;
+
+ (function() {
+
+ var _args;
+
+ if (typeof FlashObject != UNDEFINED)
+ SWFObject = FlashObject;
+ if (typeof SWFObject != UNDEFINED && SWFObject.prototype && SWFObject.prototype.write) {
+ var _s1 = SWFObject.prototype.write;
+ SWFObject.prototype.write = function() {
+ _args = arguments;
+ if (this.getAttribute('version').major < 8) {
+ this.addVariable('$swfaddress', SWFAddress.getValue());
+ ((typeof _args[0] == 'string') ?
+ document.getElementById(_args[0]) : _args[0]).so = this;
+ }
+ var success;
+ if (success = _s1.apply(this, _args))
+ _ref.addId(this.getAttribute('id'));
+ return success;
+ }
+ }
+
+ if (typeof swfobject != UNDEFINED) {
+ var _s2r = swfobject.registerObject;
+ swfobject.registerObject = function() {
+ _args = arguments;
+ _s2r.apply(this, _args);
+ _ref.addId(_args[0]);
+ }
+ var _s2c = swfobject.createSWF;
+ swfobject.createSWF = function() {
+ _args = arguments;
+ var swf = _s2c.apply(this, _args);
+ if (swf)
+ _ref.addId(_args[0].id);
+ return swf;
+ }
+ var _s2e = swfobject.embedSWF;
+ swfobject.embedSWF = function() {
+ _args = arguments;
+ if (typeof _args[8] == UNDEFINED)
+ _args[8] = {};
+ if (typeof _args[8].id == UNDEFINED)
+ _args[8].id = _args[1];
+ _s2e.apply(this, _args);
+ _ref.addId(_args[8].id);
+ }
+ }
+
+ if (typeof UFO != UNDEFINED) {
+ var _u = UFO.create;
+ UFO.create = function() {
+ _args = arguments;
+ _u.apply(this, _args);
+ _ref.addId(_args[0].id);
+ }
+ }
+
+ if (typeof AC_FL_RunContent != UNDEFINED) {
+ var _a = AC_FL_RunContent;
+ AC_FL_RunContent = function() {
+ _args = arguments;
+ _a.apply(this, _args);
+ for (var i = 0, l = _args.length; i < l; i++)
+ if (_args[i] == 'id')
+ _ref.addId(_args[i + 1]);
+ }
+ }
+
+ })();
+};
protected function mergeJavascript() {
$dest = WS_COMPILE_ASSETS . '/fluidbook.js';
$orig = WS_COMPILE_ASSETS . '/_js/';
- $files = array('swfobject.js' => false, 'swfaddress.js' => true, 'fluidbook.js' => true);
+ $files = array('log4js.js' => false, 'esapi.js' => false, 'resources/i18n/ESAPI_Standard_en_US.properties.js' => false, 'resources/Base.esapi.properties.js' => false, 'swfobject.js' => false, 'swfaddress.js' => true, 'fluidbook.js' => true);
$refresh = false;
if (file_exists($dest)) {
-<?php\r
-\r
-class wsPackager {\r
-\r
- protected $dir;\r
- protected $vdir;\r
- public $book;\r
- protected $pages;\r
- protected $theme;\r
- protected $version;\r
- protected $book_id;\r
- protected $themeRoot;\r
- protected $daoBook;\r
- protected $zip;\r
- protected $workingDir;\r
- protected $whole = true;\r
- public $cleanOnDestruct = true;\r
-\r
- public static function package($book_id, $version, $zip = true) {\r
- global $packager;\r
-\r
- cubePHP::neverStop();\r
- if ($version == 'html') {\r
- $packager = new wsPackagerHTML($book_id);\r
- } elseif ($version == 'win-exe') {\r
- $packager = new wsPackagerWinEXE($book_id);\r
- } elseif ($version == 'win-cd') {\r
- $packager = new wsPackagerWinCD($book_id);\r
- } elseif ($version == 'win-ins') {\r
- $packager = new wsPackagerWinINST($book_id);\r
- } elseif ($version == 'mac-exe') {\r
- $packager = new wsPackagerMacEXE($book_id);\r
- } elseif ($version == 'v1') {\r
- $packager = new wsPackagerV1($book_id);\r
- } else if ($version == 'phonegap') {\r
- $packager = new wsPackagerPhonegap($book_id);\r
- }\r
-\r
- return $packager->makePackage($zip);\r
- }\r
-\r
- public function __construct($book_id, $vdir = null, $whole = true) {\r
- global $core;\r
-\r
- $this->book_id = $book_id;\r
-\r
- $this->vdir = $vdir;\r
- $this->dir = ROOT . '/fluidbook/packager/' . $book_id . '/';\r
- $this->whole = $whole;\r
-\r
- if (!file_exists($this->dir)) {\r
- mkdir($this->dir, 0777, true);\r
- }\r
-\r
- $this->daoBook = new wsDAOBook($core->con);\r
- $this->book = $this->daoBook->selectById($book_id);\r
- $this->pages = $this->daoBook->getPagesOfBook($book_id, false);\r
-\r
- $daoTheme = new wsDAOTheme($core->con);\r
- $this->theme = $daoTheme->getThemeOfBook($book_id, true);\r
- $this->themeRoot = WS_THEMES . '/' . $this->theme->theme_id . '/';\r
-\r
- $this->workingDir = WS_BOOKS . '/working/' . $book_id . '/';\r
-\r
- $this->compile();\r
- }\r
-\r
- protected function compile() {\r
- $this->daoBook->compile($this->book_id, '2');\r
- }\r
-\r
- protected function preparePackage() {\r
- $this->initTempDir();\r
- }\r
-\r
- public function makePackage($zip) {\r
- $this->preparePackage();\r
- }\r
-\r
- protected function replaceContents($str, $toReplace) {\r
- $res = $str;\r
- foreach ($toReplace as $k => $v) {\r
- if (is_null($v)) {\r
- return;\r
- }\r
- $res = str_replace('$' . $k, $v, $res);\r
- }\r
- return $res;\r
- }\r
-\r
- protected function copyFluidbookFiles() {\r
- // Copie du FB vers un répertoire temporaire\r
- $cp = new cubeCommandLine('cp');\r
- $cp->setArg('R');\r
- $cp->setArg('p');\r
- $cp->setArg(null, WS_BOOKS . '/final/' . $this->book->book_id . '/*');\r
- $cp->setArg(null, $this->vdir);\r
- $cp->execute();\r
- }\r
-\r
- protected function copyOtherFiles($files) {\r
- foreach ($files as $source => $dest) {\r
- if (is_int($source)) {\r
- $source = $dest;\r
- }\r
-\r
- $s = WS_COMPILE_ASSETS . '/' . $source;\r
- if (is_file($s) && !file_exists($this->vdir . $dest)) {\r
- $this->copy($s, $this->vdir . $dest);\r
- } else if (is_dir($s)) {\r
- $cp = new cubeCommandLine('cp');\r
- $cp->setArg('R');\r
- $cp->setArg('p');\r
- $cp->setArg(null, $s);\r
- $cp->setArg(null, $this->vdir);\r
- $cp->execute();\r
-\r
- $mv = new cubeCommandLine('mv');\r
- $mv->setArg($this->vdir . '/' . $source);\r
- $mv->setArg($this->vdir . '/' . $dest);\r
- $mv->execute();\r
- }\r
- }\r
- }\r
-\r
- protected function getBaseFile() {\r
- return $this->version . '-' . date('Ymdhis', TIME) . '-' . cubeText::str2URL($this->book->parametres->title);\r
- }\r
-\r
- protected function getRelativeBase() {\r
- return '/packager/download/' . $this->getBaseFile();\r
- }\r
-\r
- protected function getURLBase($ext = '') {\r
- $res = '/fluidbook' . $this->getRelativeBase();\r
- if ($ext != '') {\r
- $res .= '.' . $ext;\r
- }\r
- return $res;\r
- }\r
-\r
- protected function getPathBase($ext = '') {\r
- $res = WS_FILES . $this->getRelativeBase();\r
- if ($ext != '') {\r
- $res .= '.' . $ext;\r
- }\r
-\r
- return $res;\r
- }\r
-\r
- protected function zip($zipfile = null) {\r
- if (!$this->whole) {\r
- return;\r
- }\r
- $url = $this->getURLBase('zip');\r
- $final = $this->getPathBase('zip');\r
- $rename = false;\r
- if (is_null($zipfile)) {\r
- $zipfile = $final;\r
- } else {\r
- $rename = true;\r
- }\r
-\r
- $zip = new cubeCommandLine('zip');\r
- $zip->cd($this->vdir);\r
- $zip->setArg(null, $zipfile);\r
- $zip->setArg('0');\r
- $zip->setArg('r');\r
- $zip->setArg('u');\r
- $zip->setArg(null, '.');\r
- $zip->execute();\r
-\r
- if (!file_exists(WS_FILES . '/packager/download')) {\r
- mkdir(WS_FILES . '/packager/download', 0777, true);\r
- }\r
-\r
- if ($rename) {\r
- rename($zipfile, $final);\r
- }\r
- return $url;\r
- }\r
-\r
- protected function initTempDir() {\r
- if (is_null($this->vdir)) {\r
- $this->vdir = $this->dir . $this->version . '/';\r
- }\r
- $this->cleanVdir();\r
- if (!file_exists($this->vdir . '/data')) {\r
- mkdir($this->vdir . '/data', 0777, true);\r
- }\r
- }\r
-\r
- protected function cleanVdir() {\r
- if (file_exists($this->vdir)) {\r
- return;\r
- // Suppression du répertoire si il existe\r
- $rm = new cubeCommandLine('rm');\r
- $rm->setArg('r');\r
- $rm->setArg('f');\r
- $rm->setArg(null, $this->vdir);\r
- $rm->execute();\r
- }\r
- }\r
-\r
- protected function moveDatasSWF() {\r
- if (file_exists($this->vdir . '/FluidbookDatas.swf')) {\r
- rename($this->vdir . '/FluidbookDatas.swf', $this->vdir . '/data/FluidbookDatas.swf');\r
- }\r
- if (file_exists($this->vdir . '/FluidbookDatasLight.swf')) {\r
- rename($this->vdir . '/FluidbookDatasLight.swf', $this->vdir . '/data/FluidbookDatasLight.swf');\r
- }\r
- }\r
-\r
- protected function postPackage() {\r
- \r
- }\r
-\r
- public function __destruct() {\r
- if ($this->whole && $this->cleanOnDestruct) {\r
- $this->cleanVdir();\r
- }\r
- }\r
-\r
- public function copy($source, $dest) {\r
- if (!file_exists($source)) {\r
- return;\r
- }\r
- copy($source, $dest);\r
- touch($dest, filemtime($source));\r
- }\r
-\r
-}\r
-\r
+<?php
+
+class wsPackager {
+
+ protected $dir;
+ protected $vdir;
+ public $book;
+ protected $pages;
+ protected $theme;
+ protected $version;
+ protected $book_id;
+ protected $themeRoot;
+ protected $daoBook;
+ protected $zip;
+ protected $workingDir;
+ protected $whole = true;
+ public $cleanOnDestruct = true;
+
+ public static function package($book_id, $version, $zip = true) {
+ global $packager;
+
+ cubePHP::neverStop();
+ if ($version == 'html') {
+ $packager = new wsPackagerHTML($book_id);
+ } elseif ($version == 'win-exe') {
+ $packager = new wsPackagerWinEXE($book_id);
+ } elseif ($version == 'win-cd') {
+ $packager = new wsPackagerWinCD($book_id);
+ } elseif ($version == 'win-ins') {
+ $packager = new wsPackagerWinINST($book_id);
+ } elseif ($version == 'mac-exe') {
+ $packager = new wsPackagerMacEXE($book_id);
+ } elseif ($version == 'v1') {
+ $packager = new wsPackagerV1($book_id);
+ } else if ($version == 'phonegap') {
+ $packager = new wsPackagerPhonegap($book_id);
+ }
+
+ return $packager->makePackage($zip);
+ }
+
+ public function __construct($book_id, $vdir = null, $whole = true) {
+ global $core;
+
+ $this->book_id = $book_id;
+
+ $this->vdir = $vdir;
+ $this->dir = ROOT . '/fluidbook/packager/' . $book_id . '/';
+ $this->whole = $whole;
+
+ if (!file_exists($this->dir)) {
+ mkdir($this->dir, 0777, true);
+ }
+
+ $this->daoBook = new wsDAOBook($core->con);
+ $this->book = $this->daoBook->selectById($book_id);
+ $this->pages = $this->daoBook->getPagesOfBook($book_id, false);
+
+ $daoTheme = new wsDAOTheme($core->con);
+ $this->theme = $daoTheme->getThemeOfBook($book_id, true);
+ $this->themeRoot = WS_THEMES . '/' . $this->theme->theme_id . '/';
+
+ $this->workingDir = WS_BOOKS . '/working/' . $book_id . '/';
+
+ $this->compile();
+ }
+
+ protected function compile() {
+ $this->daoBook->compile($this->book_id, '2');
+ }
+
+ protected function preparePackage() {
+ $this->initTempDir();
+ }
+
+ public function makePackage($zip) {
+ $this->preparePackage();
+ }
+
+ protected function replaceContents($str, $toReplace) {
+ $res = $str;
+ foreach ($toReplace as $k => $v) {
+ if (is_null($v)) {
+ return;
+ }
+ $res = str_replace('$' . $k, $v, $res);
+ }
+ return $res;
+ }
+
+ protected function copyFluidbookFiles() {
+ // Copie du FB vers un répertoire temporaire
+ $cp = new cubeCommandLine('cp');
+ $cp->setArg('R');
+ $cp->setArg('p');
+ $cp->setArg(null, WS_BOOKS . '/final/' . $this->book->book_id . '/*');
+ $cp->setArg(null, $this->vdir);
+ $cp->execute();
+ }
+
+ protected function copyOtherFiles($files) {
+ foreach ($files as $source => $dest) {
+ if (is_int($source)) {
+ $source = $dest;
+ }
+
+ $s = WS_COMPILE_ASSETS . '/' . $source;
+ if (is_file($s) && !file_exists($this->vdir . $dest)) {
+ $this->copy($s, $this->vdir . $dest);
+ } else if (is_dir($s)) {
+ $cp = new cubeCommandLine('cp');
+ $cp->setArg('R');
+ $cp->setArg('p');
+ $cp->setArg(null, $s);
+ $cp->setArg(null, $this->vdir);
+ $cp->execute();
+
+ $mv = new cubeCommandLine('mv');
+ $mv->setArg($this->vdir . '/' . $source);
+ $mv->setArg($this->vdir . '/' . $dest);
+ $mv->execute();
+ }
+ }
+ }
+
+ protected function getBaseFile() {
+ return $this->version . '-' . date('Ymdhis', TIME) . '-' . cubeText::str2URL($this->book->parametres->title);
+ }
+
+ protected function getRelativeBase() {
+ return '/packager/download/' . $this->getBaseFile();
+ }
+
+ protected function getURLBase($ext = '') {
+ $res = '/fluidbook' . $this->getRelativeBase();
+ if ($ext != '') {
+ $res .= '.' . $ext;
+ }
+ return $res;
+ }
+
+ protected function getPathBase($ext = '') {
+ $res = WS_FILES . $this->getRelativeBase();
+ if ($ext != '') {
+ $res .= '.' . $ext;
+ }
+
+ return $res;
+ }
+
+ protected function zip($zipfile = null) {
+ if (!$this->whole) {
+ return;
+ }
+ $url = $this->getURLBase('zip');
+ $final = $this->getPathBase('zip');
+ $rename = false;
+ if (is_null($zipfile)) {
+ $zipfile = $final;
+ } else {
+ $rename = true;
+ }
+
+ $zip = new cubeCommandLine('zip');
+ $zip->cd($this->vdir);
+ $zip->setArg(null, $zipfile);
+ $zip->setArg('0');
+ $zip->setArg('r');
+ $zip->setArg('u');
+ $zip->setArg(null, '.');
+ $zip->execute();
+
+ if (!file_exists(WS_FILES . '/packager/download')) {
+ mkdir(WS_FILES . '/packager/download', 0777, true);
+ }
+
+ if ($rename) {
+ rename($zipfile, $final);
+ }
+ return $url;
+ }
+
+ protected function initTempDir() {
+ if (is_null($this->vdir)) {
+ $this->vdir = $this->dir . $this->version . '/';
+ }
+ $this->cleanVdir();
+ if (!file_exists($this->vdir . '/data')) {
+ mkdir($this->vdir . '/data', 0777, true);
+ }
+ }
+
+ protected function cleanVdir() {
+ if (file_exists($this->vdir)) {
+
+ // Suppression du répertoire si il existe
+ $rm = new cubeCommandLine('rm');
+ $rm->setArg('r');
+ $rm->setArg('f');
+ $rm->setArg(null, $this->vdir);
+ $rm->execute();
+ }
+ }
+
+ protected function moveDatasSWF() {
+ if (file_exists($this->vdir . '/FluidbookDatas.swf')) {
+ rename($this->vdir . '/FluidbookDatas.swf', $this->vdir . '/data/FluidbookDatas.swf');
+ }
+ if (file_exists($this->vdir . '/FluidbookDatasLight.swf')) {
+ rename($this->vdir . '/FluidbookDatasLight.swf', $this->vdir . '/data/FluidbookDatasLight.swf');
+ }
+ }
+
+ protected function postPackage() {
+
+ }
+
+ public function __destruct() {
+ if ($this->whole && $this->cleanOnDestruct) {
+ $this->cleanVdir();
+ }
+ }
+
+ public function copy($source, $dest) {
+ if (!file_exists($source)) {
+ return;
+ }
+ copy($source, $dest);
+ touch($dest, filemtime($source));
+ }
+
+}
+
?>
\ No newline at end of file