var ksensejs = {
    initialize : function() {
        // Create a plugin object and append to the <body> element
        var plugin_object = document.createElement('object');
        plugin_object.setAttribute('id', 'plugin0');
        plugin_object.setAttribute('type', 'application/x-ksensejs');
        document.body.appendChild(plugin_object);

        document.getElementById('plugin0').addEventListener("newskeletondata", ksensejs.handle_new_data, false);
    },

    skeleton_data : null,
    velocity_data : null,
    callback : null,

    plugin : function() {
        return document.getElementById('plugin0');
    },

    handle_new_data : function() {
        ksensejs.skeleton_data = ksensejs.plugin().getSkeletonData();
        ksensejs.velocity_data = ksensejs.plugin().getVelocityData();

        if( !(ksensejs.callback === null) ) {
            ksensejs.callback();
        }
    },

    is_tracking : function() {
        if( Object.keys(ksensejs.skeleton_data).length > 0 ) {
            return true;
        }
        return false;
    },

    get_tracking_ids : function() {
        if( ksensejs.skeleton_data === null ) {
            return [];
        } else {
            return Object.keys(ksensejs.skeleton_data);
        }
    },

    get_skeleton_data : function(id) {
        if( typeof ksensejs.skeleton_data[id] === "undefined" ) {
            throw "Invalid tracking ID.";
        } else {
            return ksensejs.skeleton_data[id];
        }
    },

    get_velocity_data : function(id) {
        if( typeof ksensejs.velocity_data[id] === "undefined" ) {
            throw "Invalid tracking ID.";
        } else {
            return ksensejs.velocity_data[id];
        }
    },

    get_joint_location : function(id, name) {
        if( typeof ksensejs.skeleton_data[id] === "undefined" ) {
            throw "Invalid tracking ID.";
        } else {
            return ksensejs.skeleton_data[id][name];
        }
    },

    get_joint_velocity : function(id, name) {
        if( typeof ksensejs.velocity_data[id] === "undefined" ) {
            throw "Invalid tracking ID.";
        } else {
            return ksensejs.velocity_data[id][name][0];
        }
    },

    get_joint_velocity_vector : function(id, name) {
        if( typeof ksensejs.velocity_data[id] === "undefined" ) {
            throw "Invalid tracking ID.";
        } else {
            return ksensejs.velocity_data[id][name].slice(1,4);
        }
    },

    set_new_data_callback : function(callback) {
        if( typeof callback === "function" ) {
            ksensejs.callback = callback;
        }
    }
};

@@ -2602,21 +2602,593 @@
 ;%0A        %7D%0A
+    %7D,%0A%0A    unset_new_data_callback : function() %7B%0A        ksensejs.callback = null;%0A    %7D,%0A%0A    scale_data : function(init_coord, scale_coord) %7B%0A        var x = init_coord%5B0%5D;%0A        var y = init_coord%5B1%5D;%0A        var z = init_coord%5B2%5D;%0A%0A        x += 2.2;%0A        if ( x %3C 0 ) %7B%0A            x = 0;%0A        %7D%0A        x = (x/4.4) * scale_coord%5B0%5D;%0A%0A        y += 1.6;%0A        if ( y %3C 0 ) %7B%0A            y = 0;%0A        %7D%0A        y = (y/3.2) * scale_coord%5B1%5D;%0A%0A        if ( z %3C 0 ) %7B%0A            z = 0;%0A        %7D%0A        z = (z/4.0) * scale_coord%5B2%5D;%0A        return %5Bx,y,z%5D;%0A
     %7D%0A%7D;%0A

Add new helper functions