/*!
 *
 * FusionCharts JavaScript Library
 *
 * Third-party attributions:
 * SWFObject v2.2 <http://code.google.com/p/swfobject/> is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
 * JSON v2 <http://www.JSON.org/js.html>
 */

/**
 * -----------------------------------------------------------------------------
 * FusionCharts Core Framework
 * FusionCharts core framework module. This module contains the basic routines
 * required by subsequent modules to extend/scale or add functionality to the
 * FusionCharts object.
 * -----------------------------------------------------------------------------
 */
(function () {

    // In case FusionCharts o
    // bject already exists, we skip this function.
    if (typeof window.FusionCharts !== 'undefined') {
        return;
    }

    /**
     * @var {object} global The global variable would store all private methods
     * and properties available to each module.
     *
     * @var {object} modules For maintaining module information.
     *
     * @var {Array} argsT Specifies the order in which the parameters of the new
     * FusionCharts objects are interpreted and converted to options object.
     */
    var global = {}, modules = {}, argsT = ['swfUrl', 'id', 'width', 'height',
    'debugMode', 'registerWithJS', 'bgColor', 'scaleMode', 'lang',
    'detectFlashVersion', 'autoInstallRedirect'];

    /**
     * This method, when added to the prototype of an object,
     * allows shallow or deep extension of the object with another
     * object.
     */
    global.extend = function (obj1, obj2) {

        // Get shallow or deep copy information
        var deep = typeof arguments[arguments.length - 1] === 'boolean' ?
        arguments[arguments.length - 1] : false;

        // Decide which parameter is going to be source and which one will be
        // sink.
        var src = obj2, snk = obj1;
        if (typeof obj2 === 'boolean' || arguments.length == 1) {
            snk = core;
            src = obj1 ;
        }
        // When 'shallow' is marked as true, the methods and properties
        // of source is not added to the prototype of the sink.
        if (deep === true) {
            snk = snk.prototype;
        }

        // Copy all methods and properties of the object passed in parameter
        // to the object to which this function is attached.
        for (var item in src) {
            snk[item] = src[item];
        }

        return snk;
    };

    // Function that auto-generates a unique id.
    global.uniqueId = function () {
        return 'chartobject-' + (global.uniqueId.lastId += 1);
    };
    global.uniqueId.lastId = 0;

    // Define the policy to create default parameters for the swfObject.
    // Values are in format [sourceOption, defaultValue]
    // This helps in building the initial FusionCharts object when new instances
    // are created from user parameters.
    global.policies = {
        /**
         * @var options {object} Contains all the customizable options that are
         * used by the library internally and has nothing to do with renderer
         * attributes, vars or parameters
         */
        options: {
            product: ['product', 'v3'],
            insertMode: ['insertMode', 'clear'],
            safeMode: ['safeMode', true],
            autoInstallRedirect: ['autoInstallRedirect', false]
        },
        /**
         * @var attributes {object} Contains configurations pertaining to the
         * host (browser) environment.
         */
        attributes: {
            lang: ['lang', 'EN'],
            'class': ['className', 'FusionCharts']
        }
    };

    /**
     * Allows the core to process an arguments object based on a set of policies
     * and construct an object out of it that is mapped exactly as respective
     * parameter policy defines. In other words, it uses an object and
     * creates another object or updates another object with values from the
     * original arguments object in a particular hierarchy and name that a set
     * of rules (policies) define.
     */
    global.parsePolicies = function (obj, policies, options) {
        var prop, policy;

        // Iterate through the data policy and correspondingly create the
        // three stacks of parameters, attributes and flashVars
        for (policy in policies) {

            // Set just the policy object in case of single-level policy.
            if (global.policies[policy] instanceof Array) {
                obj[policy] = options[policies[policy][0]] || policies[policy][1];
                continue;
            }

            // Define objects that would hold parameters for swfobject. Also
            // populate with variables from the parameters
            obj[policy] = {};

            // Set every sub-object for two-level policy
            for (prop in policies[policy]) {
                obj[policy][prop] = options[policies[policy][prop][0]] ||
                policies[policy][prop][1];
            }
        }
    };

    var core = function (command) {
        // This point onwards, we must check whether this is being used as a
        // constructor or not
        if (!(this instanceof core)) {
            // Allow private communication with modules. In case FusionCharts is
            // not called as constructor and it is passed an array that is marked
            // to do private communication, then share the global variable.
            if (arguments.length === 1 &&
                command instanceof Array && command[0] === 'private') {
                // Prevent overwriting and duplicate execution of modules.
                if (modules[command[1]] === true) {
                    return undefined;
                }
                modules[command[1]] = true;
                return global;
            }

            // Allow using FusionCharts object to directly access its new items
            if (arguments.length === 1 && typeof command === 'string') {
                return core.items[command];
            }

            throw new SyntaxError("Use the \"new\" keyword while creating a new"
                + " FusionCharts object");
        }

        // Define a variable for iterative key in various loops and the
        // object variable that stores the options.
        var options = {}, prop, lengthCleanupRegex = /[^\%\d]*$/g;

        // Check whether linear arguments are sent and convert it to object.
        if (arguments.length === 1 && typeof arguments[0] === 'object') {
            // If the above condition matches, then we can safely assume that
            // the first parameter is the options object.
            options = arguments[0];
        }
        else {
            // Iterate through the arguments template and add the keys to the
            // options object while fetching corresponding values from arguments
            // array.
            for (prop in argsT) {
                options[argsT[prop]] = arguments[prop];
            }
        }

        // Incorporate the trailing object parameter as object-style
        // parameter input overrides.
        if (typeof arguments[arguments.length - 1] === 'object') {
            delete options[arguments.length - 1];
            global.extend(options, arguments[arguments.length - 1]);
        }


        // Set autogenerated chart-id in case one is not specified
        this.id = typeof options.id === 'undefined' ?
        this.id = global.uniqueId() : options.id;

        // Look into the bare-minimum set of properties required and populate
        // other base properties.
        if (typeof (this.src = options.swfUrl) === 'undefined') {
            throw "FusionCharts.constructor.ArgumentException() " +
            "Missing required parameter swfUrl";
        }

        // Set dimension passed by user and subsequently validate the options.
        // - Remove trailing 'px'
        this.width = options.width.toString().replace(lengthCleanupRegex, '');
        this.height = options.height.toString().replace(lengthCleanupRegex, '');
        this.arguments = options;

        // If an item is created with same id, the previous item is disposed.
        if (core.items[this.id] instanceof core) {
            core.items[this.id].dispose();
        }
        // Add this object to the repository of objects within core object.
        core.items[this.id] = this;

        // Parse global policies.
        global.parsePolicies(this, global.policies, options)

        // Execute all constructors one after the other using events.
        global.raiseEvent('BeforeInitialize', options, {
            async: false,
            omni: true
        }, this);

        // Raise initialization event.
        global.raiseEvent('Initialized', options, {
            async: true,
            omni: true
        }, this);

        return this;
    };

    // Make the core extensible and reset the constructor of the object
    // for maintaining correct prototype chain.
    core.prototype = {};
    // Reset constructor.
    core.prototype.constructor = core;
    // Expose the core to the global scope.
    window.FusionCharts = core;

    global.extend({
        /**
         * The version of FusionCharts.js
         */
        version: [3, 2, 0, 'beta-1', 0],

        // Add a container of all chart objects. This will allow easy returning
        // of FusionCharts objects through getChartFromId.
        items: {},

        // Add an object to store options
        options: {},

        // Add function to access the object created by renderers.
        getObjectReference: function (id) {
            return FusionCharts.items[id];
        }
    }, false);

}());



/**
 * -----------------------------------------------------------------------------
 * Event Handler Framework
 * This module allows FusionCharts to work with W3C Level 2 style events for
 * allowing multiple handlers per event and also to do event driven development
 * on a global or per-chart basis.
 * -----------------------------------------------------------------------------
 */
(function () {

    // Try register the module with FusionCharts.
    var global = FusionCharts(['private', 'EventManager']);
    // Check whether the module has been already registered. If true, then
    // do not bother to re-register.
    if (global === undefined) {
        return;
    }

    // Collection of FusionCharts events
    window.FusionChartsEvents = {
        BeforeInitialize: 'beforeinitialize',
        Initialized: 'initialized',
        Loaded: 'loaded',
        Rendered: 'rendered',
        DataLoadRequested: 'dataloadrequested',
        BeforeDataLoad: 'beforedataload',
        DataLoaded: 'dataloaded',
        DataLoadError: 'dataloaderror',
        NoDataToDisplay: 'nodatatodisplay',
        DataXMLInvalid: 'dataxmlinvalid',
        DrawComplete: 'drawcomplete',
        Resized: 'resized',
        BeforeDispose: 'beforedispose',
        Disposed: 'disposed'
    };

    var EventTarget = {

        // Entire collection of listeners.
        listeners: {},

        // The last raised event id. Allows to calculate the next event id.
        lastEventId: 0,

        addListener: function (type, listener, bind) {
            // Validate the type parameter. Listener cannot be added without
            // valid type.
            if (typeof type !== 'string') {
                throw "EventTarget.addListener.ArgumentException() " +
                "UNSPECIFIED_EVENT_TYPE_ERR";
            }

            // Listener must be a function. It will not eval a string.
            if (typeof listener !== 'function') {
                throw "EventTarget.addListener.ArgumentException() " +
                "UNSPECIFIED_LISTENER_ERR";
            }

            // Desensitize the type case for user accessability.
            type = type.toLowerCase();

            // If the insertion position does not have a queue, then create one.
            if (!(EventTarget.listeners[type] instanceof Array)) {
                EventTarget.listeners[type] = [];
            }

            // Add the listener to the queue.
            EventTarget.listeners[type].push([listener, bind]);

        },

        removeListener: function (type, listener, bind) {

            // Validate the type parameter. Listener cannot be removed without
            // valid type.
            if (typeof type !== 'string') {
                throw "EventTarget.removeListener.ArgumentException() " +
                "UNSPECIFIED_EVENT_TYPE_ERR";
            }

            // Listener must be a function. Else we have nothing to remove!
            if (typeof listener !== 'function') {
                throw "EventTarget.removeListener.ArgumentException() " +
                "UNSPECIFIED_LISTENER_ERR";
            }

            // Desensitize the type case for user accessability.
            type = type.toLowerCase();

            // Create a reference to the slot for easy lookup in this method.
            var slot = EventTarget.listeners[type], i;

            // If slot does not have a queue, we assume that the listener
            // was never added and halt method.
            if (!(slot instanceof Array)) {
                return;
            }

            // Iterate through the slot and remove every instance of the
            // event handler.
            for (i = 0; i < slot.length; i += 1) {
                // Remove all instances of the listener found in the queue.
                if (slot[i][0] === listener && slot[i][1] === bind) {
                    slot.splice(i, 1);
                    i -= 1;
                }
            }
        },

        // opts can have { async:true, omni:true }
        triggerEvent: function (type, sender, args, opts) {

            // In case, event type is missing, dispatch cannot proceed.
            if (typeof type !== 'string') {
                throw "EventTarget.dispatchEvent.ArgumentException() " +
                "UNSPECIFIED_EVENT_TYPE_ERR";
            }

            // Just ensure that the trigger options are usable
            var options = global.extend({
                async: true,
                omni: false
            }, opts || {});

            // Desensitize the type case for user accessability.
            type = type.toLowerCase();

            // Create a reference to the slot for easy lookup in this method.
            // Also define flag variables needed during propagation of the
            // events.
            var slot = EventTarget.listeners[type], i, cancelEvent, event;

            // If slot does not have a queue, we assume that the listener
            // was never added and halt method.
            if (!(slot instanceof Array)) {
                // Statutory W3C NOT preventDefault flag
                return true;
            }

            // Model the event as per W3C standards. Add the function to cancel
            // event propagation by user handlers. Also append an incremental
            // event id.
            event = {
                eventType: type,
                eventId: (EventTarget.lastEventId += 1),
                sender: (typeof sender === 'string' ?
                    FusionCharts.items[sender] : sender),
                stopPropagation: function () {
                    cancelEvent = true;
                }
            };

            // A function to create an abstraction layer so that the try-catch /
            // error suppression of flash can be avoided while raising events.
            var sandBoxEvent = function (item, scope) {
                return function () {
                    // We change the scope of the function with respect to the
                    // object that raised the event.
                    item[0].call(scope, event, args || {});
                };
            }, scope;

            // Iterate through the slot and look for match with respect to
            // type and binding.
            for (i = 0; i < slot.length; i += 1) {

                // If there is a match found w.r.t. type and bind, we fire it.
                if (slot[i][1] === event.sender || slot[i][1] === undefined) {

                    // Determine the sender of the event for global events.
                    scope = slot[i][1] === event.sender ?
                    event.sender : FusionCharts;

                    // In case async is marked as false, we do not sandBox the
                    // event.
                    if (options.async === false) {
                        slot[i][0].call(scope, event, args || {});
                    }
                    else {
                        setTimeout(sandBoxEvent(slot[i], scope), 0);
                    }
                }

                // Check whether propagation flag is set to false and discontnue
                // iteration if needed.
                if (cancelEvent === true) {
                    break;
                }
            }

            // Statutory W3C NOT preventDefault flag
            return true;
        }
    };

    // Facilitate for raising events internally.
    global.raiseEvent = function (type, args, opts, obj) {
        return EventTarget.triggerEvent(type,
            (obj === undefined ? FusionCharts : obj), args, opts);
    };

    // Add eventListener extensibility to FusionCharts object
    global.extend({
        addEventListener: function (type, listener) {
            return EventTarget.addListener(type, listener);
        },
        removeEventListener: function (type, listener) {
            return EventTarget.removeListener(type, listener);
        }
    }, false);

    // Add eventListener extensibility to FusionCharts prototype so that
    // individual FusionCharts objects can use per-chart events
    global.extend({
        addEventListener: function (type, listener) {
            return EventTarget.addListener(type, listener, this);
        },
        removeEventListener: function (type, listener) {
            return EventTarget.removeListener(type, listener, this);
        }
    }, true);

    // Cleanup on dispose
    FusionCharts.addEventListener('BeforeDispose', function (e) {
        var type, i;
        // Iterate through all events in the collection of listeners
        for (type in EventTarget.listeners) {
            for (i = 0; i < EventTarget.listeners[type].length; i++) {
                // When a match is found, delete the listener from the
                // collection.
                if (EventTarget.listeners[type][i][1] === e.sender) {
                    EventTarget.listeners[type].splice(i, 1);
                }
            }
        }
    });

}());



/**
 * -----------------------------------------------------------------------------
 * Error Handler Framework
 * -----------------------------------------------------------------------------
 */
(function () {

    // Try register the module with FusionCharts.
    var global = FusionCharts(['private', 'ErrorHandler']);
    // Check whether the module has been already registered. If true, then
    // do not bother to re-register.
    if (global === undefined) {
        return;
    }

}());



/**
 * -----------------------------------------------------------------------------
 * Renderer Abstraction Framework
 * This module allows developers to abstract the entire rendering engine. This
 * helps in multiple implementations of FusionCharts in various technologies
 * such as flash, HTML5, etc.
 * -----------------------------------------------------------------------------
 */
(function () {

    // Register the module with FusionCharts.
    var global = FusionCharts(['private', 'RendererManager']);
    // Check whether the module has been already registered. If true, then
    // do not bother to re-register.
    if (global === undefined) {
        return;
    }

    // Allow FusionCharts to accept parameter to specify where to render the
    // chart.
    global.policies.options.containerElementId = ['renderAt', undefined];
    global.policies.options.renderer = ['renderer', undefined];

    // Collection of renderers.
    var notDefined = function () {
        throw "FusionCharts.renderers.RuntimeException() No renderer active.";
    };
    var renderers = {
        'undefined': {
            render: notDefined, 
            update: notDefined,
            policies: {}
        }
    }, store = {}; // store which chart has what renderer

    // API to add renderer and also to set/get the current renderer.
    global.renderer = {
        register: function (name, obj) {
            // Validate parameters
            if (typeof name !== 'string') {
                throw "ArgumentException():1065";
            }
            // Desensitize character case for renderer name
            name = name.toLowerCase();
            // Prevent addition of duplicate renderer
            if (renderers[name] !== undefined) {
                return false;
            }
            // Add renderer to the collection of renderers.
            renderers[name] = obj;
            // Return true when a new renderer is successfully added.
            return true;
        },

        // Set the current renderer
        setDefault: function (name) {
            // Validate parameters
            if (typeof name !== 'string') {
                throw "ArgumentException():1066";
            }
            // Desensitize character case for renderer name
            name = name.toLowerCase();
            // Validate the renderer name and see whether the parameter refers to a
            // valid renderer.
            if (typeof renderers[name] === undefined) {
                throw "ArgumentException: 1062 Renderer name invalid."
            }
            // Set reference to the current renderer.
            global.policies.options.renderer = ['renderer', name];
        },

        getRenderer: function (name) {
            return renderers[name];
        },

        currentRendererName: function () {
            return global.policies.options.renderer[1];
        },

        update: function (obj) {
            store[obj.id].update.apply(obj,
                Array.prototype.slice.call(arguments, 1));
        },

        render: function (obj) {
            store[obj.id].render.apply(obj,
                Array.prototype.slice.call(arguments, 1));
        }
    };


    // Constructor to add renderer functions
    FusionCharts.addEventListener('BeforeInitialize', function (event) {
        // Reference to event sender.
        var obj = event.sender;

        // Check if construction has the default renderer name saved.
        if (typeof obj.options.renderer === 'string' &&
            renderers[obj.options.renderer.toLowerCase()] === undefined) {
            obj.options.renderer = global.policies.options.renderer[1];
        }
        // Desensitize the case of the parameter.
        obj.options.renderer = obj.options.renderer.toLowerCase();

        // Keep a reference
        store[obj.id] = renderers[obj.options.renderer];

        // Parse construction policies specific to this renderer.
        global.parsePolicies(obj, store[obj.id].policies || {}, obj.arguments);

        // Copy the prototype of the renderer specified in constructor to the
        // main object.
        for (var prop in store[obj.id].prototype) {
            obj[prop] = store[obj.id].prototype[prop];
        }
    });

    // ============================================================================

    // Function that checks duplicate.
    var isDuplicateId = function (lookupId, container) {
        // Get the lookup element from the ID sent via parameter.
        var lookupElement = document.getElementById(lookupId),
        // Get the ID of the container element.
        containerId = container.getAttribute('id');

        // Check whether the element exists or not. If it does not exist, it
        // implies that there cannot be any duplicate.
        if (lookupElement === null) {
            return false;
        }

        // In case chart's Id and container's Id is same then is duplicate.
        if (lookupId === containerId) {
            return true;
        }

        // Check whether the lookup element returned before is actually
        // inside container or not.
        var children = container.getElementsByTagName('*');
        for (var i = 0; i < children.length; i += 1) {
            if (children[i] === lookupElement) {
                return false;
            }
        }
        // If the lookupElement is outside/before the container, it implies
        // that it is a duplicate.
        return true;
    };

    // Define a function that saves the reference to the embedded object
    // after it has been rendered.
    var updatePostRender = function (status) {
        // Check whether the render was successful.
        if (status.success === false) {
            throw "FusionCharts.render~postRender() There was an error " +
            "rendering the chart.";
        }

        // Lookup the FusionCharts object within its "items" repository.
        FusionCharts.items[status.id].ref = status.ref;
        status.ref.FusionCharts = FusionCharts.items[status.id];

        // Raise event that this chart has a DOM element
        global.raiseEvent('internal.DOMElementCreated',
            status, {
                async: false
            }, FusionCharts.items[status.id]);

    };

    global.extend({
        render: function (containerElement) {

            // Check IE-Safe variable name collision within Global Scope
            if (window[this.id] !== undefined) {
                // Design-time error. Must throw JS error here.
                throw "FusionCharts.render.IECompatibility() " +
                "Chart Id is same as a JavaScript variable name in window " +
                "scope. This causes errors with Internet Explorer."
            }

            // Create a blank element inside to mimic alternativecontent
            var alt = document.createElement('span');

            // Procure containerElement from internal object options that has
            // been passed via parameters.
            if (containerElement === undefined) {
                containerElement = this.options.containerElementId;
            }

            // In case user sends the element id, we get the object from it
            if (typeof containerElement === 'string') {
                containerElement = document.getElementById(containerElement);
            }
            if (containerElement === undefined || containerElement === null) {
                throw "FusionCharts.render.ArgumentException() " +
                "Unable to find the container HTMLNode";
            }

            // Check duplicate rendering with same id
            if (isDuplicateId(this.id, containerElement)) {
                throw "FusionCharts.render.RuntimeException() " +
                "A duplicate object already exists with the specific Id: " +
                this.id;
            }

            // Set the attribute of this element that will be replaced by
            // swfobject
            alt.setAttribute('id', this.id);

            // Clear the contents of the containerElement and subsequently
            // append the new alt content.
            if (this.options.insertMode === 'clear') {
                while (containerElement.hasChildNodes()) {
                    containerElement.removeChild(containerElement.firstChild);
                }
            }
            containerElement.appendChild(alt);

            // Update the present container details in object.
            this.options.containerElement = containerElement;
            this.options.containerElementId = containerElement.id;

            // Call the current renderer.
            global.renderer.render(this, containerElement, updatePostRender);

            // Return the fusioncharts object for chainability
            return this;
        }
    }, true);

    global.extend({
        setCurrentRenderer: global.renderer.setDefault,

        /**
         * Render FusionCharts directly using the simplest one-line argument
         * parameter.
         * This function directly renders FusionCharts into the container
         * specified in arguments.
         */
        render: function () {

            // The order in which to parse the linear parameters.
            var argsT = ['swfUrl', 'id', 'width', 'height', 'renderAt',
            'dataSource', 'dataFormat'], params = {}, i;

            // Iterate through the linear parameters using the argument template
            // array defined above and create a parameter object out of it.
            for (i = 0; (i < arguments.length && i < argsT.length); i += 1) {
                params[argsT[i]] = arguments[i];
            }

            // Incorporate the trailing object parameter as object-style
            // parameter input overrides.
            if (typeof arguments[arguments.length - 1] === 'object') {
                delete params[argsT[i - 1]];
                global.extend(params, arguments[arguments.length - 1]);
            }

            // Pre-specify the 'xmlurl' format
            if (params.dataFormat === undefined) {
                params.dataFormat = 'xmlurl';
            }

            // Render a new FusionCharts out of the parameters and return the
            // object.
            return new FusionCharts(params).render();

        }
    }, false);
}());



/**
 * -----------------------------------------------------------------------------
 * Data-Handler Abstraction Framework
 * This allows developers to dynamically integrate a data transcoder so that
 * FusionCharts core can seamlessly work with multiple formats for data
 * provisioning.
 * -----------------------------------------------------------------------------
 */

(function () {

    // Register the module with FusionCharts.
    var global = FusionCharts(['private', 'DataHandlerManager']);
    // Check whether the module has been already registered. If true, then
    // do not bother to re-register.
    if (global === undefined) {
        return;
    }

    // Add local AJAX framework
    global.ajax = (function () {

        var error = function (x, u, e, args) {
            if (typeof api.error === 'function') {
                args[1] = {
                    status: x.status,
                    url: u,
                    error: e,
                    source: 'XmlHttpRequest'
                };
                api.error.apply(api, args);
            }
        };

        var api = {
            x: function () {
                var x;
                try {
                    x = new ActiveXObject('Msxml2.XMLHTTP');
                    this.x = function () {
                        return new ActiveXObject('Msxml2.XMLHTTP');
                    };
                    return x;
                }
                catch (e1) {
                    try {
                        x = new ActiveXObject('Microsoft.XMLHTTP');
                        this.x = function () {
                            return new ActiveXObject('Microsoft.XMLHTTP');
                        };
                        return x;
                    }
                    catch (e2) {
                        x = new XMLHttpRequest();
                        this.x = function () {
                            return new XMLHttpRequest();
                        };
                        return x;
                    }
                }
            },

            get: function (u, f) {

                var x = this.x(), args = arguments;
                x.onreadystatechange = function () {
                    try {
                        if (x.readyState === 4) {
                            if (x.status === 200 || x.status === 0) {
                                f(x.responseText);
                            }
                            else {
                                error(x, u, new Error('Network Error.'), args);
                            }
                        }
                    }
                    catch (e) { }
                };

                try {
                    x.open('GET', u, true);
                    x.setRequestHeader('If-Modified-Since', 'Sat, 29 Oct 1994 19:43:31 GMT');
                    x.setRequestHeader("X-Requested-With", "XMLHttpRequest");
                    x.send();
                }
                catch (e) {
                    error(x, u, e, args);
                }
            }
        };

        return api;

    }());

    // Store all data handlers here in a collection and also store all 'data' of
    // every chart in an object.
    var handlers = {}, dataStore = {};

    // Allow data-related parameters to be passed in constructor
    global.policies.options.dataSource = ['dataSource', undefined];
    global.policies.options.dataFormat = ['dataFormat', undefined];

    // Expose Data handler and related management API.
    global.addDataHandler = function (name, obj) {
        if (typeof name !== 'string' || handlers[name.toLowerCase()] !== undefined) {
            throw "FusionCharts.data.addHandler.ArgumentException()"
            + " Invalid Data Handler.";
        }
        handlers[name.toLowerCase()] = obj;

        // Create Handler Direct Access API. This adds common fuctions for the
        // handler.
        var api = {};
        api['set' + name + 'Url'] = function (url) {
            return this.setChartData(url, name + 'url');
        };

        api['set' + name + 'Data'] = function (data) {
            return this.setChartData(data, name);
        };

        api['get' + name + 'Data'] = function () {
            return this.getChartData(name);
        };

        // Extend FusionCharts objects
        global.extend(api, true);
    };

    // Add constructor to initialize datastore or to clear any garbage.
    FusionCharts.addEventListener('BeforeInitialize', function (event) {

        // Get short reference to the event sender.
        var obj = event.sender;

        // Clear the dataStore when new chart is created.
        dataStore[obj.id] = '';

        // Set intitial data if present
        if (obj.options.dataSource !== undefined &&
            typeof obj.options.dataFormat === 'string') {
            obj.setChartData(obj.options.dataSource, obj.options.dataFormat);
        }
    });

    // Add method to make sure to delete all fusioncharts objects when
    // dispose method is invoked
    FusionCharts.addEventListener('BeforeDispose', function (e) {
        delete dataStore[e.sender.id];
    });

    // Function to manage ajax error events
    global.ajax.error = function (url, status, method, obj) {

        // Raise data load error message.
        global.raiseEvent('DataLoadError', status, {
            source: 'XmlHttpRequest',
            url: url,
            httpStatus: status,
            method: method
        }, obj);

        // Call legacy event handler.
        if (typeof window.FC_DataLoadError === 'function') {
            FC_DataLoadError(obj.id, status);
        }
    };

    // Add getter and setter to FusionCharts Objects
    global.extend({
        setChartDataUrl: function (url, format, silent) {
            if (typeof format !== 'string') {
                throw "FusionCharts.setChartDataUrl.ArgumentException() " +
                "Invalid format."
            }

            this.setChartData(url, /url$/i.test(format) ?
                format : format + 'url', silent);
        },

        setChartData: function (data, format, silent, _recursed) {
            if (format === undefined || typeof format.toString !== 'function') {
                throw "FusionCharts.setChartData.ArgumentException() " +
                "Invalid format."
            }
            // Desensitize case of parameter.
            format = format.toString().toLowerCase();

            // Thebase format is set by truncating fetching method from the
            // formatg-string and then stored in 'baseFormat' variable.
            var baseFormat, obj = this;

            // Check whether the data-format has "url" at the end of it. If true,
            // then we call the setChartDataUrl method and that in turn calls this
            // method as callback (marked as _recursed.)
            if (/url$/i.test(format)) {
                // Derive the true format by removing the "url" part of the
                // format.
                baseFormat = format.slice(0, -3);

                // If _recursed is marked as true, it imples that data was loaded
                // using URL data-format.
                if (_recursed !== true) {
                    // update reference to data-source.
                    this.options.dataSource = data;

                    // Raise event to notify xmlhttprequest transaction start.
                    global.raiseEvent('DataLoadRequested', {
                        source: 'XmlHttpRequest',
                        url: data,
                        format: baseFormat
                    }, {
                        async: false,
                        omni: false
                    }, obj);

                    // Initiate XmlHttpRequest.
                    global.ajax.get(data, function (responseText) {

                        // Allow cancellation of data loaing
                        var userCancelled = false, cancelDataLoad = function () {
                            userCancelled = true;
                        }

                        // Raise pre data-load event
                        global.raiseEvent('BeforeDataLoad', {
                            source: 'XmlHttpRequest',
                            url: data,
                            data: responseText,
                            format: baseFormat,
                            cancelled: userCancelled,
                            cancelDataLoad: cancelDataLoad
                        }, {
                            async: false,
                            omni: false
                        }, obj);

                        // Update the chart's dataStore with data received
                        // from url.
                        if (userCancelled === false) {
                            obj.setChartData(responseText, format, silent, true);
                        }

                        // Raise post data load event .
                        global.raiseEvent('DataLoaded', {
                            source: 'XmlHttpRequest',
                            url: data,
                            format: baseFormat,
                            cancelled: userCancelled
                        }, {}, obj);

                        // Call legacy event handler.
                        if (typeof window.FC_DataLoaded === 'function') {
                            FC_DataLoaded(obj.id);
                        }
                    }, 'XmlHttpRequest', this);
                    return;
                }
            }
            // When there is no trailing "url" in data-format, we assume that
            // the format provided is baseFormat itself.
            else {
                // Update the dataSource here only when we know that this call
                // was not recursed for dataurl purpose
                this.options.dataSource = data;
                baseFormat = format;
            }
            // Update chart's internal data-format options
            this.options.dataFormat = format;

            // Fetch the data-handler function from the dataHandler collection.
            var handler = handlers[baseFormat];

            // If the handler has been successfully fetched, execute it.
            if (typeof handler === 'undefined') {
                throw "FusionCharts.setChartData.ArgumentException() " +
                "Format is not registered";
            }
            // Save data within dataStore
            dataStore[this.id] = handler.encode(data, this);

            // Raise data updation event if it is not marked as silent data
            // updating.
            if (silent !== true) {
                global.renderer.update(this, {
                    data: data,
                    format: baseFormat
                });
            }

            // DevNote: This event must not be raised asynchronously in order
            // to maintain integrity and timing of related codes.
            global.raiseEvent('internal.DataUpdated', {
                dataSource: dataStore[this.id],
                dataFormat: baseFormat
            }, {
                async: false
            }, this);
        },

        getChartData: function (format) {
            if (format === undefined || typeof format.toString !== 'function') {
                throw "FusionCharts.setChartData.ArgumentException() " +
                "Invalid format."
            }
            // Desensitize case of parameter.
            format = format.toString().toLowerCase();

            // Fetch the data-handler function from the dataHandler collection.
            var handler = handlers[format];

            // If the handler has not been successfully fetched abort.
            if (typeof handler === 'undefined') {
                return undefined;
            }
            return handler.decode(dataStore[this.id], this);
        }
    }, true);

}());



/**
 * -----------------------------------------------------------------------------
 * XML Data Handler Stub Module
 * -----------------------------------------------------------------------------
 */
(function () {

    // Register the module with FusionCharts.
    var global = FusionCharts(['private', 'GenericRuntime']);
    // Check whether the module has been already registered. If true, then
    // do not bother to re-register.
    if (global === undefined) {
        return;
    }

    // Set the FusionCharts filename
    var SCRIPT_NAME = 'fusioncharts.js';

    // Get the script base uri
    FusionCharts.options.scriptBaseUri = function () {
        var scripts = document.getElementsByTagName('script'),
        scriptName = SCRIPT_NAME.replace(/\./g, '\\.'),
        regex = new RegExp(scriptName + '(\\?.*)?$' , 'i'),
        i, l, scriptBaseUri = '';

        l = scripts.length;
        for (i = 0; i < l; i += 1) {
            if (regex.test(scripts[i].getAttribute('src'))) {
                scriptBaseUri = scripts[i].getAttribute('src').split(regex)[0];
                break;
            }
        }

        return scriptBaseUri;


    }();

    // Deconstruct policies.
    // Update the arguments with latest copy of all variables by
    // reverse engineering the policies.
    var deconstructPolicySet = function (policies, options, obj) {
        for (var policy in policies) {
            // Set just the policy object in case of single-level policy.
            if (policies[policy] instanceof Array) {
                options[policies[policy][0]] = obj[policy]
                continue;
            }
            // Copy the source of multi-level policies
            for (var prop in policies[policy]) {
                options[policies[policy][prop][0]] = obj[policy][prop];
            }
        }
    };

    global.extend({
        // Add default object management prototype method to raise deletion
        // event.
        dispose: function () {
            // The event must be async in order to prevent integrity.
            global.raiseEvent('BeforeDispose', {}, {
                async: false
            }, this);
            // Delete the reference of the item
            delete FusionCharts.items[this.id];

            // Raise a post-disposal event
            global.raiseEvent('Disposed', {}, {}, this);
        },

        clone: function (params, noCreate) {

            // Create a copy of arguments of this object.
            var options = global.extend({}, this.arguments);

            // Recreate construction parameters by reverse calculating the global
            // policies.
            deconstructPolicySet(global.policies, options, this);
            // Also deconstruct the rendere specific policies.
            deconstructPolicySet(global.renderer.getRenderer(this.options.renderer).policies || {},
                options, this);

            // Remove any specific parameters that if cloned will create issues.
            delete options.id;
            delete options.animate;
            delete options.stallLoad;

            // Override any of the options by parameters sent by user
            if (typeof params === 'object') {
                global.extend(options, params);
            }

            // Create new FusionCharts object from the computed options
            return noCreate ? options : new FusionCharts(options);

        }
    }, true);

    // Add flash renderer legacy functions.
    global.extend({
        // Legacy function
        setDataXML: function (xml) {
            // Check whether the XML as parameter can be converted to
            // string or not.
            if (typeof xml.toString !== 'function') {
                return; //throw new TypeError('FusionCharts.setDataXML()');
            }

            this.setChartData(xml, 'xml');
        },

        // Legacy function
        setDataURL: function (url) {
            // Check whether the URL as parameter can be converted to
            // string or not.
            if (typeof url.toString !== 'function') {
                return; //throw new TypeError('FusionCharts.setDataURL()');
            }

            //if the renderer is not javascript
            if(this.options.renderer !== 'javascript'){
                // Check whether the SWF object is alive and kicking! If so,
                // we can then set data url directly on object
                if (this.ref && this.ref.setDataURL) {
                    this.ref.setDataURL(url.toString());
                }
                // When object is not available, we simply set the flashvars
                else if (typeof window.__fusioncharts_vars === 'function') {
                    window.__fusioncharts_vars(this.id, {
                        dataURL: url
                    });
                }
            }else {//if it is an javascript renderer
                this.setChartData(url, 'xmlurl');
            }

        },

        isActive: function () {
            try {
                return /^FusionCharts/.test(this.ref.signature());
            }
            catch (e) {
                return false;
            }
        },

        resizeTo: function (w, h) {
            var dimension = {
                width: w,
                height: h
            };

            if (arguments.length === 1 && typeof arguments[0] === 'object') {
                dimension.width = arguments[0].width;
                dimension.height = arguments[0].height;
            }

            if (dimension.width) {
                this.width = dimension.width;
            }
            if (dimension.height) {
                this.height = dimension.height;
            }

            global.renderer.update(this, dimension);
        }

    }, true);

    // Globally expose getChartFromId method.
    window.getChartFromId = function(id) {
        return FusionCharts.getObjectReference(id) instanceof FusionCharts ?
        FusionCharts.getObjectReference(id).ref : undefined;
    };


    // This function allows users to make a generic call from renderer
    // of the chart to main FusionCharts object.
    var jsCall = function (obj, prop) {
        // Check whether me
        if (typeof obj[prop] === 'function') {
            return function() {
                return obj[prop].apply(obj, arguments);
            };
        }
        return obj[prop];
    };

    /**
     * Extend FusionCharts capabilities to swf HTMLNode object
     */
    FusionCharts.addEventListener('internal.DOMElementCreated', function (event, args) {
        // Check whether the object was added to DOM or not.
        if (args.ref === undefined || args.success !== true) {
            return;
        }

        // List the properties that are not to be extended.
        var ignore = {
            options: true,
            vars: true,
            attributes: true,
            params: true,
            src: true,
            ref: true,
            constructor: true,
            setDataXML: true,
            setDataURL: true,
            hasRendered: true,
            getXML: true,
            getDataAsCSV: true,
            print: true,
            exportChart: true,
            signature: true,
            link: true
        };

        // Iterate through the FusionCharts object and add its variables to the
        // HTMLNode object.
        for (var prop in event.sender) {
            // Discontinue adding this object in case the property is marked to
            // be ignored.
            if (ignore[prop] === true || args.ref[prop] !== undefined) {
                continue;
            }
            try {
                args.ref[prop] = jsCall(event.sender, prop);
            }
            // Suppress error while updating DOM events.
            catch (e) { }
        }
    });

}());



/**
 * -----------------------------------------------------------------------------
 * Dynamic Chart Attributes Module
 * -----------------------------------------------------------------------------
 * This module contains codes required to get and set chart attributes from a
 * FusionCharts object using simple getter and setter functions. These method
 * completely bypasses the data transfer from the SWF and computes chart
 * attributes based on the last set data.
 */
(function () {

    // Register the module with FusionCharts.
    var global = FusionCharts(['private', 'DynamicChartAttributes']);
    // Check whether the module has been already registered. If true, then
    // do not bother to re-register.
    if (global === undefined) {
        return;
    }

    // Global store for chart attributes
    var chartAttStore = {};

    /**
     * This event lsitener keeps the chartAttributes object always updated.
     */
    FusionCharts.addEventListener('internal.DataUpdated', function(e) {

        // Fetch JSON form of the data. It is easier to isolate chart attributes
        // from the JSON data.
        var data = e.sender.getChartData('json');

        // Store the chart attributes internally.
        chartAttStore[e.sender.id] = data.chart || {};
    });

    // Add constructor to reset chartAttributes upon new chart creation
    FusionCharts.addEventListener('BeforeInitialize', function (event) {
        chartAttStore[event.sender.id] = {};
    });

    // Add method to make sure to delete all chartattribute objects when
    // dispose method is invoked
    FusionCharts.addEventListener('BeforeDispose', function (e) {
        delete chartAttStore[e.sender.id];
    });

    /**
     * Updates a FusionCharts DataXML root's attribute with the new
     * attribute-value pair. In case the attribute does not exist, it adds
     * it.
     *
     * @param xml {string} The source FusionCharts DataXML.
     * @param attribute {string} The attribute to be updated.
     * @param value {string} The new value for the attribute to be updated.
     *
     * @type string
     * @return Updated FusionCharts DataXML with the new attribute added or
     * updated
     */
    var updateXML = function (xml, attribute, value) {

        // In case user sends multiple number of attributes in
        // {attribute: value} format, then loop through the attributes
        // and update xml
        if (typeof attribute === 'object' && typeof value === 'undefined') {
            for (var item in attribute) {
                xml = updateXML(xml, item, attribute[item]);
            }
            return xml;
        }

        // Create a RegExp that would extract the attribute as provided
        attribute = attribute.toLowerCase();
        var r = new RegExp("\\s" + attribute + "=\\\"[^\"]+?\\\"|" +
            attribute + "=\\\'[^']+?\\\'", 'i'),

        // Create the replacement string for the attribute like
        // attribute= 'value'
        v = ' ' + attribute + '=\"' + value.toString()
        .replace(/\"/g, '&quot;').replace(/\$/g, '\u0024') + '\"';

        // Check whether the attribute already exists in XML. If it exists
        // then do a replace, else add a new attribute
        return r.test(xml) ? xml.replace(r, v) :
        xml.replace(/(<\w+?)([\s\>])+?/, '$1' + v + '$2');
    };

    global.extend({
        /**
         * Updates a FusionCharts object's XML root's attribute with the new
         * attribute-value pair. In case the attribute does not exist, it adds
         * it.
         *
         * @param attributes {object} The attributes to be updated.
         *
         * @type string
         * @return Updated FusionCharts DataXML with the new attribute added or
         * updated
         */
        setChartAttribute: function (attributes) {

            // In case attribute is sent as separate arguments, combine them
            // to one object.
            if (arguments.length > 1 && typeof attributes === 'string') {
                var temp = arguments[0];
                attributes = {};
                attributes[temp] = arguments[1];
            }

            // Get the current XML from the chart.
            var xml = this.getChartData('xml'), prop;

            // In case animation is not specified, then turn it off.
            if (typeof attributes.animation === 'undefined') {
                attributes.animation = '0';
            }

            // Iterate through attributes and update them.
            for (prop in attributes) {
                xml = updateXML(xml, prop, attributes[prop]);
            }
            // Update chart's XML.
            this.setChartData(xml, 'xml');
        },

        /**
         * Returns the value of a specific chart attribute.
         *
         * @param attribute {string} The attributes to be fetched.
         *
         * @type string
         * @return The value of the attribute.
         */
        getChartAttribute: function (attribute) {
            // In case no argument is passed, we return the entire set of
            // chart attributes object.
            if (arguments.length === 0) {
                return chartAttStore[this.id];
            }

            // Create a variable that will store reference to the parameter that
            // contains attributes. This helps in case user sends one attribute
            // as string, we covert it to an array witj one element.
            var value, i;

            // Convert single attribute to array with one element or directly
            // send the value as return.
            if (typeof attribute === 'string') {
                value = chartAttStore[this.id][attribute.toLowerCase()];
            }

            // In case user sends an array of attributes, we compile an object
            // for the same and return.
            if (attribute instanceof Array) {
                value = {};
                for (i = 0; i < attribute.length; i += 1) {
                    value[attribute[i]] =
                    chartAttStore[this.id][attribute[i].toLowerCase()];
                }
            }

            // If all above conditions fail, there mustt be some issue with the
            // parameters.

            // We return 'value' variable here as because it is equivalent to
            // sending '{}' in case above conditions fail.
            return value;
        }
    }, true);
}());




/**
 * -----------------------------------------------------------------------------
 * Flash Renderer Module
 * -----------------------------------------------------------------------------
 */
(function () {

    // Register the module with FusionCharts and als oget access to a global
    // variable within the core's scope.
    var global = FusionCharts(['private', 'Flash_Renderer']);
    // Check whether the module has been already registered. If true, then
    // do not bother to re-register.
    if (global === undefined) {
        return;
    }

    // Include swfobject in local scope if not already present in the global
    // scope. Make sure to double test original swfobject by testing expected
    // properties of swfobject.
    var swfobject = global.swfobject = (function(){
        var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){
            var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;
            if(typeof t.plugins!=D&&typeof t.plugins[S]==r){
                ab=t.plugins[S].description;
                if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){
                    T=true;
                    X=false;
                    ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");
                    ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);
                    ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);
                    ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0
                }
            }else{
                if(typeof O.ActiveXObject!=D){
                    try{
                        var ad=new ActiveXObject(W);
                        if(ad){
                            ab=ad.GetVariable("$version");
                            if(ab){
                                X=true;
                                ab=ab.split(" ")[1].split(",");
                                ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]
                            }
                        }
                    }catch(Z){}
                }
            }
            return{
                w3:aa,
                pv:ag,
                wk:af,
                ie:X,
                win:ae,
                mac:ac
            }
        }(),k=function(){
            if(!M.w3){
                return
            }
            if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){
                f()
            }
            if(!J){
                if(typeof j.addEventListener!=D){
                    j.addEventListener("DOMContentLoaded",f,false)
                }
                if(M.ie&&M.win){
                    j.attachEvent(x,function(){
                        if(j.readyState=="complete"){
                            j.detachEvent(x,arguments.callee);
                            f()
                        }
                    });
                    if(O==top){
                        (function(){
                            if(J){
                                return
                            }
                            try{
                                j.documentElement.doScroll("left")
                            }catch(X){
                                setTimeout(arguments.callee,0);
                                return
                            }
                            f()
                        })()
                    }
                }
                if(M.wk){
                    (function(){
                        if(J){
                            return
                        }
                        if(!/loaded|complete/.test(j.readyState)){
                            setTimeout(arguments.callee,0);
                            return
                        }
                        f()
                    })()
                }
                s(f)
            }
        }();
        function f(){
            if(J){
                return
            }
            try{
                var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));
                Z.parentNode.removeChild(Z)
            }catch(aa){
                return
            }
            J=true;
            var X=U.length;
            for(var Y=0;Y<X;Y++){
                U[Y]()
            }
        }
        function K(X){
            if(J){
                X()
            }else{
                U[U.length]=X
            }
        }
        function s(Y){
            if(typeof O.addEventListener!=D){
                O.addEventListener("load",Y,false)
            }else{
                if(typeof j.addEventListener!=D){
                    j.addEventListener("load",Y,false)
                }else{
                    if(typeof O.attachEvent!=D){
                        i(O,"onload",Y)
                    }else{
                        if(typeof O.onload=="function"){
                            var X=O.onload;
                            O.onload=function(){
                                X();
                                Y()
                            }
                        }else{
                            O.onload=Y
                        }
                    }
                }
            }
        }
        function h(){
            if(T){
                V()
            }else{
                H()
            }
        }
        function V(){
            var X=j.getElementsByTagName("body")[0];
            var aa=C(r);
            aa.setAttribute("type",q);
            var Z=X.appendChild(aa);
            if(Z){
                var Y=0;
                (function(){
                    if(typeof Z.GetVariable!=D){
                        var ab=Z.GetVariable("$version");
                        if(ab){
                            ab=ab.split(" ")[1].split(",");
                            M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]
                        }
                    }else{
                        if(Y<10){
                            Y++;
                            setTimeout(arguments.callee,10);
                            return
                        }
                    }
                    X.removeChild(aa);
                    Z=null;
                    H()
                })()
            }else{
                H()
            }
        }
        function H(){
            var ag=o.length;
            if(ag>0){
                for(var af=0;af<ag;af++){
                    var Y=o[af].id;
                    var ab=o[af].callbackFn;
                    var aa={
                        success:false,
                        id:Y
                    };

                    if(M.pv[0]>0){
                        var ae=c(Y);
                        if(ae){
                            if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){
                                w(Y,true);
                                if(ab){
                                    aa.success=true;
                                    aa.ref=z(Y);
                                    ab(aa)
                                }
                            }else{
                                if(o[af].expressInstall&&A()){
                                    var ai={};

                                    ai.data=o[af].expressInstall;
                                    ai.width=ae.getAttribute("width")||"0";
                                    ai.height=ae.getAttribute("height")||"0";
                                    if(ae.getAttribute("class")){
                                        ai.styleclass=ae.getAttribute("class")
                                    }
                                    if(ae.getAttribute("align")){
                                        ai.align=ae.getAttribute("align")
                                    }
                                    var ah={};

                                    var X=ae.getElementsByTagName("param");
                                    var ac=X.length;
                                    for(var ad=0;ad<ac;ad++){
                                        if(X[ad].getAttribute("name").toLowerCase()!="movie"){
                                            ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")
                                        }
                                    }
                                    P(ai,ah,Y,ab)
                                }else{
                                    p(ae);
                                    if(ab){
                                        ab(aa)
                                    }
                                }
                            }
                        }
                    }else{
                        w(Y,true);
                        if(ab){
                            var Z=z(Y);
                            if(Z&&typeof Z.SetVariable!=D){
                                aa.success=true;
                                aa.ref=Z
                            }
                            ab(aa)
                        }
                    }
                }
            }
        }
        function z(aa){
            var X=null;
            var Y=c(aa);
            if(Y&&Y.nodeName=="OBJECT"){
                if(typeof Y.SetVariable!=D){
                    X=Y
                }else{
                    var Z=Y.getElementsByTagName(r)[0];
                    if(Z){
                        X=Z
                    }
                }
            }
            return X
        }
        function A(){
            return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)
        }
        function P(aa,ab,X,Z){
            a=true;
            E=Z||null;
            B={
                success:false,
                id:X
            };

            var ae=c(X);
            if(ae){
                if(ae.nodeName=="OBJECT"){
                    l=g(ae);
                    Q=null
                }else{
                    l=ae;
                    Q=X
                }
                aa.id=R;
                if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){
                    aa.width="310"
                }
                if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){
                    aa.height="137"
                }
                j.title=j.title.slice(0,47)+" - Flash Player Installation";
                var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;
                if(typeof ab.flashvars!=D){
                    ab.flashvars+="&"+ac
                }else{
                    ab.flashvars=ac
                }
                if(M.ie&&M.win&&ae.readyState!=4){
                    var Y=C("div");
                    X+="SWFObjectNew";
                    Y.setAttribute("id",X);
                    ae.parentNode.insertBefore(Y,ae);
                    ae.style.display="none";
                    (function(){
                        if(ae.readyState==4){
                            ae.parentNode.removeChild(ae)
                        }else{
                            setTimeout(arguments.callee,10)
                        }
                    })()
                }
                u(aa,ab,X)
            }
        }
        function p(Y){
            if(M.ie&&M.win&&Y.readyState!=4){
                var X=C("div");
                Y.parentNode.insertBefore(X,Y);
                X.parentNode.replaceChild(g(Y),X);
                Y.style.display="none";
                (function(){
                    if(Y.readyState==4){
                        Y.parentNode.removeChild(Y)
                    }else{
                        setTimeout(arguments.callee,10)
                    }
                })()
            }else{
                Y.parentNode.replaceChild(g(Y),Y)
            }
        }
        function g(ab){
            var aa=C("div");
            if(M.win&&M.ie){
                aa.innerHTML=ab.innerHTML
            }else{
                var Y=ab.getElementsByTagName(r)[0];
                if(Y){
                    var ad=Y.childNodes;
                    if(ad){
                        var X=ad.length;
                        for(var Z=0;Z<X;Z++){
                            if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){
                                aa.appendChild(ad[Z].cloneNode(true))
                            }
                        }
                    }
                }
            }
            return aa
        }
        function u(ai,ag,Y){
            var X,aa=c(Y);
            if(M.wk&&M.wk<312){
                return X
            }
            if(aa){
                if(typeof ai.id==D){
                    ai.id=Y
                }
                if(M.ie&&M.win){
                    var ah="";
                    for(var ae in ai){
                        if(ai[ae]!=Object.prototype[ae]){
                            if(ae.toLowerCase()=="data"){
                                ag.movie=ai[ae]
                            }else{
                                if(ae.toLowerCase()=="styleclass"){
                                    ah+=' class="'+ai[ae]+'"'
                                }else{
                                    if(ae.toLowerCase()!="classid"){
                                        ah+=" "+ae+'="'+ai[ae]+'"'
                                    }
                                }
                            }
                        }
                    }
                    var af="";
                    for(var ad in ag){
                        if(ag[ad]!=Object.prototype[ad]){
                            af+='<param name="'+ad+'" value="'+ag[ad]+'" />'
                        }
                    }
                    aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";
                    N[N.length]=ai.id;
                    X=c(ai.id)
                }else{
                    var Z=C(r);
                    Z.setAttribute("type",q);
                    for(var ac in ai){
                        if(ai[ac]!=Object.prototype[ac]){
                            if(ac.toLowerCase()=="styleclass"){
                                Z.setAttribute("class",ai[ac])
                            }else{
                                if(ac.toLowerCase()!="classid"){
                                    Z.setAttribute(ac,ai[ac])
                                }
                            }
                        }
                    }
                    for(var ab in ag){
                        if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){
                            e(Z,ab,ag[ab])
                        }
                    }
                    aa.parentNode.replaceChild(Z,aa);
                    X=Z
                }
            }
            return X
        }
        function e(Z,X,Y){
            var aa=C("param");
            aa.setAttribute("name",X);
            aa.setAttribute("value",Y);
            Z.appendChild(aa)
        }
        function y(Y){
            var X=c(Y);
            if(X&&X.nodeName=="OBJECT"){
                if(M.ie&&M.win){
                    X.style.display="none";
                    (function(){
                        if(X.readyState==4){
                            b(Y)
                        }else{
                            setTimeout(arguments.callee,10)
                        }
                    })()
                }else{
                    X.parentNode.removeChild(X)
                }
            }
        }
        function b(Z){
            var Y=c(Z);
            if(Y){
                for(var X in Y){
                    if(typeof Y[X]=="function"){
                        Y[X]=null
                    }
                }
                Y.parentNode.removeChild(Y)
            }
        }
        function c(Z){
            var X=null;
            try{
                X=j.getElementById(Z)
            }catch(Y){}
            return X
        }
        function C(X){
            return j.createElement(X)
        }
        function i(Z,X,Y){
            Z.attachEvent(X,Y);
            I[I.length]=[Z,X,Y]
        }
        function F(Z){
            var Y=M.pv,X=Z.split(".");
            X[0]=parseInt(X[0],10);
            X[1]=parseInt(X[1],10)||0;
            X[2]=parseInt(X[2],10)||0;
            return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false
        }
        function v(ac,Y,ad,ab){
            if(M.ie&&M.mac){
                return
            }
            var aa=j.getElementsByTagName("head")[0];
            if(!aa){
                return
            }
            var X=(ad&&typeof ad=="string")?ad:"screen";
            if(ab){
                n=null;
                G=null
            }
            if(!n||G!=X){
                var Z=C("style");
                Z.setAttribute("type","text/css");
                Z.setAttribute("media",X);
                n=aa.appendChild(Z);
                if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){
                    n=j.styleSheets[j.styleSheets.length-1]
                }
                G=X
            }
            if(M.ie&&M.win){
                if(n&&typeof n.addRule==r){
                    n.addRule(ac,Y)
                }
            }else{
                if(n&&typeof j.createTextNode!=D){
                    n.appendChild(j.createTextNode(ac+" {"+Y+"}"))
                }
            }
        }
        function w(Z,X){
            if(!m){
                return
            }
            var Y=X?"visible":"hidden";
            if(J&&c(Z)){
                c(Z).style.visibility=Y
            }else{
                v("#"+Z,"visibility:"+Y)
            }
        }
        function L(Y){
            var Z=/[\\\"<>\.;]/;
            var X=Z.exec(Y)!=null;
            return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y
        }
        var d=function(){
            if(M.ie&&M.win){
                window.attachEvent("onunload",function(){
                    var ac=I.length;
                    for(var ab=0;ab<ac;ab++){
                        I[ab][0].detachEvent(I[ab][1],I[ab][2])
                    }
                    var Z=N.length;
                    for(var aa=0;aa<Z;aa++){
                        y(N[aa])
                    }
                    for(var Y in M){
                        M[Y]=null
                    }
                    M=null;
                    for(var X in swfobject){
                        swfobject[X]=null
                    }
                    swfobject=null
                })
            }
        }();
        return{
            registerObject:function(ab,X,aa,Z){
                if(M.w3&&ab&&X){
                    var Y={};

                    Y.id=ab;
                    Y.swfVersion=X;
                    Y.expressInstall=aa;
                    Y.callbackFn=Z;
                    o[o.length]=Y;
                    w(ab,false)
                }else{
                    if(Z){
                        Z({
                            success:false,
                            id:ab
                        })
                    }
                }
            },
            getObjectById:function(X){
                if(M.w3){
                    return z(X)
                }
            },
            embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){
                var X={
                    success:false,
                    id:ah
                };

                if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){
                    w(ah,false);
                    K(function(){
                        ae+="";
                        ag+="";
                        var aj={};

                        if(af&&typeof af===r){
                            for(var al in af){
                                aj[al]=af[al]
                            }
                        }
                        aj.data=ab;
                        aj.width=ae;
                        aj.height=ag;
                        var am={};

                        if(ad&&typeof ad===r){
                            for(var ak in ad){
                                am[ak]=ad[ak]
                            }
                        }
                        if(Z&&typeof Z===r){
                            for(var ai in Z){
                                if(typeof am.flashvars!=D){
                                    am.flashvars+="&"+ai+"="+Z[ai]
                                }else{
                                    am.flashvars=ai+"="+Z[ai]
                                }
                            }
                        }
                        if(F(Y)){
                            var an=u(aj,am,ah);
                            if(aj.id==ah){
                                w(ah,true)
                            }
                            X.success=true;
                            X.ref=an
                        }else{
                            if(aa&&A()){
                                aj.data=aa;
                                P(aj,am,ah,ac);
                                return
                            }else{
                                w(ah,true)
                            }
                        }
                        if(ac){
                            ac(X)
                        }
                    })
                }else{
                    if(ac){
                        ac(X)
                    }
                }
            },
            switchOffAutoHideShow:function(){
                m=false
            },
            ua:M,
            getFlashPlayerVersion:function(){
                return{
                    major:M.pv[0],
                    minor:M.pv[1],
                    release:M.pv[2]
                }
            },
            hasFlashPlayerVersion:F,
            createSWF:function(Z,Y,X){
                if(M.w3){
                    return u(Z,Y,X)
                }else{
                    return undefined
                }
            },
            showExpressInstall:function(Z,aa,X,Y){
                if(M.w3&&A()){
                    P(Z,aa,X,Y)
                }
            },
            removeSWF:function(X){
                if(M.w3){
                    y(X)
                }
            },
            createCSS:function(aa,Z,Y,X){
                if(M.w3){
                    v(aa,Z,Y,X)
                }
            },
            addDomLoadEvent:K,
            addLoadEvent:s,
            getQueryParamValue:function(aa){
                var Z=j.location.search||j.location.hash;
                if(Z){
                    if(/\?/.test(Z)){
                        Z=Z.split("?")[1]
                    }
                    if(aa==null){
                        return L(Z)
                    }
                    var Y=Z.split("&");
                    for(var X=0;X<Y.length;X++){
                        if(Y[X].substring(0,Y[X].indexOf("="))==aa){
                            return L(Y[X].substring((Y[X].indexOf("=")+1)))
                        }
                    }
                }
                return""
            },
            expressInstallCallback:function(){
                if(a){
                    var X=c(R);
                    if(X&&l){
                        X.parentNode.replaceChild(l,X);
                        if(Q){
                            w(Q,true);
                            if(M.ie&&M.win){
                                l.style.display="block"
                            }
                        }
                        if(E){
                            E(B)
                        }
                    }
                    a=false
                }
            }
        }
    }());

    // Collection of chart alias that are not same as swf filename
    var alias = {
        vled: 'realtimeverticalled'
    };

    // This function allows users to make a generic call to external interface
    // of the chart via the FusionCharts object
    var eiCall = function (method) {
        return function() {
            // Verify whether the chart is valid object and then proceed.
            if (this.ref === undefined  || typeof this.ref[method] !== 'function') {
                return undefined;
            //throw "FusionCharts." + method + ":ArgumentException() " +
            //"ExternalInterface call failed. Check whether chart has been rendered";
            }
            return this.ref[method].apply(this.ref, arguments);
        };
    };

    // Adjust flash dimension based upon flashVars
    FusionCharts.addEventListener('BeforeInitialize', function (event) {
        // Get short reference to the event sender.
        var obj = event.sender;

        // Filter objects that are generated by flash renderer only.
        if (obj.options.renderer !== 'flash') {
            return;
        }

        // Prevention is better than cure. So is precaution!
        if (obj.width === undefined) {
            obj.width = renderer.policies.flashVars.chartWidth[1];
        }
        if (obj.height === undefined) {
            obj.height = renderer.policies.flashVars.chartHeight[1];
        }
        if (obj.flashVars.DOMId === undefined) {
            obj.flashVars.DOMId = obj.id;
        }
    });


    // Add method to make sure to delete all fusioncharts objects when
    // dispose method is invoked
    FusionCharts.addEventListener('BeforeDispose', function (e) {
        // Process these events only for objects that have flash renderer!
        if (e.sender.options.renderer !== 'flash') {
            return;
        }
        // Managed removal of chart using swfObject library
        global.swfobject.removeSWF(e.sender.id);
    });

    // Routines to manage state between SWF and FusionCharts JS Object
    window.__fusioncharts_vars = function (id, vars) {

        var obj = FusionCharts.items[id];

        // Verify whether corresponding FusionCharts object exists.
        if (!(obj instanceof FusionCharts)) {
            return false;
        //throw "__fusioncharts_vars.RuntimeError() " +
        //        "FusionCharts object not found.";
        }
        // When 'vars' parameter is sent, we sync the local vars object
        if (typeof vars === 'object') {
            // If corresponding FusionCharts object is found, we update the
            // vars.
            global.extend(obj.flashVars, vars);

            // In case dataURL has been updated, we probe into an event that
            // updates local dataStore
            if (vars.dataURL !== undefined) {
                FusionCharts.addEventListener('DataLoaded', syncDataStore);
            }
            return true;
        }

        return obj.flashVars;
    };

    /**
     * Event listener that updates local chart data when there has
     * been a remote data update on renderer.
     */
    var syncDataStore =  function (e, a) {
        // Verify whether the event has been raised by JS or by Flash.
        // If event has been raised by JS, we do not need to do
        // anything further.
        if (a && a.source === 'XmlHttpRequest') {
            return;
        }

        // Test whether the required functions are available.
        if (e.sender.ref && typeof e.sender.ref.getXML === 'function') {
            // Silently update/sync the internal data of FusionCharts JS
            // objects with the new data that was directly sent to flash.
            e.sender.setChartData(unescape(e.sender.ref.getXML({
                escaped: true
            })), 'xml', true);

            // Since further data communication involves the presence of
            // data-xml in state, we remove the dataURL from flashVars and
            // keep XML fetched from chart.
            delete e.sender.flashVars.dataURL;
        }

        // Remove ebent handler association so that normal dataLoad is not
        // intercepted.
        FusionCharts.removeEventListener('DataLoaded', syncDataStore);
    };

    FusionCharts.addEventListener('Loaded', function (e) {
        // Process these events only for objects that have flash renderer!
        if (e.sender.options.renderer !== 'flash') {
            return;
        }

        // Upon render completion, disable animation of the chart by updating the
        // 'animation' flag in flashVars. This fixes the issue of FusionCharts
        // loosing its state when it is re-rendered after being hidden.
        // Set disable animation flag for state management.
        e.sender.flashVars.animation = "0";

        // Store a reference to the chart swf HTML Node.
        var chartObj = e.sender.ref;
        // Validate whether the chart swf node exists and that it has
        // the prerequisite externalInterface functions.
        if (chartObj === undefined || typeof
            chartObj.getExternalInterfaceMethods !== 'function') {
            return;
        }
        // The externalInterfaceMethods names are parsed from CSV to
        // Array.
        var eiItems = chartObj.getExternalInterfaceMethods().split(','),
        i;
        // We iterate through all the externalInterface method names and
        // create an extensible API object that is added to main
        // FusionCharts object as reference.
        for (i = 0; i < eiItems.length; i += 1) {
            if (e.sender[eiItems[i]] === undefined) {
                e.sender[eiItems[i]] = eiCall(eiItems[i]);
            }
        }
    });

    FusionCharts.addEventListener('DataLoadRequested', function (event) {
        // Reference to event sender.
        var obj = event.sender;

        // Process these events only for objects that have flash renderer!
        if (obj.options.renderer !== 'flash') {
            return;
        }

        // In case we have an active chart, we show the loading
        // message in chart itself.
        if (obj.ref && typeof obj.showChartMessage === 'function') {
            delete obj.flashVars.stallLoad;
            obj.ref.showChartMessage('XMLLoadingText');
        }
        // In case chart object is not available, we set a flashvar saying that
        // loading is to be stalled.
        else {
            obj.flashVars.stallLoad = true;
        }
    });

    FusionCharts.addEventListener('DataLoadError', function (event, args) {
        // Reference to event sender.
        var obj = event.sender;

        // Process these events only for objects that have flash renderer!
        if (obj.options.renderer !== 'flash') {
            return;
        }
        // On data load error, one needs to display "No Data To Display" on
        // charts.
        if (obj.ref && typeof obj.ref.showChartMessage === 'function' &&
            args.source === 'XmlHttpRequest') {
            // Show Data Load Error Message.
            obj.ref.showChartMessage('LoadDataErrorText');
        }
        else {
            obj.flashVars.dataURL = 'XmlHttpRequestDataLoadError: ' + args.url;
            delete obj.flashVars.dataXML;
            delete obj.flashVars.stallLoad;
        }

    });

    FusionCharts.addEventListener('DataLoaded', function (event, args) {
        // Reference to event sender.
        var obj = event.sender;

        // Process these events only for objects that have flash renderer!
        if (obj.options.renderer !== 'flash' || args.source !== 'XmlHttpRequest') {
            return;
        }
        // Clear load prevention flag.
        delete obj.flashVars.stallLoad;

    });

    // Bind EventTarget with the FusionCharts global event handler
    window.__fusioncharts_event = function(event, args) {
        // Create an abstraction layer so that the try-catch / error suppression
        // of flash can be avoided.
        setTimeout(function () {
            global.raiseEvent(event.type, args, {}, FusionCharts.items[event.sender]);
        }, 0);
    };

    var renderer = {
        policies: {
            // Add construction policies specific to ActiveX parameters.
            params: {
                scaleMode: ['scaleMode', 'noScale'],
                wMode: ['wMode', 'opaque'],
                bgColor: ['bgColor', undefined],
                allowScriptAccess: ['allowScriptAccess', 'always'],
                quality: ['quality', 'best']
            },
            /**
             * @var vars {object} Contains all the veriables that are local to every
             * renderer. This has a direct implication to the FlashVars of the
             * 'flash' renderer.
             */
            flashVars: {
                chartWidth: ['width', '400'],
                chartHeight: ['height', '300'],
                lang: ['lang', 'EN'],
                debugMode: ['debugMode', '0'],
                registerWithJS: ['registerWithJS', '1'],
                animation: ['animate', undefined]
            }
        },

        render: function (container, callBack) {
            // Remove the 'animation' flag of the chart.
            if (this.flashVars.animation == true || this.flashVars.animation == 'true') {
                delete this.flashVars.animation;
            }

            // Copy the flashVars and encodeURIComponent all of them before
            // sending to swfObject
            var encodedVars = {};
            global.extend(encodedVars, this.flashVars);

            // Encode dataXML and dataURL
            encodedVars.dataXML = encodeURIComponent(this.flashVars.dataXML || '');
            encodedVars.dataURL = encodeURIComponent(this.flashVars.dataURL || '');

            // Call swfobject API to render the chart
            global.swfobject.embedSWF(this.src, this.id, this.width,
                this.height, '8.0.0', undefined, encodedVars, this.params,
                this.attributes, callBack);

        },

        // Listen to the dataUpdated event, so that charts can be re-rendered with
        // new data, when data is updated on JS variable post render
        update: function (vars) {
            // In case user skips the 'vars' parameter then we ignore the update
            // command.
            if (typeof vars !== 'object') {
                return;
            }

            // Point to direct SWFObject and also get the latest data
            var chart = this.ref, data = this.getChartData('xml');

            // When updating states that dataXML has been updated
            if (vars.data !== undefined) {
                // Update FlashVars
                this.flashVars.dataXML = data;

                // Call ExternalInterface method and update the data
                if (this.isActive()) {
                    if (typeof chart.setDataXML === 'function') {
                        chart.setDataXML(data);
                    }
                    else {
                        // Remove the 'animation' flag of the chart while data was
                        // updated during unavailability of SWF
                        delete this.flashVars.dataURL;
                        delete this.flashVars.animation;
                    }
                }
            }

            // Handle resize related updated
            if (!(vars.width === undefined && vars.height === undefined)) {
                this.flashVars.chartWidth = this.width;
                this.flashVars.chartHeight = this.height;
                if (this.ref) {
                    this.ref.width = this.width;
                    this.ref.height = this.height;
                    if (typeof this.ref.resize === 'function') {
                        this.ref.resize();
                    }
                }
            }
        }
    };

    // Add flash renderer legacy functions.
    renderer.prototype = {
        // Legacy function
        getSWFHTML: function () {

            // Create temporary elements and temporary access Id
            var outElm = document.createElement('span'),
            inElm = document.createElement('span'),
            tempId = 'RnVzaW9uQ2hhcnRz' + (new Date()).getTime();

            // Create DOM hierarchy
            outElm.appendChild(inElm);
            // Specify temp access Id
            inElm.setAttribute('id', tempId);
            // Hide this element from user.
            outElm.style.display = 'none';
            // Add the element to DOM.
            document.getElementsByTagName('body')[0].appendChild(outElm);

            // Temporarily embed the swf in the above-created element.
            global.swfobject.embedSWF(this.src, tempId, this.width,
                this.height, '8.0.0', undefined, this.flashVars, this.params,
                this.attrs);

            // Get the HTML from the temp objects.
            var html = outElm.innerHTML.replace(tempId, this.id);

            // Clean up the dirty work.
            global.swfobject.removeSWF(tempId);
            outElm.parentNode.removeChild(outElm);

            // Return the HTML with its ID set to normal.
            return html;
        },

        // Add legacy setTransparent function
        setTransparent: function (transparency) {
            // Sets chart to transparent mode when isTransparent (wMode) is true
            // (default). When no parameter is passed, we assume transparent to
            // be true.
            if ( typeof transparency !== 'boolean' && transparency !== null) {
                transparency = true;
            }

            // Set the property.
            this.params.wMode = transparency === null ? 'window' :
            (transparency === true ? 'transparent' : 'opaque');
        },

        // Add function to get chart type name from SWF
        chartType: function () {
            var url = this.src.substring(this.src.indexOf('.swf'), 0),
            file = url.substring(url.lastIndexOf('/')+1).toLowerCase();
            return alias[file] === undefined ? file : alias[file];
        }
    };

    // Add the renderer to FusionCharts core repository
    global.renderer.register('flash', renderer);

    // Check for flash and iphone/ipad
    // Register the swf renderer in case we have flashPlayer.
    if (!/\(iPhone;|\(iPad;/i.test(navigator.userAgent)) {
        // Set default renderer
        global.renderer.setDefault('flash');
    }

}());




/*!
 *  HTML5 RENDER
 */

(function () {
    var global, FCC = {}, baseURL = 'JSClass/', covertToFCC, renderArray = [], FCCready = false, i, scriptTags;


    // Register the module with FusionCharts and als oget access to a global
    // variable within the core's scope.
    global = FusionCharts(['private', 'Canvas_Renderer']);
    // Check whether the module has been already registered. If true, then
    // do not bother to re-register.
    if (global === undefined) {
        return;
    }




    //set the baseURL
    //if user defined then use it
    if (FusionCharts.options && FusionCharts.options.scriptBaseUri) {
        baseURL = FusionCharts.options.scriptBaseUri
    } else {//else use the baseURL FusionCharts.js
        scriptTags = document.getElementsByTagName('script');
        for (i = 0; i < scriptTags.length; i++) {
            if (scriptTags[i].src.indexOf('FusionCharts.js') !== -1) {
                baseURL = scriptTags[i].src.split("FusionCharts.js")[0];
            }
        }
    }


    //a function to check is the FCC reday
    FCC.isReady = function () {
        return FCCready;
    };


    ///container for all FCC object with the base object & chart object
    FCC.items = {};


    //function that will call if the window resize ocured
    var FCCresize = function () {
        var FCCChart, FCCContainer, id, FCObj;
        //ittrate through all FusionCharts Html5 Items From Store
        for (var x in FCC.items) {
            id = x;
            //take the in a local a vriable
            FCCChart = FCC.items[x];
            //get the container Element of the chart
            FCCContainer = document.getElementById(FCCChart.baseObj.chart.renderTo);

            //Check whether the sixe of the container has Changed
            if (FCCContainer.offsetWidth != FCCChart.FCCObj.chartWidth || FCCContainer.offsetHeight != FCCChart.FCCObj.chartHeight) {
                //Clear the timer for the previous prevoius frequent resize function
                clearTimeout(FCCChart.timeChach);
                //FusionCharts OBJECT
                FCObj = FusionCharts.items[id];
                //render the chart after 500 ms
                FCCChart.timeChach = setTimeout((function (FCObj,loadEvent) {
                    return function () {
                        //destroy the previous chart
                        removeChart(FCObj.id);
                        //render the new chart
                        FCC.render.call(FCObj, FCObj.options.containerElement, undefined,loadEvent,true);
                    };
                }(FCObj,function () {
                    global.raiseEvent('resized', {}, {}, FCObj);
                })), 500);
            }
        }
    };

    ///add the resize event

    if (window.addEventListener) {
        window.addEventListener("resize", FCCresize, false);
        window.addEventListener("resize", FCCresize, false);
    } else if (window.attachEvent) {
        window.attachEvent("resize", FCCresize);
        window.attachEvent("resize", FCCresize);
    } else {
        window.onresize = FCCresize;
        window.onresize = FCCresize;
    }


    //Add the prototype for the FCC renderer

    FCC.prototype = {
        signature : function(){
            return 'FusionCharts/3.2.0/JS';
        },
        // Add legacy setTransparent function
        setTransparent: function (transparency) {
            // Sets chart to transparent mode when isTransparent (wMode) is true
            // (default). When no parameter is passed, we assume transparent to
            // be true.
            if ( typeof transparency !== 'boolean' && transparency !== null) {
                transparency = true;
            }

            jQuery('#'+this.id).css('background-color',(transparency === true) ? '' : '#FFFFFF');

        },
        print: function(){
            var id = this.id;
            FCC.items[id].FCCObj.print();
        },
        cancelExport: function(){
            return null;
        },
        chartType: function(){
            var id = this.id;
            if(this.hasRendered()){
                return FCC.items[id].chartType.toLowerCase();
            }else{
                return undefined;
            }
        },
        drawOverlayButton: function(){
            return null;
        },
        exportChart: function(){
            return null;
        },
        getDataAsCSV: function(){
            return null;
        },
        getExternalInterfaceMethods: function(){
            return null;
        },
        getImageData: function(){
            return null;
        },
        getSWFHTML: function(){
            return null;
        },
        getXML: function(){
            var id = this.id;
            return FusionCharts.items[id].getXMLData();
        },
        hasRendered: function(){
            var id = this.id;
            if(typeof FCC.items[id] === 'object'){
                return true;
            }else{
                return false;
            }
        },
        prepareImageDataStream: function(){
            return null;
        },
        ref: function(){
            var id = this.id;
            if(this.hasRendered()){
                return FCC.items[id].FCCObj;
            }else{
                return undefined;
            }
        },
        saveAsImage: function(){
            return null;
        }

    }

    //initialize Highcharts

    FCC.init = function () {
        //function that will chaek whether FCC is ready or not

        function checkFCCReady() {
            var temp;
            if (typeof window.Highcharts === 'object') {
                FCCready = true;
                //call all the stacked render actions
                if (typeof FCC.render == 'function') {
                    while (renderArray.length > 0) {
                        temp = renderArray.splice(0, 1)[0];
                        FCC.render.call(temp[0], temp[1], temp[2]);
                    }
                }

            //call FCC onready function
            } else {
                setTimeout(checkFCCReady,300);
            }
        }

        //load HIGFCCHARTS
        function loadFCC() {
            if (typeof jQuery === 'function') {
                if (typeof window.Highcharts !== 'object') {
                    loadScript(baseURL + 'highcharts.js');
                    setTimeout(checkFCCReady,300);
                } else {
                    checkFCCReady();
                }
            }else{
                setTimeout(loadFCC,300);
            }
        }



        //load jquery
        if (typeof jQuery !== 'function') {
            loadScript(baseURL + 'jquery.js');
            setTimeout(loadFCC,300);
        } else {
            loadFCC();
        }



        //function  that will add a script tag in head
        function loadScript(src) {
            var newele = document.createElement('script');
            newele.setAttribute('type', 'text/javascript');
            newele.setAttribute('src', src);
            var head = document.getElementsByTagName('head');
            head[0].appendChild(newele);
        }


        ////////// List of tools(function s) needed//////////


        //this functon will map chart series type with its name  and return it
        function getSeriesName(chartName) {
            return FCFCC.seriesName[chartName];
        }

        //reduce gradent color take only first color
        //converts color to compatable color format
        function convertColor(color, alpha, difColor, difAlpha) {
            if (typeof difAlpha === 'undefined') {
                difAlpha = 100;
            }
            if (!difColor) {
                difColor = '000000';
            }
            if (!alpha) {
                alpha = difAlpha;
            }
            if (!color) {
                color = difColor;
            }
            if (typeof alpha === 'string') {
                alpha = alpha.split(', ')[0];
            }

            alpha = parseInt(alpha) / 100;
            var colorStr = color.replace(/[#\s]/ig, '').split(', ')[0];
            switch (colorStr.length) {
                case 3:
                    colorStr = colorStr[0] + colorStr[0] + colorStr[1] + colorStr[1] + colorStr[2] + colorStr[2];
                    break;
                case 6:
                    break;
                default:
                    colorStr = (colorStr + 'FFFFFF').slice(0, 6);
                    break;
            }
            return 'rgba(' + parseInt(colorStr.slice(0, 2), 16) + ', ' + parseInt(colorStr.slice(2, 4), 16) + ', ' + parseInt(colorStr.slice(4, 6), 16) + ', ' + alpha + ')';
        }

        //this function will map FC name to FCC name and return the corosponding FCC name
        function convertNames(chartName) {
            return FCFCC.highCharts[chartName];
        }


        //this function will datsa to parcentage of total for pareto line
        function paretoConvert(data, sum) {
            var x, psum = 0, pareto = {
                yAxis: 1,
                data: [],
                type: 'line',
                color: 'rgba(00, 00, 00, 1)',
                FCtype: 1.5
            };
            data.sort(function (a, b) {
                return b.y - a.y;
            });
            for (x in data) {
                psum += data[x].y;
                pareto.data.push({
                    y : Math.round((psum / sum) * 10000) / 100
                });
            }
            return pareto;
        }

        //return the name of the chart swf file from it's src'
        //e.g. charts/Column2D.swf will return Column2D

        var convertSWFtoAlias = function (swf) {
            var alias = swf.substring(swf.indexOf('.swf'), 0);
            return alias.substring(alias.lastIndexOf('/') + 1);
        };


        function formrtNumber(num, obj, type) {
            // If type is undefined initialize type with 1
            type = type === undefined ? 1 : type;
            /* if(typeof num == 'string'){
                num = parseFloat(num);
            }*/

            // Defines FusionCharts default values and attributes
            var chart = {
                formatnumber: 1,
                formatnumberscale: 1,
                defaultnumberscale: '',
                numberscaleunit: 'K, M',
                numberscalevalue: '1000, 1000',
                numberprefix: "",
                numbersuffix: "",
                decimalseparator: ".",
                thousandseparator: ", ",
                indecimalseparator: "",
                inthousandseparator: "",
                decimals: "",
                forcedecimals: "0",
                yaxisvaluedecimals: "",
                sformatnumber: "1",
                sformatnumberscale: "0",
                sdefaultnumberscale: "",
                snumberscaleunit: "K, M",
                snumberscalevalue: "1000, 1000",
                snumberprefix: "",
                snumbersuffix: "",
                sdecimals: "",
                sforcedecimals: "0",
                syaxisvaluedecimals: "0"
            };

            var numberScaleValue, numberScaleUnit, result, i, res, power, formatedNum = '', c = 0, initialVal, decimalVal, splitVal, decimalLength, last;

            // Replace default attributes with new attributes
            for (i in obj) {
                chart[i.toLowerCase()] = obj[i];
            }

            // Replace the indecimalseparator value with decimal to perform numeric operations
            num = chart.indecimalseparator !== '' ? num.toString().replace(chart.indecimalseparator, '.'): num;
            // Replace the inthousandseparator value with decimal to perform numeric operations
            num = chart.inthousandseparator !== '' ? num.toString().replace(chart.inthousandseparator, ''): num;

            if (type !== 1) {
                chart.formatnumber = chart.sformatnumber;
                chart.formatnumberscale = chart.sformatnumberscale;
                chart.defaultnumberscale = chart.sdefaultnumberscale;
                chart.numberscaleunit = chart.snumberscaleunit;
                chart.numberscalevalue = chart.snumberscalevalue;
                chart.numberprefix = chart.snumberprefix;
                chart.numbersuffix = chart.snumbersuffix;
                chart.decimals = chart.sdecimals;
                chart.forcedecimals = chart.sforcedecimals;
                chart.yaxisvaluedecimals = chart.syaxisvaluedecimals;
            }

            // Creates array of numberScaleValue and numberScaleUnit to format the number
            numberScaleValue = chart.numberscalevalue.split(', ');
            numberScaleUnit = chart.numberscaleunit.split(', ');

            result = res = num.toString();

            // format the number with,
            if (chart.formatnumber == 1) {
                if (res.indexOf('.') !== -1) {
                    splitVal = res.split('.');
                    initialVal = splitVal[0];
                    decimalVal = '.' + splitVal[1];
                }
                else {
                    initialVal = res;
                    decimalVal = '';
                }
                for (i = initialVal.length; i > 0; i--) {
                    if (c % 3 === 0 && c !== 0) {
                        formatedNum = chart.thousandseparator + formatedNum;
                        c = 0;
                    }
                    formatedNum = res[i - 1] + formatedNum;
                    c++;
                }
                result = (splitVal === undefined) || ((decimalVal) === 0) ? formatedNum : (formatedNum) + decimalVal;
            }

            // Places K, M, B number format
            if (chart.formatnumberscale == 1) {
                res = num;
                for (i = 0; i < numberScaleValue.length && res / numberScaleValue[i] >= 1; i++) {
                    res = res / numberScaleValue[i];
                }
                i--;

                if (chart.decimals === '') {
                    chart.decimals = '2';
                }
                power = Math.pow(10, chart.decimals);
                result = (i === -1) ? Math.round(res * power) / power : Math.round(res * power) / power;
            }

            // force decimal is true
            if (chart.forcedecimals == 1) {
                // checkes wather the result number is in decimal or not
                if (result.toString().indexOf(chart.decimalseparator) !== -1) {
                    decimalVal = result.toString().split(chart.decimalseparator)[1];
                    decimalLength = decimalVal.length;
                } else {
                    decimalLength = 0;
                }
                if (decimalLength === 0) {
                    result += chart.decimalseparator;
                }
                if (decimalLength > chart.decimals) {
                    if (chart.decimals == 1 && decimalVal[0] >= 5) {
                        last = result[result.substring(0, result.indexOf('.')).length - 1];
                        ++last;
                        result = result.substring(0, (result.indexOf('.') - 1)) + last;
                        result = result + '.' + '0';
                    }
                    else if (decimalVal[chart.decimals - 1] >= 5) {
                        last = decimalVal[chart.decimals] >= 5 ? (parseInt(decimalVal[chart.decimals - 1]) + 1): decimalVal[chart.decimals - 1];
                        decimalVal = decimalVal.substring(0, chart.decimals - 1) + last;
                        result = result.substring(0, result.indexOf('.')) + '.' + decimalVal;
                    }
                }
                else {
                    while (decimalLength < chart.decimals) {
                        result += '0';
                        decimalLength++;
                    }
                }
            }

            if (chart.formatnumberscale == 1) {
                result += (i === -1) ? chart.defaultnumberscale : numberScaleUnit[i];
            }

            result = chart.numberprefix + result + chart.numbersuffix;

            if (chart.decimalseparator !== "." && chart.decimalseparator !== "") {
                result = result.toString().replace('.', chart.decimalseparator);
            }
            return result;
        }


        function convertAncorSide(num) {
            var x = 'triangle-down';
            switch (num) {
                case 3:
                    x = 'triangle';
                    break;
                case 4:
                    x = 'square';
                    break;
                default:
                    x = 'diamond';
                    break;
            }
            return x;
        }

        var newwindow;///variable for popup
        ///this function will open a link

        function pointClick(flag) {
            if ((flag === 2 && this.link)||(flag === 1 && this.options.chart.link)) {
                if(flag === 2 && this.link){
                    var arr = this.link.split('-'), chartId = this.options.id, sender = FusionCharts.items[chartId];
                }else if(flag === 1 && this.options.chart.link){
                    var arr = this.options.chart.link.split('-'), chartId = this.options.id, sender = FusionCharts.items[chartId];
                }

                switch (arr[0].toLowerCase()) {
                    case 'n':
                        window.open(arr[1]);
                        break;
                    case 'f':
                        if (frames[arr[1]]) {
                            frames[arr[1]].location = arr[2];
                        } else {
                            window.open(arr[2], arr[1]);
                        }
                        break;
                    case 'j':
                        try {
                            window[arr[1]](arr[2]);
                        }catch (err) {

                        }
                        break;
                    case 'p':
                        newwindow = window.open(arr[2], arr[1].match(/[^,]+/i), arr[1].replace(/[^,]+, /i, ''));
                        if (window.focus) {
                            newwindow.focus();
                        }
                        break;
                    case 'newchart':
                        var linkType = arr[1].toLowerCase() === 'url'? 'URL':'JSON', data, x, chartJson,linkchartId;
                        if(linkType === 'URL'){
                            data = this.link.replace(/[^-]+-[^-]+-/i,'');
                        }else{
                            chartJson = FCC.items[chartId].FCObj;
                            linkchartId = this.link.replace(/[^-]+-[^-]+-/i,'');
                            for(x in chartJson.linkeddata) {
                                if(chartJson.linkeddata[x].id == linkchartId){
                                    data = chartJson.linkeddata[x].linkedcharts;
                                }
                            }
                        }
                        global.raiseEvent('LinkedChartInvoked', {
                            linkType:linkType,
                            data : data
                        }, {}, sender);
                        break;
                    default:
                        arr = this.link.split(':');
                        if (arr[0].toLowerCase() == 'javascript') {
                            try{
                                eval(arr[1]);
                            } catch(err){

                            }
                        } else {
                            window.location.href = this.link;
                        }
                        break;
                }
            }
        }


        ///fiend the max z value among all the data
        function maxZVal(obj){
            var max = 0, x, y,temp;
            for(x in obj){
                for(y in obj[x].data){
                    temp =  parseInt(obj[x].data[y].z);
                    max = (max > temp)? max : temp;
                }
            }
            return max;
        }

        ///function to determine max redious for buble chart depending on the chart width and height
        function maxRedious(width,height){
            var lower,max = 5;
            lower = (width > height)? height : width;
            if(lower > 100){
                max = lower/8;
            }
            return max;
        }

        ////////////////  Working Functions /////////////////////

        //this function will create a default FCC object
        //
        function newFCCstub(cObj, specilObj) {
            var obj = {
                chart: {
                    renderTo: '',
                    events: {
                        click: function(){
                            pointClick.call(this,1);
                        }
                    },
                    margin: [15, 15, 50, 60],
                    borderRadius: 0,
                    plotBackgroundColor : '#FFFFFF'
                },
                colors: [],
                credits: {
                    href: 'http://www.FusionCharts.com',
                    text: 'FusionCharts - HighCharts'
                },
                global: {},
                labels: {},
                lang: {},
                legend: {
                    enabled : true,
                    symbolWidth: 5,
                    borderRadius: 0
                },
                loading: {},
                plotOptions: {
                    series: {
                        borderColor : '#333333',
                        dataLabels : {
                            enabled : true,
                            color: '#555555',
                            formatter : function () {
                                var x ;
                                x = (this.series.type == 'pie' && this.point.name) ?this.point.name+cObj.chart.tooltipsepchar: '';
                                x += formrtNumber(this.y, cObj.chart, 1);
                                x += (this.series.options.FCtype == 1.5 && this.series.type == 'line') ? '%': '';
                                return x;
                            }
                        },
                        point: {
                            events: {
                                click:  function(){
                                    pointClick.call(this,2);
                                }
                            }
                        }
                    },
                    area: {
                        marker: {
                            lineWidth: 1,
                            radius: 3,
                            states: {
                                hover: {
                                    enabled: false
                                },
                                select: {
                                    enabled: false
                                }
                            }
                        }
                    },
                    line: {
                        marker: {
                            lineWidth: 1,
                            radius: 3,
                            states: {
                                hover: {
                                    enabled: false
                                },
                                select: {
                                    enabled: false
                                }
                            }
                        }
                    },
                    pie: {
                        size: '80%',
                        allowPointSelect: true,
                        cursor: 'pointer'
                    },
                    column: {}
                },
                point: {},
                series: [{}],
                subtitle: {
                    text: '',
                    style : {}
                },
                symbols: [],
                title: {
                    text : '',
                    style : {}
                },
                toolbar: {},
                tooltip: {
                    borderRadius: 0,
                    formatter : function () {
                        var x = '', charSep = cObj.chart.tooltipsepchar;
                        if (this.series.options.FCtype >= 2 && this.series.name !== ' ') {
                            x+= this.series.name+charSep;
                        }
                        x+= this.point.name?this.point.name + charSep: '';
                        if (this.series.options.FCtype == 1.5 && this.series.type == 'line') {
                            x+= this.y+'%';
                        }
                        else if (this.series.type == 'pie') {
                            x+= (Math.round(this.percentage * 100) /100) +'%';
                        }
                        else {
                            x+= formrtNumber(this.y, cObj.chart, 1);
                        }
                        return x;
                    }
                },
                xAxis: {
                    labels: {
                        rotation: -25,
                        formatter : function () {
                            return typeof this.value === 'string' ?this.value : '';
                        },
                        align: 'right'
                    },
                    categories: [],
                    plotLines: [],
                    title : {
                        text: ''
                    }
                },
                yAxis: [{
                    title : {
                        text : ''
                    },
                    labels: {
                        formatter : function () {
                            return formrtNumber(this.value, cObj.chart, 1);
                        }
                    },
                    plotBands: [],
                    plotLines: []
                }, {
                    title : {
                        text : ''
                    },
                    labels: {
                        enabled : false,
                        formatter : function () {
                            return formrtNumber(this.value, cObj.chart, 2);
                        }
                    },
                    opposite: true
                }]
            };

            return obj;
        }






        // This function will convert a Fusion Charts obj in to FCC obj

        function covertToFCC (renderTo, chartname, obj, id, width, height) {
            var hc, y = getSeriesName(chartname), x, z;

            //check whether graph tag present
            if (obj.graph != 'undefined' && !obj.chart ) {
                obj.chart = obj.graph;
            }
            // Fixed by SB.
            if (obj.chart === undefined) {
                obj.chart = {};
            }

            if ( !obj.chart.tooltipsepchar) {
                obj.chart.tooltipsepchar = ', ';
            }

            //creade defaule stub
            hc = newFCCstub(obj);
            //add chart container
            if (renderTo){
                hc.chart.renderTo = renderTo;
            }
            hc.chart.defaultSeriesType = convertNames(chartname);


            ////////// chart specific options  //////////////////////
            if (chartname == 'Doughnut2D' || chartname == 'Doughnut3D') {
                hc.plotOptions.pie.innerSize = '50%';
            }

            /////////// Chart Element Attributes ////////////////////
            if(obj.chart.clickurl){
                hc.chart.link = obj.chart.clickurl;
                hc.chart.id = id;
            }
            hc.plotOptions.series.animation = obj.chart.animation ==='0' ? false : true;
            if (obj.chart.showlabels == '0') {
                hc.xAxis.labels.enabled = false;
                hc.chart.margin[2] = 15;
            }
            if (obj.chart.showyaxisvalues == '0') {
                hc.yAxis[0].labels.enabled = false;
                hc.chart.margin[3] = 15;
            }
            if ((y == 1.5 || y == 5 || y == 5.5 )&& obj.chart.showsecondarylimits != '0') {
                hc.yAxis[1].labels.enabled = true;
                hc.chart.margin[1] = 50;
            }


            //////////background canvas plot etc [cosmetics] ///////
            hc.chart.backgroundColor = convertColor(obj.chart.bgcolor, obj.chart.bgalpha, 'CBCBCB', 50);
            hc.chart.borderWidth = obj.chart.showborder == '0' ?0 : (obj.chart.borderthickness?obj.chart.borderthickness: 1);
            hc.chart.borderColor = convertColor(obj.chart.bordercolor, obj.chart.borderalpha, '767575', 50);
            hc.chart.plotBackgroundColor = convertColor(obj.chart.canvasbgcolor, obj.chart.canvasbgbgalpha, 'FFFFFF', 100);
            hc.chart.plotBorderColor = convertColor(obj.chart.canvasbordercolor, obj.chart.canvasborderalpha, '545454', 100);
            hc.chart.plotBorderWidth = obj.chart.canvasborderthickness?obj.chart.canvasborderthickness: 2;
            /*plot*/
            hc.plotOptions.series.borderColor = convertColor(obj.chart.plotbordercolor, obj.chart.plotborderalpha, '333333', 95);
            hc.plotOptions.series.borderWidth = obj.chart.showplotborder == '0'? 0 : (obj.chart.plotborderthickness ?  obj.chart.plotborderthickness : 1);
            hc.plotOptions.series.borderRadius = obj.chart.useroundedges == '1' ? 5 : 0;




            ////////// Anchors //////////////////////

            if (obj.chart.drawanchors == '0') {
                hc.plotOptions.area.marker.enabled = hc.plotOptions.line.marker.enabled = false;
                hc.tooltip.enabled = false;
            }
            if (obj.chart.anchorradius) {
                hc.plotOptions.area.marker.radius = hc.plotOptions.line.marker.radius = obj.chart.anchorradius;
            }
            hc.plotOptions.line.marker.lineColor = convertColor(obj.chart.anchorbordercolor, obj.chart.anchoralpha, '767575', 100);
            hc.plotOptions.area.marker.lineColor = convertColor(obj.chart.anchorbordercolor, obj.chart.anchoralpha, '767575', 0);
            if (obj.chart.anchorborderthickness) {
                hc.plotOptions.area.marker.lineWidth = hc.plotOptions.line.marker.lineWidth = obj.chart.anchorborderthickness;
            }
            hc.plotOptions.line.marker.fillColor = convertColor(obj.chart.anchorbgcolor, obj.chart.anchorbgalpha, 'FFFFFF', 100);
            hc.plotOptions.area.marker.fillColor = convertColor(obj.chart.anchorbgcolor, obj.chart.anchorbgalpha, 'FFFFFF', 0);
            if (obj.chart.anchorsides) {
                hc.plotOptions.area.marker.symbol = hc.plotOptions.line.marker.symbol = convertAncorSide(parseInt(obj.chart.anchorsides));
            }




            //////////////////////////  Divisional Lines & Grids  //////////////
            hc.yAxis[1].alternateGridColor = hc.yAxis[0].alternateGridColor = convertColor(obj.chart.alternatehgridcolor, obj.chart.alternatehgridalpha, 'EEEEEE', 50);
            hc.yAxis[1].gridLineColor = hc.yAxis[0].gridLineColor = convertColor(obj.chart.divlinecolor, obj.chart.divlinealpha, '717170', 40);
            hc.yAxis[1].gridLineWidth = hc.yAxis[0].gridLineWidth = obj.chart.divlinethickness  ? obj.chart.divlinethickness : 1 ;


            //////////titles captions////////////
            if (obj.chart.caption) {
                hc.title.text = obj.chart.caption;
                hc.chart.margin[0] = 35;
            }
            if (obj.chart.subcaption) {
                hc.subtitle.text = obj.chart.subcaption;
                hc.chart.margin[0] = 55;
            }
            if (obj.chart.xaxisname) {
                hc.xAxis.title.text = obj.chart.xaxisname;
                hc.xAxis.title.margin = hc.chart.margin[2];
                hc.chart.margin[2] += 20;
            }

            if(y == 5 || y == 5.5 || y == 1.5 ){//dual y type chart and pareto chart
                if (obj.chart.pyaxisname) {
                    hc.yAxis[0].title.text = obj.chart.pyaxisname;
                    hc.yAxis[0].title.margin = hc.chart.margin[3];
                    hc.chart.margin[3] += 15;
                }
                if (obj.chart.syaxisname) {
                    hc.yAxis[1].title.text = obj.chart.syaxisname;
                    hc.yAxis[1].title.margin = hc.chart.margin[1];
                    hc.chart.margin[1] += 15;
                }
            }else if (obj.chart.yaxisname){
                hc.yAxis[0].title.text = obj.chart.yaxisname;
                hc.yAxis[0].title.margin = hc.chart.margin[3];
                hc.chart.margin[3] += 15;
            }

            ///////// tooltip Options//////////////
            if (obj.chart.showtooltip == '0' ){ //area/line ancor conflict
                hc.tooltip.enabled =  false;
            }
            hc.tooltip.backgroundColor = convertColor(obj.chart.tooltipbgcolor, obj.chart.tooltipbgalpha, 'FFFFFF', 100);
            hc.tooltip.borderColor = convertColor(obj.chart.tooltipbordercolor, obj.chart.tooltipborderalpha, '545454', 100);
            hc.tooltip.shadow = obj.chart.showtooltipshadow == '1' ? true : false;


            //////// modify Lables///////
            hc.plotOptions.series.dataLabels.enabled = obj.chart.showvalues == '0' ? false : true ;


            ///////////Trend-lines /////////////////

            for (x in obj.trendlines) {
                for (z in obj.trendlines[x].line) {
                    if (obj.trendlines[x].line[z].istrendzone == '1') {
                        hc.yAxis[0].plotBands.push({
                            color: convertColor(obj.trendlines[x].line[z].color, obj.trendlines[x].line[z].alpha, '333333', 99),
                            from: obj.trendlines[x].line[z].startvalue? obj.trendlines[x].line[z].startvalue : 0,
                            to: obj.trendlines[x].line[z].endvalue
                        });
                    }
                    hc.yAxis[0].plotLines.push({
                        color: convertColor(obj.trendlines[x].line[z].color, obj.trendlines[x].line[z].alpha, '333333', 99),
                        value: obj.trendlines[x].line[z].startvalue? obj.trendlines[x].line[z].startvalue: 0,
                        width: obj.trendlines[x].line[z].thickness?obj.trendlines[x].line[z].thickness: 1
                    });
                }
            }




            ///modify as per series /////
            ModifyType(obj, y, chartname, hc, width, height, id);


            /////modify for legend //////
            if (y >= 2) {
                ModyfyLegend(hc, obj);
            }


            //return the converted object
            return hc;
        }

        ///modify as per legend
        function ModyfyLegend(hc, obj) {
            var noSeries = hc.series.length, legendPos, legendWidth, legendHeight;

            if (obj.chart.showlegend == '0') {
                hc.legend.enabled = false;
            } else {
                hc.legend.backgroundColor = obj.legendbgcolor ? obj.legendbgcolor : '#ffffff';
                hc.legend.borderColor = obj.legendbordercolor ? obj.legendbordercolor : '#545454';
                hc.legend.borderWidth = obj.legendborderthickness ? obj.legendborderthickness : 1;
                hc.legend.reversed = obj.reverselegend == '1'? true : false;

                if (obj.chart.legendposition == 'RIGHT') {
                    hc.legend.verticalAlign = 'middle';
                    hc.legend.align = 'right';
                    hc.legend.width = 70;
                    hc.legend.x = -15;
                    hc.chart.margin[1] += 85;
                } else {
                    hc.legend.verticalAlign = 'bottom';
                    hc.legend.align = 'center';
                    hc.chart.margin[2] += 30;
                }
            }

        }

        function ModifyType(obj, series, chartName, hc, width, height, id) {
            var a = [], x, y, z, m, count_set, getScolor, pareto, paretoSum = 0, countCat = 0;
            //thi s function widecide the default color for a series or data;
            getScolor = function (index) {
                var palett;
                if (obj.chart.palettecolors) {
                    palett = obj.chart.palettecolors;
                    if (typeof palett === 'string') {
                        palett = palett.split(', ');

                    }
                    return palett[index%palett.length];
                } else {
                    return FCFCC.color[index%FCFCC.color.length];
                }
            };
            switch (series) {
                case 1:
                case 1.5:
                    if (series == 1.5) {///options that have to change for pareto chart
                        hc.yAxis[1].max = 100;
                        hc.yAxis[1].labels.formatter = function () {
                            return this.value+'%';
                        };

                    }


                    ///// special setings for single series /////


                    hc.legend.enabled = false;

                    //////category///
                    if (obj.data) {
                        for (x in obj.data) {
                            hc.xAxis.categories.bbb = [1,2,3]
                            if (!obj.data[x].vline) {
                                hc.xAxis.categories.push(obj.data[x].label?obj.data[x].label: '');
                                countCat += 1;
                            } else {
                                hc.xAxis.plotLines.push({
                                    color: convertColor(obj.data[x].color,obj.data[x].alpha, '444444',80),
                                    width: obj.data[x].thickness?obj.data[x].thickness: 1,
                                    value: countCat-0.5
                                });
                            }
                        }



                        //data



                        z = {
                            data: [],
                            FCtype: series,
                            color: convertColor((obj.chart.lineColor?obj.chart.lineColor:obj.chart.plotfillcolor),100,'767575',100)
                        };
                        count_set = 0;
                        for (x in obj.data) {
                            if (!obj.data[x].vline) {
                                paretoSum += parseInt(obj.data[x].value);
                                if (obj.data[x].link && z.cursor != 'pointer'){
                                    z.cursor = 'pointer';
                                }
                                z.data.push({
                                    y: obj.data[x].value?parseFloat(obj.data[x].value): '',
                                    color: convertColor(obj.data[x].color,obj.data[x].alpha,getScolor(count_set),100),
                                    name: obj.data[x].label,
                                    link: obj.data[x].link,
                                    id: id
                                });
                                count_set++;
                            }
                        }

                        if (convertNames(chartName) == 'pie') {//revarse the series for pie/douggnut
                            z.data.reverse();
                            hc.chart.plotBorderWidth = 0;
                            x = hc.chart.borderWidth + 1;
                            hc.chart.margin = [hc.chart.margin[0], x, x, x];
                        }else if(convertNames(chartName) == 'line' && convertNames(chartName) == 'area'){

                        }
                        a.push(z);
                        if (chartName == 'Pareto2DChart' || chartName == 'Pareto3DChart') {
                            pareto = paretoConvert(z.data, paretoSum);
                            a.push(pareto);
                        }
                    }
                    break;




                case 2:
                case 2.5:
                    if(series == 2.5){
                        hc.xAxis.maxZoom = 2;
                        hc.chart.zoomType = 'x';
                        hc.plotOptions.series.dataLabels.enabled = obj.chart.showvalues == '1' ? true : false ;
                    }
                case 3:
                    if (series == 3) {
                        hc.plotOptions.series.stacking = obj.chart.stack100percent == '1' ? 'percent' : 'normal';
                    }
                case 4:
                case 5:
                case 5.5:
                    if (series == 5.5) {
                        hc.plotOptions.column.stacking = obj.chart.stack100percent == '1' ? 'percent' : 'normal';
                    }

                    ////////category////////

                    if (obj.categories) {
                        for (x in obj.categories[0].category) {
                            if(typeof obj.categories[0].category[x] === 'object'){
                                if (!obj.categories[0].category[x].vline) {
                                    hc.xAxis.categories.push(obj.categories[0].category[x].label?obj.categories[0].category[x].label: '');
                                    countCat += 1;
                                } else {
                                    hc.xAxis.plotLines.push({
                                        color: obj.categories[0].category[x].color?convertColor(obj.categories[0].category[x].color): '#444444',
                                        width: obj.categories[0].category[x].thickness?obj.categories[0].category[x].thickness: 1,
                                        value: countCat-0.5
                                    });
                                }
                            }else if(typeof obj.categories[0].category[x] === 'string' && obj.chart.compactdatamode == '1'){
                                var dataseperator = obj.chart.dataseparator ? obj.chart.dataseparator : '|' ;
                                hc.xAxis.categories = hc.xAxis.categories.concat(obj.categories[0].category[x].split(dataseperator));
                            }
                        }
                    }


                    ////////data////////
                    if (obj.dataset) {
                        count_set = 0;
                        for (x in obj.dataset) {
                            z = {
                                FCtype: series,
                                type: obj.dataset[x].renderas ? FCFCC.combi[obj.dataset[x].renderas]: ((obj.dataset[x].parentyaxis == 'S' && (series == 5 || series == 5.5)) ? 'line': undefined),
                                name: obj.dataset[x].seriesname?obj.dataset[x].seriesname: ' ',
                                data: [],
                                color: convertColor(obj.dataset[x].color,obj.dataset[x].alpha,getScolor(count_set),100),
                                yAxis: obj.dataset[x].parentyaxis == 'S' ? 1 : undefined
                            };
                            count_set++;

                            for (y in obj.dataset[x].data) {
                                if(typeof obj.dataset[x].data[y] === 'object'){
                                    if (!obj.dataset[x].data[y].vline) {
                                        if (obj.dataset[x].data[y].link && z.cursor != 'pointer') {
                                            z.cursor = 'pointer';
                                        }
                                        z.data.push({
                                            y: obj.dataset[x].data[y].value?parseFloat(obj.dataset[x].data[y].value): '',
                                            link:  obj.dataset[x].data[y].link,
                                            id: id,
                                            color: obj.dataset[x].data[y].color? convertColor(obj.dataset[x].data[y].color,obj.dataset[x].data[y].alpha,getScolor(count_set),100) : undefined
                                        });
                                    }
                                }else if(typeof obj.dataset[x].data[y] === 'string' && obj.chart.compactdatamode == '1'){
                                    var dataseperator = obj.chart.dataseparator ? obj.chart.dataseparator : '|' ;
                                    var tempDataArr = obj.dataset[x].data[y].split(dataseperator);
                                    for(m in tempDataArr){
                                        z.data.push(parseFloat(tempDataArr[m]));
                                    }
                                }
                            }
                            a.push(z);
                        }
                        if (series == 3 || convertNames(chartName) == 'bar') {
                            a.reverse();
                        }
                    }
                    break;
                case 6:
                    break;
                case 7:
                case 7.5:
                    ////////special conf. for x-y plot charts
                    hc.plotOptions.series.dataLabels.enabled = obj.chart.showvalues == '1' ? true : false ;

                    ////////category////////

                    if (obj.categories) {
                        for (x in obj.categories[0].category) {
                            hc.xAxis.categories[obj.categories[0].category[x].x] = obj.categories[0].category[x].label?obj.categories[0].category[x].label: '';
                        }

                    }
                    ////////data////////

                    var bubbleRRatio = maxZVal(obj.dataset)/maxRedious(width, height);
                    if (obj.dataset) {
                        count_set = 0;
                        for (x in obj.dataset) {
                            z = {
                                FCtype: series,
                                type: obj.dataset[x].renderas ? FCFCC.combi[obj.dataset[x].renderas]: ((obj.dataset[x].parentyaxis == 'S' && (series == 5 || series == 5.5)) ? 'line': undefined),
                                name: obj.dataset[x].seriesname?obj.dataset[x].seriesname: ' ',
                                data: [],
                                color: convertColor(obj.dataset[x].color,obj.dataset[x].alpha,getScolor(count_set),100),
                                yAxis: obj.dataset[x].parentyaxis == 'S' ? 1 : undefined,
                                marker: {
                                    symbol: (series == 7.5)? 'circle' : convertAncorSide(obj.dataset[x].anchorsides),
                                    states: {
                                        hover: {
                                            enabled: false
                                        }
                                    }
                                }
                            };
                            count_set++;
                            for (y in obj.dataset[x].data) {
                                if (!obj.dataset[x].data[y].vline) {
                                    if (obj.dataset[x].data[y].link && z.cursor != 'pointer'){
                                        z.cursor = 'pointer';
                                    }
                                    z.data.push({
                                        x: parseFloat(obj.dataset[x].data[y].x),
                                        y: parseFloat(obj.dataset[x].data[y].y),
                                        link:  obj.dataset[x].data[y].link,
                                        id: id,
                                        color: obj.dataset[x].data[y].color? convertColor(obj.dataset[x].data[y].color,obj.dataset[x].data[y].alpha,getScolor(count_set),100) : undefined ,
                                        marker:{
                                            radius: obj.dataset[x].data[y].z? obj.dataset[x].data[y].z/bubbleRRatio: undefined
                                        }
                                    });
                                }
                            }
                            a.push(z);
                        }
                    }


                    hc.xAxis.max = obj.chart.xaxismaxvalue?parseInt(obj.chart.xaxismaxvalue):undefined;
                    hc.xAxis.min = obj.chart.xaxisminvalue?parseInt(obj.chart.xaxisminvalue):undefined;
                    hc.xAxis.showLastLabel  = true
                    break;
                default:
                    break;
            }

            hc.series = a;
        }


        /**
         * @var {RegExp} lengthPercentageRegExp determines whether a string has
         * trailing percentage character or not. Ignoring white-spaces.
         */
        var lengthPercentageRegExp = /\%\s*?$/ig;

        FCC.render = function (__container, callBack, loadEvent, stopAnimation) {
            var width = this.width, height = this.height, chart = convertSWFtoAlias(this.src), jsonObj, id = this.id,
            z, sender = this, container;
            if (FCC.isReady()) {//check whether FCC is ready
                ////
                ///delete the span created by FC.js
                __container.removeChild(document.getElementById(id));
                //create a div as per chart id
                // set the height and width and relative position for the back button
                //set the background white for transparency 0
                container = document.createElement('div');
                container.setAttribute('id', id);
                container.style.position = 'relative';
                __container.appendChild(container);
                container.style.width = width + (width.match(lengthPercentageRegExp) ? '' : 'px');
                container.style.height = height + (height.match(lengthPercentageRegExp) ? '' : 'px');
                jQuery('#'+this.id).css('background-color','#FFFFFF');


                //get the chart data
                jsonObj = this.getChartData('json');
                //convart it into FCC data
                z = covertToFCC(id, chart, jsonObj, id, container.offsetWidth, container.offsetHeight);

                if(typeof loadEvent == 'function'){
                    z.chart.events.load = loadEvent;
                }else{//this is the time chart rendering
                    //rais the loaded event
                    global.raiseEvent('loaded', {}, {}, sender);
                    z.chart.events.load = function () {
                        global.raiseEvent('rendered', {}, {}, sender);
                        global.raiseEvent('drawcomplete', {}, {}, sender);
                        try {// try old FC_Rendered function
                            FC_Rendered(sender.id);
                        }
                        catch (err) {
                        }
                    };
                }
                if(stopAnimation){
                    z.plotOptions.series.animation = false;
                }

                //check whether no data to display occure
                if (z.series.length == 0){
                    z = FCFCC.JSONconf.noData;
                    z.chart.renderTo = id;
                    global.raiseEvent('nodatatodisplay', {}, {}, sender);
                }
                var x = new Highcharts.Chart(z);
                //if it is a link chart then add the back button
                if(this.link && this.link.level > 0){
                    //createw a span for back button
                    //add the text
                    //set border color onclock function etc.
                    var back = document.createElement('span');
                    back.innerHTML = 'Back';
                    back.style.border = '1px solid #333333';
                    back.style.position = 'absolute';
                    back.style.top = '1px';
                    back.style.right = '1px';
                    back.style.cursor = 'pointer';
                    back.onclick = (function(sender){
                        return function(){
                            global.raiseEvent('OverlayButtonClick', {}, {}, sender);
                        }
                    })(this)
                    container.appendChild(back);
                }

                //arrange vlines & trendlines trendZones etc.
                var verticalPlotElements = jQuery('.highcharts-grid')[0];
                var horizontalPlotElements = jQuery('.highcharts-grid')[1];
                if(verticalPlotElements && horizontalPlotElements){
                    verticalPlotElements.parentNode.insertBefore(horizontalPlotElements, verticalPlotElements);
                }
                //save the chart's various objects in local store
                FCC.items[id] = {
                    'FCObj':jsonObj,
                    'baseObj': z,
                    'FCCObj': x,
                    'chartType': chart
                };

                //call the call back function
                if (typeof callBack === 'function') {
                    try {
                        callBack({
                            success: true,
                            ref: x,
                            id: id
                        });
                    }catch (err) {
                    }
                }
            } else {// if FCCReady return false then save the current render status in local obj which will be called after FCCReady automaticaly
                renderArray.push([this, __container, callBack]);
            }
        };

        //uodater function
        FCC.update = function (vars) {
            var id = this.id,
            loadEvent = function () {
                global.raiseEvent('drawcomplete', {}, {}, this);
            };


            // check whether chart already rendered and update the data
            if (typeof this.options.containerElementId !== 'undefined' && typeof FCC.items[id] !== 'undefined') {
                //destroy the old chart
                removeChart(id);
                //render the new chart
                FCC.render.call(this, this.options.containerElement, undefined,loadEvent);
            }
        };


        //variable to store various default values
        var FCFCC = {
            color: ["AFD8F8", "F6BD0F", "8BBA00", "FF8E46", "008E8E", "D64646", "8E468E", "588526", "B3AA00", "008ED6", "9D080D", "A186BE", "CC6600", "FDC689", "ABA000", "F26D7D", "FFF200", "0054A6", "F7941C", "CC3300", "006600", "663300", "6DCFF6"],
            seriesName : {
                'Column2D' : 1,
                'Column3D' : 1,
                'Line' : 1,
                'Area2D' : 1,
                'Bar2D' : 1,
                'Pie2D' : 1,
                'Pie3D' : 1,
                'Doughnut2D' : 1,
                'Doughnut3D' : 1,
                'Pareto2D' : 1.5,
                'Pareto3D' : 1.5,
                'MSColumn2D' : 2,
                'MSColumn3D' : 2,
                'MSLine' : 2,
                'ZoomLine': 2.5,
                'MSBar2D' : 2,
                'MSBar3D' : 2,
                'MSArea' : 2,
                'StackedColumn3D' : 3,
                'StackedColumn2D' : 3,
                'StackedBar2D' : 3,
                'stackColumn2DLine':3,
                'stackColumn3DLine':3,
                'StackedBar3D' : 3,
                'StackedArea2D' : 3,
                'MSCombi3D' : 4,
                'MSCombi2D' : 4,
                'MSCombiDY2D' : 5,
                'MSColumnLine3D' : 4,
                'MSColumn3DLineDY' : 5,
                'MSStackedColumn2D' : 6,
                'MSStackedColumn2DLineDY' : 6,
                'StackedColumn3DLineDY' : 5.5,
                'Scatter' : 7,
                'Bubble' : 7.5,
                'ScrollColumn2D' : 8,
                'ScrollLine2D' : 8,
                'ScrollArea2D' : 8,
                'ScrollStackedColumn2D' : 8,
                'ScrollCombi2D' : 8,
                'ScrollCombiDY2D' : 8,
                'SSGrid' : 9
            },
            highCharts : {
                'Column2D' : 'column',
                'Column3D' : 'column',
                'Line' : 'line',
                'Area2D' : 'area',
                'Bar2D' : 'bar',
                'Pie2D' : 'pie',
                'Pie3D' : 'pie',
                'Doughnut2D' : 'pie',
                'Doughnut3D' : 'pie',
                'Pareto2D' : 'column',
                'Pareto3D' : 'column',
                'MSColumn2D' : 'column',
                'MSColumn3D' : 'column',
                'MSLine' : 'line',
                'ZoomLine':'line',
                'MSBar2D' : 'bar',
                'MSBar3D' : 'bar',
                'MSArea' : 'area',
                'StackedColumn3D' : 'column',
                'StackedColumn2D' : 'column',
                'stackColumn2DLine':'column',
                'stackColumn3DLine':'column',
                'StackedBar2D' : 'bar',
                'StackedBar3D' : 'bar',
                'StackedArea2D' : 'area',
                'MSCombi3D' : 'column',
                'MSCombi2D' : 'column',
                'MSCombiDY2D' : 'column',
                'MSColumnLine3D' : 'column',
                'MSColumn3DLineDY' : 'column',
                'MSStackedColumn2D' : '',
                'MSStackedColumn2DLineDY' : '',
                'StackedColumn3DLineDY' : 'column',
                'Scatter' : 'scatter',
                'Bubble' : 'scatter',
                'ScrollColumn2D' : 'column',
                'ScrollLine2D' : 'line',
                'ScrollArea2D' : 'area',
                'ScrollStackedColumn2D' : '',
                'ScrollCombi2D' : '',
                'ScrollCombiDY2D' : '',
                'SSGrid' : ''
            },
            combi : {
                'Column2D' : 'column',
                'Column3D' : 'column',
                'Line' : 'line',
                'Area' : 'area'
            },
            JSONconf: {
                noData: {
                    chart: {

                    },
                    credits: {
                        enabled: false
                    },
                    legend: {
                        enabled: false
                    },
                    title: {
                        text: 'No data to display'
                    }
                }
            }
        };

    }();


    // Add method to make sure to delete all fusioncharts objects when
    // dispose method is invoked
    FusionCharts.addEventListener('BeforeDispose', function (e) {
        // Process these events only for objects that have javascript renderer!
        if (e.sender.options.renderer !== 'javascript') {
            return;
        }
        // Managed removal of chart using swfObject library
        removeChart(e.sender.id);
    });


    //function that will remove a chart
    function removeChart(id){
        //destroy the HC obj from HC methode
        if(FCC.items[id] && FCC.items[id].FCCObj){
            FCC.items[id].FCCObj.destroy();
        }
        //delete the HC obj from local store
        delete FCC.items[id];
    }

    ///add event listners/////
    FusionCharts.addEventListener('DataLoadError', function (event, args) {
        });

    // Add the renderer to FusionCharts core repository
    global.renderer.register('javascript', FCC);

    // Register the swf renderer in case we have iPad or iPhone.
    if (/\(iPhone;|\(iPod;|\(iPad;/i.test(navigator.userAgent)) {
        // Set default renderer
        global.renderer.setDefault('javascript');
    }

}());


/**
 * -----------------------------------------------------------------------------
 * XML Data Handler Stub Module
 * -----------------------------------------------------------------------------
 * This module contains the XML transcoder. This module adds the 'XML' data
 * handler.
 */
(function () {

    // Register the module with FusionCharts.
    var global = FusionCharts(['private', 'XMLDataHandler']);
    // Check whether the module has been already registered. If true, then
    // do not bother to re-register.
    if (global === undefined) {
        return;
    }

    // Add Abstract data handler as because when the primary data-type is XML,
    // it requires a transparent transcoder that has nothing to do.
    global.addDataHandler('XML', {
        encode: function (data) {
            // We do not need to normalize the data while encoding as because
            // the data is saved in JS scope and is now not sent via flashVars.
            return data;
        },
        decode: function (data) {
            return data;
        }
    });

}());



/**
 * -----------------------------------------------------------------------------
 * JSON Data-Handler Module
 * -----------------------------------------------------------------------------
 */

// Include JSON parser.
if(!this.JSON){
    this.JSON={}
}(function(){
    function f(n){
        return n<10?'0'+n:n
    }
    if(typeof Date.prototype.toJSON!=='function'){
        Date.prototype.toJSON=function(a){
            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(a){
            return this.valueOf()
        }
    }
    var e=/[\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={
        '\b':'\\b',
        '\t':'\\t',
        '\n':'\\n',
        '\f':'\\f',
        '\r':'\\r',
        '"':'\\"',
        '\\':'\\\\'
    },rep;
    function quote(b){
        escapable.lastIndex=0;
        return escapable.test(b)?'"'+b.replace(escapable,function(a){
            var c=meta[a];
            return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4)
        })+'"':'"'+b+'"'
    }
    function str(a,b){
        var i,k,v,length,mind=gap,partial,value=b[a];
        if(value&&typeof value==='object'&&typeof value.toJSON==='function'){
            value=value.toJSON(a)
        }
        if(typeof rep==='function'){
            value=rep.call(b,a,value)
        }
        switch(typeof value){
            case'string':
                return quote(value);
            case'number':
                return isFinite(value)?String(value):'null';
            case'boolean':case'null':
                return String(value);
            case'object':
                if(!value){
                    return'null'
                }
                gap+=indent;
                partial=[];
                if(Object.prototype.toString.apply(value)==='[object Array]'){
                    length=value.length;
                    for(i=0;i<length;i+=1){
                        partial[i]=str(i,value)||'null'
                    }
                    v=partial.length===0?'[]':gap?'[\n'+gap+partial.join(',\n'+gap)+'\n'+mind+']':'['+partial.join(',')+']';
                    gap=mind;
                    return v
                }
                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{
                    for(k in value){
                        if(Object.hasOwnProperty.call(value,k)){
                            v=str(k,value);
                            if(v){
                                partial.push(quote(k)+(gap?': ':':')+v)
                            }
                        }
                    }
                }
                v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+mind+'}':'{'+partial.join(',')+'}';
                gap=mind;
                return v
        }
    }
    if(typeof JSON.stringify!=='function'){
        JSON.stringify=function(a,b,c){
            var i;
            gap='';
            indent='';
            if(typeof c==='number'){
                for(i=0;i<c;i+=1){
                    indent+=' '
                }
            }else if(typeof c==='string'){
                indent=c
            }
            rep=b;
            if(b&&typeof b!=='function'&&(typeof b!=='object'||typeof b.length!=='number')){
                throw new Error('JSON.stringify');
            }
            return str('',{
                '':a
            })
        }
    }
    if(typeof JSON.parse!=='function'){
        JSON.parse=function(c,d){
            var j;
            function walk(a,b){
                var k,v,value=a[b];
                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 d.call(a,b,value)
            }
            c=String(c);
            e.lastIndex=0;
            if(e.test(c)){
                c=c.replace(e,function(a){
                    return'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4)
                })
            }
            if(/^[\],:{}\s]*$/.test(c.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){
                j=eval('('+c+')');
                return typeof d==='function'?walk({
                    '':j
                },''):j
            }
            throw new SyntaxError('JSON.parse');
        }
    }
}());

(function () {

    // Register the module with FusionCharts.
    var global = FusionCharts(['private', 'JSON_DataHandler']);
    // Check whether the module has been already registered. If true, then
    // do not bother to re-register.
    if (global === undefined) {
        return;
    }

    var xml2json = (function () {
        var listarr = { //list of tags that will be an array
            set: true,
            trendlines: true,
            line: true,
            data: true,
            dataset: true,
            categories: true,
            category: true,
            styles: true,
            definition: true,
            style: true,
            application: true,
            apply: true,
            linkeddata: true
        },spTag = {  //for all this will be same because it will represent the data link  ref. html5 link chart manager
            chart: 'linkedcharts',
            map: 'linkedcharts',
            graph: 'linkedcharts'
        },textNode = {
            dataset: 'data',
            categories: 'category'
        };

        var addChild = function (obj, childNode,pNodeName,baseObj) {//add the child nodes
            var i, nodeName, tempobj,dataseperator;
            for (i = 0;i < childNode.length; i++){
                nodeName = childNode[i].nodeName.toLowerCase();
                if (childNode[i].nodeType == 1){//node is a child node
                    if (typeof spTag[nodeName] !== 'string'){
                        tempobj = addAttr(childNode[i].attributes);
                    }else{
                        tempobj = {};
                        tempobj[nodeName] = addAttr(childNode[i].attributes);
                        nodeName = spTag[nodeName];
                    }
                    if (childNode[i].childNodes.length)
                        addChild(tempobj,childNode[i].childNodes, nodeName, baseObj);
                    if (listarr[nodeName]){
                        if (!obj[nodeName]){
                            obj[nodeName] = [];
                        }
                        obj[nodeName].push(tempobj);
                    }
                    else {
                        obj[nodeName] = tempobj;
                    }

                }else if(childNode[i].nodeType == 3 && baseObj.chart && parseInt(baseObj.chart.compactdatamode) &&  typeof textNode[pNodeName] === 'string'){///child node is a text node  [[[may me compect format]]]
                    nodeName = textNode[pNodeName];
                    tempobj = childNode[i].data;
                    if (listarr[nodeName]){
                        if (!obj[nodeName]){
                            obj[nodeName] = [];
                        }
                        obj[nodeName].push(tempobj);
                    }
                    else {
                        obj[nodeName] = tempobj;
                    }
                }
            }
        };




        var addAttr = function (attr){//add the attribute
            var i, obj = {};
            if(attr){
                for(i = 0; i < attr.length; i++){
                    obj[attr[i].nodeName.toLowerCase()] = attr[i].nodeValue;
                }
            }
            return obj;
        };

        return function (xml){
            var FCjson = {}, xmlDoc;
            //trim all starting  and endind space
            xml = xml.replace(/^\s*/g,'').replace(/\s*$/g,'');

            if(xml){//chaeck whether unwanted data like undefined, null blank string etc.
                //convert all Vline tag as category/data as per its position
                xml = xml.replace(/(<category [^\>]*\>[^<]*\<)vLine([^>]*\>)/ig,/$1category vline='true'$2/ig).replace(/(<category [^\>]*\>[^<]*\<)vLine([^>]*\>)/ig,/$1category vline='true'$2/ig).replace(/(<category [^\>]*\>[^<]*\<)vLine([^>]*\>)/ig,/$1category vline='true'$2/ig).replace(/\<set/ig,'<data').replace(/\<vLine/ig,"<data vline='true'").replace(/\<\![^\>]*\>/ig,'');
                ////geting error if \ before <  >
                if (window.DOMParser) {
                    var parser = new DOMParser();
                    xmlDoc = parser.parseFromString(xml,"text/xml");
                } else { // Internet Explorer
                    xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
                    xmlDoc.async = "false";
                    xmlDoc.loadXML(xml);
                }
                if(xmlDoc.childNodes.length === 1 && xmlDoc.childNodes[0].nodeName &&  (xmlDoc.childNodes[0].nodeName.toLowerCase() === 'chart' || xmlDoc.childNodes[0].nodeName.toLowerCase() === 'map' || xmlDoc.childNodes[0].nodeName.toLowerCase() === 'graph') ){
                    FCjson[xmlDoc.childNodes[0].nodeName.toLowerCase()] = addAttr(xmlDoc.childNodes[0].attributes);
                    if(xmlDoc.childNodes[0].childNodes){
                        addChild(FCjson, xmlDoc.childNodes[0].childNodes,'',FCjson);
                    }
                    return FCjson;
                }else{
                    return {
                        text:'Xml error'
                    };
                }


            }else{
                return {
                    text:'Xml error'
                };
            }
        };
    }());

    var json2xml = (function () {

        // Collection of conversion rules for array expansion
        var rules = {
            explode: {
                data: 'set'
            },
            attr: {
                chart: {
                    chart: 'chart'
                },
                graph: {
                    graph: 'graph'
                },
                map: {
                    map: 'map'
                },
                linkedcharts:{
                    chart: 'chart',
                    graph: 'graph',
                    map: 'map'
                }
            },
            group: {
                styles: {
                    definition: 'style',
                    application: 'apply'
                }
            }
        };

        var parse = function (obj, namespace) {

            var attrString = '', innerXML = '', nodeName = '', outerXML = '',
            item, lcaseItem, lcaseNS = namespace.toLowerCase();

            // In case the object is an array, apply explosion rule.
            if (obj instanceof Array){
                // Iterate through every item within the array and expand it.
                for (item in obj) {
                    if(typeof obj[item] !== 'string'){
                        outerXML += json2xml(obj[item], namespace);
                    }else{
                        outerXML += obj[item];
                    }
                }
            } else {
                for (item in obj) {
                    lcaseItem = item.toLowerCase();
                    // Parse "group" rule
                    if (obj[item] instanceof Array &&
                        (typeof rules.group[lcaseNS] === 'object' &&
                            typeof rules.group[lcaseNS][lcaseItem] === 'string') ) {
                        innerXML += '<' + item + '>' +
                        json2xml(obj[item], rules.group[lcaseNS][lcaseItem]) +
                        '</' + item + '>';
                    }

                    // Parse "attrgroup" rule
                    else if (typeof obj[item] === 'object') {
                        if (typeof rules.attr[lcaseNS] === 'object' &&
                            typeof rules.attr[lcaseNS][lcaseItem] === 'string') {
                            nodeName = json2xml(obj[item], rules.attr[lcaseNS][lcaseItem]).replace(/\/\>/ig, '');
                            namespace = item;
                        }
                        else {
                            innerXML += json2xml(obj[item], item);
                        }

                    }
                    // Parse "attr" rule
                    else {
                        if (lcaseItem === 'vline' && Boolean(obj[item])) {
                            namespace = 'vLine';
                            lcaseNS = namespace.toLowerCase();
                        }
                        else {
                            attrString += ' ' + item + '=\"' + obj[item]
                            .toString().replace(/\"/ig, '&quot;') + '\"';
                        }
                    }
                }

                // When parsing completes, we need to check whether we have any
                // namespace adjustments or not.
                // Explode rule.
                if (typeof rules.explode[lcaseNS] === 'string') {
                    namespace = rules.explode[lcaseNS];
                }

                outerXML = (nodeName !== '' ? nodeName : '<' + namespace) +
                attrString + (innerXML !== '' ? '>' + innerXML + '</' +
                    namespace + '>' : ' />');
            }
            return outerXML;
        }

        return parse;
    }());

    // Add the data-handler to FusionCharts collection of data-handlers
    global.addDataHandler('JSON', {
        encode: function (data) {
            if (typeof data === 'string') {
                data = JSON.parse(data);
            }
            return json2xml(data, 'chart');
        },

        decode: function (data) {
            return xml2json(data);
        }
    });

}());



/* -----------------------------------------------------------------------------
 * Link Manager Module
 * -----------------------------------------------------------------------------
 * This module allows for easy drill-down of charts by handling the link
 * attrribute of charts.
 */
(function () {

    // Register the module with FusionCharts.
    var global = FusionCharts(['private', 'LinkManager']);
    // Check whether the module has been already registered. If true, then
    // do not bother to re-register.
    if (global === undefined) {
        return;
    }

    // Add parameter policy to pass link information during construction of
    // new FusionCharts object.
    global.policies.link = ['link', undefined];

    // Create a collection to store configuration of every root link.
    var store = {};

    // Store root and parent reference of every element. This would allow us to
    // save the parent and root reference of the "link" object of every chart.
    var LinkInformation = function (root, parent) {
        this.items = {};
        this.root = root;
        this.parent = parent;

        // Do initialization work in case this is the root link. We verify root
        // link in case parent is undefined
        if (parent instanceof FusionCharts) {
            this.level = this.parent.link.level + 1;
        }
        // Parent is not an instance of FusionCharts, this implies this link is
        // a root link
        else {
            store[root.id] = [{}];
            this.level = 0;
        }
    };

    // This function would return the current configuration of the link that is
    // to be used for construction of a new chart.
    LinkInformation.prototype.configuration = function () {
        var param = store[this.root.id][this.level] ||
        (store[this.root.id][this.level] = {});
        // Check whether the above parameter provides a chart-id, if not then
        // generate one.
        if (typeof param.id === 'undefined') {
            param.id = store[this.root.id][this.level].id =
            global.uniqueId();
        }
        // Return the parameters
        return param;
    };

    // Add global link configuration API using which users will be able to set
    // parameters for every level of link.
    global.extend({
        configureLink: function (param, level) {
            // In case user provides an array of configuration, we assume that the
            // user wants to redefine the entire configuration train.
            if (param instanceof Array) {
                for (var i = 0; i < param.length; i++) {
                    // We initialize a blank configuration object for
                    // the link configuration train, in case it is not
                    // pre-defined.
                    if (typeof store[this.link.root.id][i] !== 'object') {
                        store[this.link.root.id][i] = {};
                    }
                    // The configuration is one-by-one copied two the store.
                    global.extend(store[this.link.root.id][i], param[i]);
                }
                // Delete any extra configuration.
                store[this.link.root.id].splice(param.length);
            }
            // If user has sent one object, we assume he wants to configure
            else if (typeof param === 'object') {
                // In case level is undefined, we need to assign the current
                // level of the object.
                if (typeof level !== 'number') {
                    level = this.link.level;
                }
                // Create a blank parameter object in store in case it is not
                // defined.
                if (store[this.link.root.id][level] === undefined){
                    store[this.link.root.id][level] = {};
                }
                // Copy all parameters passed on to the store.
                global.extend(store[this.link.root.id][level], param);
            }
            else {
                throw new TypeError("FusionCharts.configureLink() Invalid Parameters.");
            }
        }
    }, true);


    // Add construction routines to manage link parameters.
    FusionCharts.addEventListener('BeforeInitialize', function (event) {

        // If LinkInformation is not present in the object, we can assume
        // that this chart is a root chart and hence we need to create
        // link related information.
        if (!(event.sender.link instanceof LinkInformation)) {
            event.sender.link = new LinkInformation(event.sender);
        }
        // In case link is predefined, we need to add the new object to the
        // 'items' collection of parent of the new object.
        else {
            // In case of root link, parent is undefined, we do not need to
            // add any type of item configuration.
            if (event.sender.link.parent instanceof FusionCharts) {
                event.sender.link.parent.link.items[event.sender.id] =
                event.sender;
            }
        }
    });

    // Handle the linked-chart click event.
    FusionCharts.addEventListener('LinkedChartInvoked', function (event, args) {
        var obj = event.sender, param = obj.clone({
            dataSource: args.data,
            dataFormat: args.linkType === 'URL' ? 'xmlurl' : args.linkType,
            // Create a new link between the source chart and the to-be-created
            // new chart.
            link: new LinkInformation(obj.link.root, obj)
        }, true);


        // Delete certain default or post-render state related variables from
        // params.
        if (obj.arguments.animate != 0) {
            delete param.animate;
        }
        // Update parameters by overrides set by user
        global.extend(param, obj.link.configuration());

        // Create a new FusionCharts object with the construction parameters of
        // the above link configuration. Also directly render the chart.
        var childObj = new FusionCharts(param).render();

        global.raiseEvent('LinkedItemOpened', {
            level: obj.link.level,
            item: childObj
        }, {}, obj.link.root);
    });

    /**
     * This method handles the routines that are performed when a linked chart
     * is closed.
     */
    FusionCharts.addEventListener('OverlayButtonClick', function (event) {
        var chartObj = FusionCharts.items[event.sender.id],
        root = chartObj.link.root,
        level = chartObj.link.level - 2,
        parentObj = (level < 0) ? root :
        FusionCharts.items[store[root.id][level].id];

        // Dispose the item closed.
        chartObj.dispose();

        // Raise event that link has been closed for a root chart.
        global.raiseEvent('LinkedItemClosed', {
            level: level,
            item: chartObj
        }, {}, chartObj.link.root);

        if (!parentObj.isActive()){
            parentObj.render();
        }
    });

    FusionCharts.addEventListener('Loaded', function (event, args) {
        // Verify whether the loaded item is a root item or not. In case the
        // item is a root item, we do not need to process an overlay button.
        if (event.sender.link.root === event.sender) {
            return;
        }

        // Get configuration of overlay button
        var config = global.extend({
            show: true
        }, event.sender.link.parent.link.configuration().overlayButton || {});

        event.sender.ref.drawOverlayButton(config);

    });

    // Add method to make sure to delete all fusioncharts objects when
    // dispose method is invoked.
    FusionCharts.addEventListener('BeforeDispose', function (e) {
        // In case the object is not a root object, we would need to perform
        // additional cleanup.
        if (e.sender.link.parent instanceof FusionCharts) {
            // Cleanup the reference to this object to the 'items' collection
            // of its parent.
            delete e.sender.link.parent.link.items[e.sender.id];
        }
        // Remove any configuration set as root configuration
        delete store[e.sender.id];
    });

    FusionChartsEvents.LinkedItemOpened = 'linkeditemopened';
    FusionChartsEvents.LinkedItemClosed = 'linkeditemclosed';

}());



/* -----------------------------------------------------------------------------
 * Print Manager Module
 * -----------------------------------------------------------------------------
 */
(function () {

    // Register the module with FusionCharts.
    var global = FusionCharts(['private', 'PrintManager']);
    // Check whether the module has been already registered. If true, then
    // do not bother to re-register.
    if (global === undefined) {
        return;
    }

    // Default configuration of print manager. This can be overriden using
    // parameter of constructor.
    var config = {
        enabled: false,
        invokeCSS: true,
        processPollInterval: 2000,
        message: 'Chart is being prepared for print.',
        bypass: false
    };

    // Contains all independent library functions to be used by various sections
    // of this code.
    var lib = {

        getCanvasElementOf: function (obj, width, height) {
            // Proceed with creating canvas only if it is not already created.
            if (obj.__fusioncharts__canvascreated !== true) {
                // Create <canvas> DOM element.
                var canvas = document.createElement('canvas'),
                identifier = FusionCharts.items[obj.id].attributes['class'];

                // Set the class of the canvas to an identifyable value.
                canvas.setAttribute('class', identifier);

                // Insert the canvas immediately after the embed element.
                obj.parentNode.insertBefore(canvas, obj.nextSibling);
                // Mark that canvas has been created.
                obj.__fusioncharts__canvascreated = true;
            }

            // Set dimensions of canvas element
            obj.nextSibling.setAttribute('width', width || obj.offsetWidth || 2);
            obj.nextSibling.setAttribute('height', height || obj.offsetHeight || 2);

            // Return the canvas element for further manipulation.
            return obj.nextSibling;
        },

        removeCanvasElementOf: function (obj) {
            if (obj.__fusioncharts__canvascreated !== true ||
                obj.parentNode === null) {
                return;
            }
            obj.parentNode.removeChild(obj.nextSibling);
            obj.__fusioncharts__canvascreated = false;
        },

        rle2rgba: function (rle, rgba, base) {

            // Check if base colour has been provided. If not then set it to
            // white.
            if (typeof base !== 'string') {
                base = "FFFFFF";
            }

            // Tokenize the incoming RLE stream data.
            var raw = rle.split(/[;,_]/), run, i, r, g, b, x = 0;
            // Process every token.
            for (i = 0; i < raw.length; i += 2) {
                // Replace missing colour with base colour.
                if (raw[i] === '') {
                    raw[i] = base;
                }

                // Padding maximum left of the colour-data by 0. This allows
                // easy string manipulation from the right.
                raw[i] = ('000000' + raw[i]).substr(-6);

                // Separate the colour components and convert decimal to hex.
                r = parseInt('0x' + raw[i].substring(0, 2), 16);
                g = parseInt('0x' + raw[i].substring(2, 4), 16);
                b = parseInt('0x' + raw[i].substring(4, 6), 16);

                // Fill the run-length with the extracted rgba data.
                for (run = 0; run < raw[i + 1]; run += 1) {
                    rgba[x] = r;
                    rgba[x + 1] = g;
                    rgba[x + 2] = b;
                    rgba[x + 3] = 255;
                    x += 4;
                }
            }
            return rgba;
        },

        rle2array: function (rle, base) {
            // Check if base colour has been provided. If not then set it to
            // white.
            if (typeof base !== 'string') {
                base = "FFFFFF";
            }

            // Tokenize the RLE stream.
            var raw = rle.split(';'), run, i;
            for (run in raw) {
                // Tokenize every run within the stream.
                raw[run] = raw[run].split(/[_,]/);
                for (i = 0; i < raw[run].length; i += 2) {
                    // Restore RLE sub-compression losses.
                    // As per processed value, update it with base colour or
                    // Left-pad zero.
                    raw[run][i] = raw[run][i] === '' ?
                    base : ('000000' + raw[run][i]).substr(-6);
                }
            }
            return raw;
        },

        drawRLE: function (canvas, rle, width, height, baseColor) {

            // Failsafe height and width parameters
            width = width || 2;
            height = height || 2;

            // Adjust canvas dimension
            canvas.setAttribute('width', width);
            canvas.setAttribute('height', height);

            var context = canvas.getContext('2d'), imageData;

            // Prepare image data from rle sent from embed parameter.
            if (typeof context.putImageData === 'function' &&
                typeof context.createImageData === 'function') {
                imageData = context.createImageData(width, height)
                lib.rle2rgba(rle, imageData.data, baseColor);
                context.putImageData(imageData, 0, 0);
            }
            // Fall-back drawing method
            else {
                imageData = lib.rle2array(rle, baseColor);
                var x = 0, y = 0, z = 0;
                for (y in imageData) {
                    x = 0;
                    for (z = 0; z < imageData[y].length; z += 2) {
                        context.fillStyle = "#" + imageData[y][z];
                        context.fillRect(x, y, imageData[y][z + 1], 1);
                        x += parseInt(imageData[y][z+1]);
                    }

                }
            }
            return true;
        },

        drawText: function (canvas, text, width, height) {
            var context = canvas.getContext('2d'), w = width || 2,
            h = height || 2;
            context.clearRect(0, 0, w, h);
            context.textBaseline = 'middle';
            context.textAlign = 'center';
            context.font = '8pt verdana';
            context.fillStyle = '#776666';

            if (typeof context.fillText === 'function') {
                context.fillText(text, w / 2, h / 2);
            }
            else if (typeof context.mozDrawText === 'function') {
                context.translate( w / 2, h / 2);
                context.mozDrawText(text);
            }
            else {
            }
            return true;
        },

        // Appends a given CSS Text to the page <head> element.
        appendCSS: function (css) {
            // Create a DOM style element and set its required attributes.
            var el = document.createElement('style');
            el.setAttribute('type', 'text/css');

            // Add the CSS passed as argument to the newly created style element.
            // For IE, use the 'stylesheet.cssText' property and for rest, simply
            // add the CSS as text to the style element.
            if (typeof el.styleSheet === 'undefined') {
                el.appendChild(document.createTextNode(css));
            } else {
                el.styleSheet.cssText = css;
            }

            // Append the style element to DOM head and return the same.
            return document.getElementsByTagName('head')[0].appendChild(el);
        }
    };

    // Manages the dynamically generated CSS of the page
    var css = {
        // Available library styles.
        styles: {
            print: 'canvas.FusionCharts{display:none;}@media print{object.FusionCharts{display:none;}canvas.FusionCharts{display:block;}}',
            error: 'canvas.FusionCharts{display:none;}',
            normal: ''
        },

        // A common variable that stores a reference to the current stylesheet.
        cssNode: undefined,

        // Define function that allows switch between stylesheets.
        invoke: function (style) {
            // Check whether to use one of the available library styles.
            if (typeof this.styles[style] !== 'undefined') {
                style = this.styles[style];
            }
            // If style is not set as undefined, set the style.
            if (typeof style !== 'undefined') {
                if (this.cssNode !== undefined && this.cssNode.parentNode !== undefined) {
                    this.cssNode.parentNode.removeChild(this.cssNode);
                }
                css.cssNode = lib.appendCSS(style);
            }
        }
    }, activeItems = {}, queuedItems = {}, activeCount = 0;

    var queueTrigger  = function (obj) {
        // In case the first argument is not undefined, it implies that an item
        // is to be queued up
        if (obj instanceof FusionCharts) {
            queuedItems[obj.id] = obj;
            return;
        }

        // Proceed with processing the queue
        for(var item in queuedItems) {
            onDrawComplete({
                sender: queuedItems[item]
            }, {});
            delete queuedItems[item];
        }
    };

    var onDrawComplete = function (event, args) {

        // Get reference to the rendered object refetence
        var obj = event.sender.ref, w, h;

        // We just verify the external interface for safety sake. Though it is
        // very unlikely that this event will be fired with crippled EI.
        if (obj === undefined || typeof obj.prepareImageDataStream !== 'function'
            || obj.prepareImageDataStream() === false) {
            // Request obj to prepare image data stream or queue it up in case SWF
            // is busy.
            queueTrigger(event.sender);
            return;
        }
        // Add the object to te collection of active objects post successful
        // imagestream preparation call.
        if (!activeItems[event.sender.id]) {
            activeItems[event.sender.id] = obj;
            activeCount += 1;
            if (activeCount === 1) {
                global.raiseEvent('PrintReadyStateChange', {
                    ready: false,
                    bypass: config.bypass
                });
            }
        }
        // While image is being prepared, render the "waiting" message.
        try {
            w = obj.offsetWidth;
            h = obj.offsetHeight;
            lib.drawText(lib.getCanvasElementOf(obj, w, h), config.message, w, h);
        }
        // In case of error, remove the CSS so that the SWF is still
        // printable.
        catch (e) {
            css.invoke('error'); // invoke the css that hides canvas
        }
    };

    var onImageStreamReady = function (event, args) {
        try {
            if (lib.drawRLE(lib.getCanvasElementOf(event.sender.ref,
                args.width, args.height), args.stream, args.width, args.height,
            args.bgColor) === true) {
                // On successful canvas rendering, remove the item from active
                // item collection.
                if (activeItems[event.sender.id]) {
                    delete activeItems[event.sender.id];
                    activeCount -= 1;

                    if (activeCount === 0) {
                        global.raiseEvent('PrintReadyStateChange', {
                            ready: true,
                            bypass: config.bypass
                        });
                    }
                }
            }
        }
        // In case of error, remove the CSS so that the SWF is still
        // printable.
        catch (e) {
            css.invoke('error'); // invoke the css that hides canvas
        }
    };

    // Mehtod to remove canvas and other print manager stuffs when an object is
    // disposed.
    var onBeforeDispose = function (event) {
    // lib.removeCanvasElementOf(event.sender.ref);
    };

    var subscribeToEvents = function (state) {
        var eventAction = state ? 'addEventListener' :
        'removeEventListener';

        // Apply the event listener states to the eventHandlers.
        FusionCharts[eventAction]('ImageStreamReady', onImageStreamReady);
        FusionCharts[eventAction]('DrawComplete', onDrawComplete);
        FusionCharts[eventAction]('BeforeDispose', onBeforeDispose);
    };

    var initialize = function () {
        if (config.invokeCSS === true) {
            css.invoke('print');
        }
        // Iterate through all FusionCharts object reference and
        // do a fake call to onDrawComplete event
        for (var item in FusionCharts.items) {
            queueTrigger(FusionCharts.items[item]);
            queueTrigger();
        }

    };

    var destroy = function () {
        // Hide any of the canvas element in case user disables
        // print manager.
        css.invoke('error');
        // Iterate through all FusionCharts object reference and remove
        // their canvases if present.
        for (var item in FusionCharts.items) {
            if (FusionCharts.items[item].ref === undefined) {
                continue;
            }
            lib.removeCanvasElementOf(FusionCharts.items[item].ref);
        }
        // Finally remove all traces of CSS
        css.invoke('normal');
    };

    global.extend({
        printManager: {
            // This method allows users to confiure and reconfigure the
            // configuration of this script.
            configure: function (configuration) {
                global.extend(config, configuration || {});
            },

            isReady: function () {

                if (config.bypass) {
                    return true;
                }
                if (activeCount > 0 || !config.enabled) {
                    return false;
                }

                var item, ref;
                for (item in FusionCharts.items) {
                    if ((ref = FusionCharts.items[item].ref) === undefined) {
                        continue;
                    }
                    if (ref.hasRendered && ref.hasRendered() === false) {
                        return false;
                    }
                }
                return true;
            },

            // Enable or disable canvas print manager. In case browser is not
            // supported, do not allow to enable
            enabled: function (state) {
                // If no parameter is passed, it is assumed that user simply
                // needs the current status. So we return the current status.
                if (state === undefined) {
                    return config.enabled;
                }

                // Check browser capability to fulfill minimum requirements for
                // this script. Do not proceed if browser is IE
                if ('\v1' === 'v' || global.renderer.currentRendererName() !== 'flash' ||
                    typeof document.createElement('canvas').getContext !== 'function') {
                    config.bypass = true;
                    global.raiseEvent('PrintReadyStateChange', {
                        ready: true,
                        bypass: config.bypass
                    });
                    return config.enabled;
                }
                config.bypass = false;

                // Apply the event listener states to the eventHandlers.
                subscribeToEvents(state);

                // Perform initialization or cleanup depending upon the state.
                if (state === true) {
                    initialize();
                }
                else {
                    destroy();
                }
                // Return the updated state value.
                return config.enabled = state;
            },

            managedPrint: function () {

                if (config.bypass) {
                    window.print();
                    return;
                }

                if (!FusionCharts.printManager.isReady()) {
                    // Enable Print Manager
                    if (FusionCharts.printManager.enabled(true) !== true) {
                        // If enabling fails, then just invoke a print.
                        window.print();
                        return;
                    }
                    // Subscribe to the print ready state change event
                    FusionCharts.addEventListener('PrintReadyStateChange',
                        FusionCharts.printManager.managedPrint);

                    return;
                }

                // In case this function is invoked by event-handler, I check
                // when active is marked as true.
                if (typeof arguments[1] === 'object' && arguments[1].ready !== true) {
                    return;
                }

                // Remove the event that watches completion of canvas image creation
                FusionCharts.removeEventListener('PrintReadyStateChange',
                    FusionCharts.printManager.managedPrint);

                // Execute Printing.
                window.print();
            }
        }
    }, false);

    FusionChartsEvents.PrintReadyStateChange = 'printreadystatechange';

}());





/**
 * -----------------------------------------------------------------------------
 * Export Component Module
 * -----------------------------------------------------------------------------
 */
(function () {

    // Register the module with FusionCharts.
    var global = FusionCharts(['private', 'ExportComponent']);
    // Check whether the module has been already registered. If true, then
    // do not bother to re-register.
    if (global === undefined) {
        return;
    }

    window.FC_ExportDataReady = function (args) {
        global.raiseEvent('ExportDataReady', args, {},
            FusionCharts.items[args.meta.DOMId]);
    };

    window.FC_ExportComponentReady = function (args) {
        global.raiseEvent('ExportComponentReady', {}, {},
            document.getElementById('chartobject-1-exporter'));
    };

    var store = {};

    FusionCharts.addEventListener('BeforeInitialize', function (event) {
        delete store[event.sender.id + '-exporter'];
    });

    FusionCharts.addEventListener('Disposed', function(event) {
        delete store [event.sender.id + '-exporter'];
    });

    FusionCharts.addEventListener('ExportDataReady', function(event, args) {

        var obj = event.sender, params = args.parameters;
        if (!(params.exportAtClient == 1 &&
            document.getElementById(params.exportHandler) === null)) {
            return;
        }

        var ecId = obj.id + '-exporter';

        store[ecId] = args;

        var alt = document.createElement('span');
        alt.setAttribute('id', ecId);
        obj.options.containerElement.appendChild(alt);

        global.swfobject.embedSWF(FusionCharts.options.scriptBaseUri + 'FCExporter.swf', alt.id, obj.width,
            obj.height, '10.0.0', undefined, {
                registerWithJS: '1'
            },

            {
                wMode: 'transparent'
            }, {
                'class': 'FusionChartsExportComponent',
                style: 'margin-left: -' + obj.ref.offsetWidth + 'px'
            });

    });

    FusionCharts.addEventListener('ExportComponentReady', function(event, args) {
        var obj = event.sender;
        if (store[obj.id] === undefined) {
            return;
        }
        obj.pushData([store[obj.id]]);
    });


}());

