(function($) {
if(!window.DCP){
	$.initWindowMsg();
	var DCP = {
		urls:{
			'registration-mail-resend':'/jsonservice/resenduserregistrationmail',
			'password-reset-mail-resend':'/jsonservice/sendpasswordresetmail',
			'api-url':'http://www.mmaprofighter.com/api'
		},
		getUrl:function(name){
			return DCP.urls[name];
		}
	}
	window.DCP 		= DCP
	window.Library 	= DCP;
}

//include public/javascripts/library/third-party/json2.js
/**
 * This is the stock JSON2 implementation from www.json.org.
 *
 * Modifications include:
 * 1/ Removal of jslint settings
 *
 * @provides dc.thirdparty.json2
 */

/*
    http://www.JSON.org/json2.js
    2009-09-29

    Public Domain.

    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.

    See http://www.JSON.org/js.html

    This file creates a global JSON object containing two methods: stringify
    and parse.

        JSON.stringify(value, replacer, space)
            value       any JavaScript value, usually an object or array.

            replacer    an optional parameter that determines how object
                        values are stringified for objects. It can be a
                        function or an array of strings.

            space       an optional parameter that specifies the indentation
                        of nested structures. If it is omitted, the text will
                        be packed without extra whitespace. If it is a number,
                        it will specify the number of spaces to indent at each
                        level. If it is a string (such as '\t' or '&nbsp;'),
                        it contains the characters used to indent at each level.

            This method produces a JSON text from a JavaScript value.

            When an object value is found, if the object contains a toJSON
            method, its toJSON method will be called and the result will be
            stringified. A toJSON method does not serialize: it returns the
            value represented by the name/value pair that should be serialized,
            or undefined if nothing should be serialized. The toJSON method
            will be passed the key associated with the value, and this will be
            bound to the value

            For example, this would serialize Dates as ISO strings.

                Date.prototype.toJSON = function (key) {
                    function f(n) {
                        // Format integers to have at least two digits.
                        return n < 10 ? '0' + n : n;
                    }

                    return this.getUTCFullYear()   + '-' +
                         f(this.getUTCMonth() + 1) + '-' +
                         f(this.getUTCDate())      + 'T' +
                         f(this.getUTCHours())     + ':' +
                         f(this.getUTCMinutes())   + ':' +
                         f(this.getUTCSeconds())   + 'Z';
                };

            You can provide an optional replacer method. It will be passed the
            key and value of each member, with this bound to the containing
            object. The value that is returned from your method will be
            serialized. If your method returns undefined, then the member will
            be excluded from the serialization.

            If the replacer parameter is an array of strings, then it will be
            used to select the members to be serialized. It filters the results
            such that only members with keys listed in the replacer array are
            stringified.

            Values that do not have JSON representations, such as undefined or
            functions, will not be serialized. Such values in objects will be
            dropped; in arrays they will be replaced with null. You can use
            a replacer function to replace those with JSON values.
            JSON.stringify(undefined) returns undefined.

            The optional space parameter produces a stringification of the
            value that is filled with line breaks and indentation to make it
            easier to read.

            If the space parameter is a non-empty string, then that string will
            be used for indentation. If the space parameter is a number, then
            the indentation will be that many spaces.

            Example:

            text = JSON.stringify(['e', {pluribus: 'unum'}]);
            // text is '["e",{"pluribus":"unum"}]'


            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'

            text = JSON.stringify([new Date()], function (key, value) {
                return this[key] instanceof Date ?
                    'Date(' + this[key] + ')' : value;
            });
            // text is '["Date(---current time---)"]'


        JSON.parse(text, reviver)
            This method parses a JSON text to produce an object or array.
            It can throw a SyntaxError exception.

            The optional reviver parameter is a function that can filter and
            transform the results. It receives each of the keys and values,
            and its return value is used instead of the original value.
            If it returns what it received, then the structure is not modified.
            If it returns undefined then the member is deleted.

            Example:

            // Parse the text. Values that look like ISO date strings will
            // be converted to Date objects.

            myData = JSON.parse(text, function (key, value) {
                var a;
                if (typeof value === 'string') {
                    a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
                    if (a) {
                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
                            +a[5], +a[6]));
                    }
                }
                return value;
            });

            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
                var d;
                if (typeof value === 'string' &&
                        value.slice(0, 5) === 'Date(' &&
                        value.slice(-1) === ')') {
                    d = new Date(value.slice(5, -1));
                    if (d) {
                        return d;
                    }
                }
                return value;
            });


    This is a reference implementation. You are free to copy, modify, or
    redistribute.

    This code should be minified before deployment.
    See http://javascript.crockford.com/jsmin.html

    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
    NOT CONTROL.
*/


// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.

if (!this.JSON) {
    this.JSON = {};
}

(function () {

    function f(n) {
        // Format integers to have at least two digits.
        return n < 10 ? '0' + n : n;
    }

    if (typeof Date.prototype.toJSON !== 'function') {

        Date.prototype.toJSON = function (key) {

            return isFinite(this.valueOf()) ?
                   this.getUTCFullYear()   + '-' +
                 f(this.getUTCMonth() + 1) + '-' +
                 f(this.getUTCDate())      + 'T' +
                 f(this.getUTCHours())     + ':' +
                 f(this.getUTCMinutes())   + ':' +
                 f(this.getUTCSeconds())   + 'Z' : null;
        };

        String.prototype.toJSON =
        Number.prototype.toJSON =
        Boolean.prototype.toJSON = function (key) {
            return this.valueOf();
        };
    }

    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        gap,
        indent,
        meta = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        rep;


    function quote(string) {

// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.

        escapable.lastIndex = 0;
        return escapable.test(string) ?
            '"' + string.replace(escapable, function (a) {
                var c = meta[a];
                return typeof c === 'string' ? c :
                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
            }) + '"' :
            '"' + string + '"';
    }


    function str(key, holder) {

// Produce a string from holder[key].

        var i,          // The loop counter.
            k,          // The member key.
            v,          // The member value.
            length,
            mind = gap,
            partial,
            value = holder[key];

// If the value has a toJSON method, call it to obtain a replacement value.

        if (value && typeof value === 'object' &&
                typeof value.toJSON === 'function') {
            value = value.toJSON(key);
        }

// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.

        if (typeof rep === 'function') {
            value = rep.call(holder, key, value);
        }

// What happens next depends on the value's type.

        switch (typeof value) {
        case 'string':
            return quote(value);

        case 'number':

// JSON numbers must be finite. Encode non-finite numbers as null.

            return isFinite(value) ? String(value) : 'null';

        case 'boolean':
        case 'null':

// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.

            return String(value);

// If the type is 'object', we might be dealing with an object or an array or
// null.

        case 'object':

// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.

            if (!value) {
                return 'null';
            }

// Make an array to hold the partial results of stringifying this object value.

            gap += indent;
            partial = [];

// Is the value an array?

            if (Object.prototype.toString.apply(value) === '[object Array]') {

// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.

                length = value.length;
                for (i = 0; i < length; i += 1) {
                    partial[i] = str(i, value) || 'null';
                }

// Join all of the elements together, separated with commas, and wrap them in
// brackets.

                v = partial.length === 0 ? '[]' :
                    gap ? '[\n' + gap +
                            partial.join(',\n' + gap) + '\n' +
                                mind + ']' :
                          '[' + partial.join(',') + ']';
                gap = mind;
                return v;
            }

// If the replacer is an array, use it to select the members to be stringified.

            if (rep && typeof rep === 'object') {
                length = rep.length;
                for (i = 0; i < length; i += 1) {
                    k = rep[i];
                    if (typeof k === 'string') {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            } else {

// Otherwise, iterate through all of the keys in the object.

                for (k in value) {
                    if (Object.hasOwnProperty.call(value, k)) {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            }

// Join all of the member texts together, separated with commas,
// and wrap them in braces.

            v = partial.length === 0 ? '{}' :
                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
                        mind + '}' : '{' + partial.join(',') + '}';
            gap = mind;
            return v;
        }
    }

// If the JSON object does not yet have a stringify method, give it one.

    if (typeof JSON.stringify !== 'function') {
        JSON.stringify = function (value, replacer, space) {

// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.

            var i;
            gap = '';
            indent = '';

// If the space parameter is a number, make an indent string containing that
// many spaces.

            if (typeof space === 'number') {
                for (i = 0; i < space; i += 1) {
                    indent += ' ';
                }

// If the space parameter is a string, it will be used as the indent string.

            } else if (typeof space === 'string') {
                indent = space;
            }

// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.

            rep = replacer;
            if (replacer && typeof replacer !== 'function' &&
                    (typeof replacer !== 'object' ||
                     typeof replacer.length !== 'number')) {
                throw new Error('JSON.stringify');
            }

// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.

            return str('', {'': value});
        };
    }


// If the JSON object does not yet have a parse method, give it one.

    if (typeof JSON.parse !== 'function') {
        JSON.parse = function (text, reviver) {

// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.

            var j;

            function walk(holder, key) {

// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.

                var k, v, value = holder[key];
                if (value && typeof value === 'object') {
                    for (k in value) {
                        if (Object.hasOwnProperty.call(value, k)) {
                            v = walk(value, k);
                            if (v !== undefined) {
                                value[k] = v;
                            } else {
                                delete value[k];
                            }
                        }
                    }
                }
                return reviver.call(holder, key, value);
            }


// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.

            cx.lastIndex = 0;
            if (cx.test(text)) {
                text = text.replace(cx, function (a) {
                    return '\\u' +
                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
                });
            }

// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.

// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

            if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

                j = eval('(' + text + ')');

// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.

                return typeof reviver === 'function' ?
                    walk({'': j}, '') : j;
            }

// If the text is not JSON parseable, then a SyntaxError is thrown.

            throw new SyntaxError('JSON.parse');
        };
    }
}());

//include public/javascripts/library/third-party/qshelper.js
if(!window.QsHelper){
	var QsHelper = {
		getParams:function(url){
			if(url == null || url === undefined){
				url = document.location.search;
			}
			var urlSplit=url.split("?");
			qs = (urlSplit.length == 1) ? url : urlSplit[1];
			if(qs){
				var params = qs.split("&");
				var curParamSplit;
				var ret = {};
				for(var i = 0; i < params.length; i++){
					curParamSplit =  params[i].split("=");
					if(curParamSplit[0]){
						ret[curParamSplit[0]] = curParamSplit[1];
					}
				}
				return ret;
			}
			return null;
		},
		
		getQueryString:function(params, url){
			var retString = "";
			var isFirst = true;
			if(url){
				retString = url;
				if(retString.indexOf("?") < 0){
					retString += "?"
				}
			}
			for(var i in params){
				if(!isFirst){
					retString += "&";
				}else{
					isFirst = false;
				}
				retString += escape(i) + "=" + escape(params[i]);
			}
			return retString;
		}		
	}
	window.QsHelper = QsHelper;
}
//include public/javascripts/library/core/prelude.js
var lib = window.Library
if (lib) {
	lib.copy = function(target, source, overwrite, transform) {
		for ( var key in source) {
			if (overwrite || typeof target[key] === 'undefined') {
				target[key] = transform ? transform(source[key])
						: source[key];
			}
		}
		return target;
	}
	
	/**
	 * Create a namespaced object.
	 * 
	 * @access private
	 * @param name
	 *            {String} full qualified name ('Util.foo', etc.)
	 * @param value
	 *            {Object} value to set. Default value is {}. [Optional]
	 * @return {Object} The created object
	 */
	lib.create = function(name, value) {
		var node = lib, nameParts = name ? name.split('.') : [], c = nameParts.length;
		for ( var i = 0; i < c; i++) {
			var part = nameParts[i];
			var nso = node[part];
			if (!nso) {
				nso = (value && i + 1 == c) ? value : {};
				node[part] = nso;
			}
			node = nso;
		}
		return node;
	}
	
	/**
	 * Copy stuff from one object to the specified namespace that is lib.<target>.
	 * If the namespace target doesn't exist, it will be created
	 * automatically.
	 * 
	 * @access private
	 * @param target
	 *            {Object|String} the target object to copy into
	 * @param source
	 *            {Object} the source object to copy from
	 * @param overwrite
	 *            {Boolean} indicate if we should overwrite
	 * @return {Object} the *same* target object back
	 */
	lib.provide = function(target, source, overwrite) {
		// a string means a dot separated object that gets appended to,
		// or created
		return lib.copy(typeof target == 'string' ? lib.create(target)
				: target, source, overwrite);
	}
}
//include public/javascripts/library/common/utils.js
window.Library.provide('Url', {
	getParams:function(url){
		return QsHelper.getParams(url);
	},
	
	getQueryString:function(params){
		return QsHelper.getQueryString(params);
	}
})

window.Library.provide('', {
	
	/**
	 * Generates a weak random ID.
	 * 
	 * @access private
	 * @return {String} a random ID
	 */
	guid:function() {
		return 'f' + (Math.random() * (1 << 30)).toString(16).replace('.','');
	},
	
	
	/**
	 * Logs a message for the developer if logging is on.
	 * 
	 * @access private
	 * @param args
	 *            {Object} the thing to log
	 */
	log:function(args) {
		if (lib._logging) {
			// TODO what is window.Debug, and should it instead be
			// relying on the
			// event fired below?
			// #JSCOVERAGE_IF 0
			if (window.Debug && window.Debug.writeln) {
				window.Debug.writeln(args);
			} else if (window.console) {
				window.console.log(args);
			}
			// #JSCOVERAGE_ENDIF
		}
	
		// fire an event if the event system is available
		if (lib.Event) {
			lib.Event.fire('Library.log', args);
		}
	},
	
	error:function(msg){
		if (window.Debug && window.Debug.writeln) {
			window.Debug.writeln(msg);
		} else if (window.console) {
			window.console.error(msg);
		}
	},
	
	debug:function(msg){
		if (window.Debug && window.Debug.writeln) {
			window.Debug.writeln(msg);
		} else if (window.console) {
			window.console.debug(msg);
		}
	},
	
	/**
	 * Shortcut for document.getElementById
	 * 
	 * @method $
	 * @param {string}
	 *            DOM id
	 * @return DOMElement
	 * @access private
	 */
	$:function(id) {
		return document.getElementById(id);
	}
})
//include public/javascripts/library/common/type.js
/**
 * @provides dc.type
 * @layer basic
 * @requires dc.prelude
 */

/**
 * @class DC
 * @static
 */
window.Library.provide('', {
  /**
   * Bind a function to a given context and arguments.
   *
   * @static
   * @access private
   * @param fn {Function} the function to bind
   * @param context {Object} object used as context for function execution
   * @param {...} arguments additional arguments to be bound to the function
   * @returns {Function} the bound function
   */
  bind: function() {
    var
      args    = Array.prototype.slice.call(arguments),
      fn      = args.shift(),
      context = args.shift();
    return function() {
      return fn.apply(
        context,
        args.concat(Array.prototype.slice.call(arguments))
      );
    };
  },

  /**
   * Create a new class.
   *
   * Note: I have to use 'Class' instead of 'class' because 'class' is
   * a reserved (but unused) keyword.
   *
   * @access private
   * @param name {string} class name
   * @param constructor {function} class constructor
   * @param proto {object} instance methods for class
   */
  Class: function(name, constructor, proto) {
    if (window.Library.CLASSES[name]) {
      return window.Library.CLASSES[name];
    }

    var newClass = constructor ||  function() {};

    newClass.prototype = proto;
    newClass.prototype.bind = function(fn) {
      return window.Library.bind(fn, this);
    };

    newClass.prototype.constructor = newClass;
    window.Library.create(name, newClass);
    window.Library.CLASSES[name] = newClass;
    return newClass;
  },

  /**
   * Create a subclass
   *
   * Note: To call base class constructor, use this._base(...).
   * If you override a method 'foo' but still want to call
   * the base class's method 'foo', use this._callBase('foo', ...)
   *
   * @access private
   * @param {string} name class name
   * @param {string} baseName,
   * @param {function} constructor class constructor
   * @param {object} proto instance methods for class
   */
  subclass: function(name, baseName, constructor, proto) {
    if (window.Library.CLASSES[name]) {
      return window.Library.CLASSES[name];
    }
    var base = window.Library.create(baseName);
    window.Library.copy(proto, base.prototype);
    proto._base = base;
    proto._callBase = function(method) {
      var args = Array.prototype.slice.call(arguments, 1);
      return base.prototype[method].apply(this, args);
    };

    return window.Library.Class(
      name,
      constructor ? constructor : function() {
        if (base.apply) {
          base.apply(this, arguments);
        }
      },
      proto
    );
  },

  CLASSES: {}
});

/**
 * @class window.Library.Type
 * @static
 * @private
 */
window.Library.provide('Type', {
  isType: function(obj, type) {
    while (obj) {
      if (obj.constructor === type || obj === type) {
        return true;
      } else {
        obj = obj._base;
      }
    }
    return false;
  }
});

//include public/javascripts/library/dcp/init.js
DCP.provide('', {
	init:function(options){
		DCP.FB.initFb(options.fbInit);
		DCP.XD.init();
	}
})
//include public/javascripts/library/dcp/intl.js
DCP.provide('Intl', {
	_strings:{
		'feedback-dialog.register-feedback':i18n('feedback-dialog.register-feedback'),
		'feedback-dialog.reset-password-feedback':i18n('feedback-dialog.reset-password-feedback'),
		'feedback-dialog.register-sent-title':i18n('feedback-dialog.register-sent-title'),
		'feedback-dialog.password-reset-title':i18n('feedback-dialog.password-reset-title'),
		'login-dialog.wrong-credentials':i18n('login-dialog.wrong-credentials'),
		'error.password-length-error':i18n('error.password-length-error'),
		'error.password-match-error':i18n('error.password-match-error'),
		'error.password-required-error':i18n('error.password-required-error'),
		'error.invalid-email-error':i18n('error.invalid-email-error'),
		'error.invalid-bday':i18n('error.invalid-bday'),
		'error.user-is-fb-connected':i18n('error.user-is-fb-connected'),
		'error.no-emails-inserted':i18n('error.no-emails-inserted'),
		'error.invalid-field':i18n('error.invalid-field'),
		'account.change-email-confirm':i18n('account.change-email-confirm')
	},

	get:function(name){
		return DCP.Intl._strings[name];
	}
})
//include public/javascripts/library/core/event.js
/**
 * @provides window.Library.event
 * @requires window.Library.prelude window.Library.array
 */

// NOTE: We tag this as window.Library.Event even though it is actually window.Library.EventProvider to
// work around limitations in the documentation system.
/**
 * Event handling mechanism for globally named events.
 *
 * @static
 * @class window.Library.Event
 */
window.Library.provide('EventProvider', {
  /**
   * Returns the internal subscriber array that can be directly manipulated by
   * adding/removing things.
   *
   * @access private
   * @return {Object}
   */
  subscribers: function() {
    // this odd looking logic is to allow instances to lazily have a map of
    // their events. if subscribers were an object literal itself, we would
    // have issues with instances sharing the subscribers when its being used
    // in a mixin style.
    if (!this._subscribersMap) {
      this._subscribersMap = {};
    }
    return this._subscribersMap;
  },

  /**
   * Subscribe to a given event name, invoking your callback function whenever
   * the event is fired.
   *
   * @access public
   * @param name {String} Name of the event.
   * @param cb {Function} The handler function.
   */
  subscribe: function(name, cb) {
    var subs = this.subscribers();

    if (!subs[name]) {
      subs[name] = [cb];
    } else {
      subs[name].push(cb);
    }
  },

  /**
   * Removes subscribers, inverse of [window.Library.Event.subscribe](DV.Event.subscribe).
   *
   * Removing a subscriber is basically the same as adding one. You need to
   * pass the same event name and function to unsubscribe that you passed into
   * subscribe. If we use a similar example to
   * [window.Library.Event.subscribe](window.Library.event.subscribe), we get:
   *
   *     var onSessionChange = function(response) {
   *       // do something with response.session
   *     };
   *     window.Library.Event.subscribe('auth.sessionChange', onSessionChange);
   *
   *     // sometime later in your code you dont want to get notified anymore
   *     window.Library.Event.unsubscribe('auth.sessionChange', onSessionChange);
   *
   * @access public
   * @param name {String} Name of the event.
   * @param cb {Function} The handler function.
   */
  unsubscribe: function(name, cb) {
    var subs = this.subscribers()[name];

    window.Library.Array.forEach(subs, function(value, key) {
      if (value == cb) {
        subs[key] = null;
      }
    });
  },

  /**
   * Repeatedly listen for an event over time. The callback is invoked
   * immediately when monitor is called, and then every time the event
   * fires. The subscription is canceled when the callback returns true.
   *
   * @access private
   * @param {string} name Name of event.
   * @param {function} callback A callback function. Any additional arguments
   * to monitor() will be passed on to the callback. When the callback returns
   * true, the monitoring will cease.
   */
  monitor: function(name, callback) {
    if (!callback()) {
      var
        ctx = this,
        fn = function() {
          if (callback.apply(callback, arguments)) {
            ctx.unsubscribe(name, fn);
          }
        };

      this.subscribe(name, fn);
    }
  },

  /**
   * Removes all subscribers for named event.
   *
   * You need to pass the same event name that was passed to window.Library.Event.subscribe.
   * This is useful if the event is no longer worth listening to and you
   * believe that multiple subscribers have been set up.
   *
   * @access private
   * @param name    {String}   name of the event
   */
  clear: function(name) {
    delete this.subscribers()[name];
  },

  /**
   * Fires a named event. The first argument is the name, the rest of the
   * arguments are passed to the subscribers.
   *
   * @access private
   * @param name {String} the event name
   */
  fire: function() {
    var
      args = Array.prototype.slice.call(arguments),
      name = args.shift();

    window.Library.Array.forEach(this.subscribers()[name], function(sub) {
      // this is because we sometimes null out unsubscribed rather than jiggle
      // the array
      if (sub) {
        sub.apply(this, args);
      }
    });
  }
});

/**
 * Event handling mechanism for globally named events.
 *
 * @class window.Library.Event
 * @extends window.Library.EventProvider
 */
window.Library.provide('Event',window.Library.EventProvider);

//include public/javascripts/library/core/fb.js
window.Library.provide('FB', {
	
	_fbLoginStatus:"pending",
	
	isFbConnected:function(){
		return window.Library.FB._fbLoginStatus == "connected"
	},
	
	getFbStatus:function(){
		return window.Library.FB._fbLoginStatus;
	},
	
	onFbLogin:function(response, redirectUrl, doAjaxLogin){
		if(response.status == "connected"){
			window.Library.Event.fire('fb-elem-login', redirectUrl, doAjaxLogin == 'true');
		}
	},
	
	login:function(){
		FB.login();
	},
	
	initFb:function(fbInit){
		if(window.FB && $("#fb-root").length > 0){
			FB.Event.subscribe('auth.statusChange', function(response) {
				window.Library.FB.queryFbLoginStatus();
			});
			FB.init(fbInit);
			/*if(!window.Library.Obj.user){
				FB.logout();
			}*/
			if(!window.Library.Obj.user){
				window.Library.FB.queryFbLoginStatus();
			}
		}
	},
	
	queryFbLoginStatus:function(params){
		window.Library.Event.fire("fb-login-status-changed", [window.Library.FB._fbLoginStatus]);
		FB.getLoginStatus(function(response) {
			window.Library.FB._fbLoginStatus = response.status;
			window.Library.Event.fire("fb-login-status-changed", [window.Library.FB._fbLoginStatus]);
		});
	},
	
	checkElementFbLogin:function(element){
		var elem		= $(element);
		var fb			= $(elem.children()[1]);
		var preloder	= $(elem.children()[0]);

		if ( elem.attr("alwaysVisible") == "true" ){
			preloder.hide(); fb.show();
		} else if(!window.Library.Obj.user){
			preloder.hide(); fb.show();
		}else if(window.Library.FB._fbLoginStatus == "pending"){
			preloder.show(); fb.hide();
		}else if(window.Library.FB._fbLoginStatus == "connected"){
			preloder.hide(); fb.hide();
		}else{
			preloder.hide(); fb.show();
		}
	}
})
//include public/javascripts/library/common/array.js
/**
 * @provides dc.array
 * @layer basic
 * @requires dc.prelude
 */

/**
 * Array related helper methods.
 *
 * @class window.Library.Array
 * @private
 * @static
 */
window.Library.provide('Array', {
  /**
   * Get index of item inside an array. Return's -1 if element is not found.
   *
   * @param arr {Array} Array to look through.
   * @param item {Object} Item to locate.
   * @return {Number} Index of item.
   */
  indexOf: function (arr, item) {
    if (arr.indexOf) {
      return arr.indexOf(item);
    }
    var length = arr.length;
    if (length) {
      for (var index = 0; index < length; index++) {
        if (arr[index] === item) {
          return index;
        }
      }
    }
    return -1;
  },

  /**
   * Merge items from source into target, but only if they dont exist. Returns
   * the target array back.
   *
   * @param target {Array} Target array.
   * @param source {Array} Source array.
   * @return {Array} Merged array.
   */
  merge: function(target, source) {
    for (var i=0; i < source.length; i++) {
      if (window.Library.Array.indexOf(target, source[i]) < 0) {
        target.push(source[i]);
      }
    }
    return target;
  },

  /**
   * Create an new array from the given array and a filter function.
   *
   * @param arr {Array} Source array.
   * @param fn {Function} Filter callback function.
   * @return {Array} Filtered array.
   */
  filter: function(arr, fn) {
    var b = [];
    for (var i=0; i < arr.length; i++) {
      if (fn(arr[i])) {
        b.push(arr[i]);
      }
    }
    return b;
  },

  /**
   * Create an array from the keys in an object.
   *
   * Example: keys({'x': 2, 'y': 3'}) returns ['x', 'y']
   *
   * @param obj {Object} Source object.
   * @param proto {Boolean} Specify true to include inherited properties.
   * @return {Array} The array of keys.
   */
  keys: function(obj, proto) {
    var arr = [];
    for (var key in obj) {
      if (proto || obj.hasOwnProperty(key)) {
        arr.push(key);
      }
    }
    return arr;
  },

  /**
   * Create an array by performing transformation on the items in a source
   * array.
   *
   * @param arr {Array} Source array.
   * @param transform {Function} Transformation function.
   * @return {Array} The transformed array.
   */
  map: function(arr, transform) {
    var ret = [];
    for (var i=0; i < arr.length; i++) {
      ret.push(transform(arr[i]));
    }
    return ret;
  },

  /**
   * For looping through Arrays and Objects.
   *
   * @param {Object} item   an Array or an Object
   * @param {Function} fn   the callback function for iteration.
   *    The function will be pass (value, [index/key], item) paramters
   * @param {Bool} proto  indicate if properties from the prototype should
   *                      be included
   *
   */
   forEach: function(item, fn, proto) {
    if (!item) {
      return;
    }

    if (Object.prototype.toString.apply(item) === '[object Array]' ||
        (!(item instanceof Function) && typeof item.length == 'number')) {
      if (item.forEach) {
        item.forEach(fn);
      } else {
        for (var i=0, l=item.length; i<l; i++) {
          fn(item[i], i, item);
        }
      }
    } else {
      for (var key in item) {
        if (proto || item.hasOwnProperty(key)) {
          fn(item[key], key, item);
        }
      }
    }
  }
});

//include public/javascripts/library/common/obj.js
/**
 * @provides dc.obj
 * @requires dc.type
 *           fdc.json
 *           dc.event
 */

/**
 * Base object type that support events.
 *
 * @class window.Library.Obj
 * @private
 */
window.Library.Class('Obj', null,
  window.Library.copy({
    /**
     * Set property on an object and fire property changed event if changed.
     *
     * @param {String} Property name. A event with the same name
     *                 will be fire when the property is changed.
     * @param {Object} new value of the property
     * @private
     */
     setProperty: function(name, value) {
       // Check if property actually changed
       if (window.Library.JSON.stringify(value) != window.Library.JSON.stringify(this[name])) {
         this[name] = value;
         this.fire(name, value);
       }
     }
  }, window.Library.EventProvider)
);

//include public/javascripts/library/common/string.js
/**
 * @provides dc.string
 * @layer basic
 * @requires dc.prelude
 *
 */

/**
 * Utility function related to Strings.
 * 
 * @class window.Library.String
 * @static
 * @private
 */
window.Library.provide('String', {
  /**
	 * Strip leading and trailing whitespace.
	 * 
	 * @param s
	 *            {String} the string to trim
	 * @returns {String} the trimmed string
	 */
  trim: function(s) {
    return s.replace(/^\s*|\s*$/g, '');
  },

  /**
	 * Format a string.
	 * 
	 * Example: window.Library.String.format('{0}.digitalchocolate.com/{1}',
	 * 'www', 'login.php') Returns: 'www.digitalchocolate.com/login.php'
	 * 
	 * Example: window.Library.String.format('foo {0}, {1}, {0}', 'x', 'y')
	 * Returns: 'foo x, y, x'
	 * 
	 * @static
	 * @param format
	 *            {String} the format specifier
	 * @param arguments
	 *            {...} placeholder arguments
	 * @returns {String} the formatted string
	 */
  format: function(format) {
    if (!window.Library.String.format._formatRE) {
      window.Library.String.format._formatRE = /(\{[^\}^\{]+\})/g;
    }

    var values = arguments;

    return format.replace(
      window.Library.String.format._formatRE,
      function(str, m) {
        var
          index = parseInt(m.substr(1), 10),
          value = values[index + 1];
        if (value === null || value === undefined) {
          return '';
        }
        return value.toString();
      }
    );
  },

  /**
	 * Escape an string so that it can be embedded inside another string as
	 * quoted string.
	 * 
	 * @param value
	 *            {String} string to quote
	 * @return {String} an quoted string
	 */
  quote: function(value) {
    var
      quotes = /["\\\x00-\x1f\x7f-\x9f]/g,
      subst = {    // table of character substitutions
        '\b': '\\b', 
        '\t': '\\t',
        '\n': '\\n',
        '\f': '\\f',
        '\r': '\\r',
        '"' : '\\"',
        '\\': '\\\\'
      };

    return quotes.test(value) ?
      '"' + value.replace(quotes, function (a) {
        var c = subst[a];
        if (c) {
          return c;
        }
        c = a.charCodeAt();
        return '\\u00' + Math.floor(c/16).toString(16) + (c % 16).toString(16);
      }) + '"' :
      '"' + value + '"';
  },
  
	validateEmail:function(value) {
		if (value != ""
				&& /^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/
						.test(value)) {
			return "";
		} else {
			return DCP.Intl.get("error.invalid-email-error");
		}
	}
});

//include public/javascripts/library/dcp/xd.js
(function($) {
	DCP.XD = {
		
		_origin 	: null,
		_transport 	: null,
			
		init:function(){
			if ((window.addEventListener || window.attachEvent) && window.postMessage) {
				
				// The origin here is used for postMessage security. It needs to be
				// based
				// on the URL of the current window. It is required and validated by
				// Digital Chocolate as part of the xd_proxy.php.
				/*DC.XD._origin = (window.location.protocol + '//'
						+ window.location.host + '/' + DC.guid());*/
				DCP.XD.PostMessage.init();
				DCP.XD._transport = 'postmessage';
			} else if (!channelUrl && (DC.Flash!=null && DC.Flash.hasMinVersion())) {
				// The origin here is used for Flash XD security. It needs to be
				// based on
				// document.domain rather than the URL of the current window. It is
				// required and validated by Digital Chocolate as part of the
				// xd_proxy.php.
				/*DC.XD._origin = (window.location.protocol + '//' + document.domain
						+ '/' + DC.guid());
				DC.XD.Flash.init();
				DC.XD._transport = 'flash';*/
			} else {
				/*DC.XD._transport = 'fragment';
				DC.XD.Fragment._channelUrl = channelUrl
						|| window.location.toString();*/
			}
		},
	
		PostMessage : {
			/**
			 * Initialize the native PostMessage system.
			 * 
			 * @access private
			 */
			init : function() {
				var H = DCP.XD.PostMessage.onMessage;
				window.addEventListener ? window.addEventListener('message', H,
						false) : window.attachEvent('onmessage', H);
			},
		
			/**
			 * Handles a message event.
			 * 
			 * @access private
			 * @param event
			 *            {Event} the event object
			 */
			onMessage : function(event) {
				var data 	= QsHelper.getParams(decodeURIComponent(event.data));
				var method	= data.method;
				if(method){
					var params = JSON.parse(data.params);
					DCP.Event.fire("XDCommand_"+method, params);
				}
			}
		},
		
		sendMessage:function(channel, data){
			var params = DCP.Url.getParams(document.location.search);
			var channelParams = DCP.Url.getParams(unescape(params[channel]));
			if(data){
				channelParams.result = $.toJSON(data);
			}
			window.parent.postMessage(DCP.Url.getQueryString(channelParams), "*");
		}
	}
})(PJQ);
//include public/javascripts/library/dcp/dialogs.js
(function($) {
	window.Library.provide('Dialogs', {
		
		isOpen:function(name){
			return DialogManager.isOpened(name);
		},
		
		open:function(params){
			DialogManager.openDialog(params.method, params);
		},
		
		hide:function(name, closeParams){
			DialogManager.closeDialog(name, closeParams)
		},
		
		closeAll:function(openDialog, closeParams){
			DialogManager.closeAll(closeParams);
		},
		
		addDialogInitHandler:function(dialog, handler){
			/*if(this.dialogs[dialog]){
				handler(null, this.dialogs[dialog]);
			}else{
				DCP.Event.subscribe(dialog+"-registered", handler);
			}*/
		}
	})
})(PJQ);
//include public/javascripts/library/dcp/service.js
(function($) {
	DCP.provide('Service', {
		call:function(params){
		    $.post(
		        params.url,
		        params.data,
		        function(response){
		        	if(params.callback){
		        		params.callback(response);
		        	}
		        	if(response.status == "ERROR" && params.fail){
		        		params.fail(response.response.errorCode, response.response.errorMessage);
		        	}else if(response.status == "SUCCESS" && params.success){
		        		params.success(response.response);
		        	}
		        }
		    );
		}
	})
})(PJQ);
(function($) {
	DCP.provide('Cookie', {
		set:function(name, value, options) {
		    if (typeof value != 'undefined') { // name and value given, set cookie
		        options = options || {};
		        if (value === null) {
		            value = '';
		            options.expires = -1;
		        }
		        var expires = '';
		        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
		            var date;
		            if (typeof options.expires == 'number') {
		                date = new Date();
		                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
		            } else {
		                date = options.expires;
		            }
		            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
		        }
		        // CAUTION: Needed to parenthesize options.path and options.domain
		        // in the following expressions, otherwise they evaluate to undefined
		        // in the packed version for some reason...
		        var path = options.path ? '; path=' + (options.path) : '';
		        var domain = options.domain ? '; domain=' + (options.domain) : '';
		        var secure = options.secure ? '; secure' : '';
		        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
		    } else { // only name given, get cookie
		        var cookieValue = null;
		        if (document.cookie && document.cookie != '') {
		            var cookies = document.cookie.split(';');
		            for (var i = 0; i < cookies.length; i++) {
		                var cookie = $.trim(cookies[i]);
		                // Does this cookie string begin with the name we want?
		                if (cookie.substring(0, name.length + 1) == (name + '=')) {
		                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
		                    break;
		                }
		            }
		        }
		        return cookieValue;
		    }
		}
	})
})(PJQ);
/**
 * @provides dcp.ga
 */

/**
 * @class DCP.GA
 * @static
 * @access private
 */
DCP.provide('GA', {
	
	/**
	* check ga enabled
	*/
	isGaEnabled : function(){
		return DCP.Obj.ga_enabled;
	},
	
	/**
	* register event
	*
	*/
	registerEvent: function(category, action, label, value) {
		if ( !category || !action || !DCP.GA.isGaEnabled() ) {
			return ;
		}
		label = label ? label : null;
		value = value ? value : null;
		_gaq.push(['_trackEvent', category, action, label, value]);
	}
});


	$(function(){
		DCP.Event.subscribe("fb-login-status-changed", function(){
			$('[purpose="fb-login"]').each(function(){
				DCP.FB.checkElementFbLogin(this);
			});
		});
		DCP.Event.subscribe("fb-elem-login", function(redirectUrl, doAjaxLogin){
			if(redirectUrl){
				if(!doAjaxLogin){
					DCP.GA.registerEvent('sign in', 'signed in using fconnect');
					window.location = redirectUrl;
				}else{
					DCP.Service.call({
						url:redirectUrl, data:{},
						success:function(data){
							DCP.GA.registerEvent('sign in', 'signed in using fconnect');
							DCP.Event.fire("fb-login-success", data);
						},
						fail:function(code, message){
							DCP.Event.fire("fb-login-fail", code, message);
						}
					})
				}
			}
		});
		$('[purpose="fb-login"]').livequery(function(){
			var loginComp	= $(this);
			var fbButton 	= $("a", loginComp);
			fbButton.click(function(){
				DCP.GA.registerEvent(
					'sign in', 
					(loginComp.attr("type")== 'account' ? 'hit fconnect from account' : 'signed in using fconnect')
				);
				
				var perms = loginComp.attr("perms");
				FB.login(function(response){
					DCP.Cookie.set("fbUserId", response.authResponse.userID,{path:"/"});
					DCP.Cookie.set("fbToken", response.authResponse.accessToken,{path:"/"});
					if (response.authResponse || response.session) {
						DCP.FB.onFbLogin(response, loginComp.attr("redirectUrl"), loginComp.attr("doAjaxLogin"));
					}
				}, {scope:perms});
			});
			DCP.FB.checkElementFbLogin(this);
			
		});
		$("[purpose='event-dispatch']").livequery(function(){
			var elem	= $(this);
			var trigger	= $(this).attr("trigger");
			var event 	= $(this).attr("event");
			if(event && trigger){
				elem.bind(trigger, function(){
					DCP.Event.fire(event, elem, this);	
				})
			}
		});
		$('[purpose="sign-out"]').livequery(function(){
			$(this).click(function(){
				DCP.GA.registerEvent('sign out', 'hit sign out');
				return true;
			})
		});
		$('[purpose="manage-account"]').livequery(function(){
			$(this).click(function(){
				DCP.GA.registerEvent('account', 'hit manage account');
				return true;
			})
		});
	});
})(PJQ);

