<commit_before>/**
 * Parses text to return to the log items
 * Created by cos-caner on 12/4/15.
 * Remember to embed nodes, user, linked_node and template_node in api call i.e. var url = $osf.apiV2Url('nodes/' + nodeId + '/logs/', { query : { 'embed' : ['nodes', 'user']}});
 */
var m = require('mithril'); // exposes mithril methods, useful for redraw etc.
var logActions = require('json!js/_allLogTexts.json');
var $ = require('jquery');  // jQuery
var $osf = require('js/osfHelpers');

var ravenMessagesCache = []; // Cache messages to avoid sending multiple times in one page view
/**
 * Utility function to not repeat logging errors to Sentry
 * @param message {String} Custom message for error
 * @param logObject {Object} the entire log object returned from the api
 */
function ravenMessage (message, logObject) {
    if(ravenMessagesCache.indexOf(message) === -1){
        Raven.captureMessage(message, {logObject: logObject});
        ravenMessagesCache.push(message);
    }
}

/**
 * Checks if the required parameter to complete the log is returned
 * This may intentionally not be returned to make log anonymous
 * @param param {string|number} The parameter to be used
 * @param logObject {Object} the entire log object returned from the api
 * @returns {boolean}
 */
var paramIsReturned = function _paramIsReturned (param, logObject){
    if(!param){
        var message = 'Expected parameter for Log action ' + logObject.attributes.action + ' was not returned from log api.';
        ravenMessage(message, logObject);
        return false;
    }
    if (param.errors){
        return false;
    }
    return true;
};

/**
 * Returns the text parameters since their formatting is mainly the same
 * @param param {string} The parameter to be used, has to be available under logObject.attributes.param
 * @param text {string} The text to be used if param is not available
 * @param logObject {Object} the entire log object returned from the api
 * @returns {*}
 */
var returnTextParams = function (param, text, logObject) {
    var source = logObject.attributes.params[param];
    var view_url = logObject.attributes.params.view_url;

    if(paramIsReturned(source, logObject)){
        if($.isArray(source)){
            return m('span', [
                source.map(function(item, index, arr){
                    if(arr.length === 1 && index === 0){
                        return m('span', item);
                    }
                    if(index === arr.length-1) {
                        return m('span', ', and ' + item);
                    }
                    return m('span', item + ', ');
                })
            ]);
        }
        return view_url ? m('a', {href: view_url},'"' + source + '"') : m('span', '"' + source + '"');
    }
    return m('span', text);
};

var LogText = {
    controller: function(logObject){
        var self = this;

        self.userInfoReturned = function(userObject){
            if (userObject){
                if (userObject.data){
                    return true;
                }
                else if (userObject.errors[0].meta){
                    return true;
                }
            }
            return false;
        };

        self.logText = function() {
            var text = logActions[logObject.attributes.action];
            if (text) {
                if (text.indexOf('${user}') !== -1) {
                    var userObject = logObject.embeds.user;
                    if (self.userInfoReturned(userObject)) {
                        return text;
                    }
                    else {
                        var newAction = logObject.attributes.action + '_no_user';
                        return logActions[newAction] ? logActions[newAction]: text;
                    }
                }
                return text;
            }
        return null;
        };
    },
    view : function(ctrl, logObject) {
        var message = '';
        var text = ctrl.logText();
        if(text){
            var list = text.split(/(\${.*?})/);
            return m('span.osf-log-item',[
                list.map(function(piece){
                    if (piece === '') {
                        return m('span');
                    }
                    var startsWith = piece.substring(0,2);
                    if(startsWith === '${'){
                        var last = piece.length-1;
                        var logComponentName = piece.substring(2,last);
                        if(LogPieces[logComponentName]){
                            return m.component(LogPieces[logComponentName], logObject);
                        } else {
                            message = 'There is no template in logTextParser.js for  ' + logComponentName + '.';
                            ravenMessage(message, logObject);
                            return m('');
                        }
                    }
                    return piece;
                })
            ]);
        } else {
            message = 'There is no text entry in dictionary for the action :' + logObject.attributes.action;
            ravenMessage(message, logObject);
            return m('');
        }
    }
};

var LogPieces = {
    // User that took the action
    user: {
        view: function (ctrl, logObject) {
            var userObject = logObject.embeds.user;
            if(paramIsReturned(userObject, logObject) && userObject.data) {
                return m('a', {href: userObject.data.links.html, onclick: function() {
                    $osf.trackClick(logObject.trackingCategory, logObject.trackingAction, 'navigate-to-user-from-logs');
                }}, userObject.data.attributes.full_name);
            }
            else if (userObject && userObject.errors[0].meta) {
                return m('span', userObject.errors[0].meta.full_name);
            }
            else {
                return m('span', 'A user');
            }
        }
    },
    // Node involved
    node: {
        view: function (ctrl, logObject) {
            var nodeObject = logObject.embeds.nodes;

            if (logObject.attributes.action === 'node_removed') {
                if (logObject.attributes.params.params_node) {
                return m('span', logObject.attributes.params.params_node.title);
            }}
            else if(paramIsReturned(nodeObject, logObject) && nodeObject.data[0]){
                if (nodeObject.data[0].links && nodeObject.data[0].attributes) {
                    return m('a', {href: nodeObject.data[0].links.html, onclick: function() {
                        $osf.trackClick(logObject.trackingCategory, logObject.trackingAction, 'navigate-to-project-from-logs');
                    }}, nodeObject.data[0].attributes.title);
                }
                else if (nodeObject.data[0].attributes) {
                    return m('span', nodeObject.data[0].attributes.title);
                }
            } else {
                return m('span', 'a project');
            }
        }
    },
    // Contrubutor list of added, updated etc.
    contributors: {
        view: function (ctrl, logObject) {
            var contributors = logObject.embeds.contributors;
            if(paramIsReturned(contributors, logObject)) {
                return m('span', contributors.data.map(function(item, index, arr){
                    var comma = ' ';
                    if(index !== arr.length - 1){
                        comma = ', ';
                    }
                    if(index === arr.length-2){
                        comma = ' and ';
                    }
                    if (item.attributes.active) {
                        return [ m('a', {href: item.links.html}, item.attributes.full_name), comma];
                    }
                    else {
                        return [item.attributes.full_name, comma];

                    }
                }));
            }
            return m('span', 'some users');
        }
    },
    // The tag added to item involved
    tag: {
        view: function (ctrl, logObject) {
            var tag = logObject.attributes.params.tag;
            if(paramIsReturned(tag, logObject)) {
               return m('a', {href: '/search/?q=%22' + tag + '%22'}, tag);
            }
            return m('span', 'a tag');
       }
    },
    // Node that is linked to the node involved
    pointer: {
        view: function (ctrl, logObject) {
            var linked_node = logObject.embeds.linked_node;
            if(paramIsReturned(linked_node, logObject)){
                return m('a', {href: linked_node.data.links.html}, linked_node.data.attributes.title);
            }
            return m('span','a project' );
        }
    },
    // Node that acted as template to create a new node involved
    template: {
        view: function (ctrl, logObject) {
            var template_node = logObject.embeds.template_node;
            if(paramIsReturned(template_node, logObject)){
                return m('a', {href: template_node.data.links.html}, template_node.data.attributes.title);
            }
            return m('span','a project' );
        }
    },
    // The original title of node involved
    title_original: {
        view: function (ctrl, logObject) {
            return returnTextParams('title_original', 'a title', logObject);
        }
    },
    // The new title of node involved
    title_new: {
        view: function (ctrl, logObject) {
            return returnTextParams('title_new', 'a title', logObject);
        }
    },
    // Update fields for the node
    updated_fields: {
        view: function (ctrl, logObject) {
            return returnTextParams('updated_fields', 'field(s)', logObject);
        }
    },
    // external identifiers on node
    identifiers: {
        view: function (ctrl, logObject) {
            return returnTextParams('identifiers', 'identifier(s)', logObject);
        }
    },
    // Wiki page name
    page: {
        view: function (ctrl, logObject) {
            return returnTextParams('page', 'a title', logObject);
        }
    },
    // Old wiki title that's renamed
    old_page: {
        view: function (ctrl, logObject) {
            return returnTextParams('old_page', 'a title', logObject);
        }
    },
    // Wiki page version
    version: {
        view: function (ctrl, logObject) {
            var version = logObject.attributes.params.version;
            if(paramIsReturned(version, logObject)){
                return m('span', version);
            }
            return m('span', '#');
        }
    },
    //
    source: {
        view: function (ctrl, logObject) {
            var source = logObject.attributes.params.source;
            if(paramIsReturned(source, logObject)){
                return m('span', [source.materialized, ' in ', source.addon]);
            }
            return m('span','a name/location' );
        }
    },
    //
    destination: {
        view: function (ctrl, logObject) {
            var destination = logObject.attributes.params.destination;
            if(paramIsReturned(destination, logObject)){
                if (destination.materialized.endsWith('/')){
                    return m('span', [destination.materialized, ' in ', destination.addon]);
                }
                return m('span', [m('a', {href: destination.url}, destination.materialized), ' in ', destination.addon]);
            }
            return m('span','a new name/location' );
        }
    },
        //
    path: {
        view: function (ctrl, logObject) {
            return returnTextParams('path', 'a file', logObject);
        }
    },
        //
    filename: {
        view: function (ctrl, logObject) {
            return returnTextParams('filename', 'a title', logObject);
        }
    },

    folder: {
        view: function(ctrl, logObject) {
            return returnTextParams('folder', 'a folder', logObject);
        }
    },

    repo: {
        view: function(ctrl, logObject) {
            var github_user = logObject.attributes.params.github_user;
            var github_repo = logObject.attributes.params.github_repo;
            if (paramIsReturned(github_repo, logObject) && paramIsReturned(github_user, logObject)){
                return m('span', github_user + '/' + github_repo);
            }
            return m('span', '');
        }
    },

    folder_name: {
        view: function(ctrl, logObject) {
            return returnTextParams('folder_name', 'a folder', logObject);
        }
    },

    bucket: {
        view: function(ctrl, logObject) {
            return returnTextParams('bucket', 'a bucket', logObject);
        }
    },

    forward_url: {
        view: function(ctrl, logObject) {
            return returnTextParams('forward_url', 'a new URL', logObject);
        }
    },

    box_folder: {
        view: function(ctrl, logObject) {
            var folder = logObject.attributes.params.folder;
            if(paramIsReturned(folder, logObject)){
                return m('span', folder === 'All Files' ? '/ (Full Box)' : (folder || '').replace('All Files',''));
            }
            return m('span', '');
        }
    },

    citation: {
        view: function(ctrl, logObject) {
            return returnTextParams('citation_name', '', logObject);
        }
    },

    dataset: {
        view: function(ctrl, logObject){
            return returnTextParams('data_set', '', logObject);
        }
    },

    study: {
        view: function(ctrl, logObject){
            return returnTextParams('study', '', logObject);
        }
    },

    googledrive_path: {
        view: function(ctrl, logObject){
            var path = logObject.attributes.params.path;
            if(paramIsReturned(path, logObject)){
                return m('span', decodeURIComponent(path));
            }
            return m('span', '');
        }
    },

    googledrive_folder: {
        view: function(ctrl, logObject){
            var folder = logObject.attributes.params.folder;
            if(paramIsReturned(folder, logObject)){
                return m('span', folder === '/' ? '(Full Google Drive)' : decodeURIComponent(folder));
            }
            return m('span', '');
        }
    },

    addon: {
        view: function(ctrl, logObject){
            return returnTextParams('addon', '', logObject);
        }
    },

    previous_institution: {
        view: function(ctrl, logObject){
            var previous_institution = logObject.attributes.params.previous_institution;
            if (paramIsReturned(previous_institution, logObject)){
                return m('span', previous_institution.name);
            }
            return m('span', 'an institution');
        }
    },

    institution: {
        view: function(ctrl, logObject){
            var institution = logObject.attributes.params.institution;
            if (paramIsReturned(institution, logObject)){
                return m('span', institution.name);
            }
            return m('span', 'an institution');
        }
    },

    comment_file: {
        view: function(ctrl,logObject){
            var file = logObject.attributes.params.file;
            if (file){  // skipe paramIsReturned, as not having a file is expected at times
                return m('span', ['in ', m('a', {href: file.url}, file.name)]);
            }
            return m('span', '');
        }
    }
};

module.exports = LogText;
<commit_msg>Add url as parameter to returnTextParams.<commit_after>/**
 * Parses text to return to the log items
 * Created by cos-caner on 12/4/15.
 * Remember to embed nodes, user, linked_node and template_node in api call i.e. var url = $osf.apiV2Url('nodes/' + nodeId + '/logs/', { query : { 'embed' : ['nodes', 'user']}});
 */
var m = require('mithril'); // exposes mithril methods, useful for redraw etc.
var logActions = require('json!js/_allLogTexts.json');
var $ = require('jquery');  // jQuery
var $osf = require('js/osfHelpers');

var ravenMessagesCache = []; // Cache messages to avoid sending multiple times in one page view
/**
 * Utility function to not repeat logging errors to Sentry
 * @param message {String} Custom message for error
 * @param logObject {Object} the entire log object returned from the api
 */
function ravenMessage (message, logObject) {
    if(ravenMessagesCache.indexOf(message) === -1){
        Raven.captureMessage(message, {logObject: logObject});
        ravenMessagesCache.push(message);
    }
}

/**
 * Checks if the required parameter to complete the log is returned
 * This may intentionally not be returned to make log anonymous
 * @param param {string|number} The parameter to be used
 * @param logObject {Object} the entire log object returned from the api
 * @returns {boolean}
 */
var paramIsReturned = function _paramIsReturned (param, logObject){
    if(!param){
        var message = 'Expected parameter for Log action ' + logObject.attributes.action + ' was not returned from log api.';
        ravenMessage(message, logObject);
        return false;
    }
    if (param.errors){
        return false;
    }
    return true;
};

/**
 * Returns the text parameters since their formatting is mainly the same
 * @param param {string} The parameter to be used, has to be available under logObject.attributes.param
 * @param text {string} The text to be used if param is not available
 * @param logObject {Object} the entire log object returned from the api
 * @returns {*}
 */
var returnTextParams = function (param, text, logObject, view_url) {
    var source = logObject.attributes.params[param];

    if(paramIsReturned(source, logObject)){
        if($.isArray(source)){
            return m('span', [
                source.map(function(item, index, arr){
                    if(arr.length === 1 && index === 0){
                        return m('span', item);
                    }
                    if(index === arr.length-1) {
                        return m('span', ', and ' + item);
                    }
                    return m('span', item + ', ');
                })
            ]);
        }
        return view_url ? m('a', {href: view_url},'"' + source + '"') : m('span', '"' + source + '"');
    }
    return m('span', text);
};

var LogText = {
    controller: function(logObject){
        var self = this;

        self.userInfoReturned = function(userObject){
            if (userObject){
                if (userObject.data){
                    return true;
                }
                else if (userObject.errors[0].meta){
                    return true;
                }
            }
            return false;
        };

        self.logText = function() {
            var text = logActions[logObject.attributes.action];
            if (text) {
                if (text.indexOf('${user}') !== -1) {
                    var userObject = logObject.embeds.user;
                    if (self.userInfoReturned(userObject)) {
                        return text;
                    }
                    else {
                        var newAction = logObject.attributes.action + '_no_user';
                        return logActions[newAction] ? logActions[newAction]: text;
                    }
                }
                return text;
            }
        return null;
        };
    },
    view : function(ctrl, logObject) {
        var message = '';
        var text = ctrl.logText();
        if(text){
            var list = text.split(/(\${.*?})/);
            return m('span.osf-log-item',[
                list.map(function(piece){
                    if (piece === '') {
                        return m('span');
                    }
                    var startsWith = piece.substring(0,2);
                    if(startsWith === '${'){
                        var last = piece.length-1;
                        var logComponentName = piece.substring(2,last);
                        if(LogPieces[logComponentName]){
                            return m.component(LogPieces[logComponentName], logObject);
                        } else {
                            message = 'There is no template in logTextParser.js for  ' + logComponentName + '.';
                            ravenMessage(message, logObject);
                            return m('');
                        }
                    }
                    return piece;
                })
            ]);
        } else {
            message = 'There is no text entry in dictionary for the action :' + logObject.attributes.action;
            ravenMessage(message, logObject);
            return m('');
        }
    }
};

var LogPieces = {
    // User that took the action
    user: {
        view: function (ctrl, logObject) {
            var userObject = logObject.embeds.user;
            if(paramIsReturned(userObject, logObject) && userObject.data) {
                return m('a', {href: userObject.data.links.html, onclick: function() {
                    $osf.trackClick(logObject.trackingCategory, logObject.trackingAction, 'navigate-to-user-from-logs');
                }}, userObject.data.attributes.full_name);
            }
            else if (userObject && userObject.errors[0].meta) {
                return m('span', userObject.errors[0].meta.full_name);
            }
            else {
                return m('span', 'A user');
            }
        }
    },
    // Node involved
    node: {
        view: function (ctrl, logObject) {
            var nodeObject = logObject.embeds.nodes;

            if (logObject.attributes.action === 'node_removed') {
                if (logObject.attributes.params.params_node) {
                return m('span', logObject.attributes.params.params_node.title);
            }}
            else if(paramIsReturned(nodeObject, logObject) && nodeObject.data[0]){
                if (nodeObject.data[0].links && nodeObject.data[0].attributes) {
                    return m('a', {href: nodeObject.data[0].links.html, onclick: function() {
                        $osf.trackClick(logObject.trackingCategory, logObject.trackingAction, 'navigate-to-project-from-logs');
                    }}, nodeObject.data[0].attributes.title);
                }
                else if (nodeObject.data[0].attributes) {
                    return m('span', nodeObject.data[0].attributes.title);
                }
            } else {
                return m('span', 'a project');
            }
        }
    },
    // Contrubutor list of added, updated etc.
    contributors: {
        view: function (ctrl, logObject) {
            var contributors = logObject.embeds.contributors;
            if(paramIsReturned(contributors, logObject)) {
                return m('span', contributors.data.map(function(item, index, arr){
                    var comma = ' ';
                    if(index !== arr.length - 1){
                        comma = ', ';
                    }
                    if(index === arr.length-2){
                        comma = ' and ';
                    }
                    if (item.attributes.active) {
                        return [ m('a', {href: item.links.html}, item.attributes.full_name), comma];
                    }
                    else {
                        return [item.attributes.full_name, comma];

                    }
                }));
            }
            return m('span', 'some users');
        }
    },
    // The tag added to item involved
    tag: {
        view: function (ctrl, logObject) {
            var tag = logObject.attributes.params.tag;
            if(paramIsReturned(tag, logObject)) {
               return m('a', {href: '/search/?q=%22' + tag + '%22'}, tag);
            }
            return m('span', 'a tag');
       }
    },
    // Node that is linked to the node involved
    pointer: {
        view: function (ctrl, logObject) {
            var linked_node = logObject.embeds.linked_node;
            if(paramIsReturned(linked_node, logObject)){
                return m('a', {href: linked_node.data.links.html}, linked_node.data.attributes.title);
            }
            return m('span','a project' );
        }
    },
    // Node that acted as template to create a new node involved
    template: {
        view: function (ctrl, logObject) {
            var template_node = logObject.embeds.template_node;
            if(paramIsReturned(template_node, logObject)){
                return m('a', {href: template_node.data.links.html}, template_node.data.attributes.title);
            }
            return m('span','a project' );
        }
    },
    // The original title of node involved
    title_original: {
        view: function (ctrl, logObject) {
            return returnTextParams('title_original', 'a title', logObject);
        }
    },
    // The new title of node involved
    title_new: {
        view: function (ctrl, logObject) {
            return returnTextParams('title_new', 'a title', logObject);
        }
    },
    // Update fields for the node
    updated_fields: {
        view: function (ctrl, logObject) {
            return returnTextParams('updated_fields', 'field(s)', logObject);
        }
    },
    // external identifiers on node
    identifiers: {
        view: function (ctrl, logObject) {
            return returnTextParams('identifiers', 'identifier(s)', logObject);
        }
    },
    // Wiki page name
    page: {
        view: function (ctrl, logObject) {
            return returnTextParams('page', 'a title', logObject);
        }
    },
    // Old wiki title that's renamed
    old_page: {
        view: function (ctrl, logObject) {
            return returnTextParams('old_page', 'a title', logObject);
        }
    },
    // Wiki page version
    version: {
        view: function (ctrl, logObject) {
            var version = logObject.attributes.params.version;
            if(paramIsReturned(version, logObject)){
                return m('span', version);
            }
            return m('span', '#');
        }
    },
    //
    source: {
        view: function (ctrl, logObject) {
            var source = logObject.attributes.params.source;
            if(paramIsReturned(source, logObject)){
                return m('span', [source.materialized, ' in ', source.addon]);
            }
            return m('span','a name/location' );
        }
    },
    //
    destination: {
        view: function (ctrl, logObject) {
            var destination = logObject.attributes.params.destination;
            if(paramIsReturned(destination, logObject)){
                if (destination.materialized.endsWith('/')){
                    return m('span', [destination.materialized, ' in ', destination.addon]);
                }
                return m('span', [m('a', {href: destination.url}, destination.materialized), ' in ', destination.addon]);
            }
            return m('span','a new name/location' );
        }
    },
        //
    path: {
        view: function (ctrl, logObject) {
            return returnTextParams('path', 'a file', logObject);
        }
    },
        //
    filename: {
        view: function (ctrl, logObject) {
            return returnTextParams('filename', 'a title', logObject);
        }
    },

    folder: {
        view: function(ctrl, logObject) {
            return returnTextParams('folder', 'a folder', logObject);
        }
    },

    repo: {
        view: function(ctrl, logObject) {
            var github_user = logObject.attributes.params.github_user;
            var github_repo = logObject.attributes.params.github_repo;
            if (paramIsReturned(github_repo, logObject) && paramIsReturned(github_user, logObject)){
                return m('span', github_user + '/' + github_repo);
            }
            return m('span', '');
        }
    },

    folder_name: {
        view: function(ctrl, logObject) {
            return returnTextParams('folder_name', 'a folder', logObject);
        }
    },

    bucket: {
        view: function(ctrl, logObject) {
            return returnTextParams('bucket', 'a bucket', logObject);
        }
    },

    forward_url: {
        view: function(ctrl, logObject) {
            return returnTextParams('forward_url', 'a new URL', logObject);
        }
    },

    box_folder: {
        view: function(ctrl, logObject) {
            var folder = logObject.attributes.params.folder;
            if(paramIsReturned(folder, logObject)){
                return m('span', folder === 'All Files' ? '/ (Full Box)' : (folder || '').replace('All Files',''));
            }
            return m('span', '');
        }
    },

    citation: {
        view: function(ctrl, logObject) {
            return returnTextParams('citation_name', '', logObject);
        }
    },

    dataset: {
        view: function(ctrl, logObject){
            return returnTextParams('data_set', '', logObject);
        }
    },

    study: {
        view: function(ctrl, logObject){
            return returnTextParams('study', '', logObject);
        }
    },

    googledrive_path: {
        view: function(ctrl, logObject){
            var path = logObject.attributes.params.path;
            if(paramIsReturned(path, logObject)){
                return m('span', decodeURIComponent(path));
            }
            return m('span', '');
        }
    },

    googledrive_folder: {
        view: function(ctrl, logObject){
            var folder = logObject.attributes.params.folder;
            if(paramIsReturned(folder, logObject)){
                return m('span', folder === '/' ? '(Full Google Drive)' : decodeURIComponent(folder));
            }
            return m('span', '');
        }
    },

    addon: {
        view: function(ctrl, logObject){
            return returnTextParams('addon', '', logObject);
        }
    },

    previous_institution: {
        view: function(ctrl, logObject){
            var previous_institution = logObject.attributes.params.previous_institution;
            if (paramIsReturned(previous_institution, logObject)){
                return m('span', previous_institution.name);
            }
            return m('span', 'an institution');
        }
    },

    institution: {
        view: function(ctrl, logObject){
            var institution = logObject.attributes.params.institution;
            if (paramIsReturned(institution, logObject)){
                return m('span', institution.name);
            }
            return m('span', 'an institution');
        }
    },

    comment_file: {
        view: function(ctrl,logObject){
            var file = logObject.attributes.params.file;
            if (file){  // skipe paramIsReturned, as not having a file is expected at times
                return m('span', ['in ', m('a', {href: file.url}, file.name)]);
            }
            return m('span', '');
        }
    }
};

module.exports = LogText;
<|endoftext|>


<commit_before>define([
	"engine/core/bloob",
	"engine/main",
	"engine/game",
	"basic/audio/sound",
	"basic/audio/music",
	"engine/input",
	"basic/canvas",
	"bloob/scenes/titlescene",
	"logic/teleport",
	"editor/server",
	"debug/debug"
], function(
	Bloob,
	main,
	Game,
	Sound,
	Track,
	Input,
	Canvas,
	TitleScene,
	Teleport,
	Server,
	Debug
) {
	var BloobGame = Game.subclass({
		testSound: new Sound("data/audio/sounds/test/cursor_sounds/water-bubble-high.wav"),
		testTrack: new Track("data/audio/music/test/217741_vibe_timid_girl.mp3"),

		initialize: function() {
			Game.prototype.initialize.apply(this, arguments);

			this.testSave();
			if(typeof env.audio.context !== "undefined") this.testAudio();

			// prepare input
			env.input.initKeyboard();
			env.input.bind(Input.KEY.LEFT_ARROW, this.Left);
			env.input.bind(Input.KEY.RIGHT_ARROW, this.Right);
			env.input.bind(Input.KEY.UP_ARROW, this.Up);
			env.input.bind(Input.KEY.DOWN_ARROW, this.Down);

			// prepare input
			env.input.initMouse();
			env.input.bind(Input.KEY.MOUSE1, this.LeftButton);
			env.input.bind(Input.KEY.MOUSE2, this.RightButton);

			var titleScene = new TitleScene().run();
		},

		Left: "left",
		Right: "right",
		Up: "up",
		Down: "down",

		LeftButton: "leftclick",
		RightButton: "rightclick",

		testAudio: function() {
			if(Bloob.debug && Bloob.debug.datGui) {
				var audioFolder = Bloob.debug.datGui.addFolder("Audio");
				audioFolder.open();
				audioFolder.add(env.audio.trackParent.gain, 'value').name('TrackVolume').min(0.0).max(1.0).listen().step(0.1);
				audioFolder.add(env.audio.soundParent.gain, 'value').name('SoundVolume').min(0.0).max(1.0).listen().step(0.1);

				audioFolder.add(this.testSound, "play").name('play test sound');

				audioFolder.add(this.testTrack, "play").name('play test track');
				audioFolder.add(this.testTrack, '_volume')
					.name('track volume')
					.min(0.0)
					.max(1.0)
					.listen()
					.step(0.1)
					.onChange(function(volume) {
						testTrack.setVolume(volume);
					});
			}
		},

		testSave: function() {
			// test for map to json conversion
			var that = this;
			var toJson = {
				"save as": "untitled.json",
				"SAVE": function() {
					Bloob.log(env.scene);
					Server.save(
						"data/maps/" + toJson["save as"],
						JSON.stringify(env.scene.getMap().toJson(), undefined, 2)
					);
				}
			};
			if(Bloob.debug && Bloob.debug.datGui) {
				Bloob.debug.datGui.add(toJson, "save as");
				Bloob.debug.datGui.add(toJson, "SAVE");
			}
		}
	});

	// canvas properties
	var canvasId = "bloobCanvas";
	var canvasWidth = 1000;
	var canvasHeight = 400;
	var canvasColor = "black";

	var canvas = new Canvas(canvasId)
		//.fixedSize(canvasWidth, canvasHeight)
		.stretch()
		.color(canvasColor);

	// Start Game instance.
	main(BloobGame, canvas);
});
<commit_msg>added datGui folder for manipulating canvas on the fly<commit_after>define([
	"engine/core/bloob",
	"engine/main",
	"engine/game",
	"basic/audio/sound",
	"basic/audio/music",
	"engine/input",
	"basic/canvas",
	"bloob/scenes/titlescene",
	"logic/teleport",
	"editor/server",
	"debug/debug"
], function(
	Bloob,
	main,
	Game,
	Sound,
	Track,
	Input,
	Canvas,
	TitleScene,
	Teleport,
	Server,
	Debug
) {
	var BloobGame = Game.subclass({
		testSound: new Sound("data/audio/sounds/test/cursor_sounds/water-bubble-high.wav"),
		testTrack: new Track("data/audio/music/test/217741_vibe_timid_girl.mp3"),

		initialize: function() {
			Game.prototype.initialize.apply(this, arguments);

			this.testSave();
			if(typeof env.audio.context !== "undefined") this.testAudio();
			this.testCanvas();

			// prepare input
			env.input.initKeyboard();
			env.input.bind(Input.KEY.LEFT_ARROW, this.Left);
			env.input.bind(Input.KEY.RIGHT_ARROW, this.Right);
			env.input.bind(Input.KEY.UP_ARROW, this.Up);
			env.input.bind(Input.KEY.DOWN_ARROW, this.Down);

			// prepare input
			env.input.initMouse();
			env.input.bind(Input.KEY.MOUSE1, this.LeftButton);
			env.input.bind(Input.KEY.MOUSE2, this.RightButton);

			var titleScene = new TitleScene().run();
		},

		Left: "left",
		Right: "right",
		Up: "up",
		Down: "down",

		LeftButton: "leftclick",
		RightButton: "rightclick",

		testAudio: function() {
			if(Bloob.debug && Bloob.debug.datGui) {
				var audioFolder = Bloob.debug.datGui.addFolder("Audio");
				audioFolder.open();
				audioFolder.add(env.audio.trackParent.gain, 'value').name('TrackVolume').min(0.0).max(1.0).listen().step(0.1);
				audioFolder.add(env.audio.soundParent.gain, 'value').name('SoundVolume').min(0.0).max(1.0).listen().step(0.1);

				audioFolder.add(this.testSound, "play").name('play test sound');

				audioFolder.add(this.testTrack, "play").name('play test track');
				audioFolder.add(this.testTrack, '_volume')
					.name('track volume')
					.min(0.0)
					.max(1.0)
					.listen()
					.step(0.1)
					.onChange(function(volume) {
						testTrack.setVolume(volume);
					});
			}
		},

		testCanvas: function() {
			if(Bloob.debug && Bloob.debug.datGui) {
				var canvasFolder = Bloob.debug.datGui.addFolder("Canvas");
				canvasFolder.open();
				canvasFolder.add(env.canvas, 'stretch');
			}
		},

		testSave: function() {
			// test for map to json conversion
			var that = this;
			var toJson = {
				"save as": "untitled.json",
				"SAVE": function() {
					Bloob.log(env.scene);
					Server.save(
						"data/maps/" + toJson["save as"],
						JSON.stringify(env.scene.getMap().toJson(), undefined, 2)
					);
				}
			};
			if(Bloob.debug && Bloob.debug.datGui) {
				Bloob.debug.datGui.add(toJson, "save as");
				Bloob.debug.datGui.add(toJson, "SAVE");
			}
		}
	});

	// canvas properties
	var canvasId = "bloobCanvas";
	var canvasWidth = 1000;
	var canvasHeight = 400;
	var canvasColor = "black";

	var canvas = new Canvas(canvasId)
		.fixedSize(canvasWidth, canvasHeight)
		//.stretch()
		.color(canvasColor);

	// Start Game instance.
	main(BloobGame, canvas);
});
<|endoftext|>


<commit_before>/**
 * @file DraggableListItem component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {DragSource, DropTarget} from 'react-dnd';
import classNames from 'classnames';

import Checkbox from '../Checkbox';
import Radio from '../Radio';
import CircularLoading from '../CircularLoading';
import Tip from '../Tip';
import Theme from '../Theme';

import Util from '../_vendors/Util';
import Position from '../_statics/Position';
import SelectMode from '../_statics/SelectMode';
import DragDrop from '../_vendors/DragDrop';

const DRAG_LIST_ITEM_SYMBOL = Symbol('DRAG_LIST_ITEM');

@DropTarget(DRAG_LIST_ITEM_SYMBOL, DragDrop.getVerticalTarget(), connect => ({
    connectDropTarget: connect.dropTarget()
}))
@DragSource(DRAG_LIST_ITEM_SYMBOL, DragDrop.getSource(), (connect, monitor) => ({
    connectDragPreview: connect.dragPreview(),
    connectDragSource: connect.dragSource(),
    isDragging: monitor.isDragging()
}))
class DraggableListItem extends Component {

    static SelectMode = SelectMode;
    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            checked: props.checked,
            tipVisible: false
        };

        this.showTip = ::this.showTip;
        this.hideTip = ::this.hideTip;
        this.checkboxChangeHandler = ::this.checkboxChangeHandler;
        this.radioChangeHandler = ::this.radioChangeHandler;
        this.touchTapHandler = ::this.touchTapHandler;
        this.mouseOverHandler = ::this.mouseOverHandler;

    }

    showTip() {

        if (this.state.tipVisible) {
            return;
        }

        this.setState({
            tipVisible: true
        });

    }

    hideTip() {
        this.setState({
            tipVisible: false
        });
    }

    checkboxChangeHandler(checked) {
        this.setState({
            checked
        }, () => {

            const {onSelect, onDeselect} = this.props;

            if (checked) {
                onSelect && onSelect();
            } else {
                onDeselect && onDeselect();
            }

        });
    }

    radioChangeHandler() {

        const {checked} = this.state;

        if (!checked) {
            this.setState({
                checked: true
            }, () => {
                const {onSelect} = this.props;
                onSelect && onSelect();
            });
        }

    }

    touchTapHandler(e) {

        e.preventDefault();

        const {disabled, isLoading, readOnly} = this.props;

        if (disabled || isLoading || readOnly) {
            return;
        }

        const {onTouchTap} = this.props;
        onTouchTap && onTouchTap(e);

        switch (this.props.selectMode) {
            case SelectMode.MULTI_SELECT:
                this.checkboxChangeHandler(!this.state.checked);
                return;
            case SelectMode.SINGLE_SELECT:
                this.radioChangeHandler();
                return;
        }

    }

    mouseOverHandler(e) {
        this.showTip();
        const {onMouseOver} = this.props;
        onMouseOver && onMouseOver(e);
    }

    static getDerivedStateFromProps(nextProps, prevState) {
        if (nextProps.checked !== prevState.checked) {
            return {
                checked: nextProps.checked
            };
        }
        return null;
    }

    render() {

        const {

                connectDragPreview, connectDragSource, connectDropTarget, isDragging, isDraggableAnyWhere, anchorIconCls,

                index, className, theme, data, text, desc, iconCls, rightIconCls, tip, tipPosition,
                disabled, isLoading, renderer, itemRenderer,

                selectTheme, selectMode, radioUncheckedIconCls, radioCheckedIconCls,
                checkboxUncheckedIconCls, checkboxCheckedIconCls, checkboxIndeterminateIconCls,

                // not passing down these props
                onMove, onSelect, onDeselect,

                ...restProps

            } = this.props,
            {checked, tipVisible} = this.state,

            listItemClassName = classNames('draggable-list-item', {
                [`theme-${theme}`]: theme,
                activated: checked,
                dragging: isDragging,
                [className]: className
            }),

            loadingIconPosition = (rightIconCls && !iconCls) ? 'right' : 'left',

            anchorEl = <i className={`${anchorIconCls} draggable-list-item-anchor`}
                          aria-hidden="true">,

            el = connectDropTarget(

 this.tipTriggerEl = el}
                     className={listItemClassName}
                     disabled={disabled || isLoading}
                     onTouchTap={this.touchTapHandler}
                     onMouseOver={this.mouseOverHandler}
                     onMouseOut={this.hideTip}>

                    {
                        selectMode === SelectMode.SINGLE_SELECT && (radioUncheckedIconCls || radioCheckedIconCls) ?
                            <Radio className="draggable-list-item-select"
                                   theme={selectTheme}
                                   checked={checked}
                                   disabled={disabled || isLoading}
                                   uncheckedIconCls={radioUncheckedIconCls}
                                   checkedIconCls={radioCheckedIconCls}
                                   disableTouchRipple={true}/>
                            :
                            null
                    }

                    {
                        selectMode === SelectMode.MULTI_SELECT ?
                            <Checkbox className="draggable-list-item-select"
                                      theme={selectTheme}
                                      checked={checked}
                                      disabled={disabled || isLoading}
                                      uncheckedIconCls={checkboxUncheckedIconCls}
                                      checkedIconCls={checkboxCheckedIconCls}
                                      indeterminateIconCls={checkboxIndeterminateIconCls}
                                      disableTouchRipple={true}/>
                            :
                            null
                    }

                    {
                        isLoading && loadingIconPosition === 'left' ?

                                <CircularLoading className="button-loading-icon"
                                                 size="small"/>

                            :
                            (
                                iconCls ?
                                    <i className={`button-icon button-icon-left ${iconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

                    {
                        itemRenderer && typeof itemRenderer === 'function' ?
                            itemRenderer(data, index)
                            :
                            (
                                renderer && typeof renderer === 'function' ?
                                    renderer(data, index)
                                    :
                                    (
                                        desc ?

                                                    {text}

                                                    {desc}

                                            :
                                            text
                                    )
                            )
                    }

                    {
                        isLoading && loadingIconPosition === 'right' ?
                            <CircularLoading className="button-icon button-icon-right button-loading-icon"
                                             size="small"/>
                            :
                            (
                                rightIconCls ?
                                    <i className={`button-icon button-icon-right ${rightIconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

                    {
                        tip ?
                            <Tip visible={tipVisible}
                                 triggerEl={this.tipTriggerEl}
                                 position={tipPosition}>
                                {tip}
                            </Tip>
                            :
                            null
                    }

                    {
                        isDraggableAnyWhere ?
                            anchorEl
                            :
                            connectDragSource(anchorEl)
                    }

            );

        return isDraggableAnyWhere ?
            connectDragSource(el)
            :
            connectDragPreview(el);

    }
}

DraggableListItem.propTypes = {

    index: PropTypes.number,

    className: PropTypes.string,
    style: PropTypes.object,
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    data: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.object]),
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    text: PropTypes.any,
    desc: PropTypes.string,

    disabled: PropTypes.bool,
    isLoading: PropTypes.bool,
    checked: PropTypes.bool,
    readOnly: PropTypes.bool,

    iconCls: PropTypes.string,
    rightIconCls: PropTypes.string,

    tip: PropTypes.string,
    tipPosition: PropTypes.oneOf(Util.enumerateValue(Position)),

    radioUncheckedIconCls: PropTypes.string,
    radioCheckedIconCls: PropTypes.string,
    checkboxUncheckedIconCls: PropTypes.string,
    checkboxCheckedIconCls: PropTypes.string,
    checkboxIndeterminateIconCls: PropTypes.string,

    isDraggableAnyWhere: PropTypes.bool,
    anchorIconCls: PropTypes.string,

    itemRenderer: PropTypes.func,
    renderer: PropTypes.func,

    onTouchTap: PropTypes.func,
    onSelect: PropTypes.func,
    onDeselect: PropTypes.func,
    onMouseEnter: PropTypes.func,
    onMouseLeave: PropTypes.func,

    // dnd
    connectDragPreview: PropTypes.func,
    connectDragSource: PropTypes.func,
    connectDropTarget: PropTypes.func,
    isDragging: PropTypes.bool,
    onMove: PropTypes.func

};

DraggableListItem.defaultProps = {

    index: 0,

    theme: Theme.DEFAULT,

    selectTheme: Theme.DEFAULT,
    selectMode: SelectMode.SINGLE_SELECT,

    disabled: false,
    isLoading: false,
    checked: false,
    readOnly: false,

    tipPosition: Position.BOTTOM,

    checkboxUncheckedIconCls: 'far fa-square',
    checkboxCheckedIconCls: 'fas fa-check-square',
    checkboxIndeterminateIconCls: 'fas fa-minus-square',

    isDraggableAnyWhere: false,
    anchorIconCls: 'fas fa-bars'

};

export default DraggableListItem;<commit_msg>update DraggableListItem<commit_after>/**
 * @file DraggableListItem component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {DragSource, DropTarget} from 'react-dnd';
import classNames from 'classnames';

import Checkbox from '../Checkbox';
import Radio from '../Radio';
import CircularLoading from '../CircularLoading';
import Tip from '../Tip';
import Theme from '../Theme';

import Util from '../_vendors/Util';
import Position from '../_statics/Position';
import SelectMode from '../_statics/SelectMode';
import DragDrop from '../_vendors/DragDrop';

const DRAG_LIST_ITEM_SYMBOL = Symbol('DRAG_LIST_ITEM');

@DropTarget(DRAG_LIST_ITEM_SYMBOL, DragDrop.getVerticalTarget(), connect => ({
    connectDropTarget: connect.dropTarget()
}))
@DragSource(DRAG_LIST_ITEM_SYMBOL, DragDrop.getSource(), (connect, monitor) => ({
    connectDragPreview: connect.dragPreview(),
    connectDragSource: connect.dragSource(),
    isDragging: monitor.isDragging()
}))
class DraggableListItem extends Component {

    static SelectMode = SelectMode;
    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            checked: props.checked,
            tipVisible: false
        };

        this.showTip = ::this.showTip;
        this.hideTip = ::this.hideTip;
        this.checkboxChangeHandler = ::this.checkboxChangeHandler;
        this.radioChangeHandler = ::this.radioChangeHandler;
        this.touchTapHandler = ::this.touchTapHandler;
        this.mouseOverHandler = ::this.mouseOverHandler;

    }

    showTip() {

        if (this.state.tipVisible) {
            return;
        }

        this.setState({
            tipVisible: true
        });

    }

    hideTip() {
        this.setState({
            tipVisible: false
        });
    }

    checkboxChangeHandler(checked) {
        this.setState({
            checked
        }, () => {

            const {onSelect, onDeselect} = this.props;

            if (checked) {
                onSelect && onSelect();
            } else {
                onDeselect && onDeselect();
            }

        });
    }

    radioChangeHandler() {

        const {checked} = this.state;

        if (!checked) {
            this.setState({
                checked: true
            }, () => {
                const {onSelect} = this.props;
                onSelect && onSelect();
            });
        }

    }

    touchTapHandler(e) {

        e.preventDefault();

        const {disabled, isLoading, readOnly} = this.props;

        if (disabled || isLoading || readOnly) {
            return;
        }

        const {onTouchTap} = this.props;
        onTouchTap && onTouchTap(e);

        switch (this.props.selectMode) {
            case SelectMode.MULTI_SELECT:
                this.checkboxChangeHandler(!this.state.checked);
                return;
            case SelectMode.SINGLE_SELECT:
                this.radioChangeHandler();
                return;
        }

    }

    mouseOverHandler(e) {
        this.showTip();
        const {onMouseOver} = this.props;
        onMouseOver && onMouseOver(e);
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.checked !== this.state.checked) {
            this.setState({
                checked: nextProps.checked
            });
        }
    }

    render() {

        const {

                connectDragPreview, connectDragSource, connectDropTarget, isDragging, isDraggableAnyWhere, anchorIconCls,

                index, className, theme, data, text, desc, iconCls, rightIconCls, tip, tipPosition,
                disabled, isLoading, renderer, itemRenderer,

                selectTheme, selectMode, radioUncheckedIconCls, radioCheckedIconCls,
                checkboxUncheckedIconCls, checkboxCheckedIconCls, checkboxIndeterminateIconCls,

                // not passing down these props
                onMove, onSelect, onDeselect,

                ...restProps

            } = this.props,
            {checked, tipVisible} = this.state,

            listItemClassName = classNames('draggable-list-item', {
                [`theme-${theme}`]: theme,
                activated: checked,
                dragging: isDragging,
                [className]: className
            }),

            loadingIconPosition = (rightIconCls && !iconCls) ? 'right' : 'left',

            anchorEl = <i className={`${anchorIconCls} draggable-list-item-anchor`}
                          aria-hidden="true">,

            el = connectDropTarget(

 this.tipTriggerEl = el}
                     className={listItemClassName}
                     disabled={disabled || isLoading}
                     onTouchTap={this.touchTapHandler}
                     onMouseOver={this.mouseOverHandler}
                     onMouseOut={this.hideTip}>

                    {
                        selectMode === SelectMode.SINGLE_SELECT && (radioUncheckedIconCls || radioCheckedIconCls) ?
                            <Radio className="draggable-list-item-select"
                                   theme={selectTheme}
                                   checked={checked}
                                   disabled={disabled || isLoading}
                                   uncheckedIconCls={radioUncheckedIconCls}
                                   checkedIconCls={radioCheckedIconCls}
                                   disableTouchRipple={true}/>
                            :
                            null
                    }

                    {
                        selectMode === SelectMode.MULTI_SELECT ?
                            <Checkbox className="draggable-list-item-select"
                                      theme={selectTheme}
                                      checked={checked}
                                      disabled={disabled || isLoading}
                                      uncheckedIconCls={checkboxUncheckedIconCls}
                                      checkedIconCls={checkboxCheckedIconCls}
                                      indeterminateIconCls={checkboxIndeterminateIconCls}
                                      disableTouchRipple={true}/>
                            :
                            null
                    }

                    {
                        isLoading && loadingIconPosition === 'left' ?

                                <CircularLoading className="button-loading-icon"
                                                 size="small"/>

                            :
                            (
                                iconCls ?
                                    <i className={`button-icon button-icon-left ${iconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

                    {
                        itemRenderer && typeof itemRenderer === 'function' ?
                            itemRenderer(data, index)
                            :
                            (
                                renderer && typeof renderer === 'function' ?
                                    renderer(data, index)
                                    :
                                    (
                                        desc ?

                                                    {text}

                                                    {desc}

                                            :
                                            text
                                    )
                            )
                    }

                    {
                        isLoading && loadingIconPosition === 'right' ?
                            <CircularLoading className="button-icon button-icon-right button-loading-icon"
                                             size="small"/>
                            :
                            (
                                rightIconCls ?
                                    <i className={`button-icon button-icon-right ${rightIconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

                    {
                        tip ?
                            <Tip visible={tipVisible}
                                 triggerEl={this.tipTriggerEl}
                                 position={tipPosition}>
                                {tip}
                            </Tip>
                            :
                            null
                    }

                    {
                        isDraggableAnyWhere ?
                            anchorEl
                            :
                            connectDragSource(anchorEl)
                    }

            );

        return isDraggableAnyWhere ?
            connectDragSource(el)
            :
            connectDragPreview(el);

    }
}

DraggableListItem.propTypes = {

    index: PropTypes.number,

    className: PropTypes.string,
    style: PropTypes.object,
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    data: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.object]),
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    text: PropTypes.any,
    desc: PropTypes.string,

    disabled: PropTypes.bool,
    isLoading: PropTypes.bool,
    checked: PropTypes.bool,
    readOnly: PropTypes.bool,

    iconCls: PropTypes.string,
    rightIconCls: PropTypes.string,

    tip: PropTypes.string,
    tipPosition: PropTypes.oneOf(Util.enumerateValue(Position)),

    radioUncheckedIconCls: PropTypes.string,
    radioCheckedIconCls: PropTypes.string,
    checkboxUncheckedIconCls: PropTypes.string,
    checkboxCheckedIconCls: PropTypes.string,
    checkboxIndeterminateIconCls: PropTypes.string,

    isDraggableAnyWhere: PropTypes.bool,
    anchorIconCls: PropTypes.string,

    itemRenderer: PropTypes.func,
    renderer: PropTypes.func,

    onTouchTap: PropTypes.func,
    onSelect: PropTypes.func,
    onDeselect: PropTypes.func,
    onMouseEnter: PropTypes.func,
    onMouseLeave: PropTypes.func,

    // dnd
    connectDragPreview: PropTypes.func,
    connectDragSource: PropTypes.func,
    connectDropTarget: PropTypes.func,
    isDragging: PropTypes.bool,
    onMove: PropTypes.func

};

DraggableListItem.defaultProps = {

    index: 0,

    theme: Theme.DEFAULT,

    selectTheme: Theme.DEFAULT,
    selectMode: SelectMode.SINGLE_SELECT,

    disabled: false,
    isLoading: false,
    checked: false,
    readOnly: false,

    tipPosition: Position.BOTTOM,

    checkboxUncheckedIconCls: 'far fa-square',
    checkboxCheckedIconCls: 'fas fa-check-square',
    checkboxIndeterminateIconCls: 'fas fa-minus-square',

    isDraggableAnyWhere: false,
    anchorIconCls: 'fas fa-bars'

};

export default DraggableListItem;<|endoftext|>


<commit_before>var obj = { //a json like object
	a: 'hello world',
	b: 42,
	c: true
};

obj.a; //"hello world"
obj.b; //42
obj.c; //true

obj['a'];	//"hello world"
obj['b'];	//42
obj['c'];	//true

///we can also add or change existing Objects
// the Number type is an Object and we can add functionality to it
// what we are doing here is called polyfilling - but its not 100% how it should be
if (!Number.isNaN) {
	//we should pollyfill directly on prototype - we will learn more about prototypes in the prototype section
	Number.isNaN = function isNaN(x) {
		return x !== x; // checking the type with coercion
	};
}

///Object.create
var foo = {
	a: 42
};

//create `bar` and link it to `foo`
var bar = Object.create( foo );

bar.b = 'hello world';

bar.b; //"hello world"
bar.a; //42
<commit_msg>Update objects.js<commit_after>var obj = { //a json like object
	a: 'hello world',
	b: 42,
	c: true
};

obj.a; //"hello world"
obj.b; //42
obj.c; //true

obj['a'];	//"hello world"
obj['b'];	//42
obj['c'];	//true

///we can also add or change existing Objects
// the Number type is an Object and we can add or change its functionality
// what we are doing here is called polyfilling - note that this is only an example and not a real pollyfill
if (!Number.isNaN) {
	//we should pollyfill directly on prototype - we will learn more about prototypes in the prototype section
	Number.isNaN = function isNaN(x) {
		return x !== x; // checking the type with coercion
	};
}

///Object.create
var foo = {
	a: 42
};

//create `bar` and link it to `foo`
var bar = Object.create( foo );

bar.b = 'hello world';

bar.b; //"hello world"
bar.a; //42
<|endoftext|>


<commit_before>(function() {
  'use strict';

  function KeyboardShortcutsOverview() {

    function link(scope, el, attr, ctrl) {

      scope.shortcutOverlay = false;

      scope.toggleShortcutsOverlay = function() {
        scope.shortcutOverlay = !scope.shortcutOverlay;
      };

    }

    var directive = {
      restrict: 'E',
      replace: true,
      templateUrl: 'views/components/umb-keyboard-shortcuts-overview.html',
      link: link,
      scope: {
        model: "="
      }
    };

    return directive;
  }

  angular.module('umbraco.directives').directive('umbKeyboardShortcutsOverview', KeyboardShortcutsOverview);

})();
<commit_msg>Rename directive function<commit_after>(function() {
  'use strict';

  function KeyboardShortcutsOverviewDirective() {

    function link(scope, el, attr, ctrl) {

      scope.shortcutOverlay = false;

      scope.toggleShortcutsOverlay = function() {
        scope.shortcutOverlay = !scope.shortcutOverlay;
      };

    }

    var directive = {
      restrict: 'E',
      replace: true,
      templateUrl: 'views/components/umb-keyboard-shortcuts-overview.html',
      link: link,
      scope: {
        model: "="
      }
    };

    return directive;
  }

  angular.module('umbraco.directives').directive('umbKeyboardShortcutsOverview', KeyboardShortcutsOverviewDirective);

})();
<|endoftext|>


<commit_before>exports.BattleMovedex = {
  "armthrust": {
<commit_msg>Multihit moves are done!<commit_after>exports.BattleMovedex = {
	"armthrust": {
		inherit: true,
		multihit: [3,3]
	},
	"barrage": {
		inherit: true,
		multihit: [3,3]
	},
	"bonerush": {
		inherit: true,
		multihit: [3,3]
	},
	"bulletseed": {
		inherit: true,
		multihit: [3,3]
	},
	"cometpunch": {
		inherit: true,
		multihit: [3,3]
	},
	"doubleslap": {
		inherit: true,
		multihit: [3,3]
	},
	"furyattack": {
		inherit: true,
		multihit: [3,3]
	},
	"furyswipes": {
		inherit: true,
		multihit: [3,3]
	},
	"iciclespear": {
		inherit: true,
		multihit: [3,3]
	},
	"pinmissile": {
		inherit: true,
		multihit: [3,3]
	},
	"rockblast": {
		inherit: true,
		multihit: [3,3]
	},
	"spikecannon": {
		inherit: true,
		multihit: [3,3]
	},
	"tailslap": {
		inherit: true,
		multihit: [3,3]
	}
};
<|endoftext|>


<commit_before>var createHmac = require('create-hmac')
var MAX_ALLOC = Math.pow(2, 30) - 1 // default in iojs

exports.pbkdf2 = pbkdf2
function pbkdf2 (password, salt, iterations, keylen, digest, callback) {
  if (typeof digest === 'function') {
    callback = digest
    digest = undefined
  }

  if (typeof callback !== 'function') {
    throw new Error('No callback provided to pbkdf2')
  }

  setTimeout(function () {
    var result = pbkdf2Sync(password, salt, iterations, keylen, digest)

    callback(null, result)
  })
}

exports.pbkdf2Sync = pbkdf2Sync
function pbkdf2Sync (password, salt, iterations, keylen, digest) {
  if (typeof iterations !== 'number') {
    throw new TypeError('Iterations not a number')
  }

  if (iterations < 0) {
    throw new TypeError('Bad iterations')
  }

  if (typeof keylen !== 'number') {
    throw new TypeError('Key length not a number')
  }

  if (keylen < 0 || keylen > MAX_ALLOC) {
    throw new TypeError('Bad key length')
  }

  digest = digest || 'sha1'

  if (!Buffer.isBuffer(password)) password = new Buffer(password, 'binary')
  if (!Buffer.isBuffer(salt)) salt = new Buffer(salt, 'binary')

  var hLen
  var l = 1
  var DK = new Buffer(keylen)
  var block1 = new Buffer(salt.length + 4)
  salt.copy(block1, 0, 0, salt.length)

  var r
  var T

  for (var i = 1; i <= l; i++) {
    block1.writeUInt32BE(i, salt.length)
    var U = createHmac(digest, password).update(block1).digest()

    if (!hLen) {
      hLen = U.length
      T = new Buffer(hLen)
      l = Math.ceil(keylen / hLen)
      r = keylen - (l - 1) * hLen
    }

    U.copy(T, 0, 0, hLen)

    for (var j = 1; j < iterations; j++) {
      U = createHmac(digest, password).update(U).digest()

      for (var k = 0; k < hLen; k++) {
        T[k] ^= U[k]
      }
    }

    var destPos = (i - 1) * hLen
    var len = (i === l ? r : hLen)
    T.copy(DK, destPos, 0, len)
  }

  return DK
}
<commit_msg>pull out type checking<commit_after>var createHmac = require('create-hmac')
var MAX_ALLOC = Math.pow(2, 30) - 1 // default in iojs

exports.pbkdf2 = pbkdf2
function pbkdf2 (password, salt, iterations, keylen, digest, callback) {
  if (typeof digest === 'function') {
    callback = digest
    digest = undefined
  }

  testParams(iterations, keylen)

  if (typeof callback !== 'function') {
    throw new Error('No callback provided to pbkdf2')
  }

  setTimeout(function () {
    var result = pbkdf2Sync(password, salt, iterations, keylen, digest)

    callback(null, result)
  })
}

function testParams(iterations, keylen) {
  if (typeof iterations !== 'number') {
    throw new TypeError('Iterations not a number')
  }

  if (iterations < 0) {
    throw new TypeError('Bad iterations')
  }

  if (typeof keylen !== 'number') {
    throw new TypeError('Key length not a number')
  }

  if (keylen < 0 || keylen > MAX_ALLOC) {
    throw new TypeError('Bad key length')
  }
}

exports.pbkdf2Sync = pbkdf2Sync
function pbkdf2Sync (password, salt, iterations, keylen, digest) {
  testParams(iterations, keylen)

  digest = digest || 'sha1'

  if (!Buffer.isBuffer(password)) password = new Buffer(password, 'binary')
  if (!Buffer.isBuffer(salt)) salt = new Buffer(salt, 'binary')

  var hLen
  var l = 1
  var DK = new Buffer(keylen)
  var block1 = new Buffer(salt.length + 4)
  salt.copy(block1, 0, 0, salt.length)

  var r
  var T

  for (var i = 1; i <= l; i++) {
    block1.writeUInt32BE(i, salt.length)
    var U = createHmac(digest, password).update(block1).digest()

    if (!hLen) {
      hLen = U.length
      T = new Buffer(hLen)
      l = Math.ceil(keylen / hLen)
      r = keylen - (l - 1) * hLen
    }

    U.copy(T, 0, 0, hLen)

    for (var j = 1; j < iterations; j++) {
      U = createHmac(digest, password).update(U).digest()

      for (var k = 0; k < hLen; k++) {
        T[k] ^= U[k]
      }
    }

    var destPos = (i - 1) * hLen
    var len = (i === l ? r : hLen)
    T.copy(DK, destPos, 0, len)
  }

  return DK
}
<|endoftext|>


<commit_before>export { Base };

import * as RandTools from "../../util/RandTools.js";
import * as NameNumberArrayObject_To_Float32Array from "../../util/NameNumberArrayObject_To_Float32Array.js";
//import * as ParamDesc from "../../Unpacker/ParamDesc.js";
//import * as ValueDesc from "../../Unpacker/ValueDesc.js";
//import * as ValueRange from "../../Unpacker/ValueRange.js";
import * as TestParams from "./TestParams.js";
import * as PointDepthPoint_TestParams from "./PointDepthPoint_TestParams.js";
import * as Block from "../../Conv/Block.js";

/**
 *
 * This is an object { id, in, out } which has one number and two sub-objects.
 *
 * @member {number} id
 *   The numeric identifier of this testing parameter combination.
 *
 * @member {object} in
 *   The "in" sub-object's data members represent every parameters of the Block.Params's constructor. That is,
 * it has the following data members: sourceHeight, sourceWidth, sourceChannelCount, stepCountRequested,
 * pointwise1ChannelCountRate, depthwiseFilterHeight, nActivationId, nActivationIdAtBlockEnd, nWhetherShuffleChannel,
 * bKeepInputTensor. It also has the following properties:
 *   - paramsNumberArrayObject
 *   - inputFloat32Array
 *   - byteOffsetBegin
 *
 * @member {object} out
 *   The "out" sub-object's data members represent the "should-be" result of Block.Params's extract(). That is, it has
 * the above data members (with outputHeight, outputWidth) except paramsNumberArrayObject, inputFloat32Array, byteOffsetBegin.
 *
 * @member {object[]} stepsArray
 *   Every element is an PointDepthPoint_TestParams object for the parameters of the step.
 */
class Base extends TestParams.Base {

  /**
   *
   */
  constructor() {
    super();
    this.stepsArray = new Array();
  }

  /**
   * Use scattered parameters to fills the following proterties:
   *   - this.in.inputFloat32Array
   *   - this.in.byteOffsetBegin
   *   - this.out
   *
   * @return {Base}
   *   Return this object self.
   */
  set_By_ParamsScattered(
    sourceHeight, sourceWidth, sourceChannelCount, stepCountRequested, pointwise1ChannelCountRate,
    depthwiseFilterHeight, nActivationId, nActivationIdAtBlockEnd, nWhetherShuffleChannel, bKeepInputTensor
  ) {
    this.in.paramsNumberArrayObject = {};
    this.out = {
      sourceHeight, sourceWidth, sourceChannelCount, stepCountRequested, pointwise1ChannelCountRate,
      depthwiseFilterHeight, nActivationId, nActivationIdAtBlockEnd, nWhetherShuffleChannel, bKeepInputTensor
    };

    Object.assign( this.in, this.out ); // So that all parameters are by specified (none is by evolution).

    let weightsElementOffsetBegin = 0;
    return this.set_By_ParamsNumberArrayMap_ParamsOut( weightsElementOffsetBegin );
  }

  /**
   * Fills the following proterties:
   *   - this.in.inputFloat32Array
   *   - this.in.byteOffsetBegin
   *   - this.out.outputHeight
   *   - this.out.outputWidth
   *
   * @param {object} this.in.paramsNumberArrayObject
   *   Pass in an object. The result will be put into this object. It is a map from a string name (e.g. parameter name) to a number array.
   * The name should be one of Base.paramsNameOrderArray[] elements.
   *
   * @param {object} this.out
   *   An object which has the following data members: sourceHeight, sourceWidth, sourceChannelCount, stepCountRequested,
   * pointwise1ChannelCountRate, depthwiseFilterHeight, nActivationId, nActivationIdAtBlockEnd, nWhetherShuffleChannel,
   * bKeepInputTensor, outputHeight, outputWidth.
   *
   * @param {number} weightsElementOffsetBegin
   *   Offset how many elements (4 bytes per element) at the beginning of the result weightsFloat32Array.
   * The this.in.byteOffsetBegin will be ( 4 * weightsElementOffsetBegin ).
   *
   * @return {Base}
   *   Return this object self.
   */
  set_By_ParamsNumberArrayMap_ParamsOut( weightsElementOffsetBegin = 0 ) {
    let blockParams = this.out;

    // Fill in outputHeight, outputWidth.
    Block.Params.set_outputHeight_outputWidth_by_sourceHeight_sourceWidth.call( blockParams, blockParams.sourceHeight, blockParams.sourceWidth );

    let stepParamsMaker = Block.Base.create_Params_to_PointDepthPointParams( blockParams );
    stepParamsMaker.determine_stepCount_depthwiseFilterHeight_Default_Last();

    this.stepsArray.length = stepParamsMaker.stepCount;
    let paramsNameOrderArray = Base.paramsNameOrderArray_Basic.slice(); // Shallow copy.

    let paramsNumberArrayObject = {};
    Object.assign( paramsNumberArrayObject, this.in.paramsNumberArrayObject ); // Shallow copy.

    let channelShuffler;
    for ( let i = 0; i < stepParamsMaker.stepCount; ++i ) { // Step0, 1, 2, 3, ..., StepLast.

      if ( 0 == i ) { // Step0.
        stepParamsMaker.configTo_beforeStep0();
      }

      if ( ( this.stepsArray.length - 1 ) == i ) { // StepLast. (Note: Step0 may also be StepLast.)
        stepParamsMaker.configTo_beforeStepLast();
      }

      // If channelShuffler is not null, keep it so that its tensors could be released.
      if ( stepParamsMaker.channelShuffler ) {
        channelShuffler = stepParamsMaker.channelShuffler;
      }

      let stepName = `step${i}`;
      paramsNameOrderArray.push( stepName ); // Place every step's parameters in sequence.

      let stepTestParams = new PointDepthPoint_TestParams.Base( this.id );
      stepTestParams.set_By_ParamsScattered(
        stepParamsMaker.channelCount0_pointwise1Before,
        stepParamsMaker.channelCount1_pointwise1Before,
        stepParamsMaker.pointwise1ChannelCount, stepParamsMaker.bPointwise1Bias, stepParamsMaker.pointwise1ActivationId,
        stepParamsMaker.depthwise_AvgMax_Or_ChannelMultiplier, stepParamsMaker.depthwiseFilterHeight, stepParamsMaker.depthwiseStridesPad,
        stepParamsMaker.bDepthwiseBias, stepParamsMaker.depthwiseActivationId,
        stepParamsMaker.pointwise21ChannelCount, stepParamsMaker.bPointwise21Bias, stepParamsMaker.pointwise21ActivationId,
        stepParamsMaker.bOutput1Requested,
        stepParamsMaker.bKeepInputTensor
      );

      this.stepsArray[ i ] = stepTestParams;
      paramsNumberArrayObject[ stepName ] = stepTestParams.in.inputFloat32Array;

      if ( 0 == i ) { // After step0 (i.e. for step1, 2, 3, ...)
        stepParamsMaker.configTo_afterStep0();
      }
    }

    // Here (i.e. in Block_TestParams), the channelShuffler is not used. Just release it for avoiding memory leak.
    if ( channelShuffler ) {
      channelShuffler.disposeTensors();
      channelShuffler = null;
    }

    let Float32Array_ByteOffsetBegin = new NameNumberArrayObject_To_Float32Array.Base();
    Float32Array_ByteOffsetBegin.setByConcat( paramsNameOrderArray, paramsNumberArrayObject, weightsElementOffsetBegin );

    this.in.inputFloat32Array = Float32Array_ByteOffsetBegin.weightsFloat32Array;
    this.in.byteOffsetBegin = Float32Array_ByteOffsetBegin.weightsByteOffsetBegin;

    return this;
  }

  /**
   * @override
   */
  onBefore_Yield() {

    // For testing not start at the offset 0.
    let weightsElementOffsetBegin = RandTools.getRandomIntInclusive( 0, 3 ); // Skip a random un-used element count.

    this.set_By_ParamsNumberArrayMap_ParamsOut( weightsElementOffsetBegin );
  }

  /**
   * @override
   */
  onAfter_Yield() {
    this.stepsArray.length = 0; // Clear steps' parameters.
  }

  /**
   * Responsible for generating testing paramters combinations.
   *
   * @param {number} sourceHeight
   *   Only test the height of input image.
   *
   * @param {number} sourceWidth
   *   Only test the width of input image.
   *
   * @yield {Base}
   *   Yield this object itself. The returned object (it is this object itself) should not be modified because it will be re-used.
   */
  * ParamsGenerator( sourceHeight, sourceWidth ) {
    this.sourceHeight = sourceHeight;
    this.sourceWidth = sourceWidth;

    // Restrict some parameter's large kinds. Otherwise, too many combination will be generated.
    this.valueOutMinMax = {
      sourceHeight: [ this.sourceHeight, this.sourceHeight ], //5,
      sourceWidth:  [ this.sourceWidth,  this.sourceWidth  ], //5,

      sourceChannelCount: [
        Block.Params.sourceChannelCount.valueDesc.range.min,
        Block.Params.sourceChannelCount.valueDesc.range.min + 4
      ],

      stepCountRequested: [
        Block.Params.stepCountRequested.valueDesc.range.min,
        Block.Params.stepCountRequested.valueDesc.range.min + 5
      ],

      pointwise1ChannelCountRate: undefined,
      depthwiseFilterHeight: undefined,

      // Because the logic of activation function is simpler than other, it is just randomly tested once
      // for speeding up testing.
      nActivationId: undefined,
//       [
//         ValueDesc.ActivationFunction.Singleton.range.min,
//         ValueDesc.ActivationFunction.Singleton.range.min + 0
//       ],

      nActivationIdAtBlockEnd: undefined,
//       [
//         ValueDesc.ActivationFunction.Singleton.range.min,
//         ValueDesc.ActivationFunction.Singleton.range.min + 0
//       ],

      nWhetherShuffleChannel: undefined,
      bKeepInputTensor: undefined,
    };

    // All the parameters to be tried.
    //
    // Note: The order of these element could be adjusted to change testing order. The last element will be tested (changed) first.
    let paramDescConfigArray = [
      new TestParams.ParamDescConfig( Block.Params.sourceHeight,               this.valueOutMinMax.sourceHeight ),
      new TestParams.ParamDescConfig( Block.Params.sourceWidth,                this.valueOutMinMax.sourceWidth ),
      new TestParams.ParamDescConfig( Block.Params.sourceChannelCount,         this.valueOutMinMax.sourceChannelCount ),
      new TestParams.ParamDescConfig( Block.Params.stepCountRequested,         this.valueOutMinMax.stepCountRequested ),
      new TestParams.ParamDescConfig( Block.Params.pointwise1ChannelCountRate, this.valueOutMinMax.pointwise1ChannelCountRate ),
      new TestParams.ParamDescConfig( Block.Params.depthwiseFilterHeight,      this.valueOutMinMax.depthwiseFilterHeight ),
      new TestParams.ParamDescConfig( Block.Params.nActivationId,              this.valueOutMinMax.nActivationId ),
      new TestParams.ParamDescConfig( Block.Params.nActivationIdAtBlockEnd,    this.valueOutMinMax.nActivationIdAtBlockEnd ),
      new TestParams.ParamDescConfig( Block.Params.nWhetherShuffleChannel,     this.valueOutMinMax.nWhetherShuffleChannel ),
      new TestParams.ParamDescConfig( Block.Params.bKeepInputTensor,           this.valueOutMinMax.bKeepInputTensor ),
    ];

    yield *Base.ParamsGenerator.call( this, paramDescConfigArray );
  }

}

/**
 * The order when generate weightsFloat32Array[].
 *
 * This order could not be changed arbitrarily. It must be the same as the parameter extracting order of Block.initer().
 */
Base.paramsNameOrderArray_Basic = [
  Block.Params.sourceHeight.paramName,
  Block.Params.sourceWidth.paramName,
  Block.Params.sourceChannelCount.paramName,
  Block.Params.stepCountRequested.paramName,
  Block.Params.pointwise1ChannelCountRate.paramName,
  Block.Params.depthwiseFilterHeight.paramName,
  Block.Params.nActivationId.paramName,
  Block.Params.nActivationIdAtBlockEnd.paramName,
  Block.Params.nWhetherShuffleChannel.paramName,
  Block.Params.bKeepInputTensor.paramName,
];
<commit_msg>Update Block_TestParams.js<commit_after>export { Base };

import * as RandTools from "../../util/RandTools.js";
import * as NameNumberArrayObject_To_Float32Array from "../../util/NameNumberArrayObject_To_Float32Array.js";
//import * as ParamDesc from "../../Unpacker/ParamDesc.js";
//import * as ValueDesc from "../../Unpacker/ValueDesc.js";
//import * as ValueRange from "../../Unpacker/ValueRange.js";
import * as TestParams from "./TestParams.js";
import * as PointDepthPoint_TestParams from "./PointDepthPoint_TestParams.js";
import * as Block from "../../Conv/Block.js";

/**
 *
 * This is an object { id, in, out } which has one number and two sub-objects.
 *
 * @member {number} id
 *   The numeric identifier of this testing parameter combination.
 *
 * @member {object} in
 *   The "in" sub-object's data members represent every parameters of the Block.Params's constructor. That is,
 * it has the following data members: sourceHeight, sourceWidth, sourceChannelCount, stepCountRequested,
 * pointwise1ChannelCountRate, depthwiseFilterHeight, nActivationId, nActivationIdAtBlockEnd, nWhetherShuffleChannel,
 * bKeepInputTensor. It also has the following properties:
 *   - paramsNumberArrayObject
 *   - inputFloat32Array
 *   - byteOffsetBegin
 *
 * @member {object} out
 *   The "out" sub-object's data members represent the "should-be" result of Block.Params's extract(). That is, it has
 * the above data members (with outputHeight, outputWidth) except paramsNumberArrayObject, inputFloat32Array, byteOffsetBegin.
 *
 * @member {object[]} stepsArray
 *   Every element is an PointDepthPoint_TestParams object for the parameters of the step.
 */
class Base extends TestParams.Base {

  /**
   *
   */
  constructor() {
    super();
    this.stepsArray = new Array();
  }

  /**
   * Use scattered parameters to fills the following proterties:
   *   - this.in.inputFloat32Array
   *   - this.in.byteOffsetBegin
   *   - this.out
   *
   * @return {Base}
   *   Return this object self.
   */
  set_By_ParamsScattered(
    sourceHeight, sourceWidth, sourceChannelCount, stepCountRequested, pointwise1ChannelCountRate,
    depthwiseFilterHeight, nActivationId, nActivationIdAtBlockEnd, nWhetherShuffleChannel, bKeepInputTensor
  ) {
    this.in.paramsNumberArrayObject = {};
    this.out = {
      sourceHeight, sourceWidth, sourceChannelCount, stepCountRequested, pointwise1ChannelCountRate,
      depthwiseFilterHeight, nActivationId, nActivationIdAtBlockEnd, nWhetherShuffleChannel, bKeepInputTensor
    };

    Object.assign( this.in, this.out ); // So that all parameters are by specified (none is by evolution).

    let weightsElementOffsetBegin = 0;
    return this.set_By_ParamsNumberArrayMap_ParamsOut( weightsElementOffsetBegin );
  }

  /**
   * Fills the following proterties:
   *   - this.in.inputFloat32Array
   *   - this.in.byteOffsetBegin
   *   - this.out.outputHeight
   *   - this.out.outputWidth
   *
   * @param {object} this.in.paramsNumberArrayObject
   *   Pass in an object. The result will be put into this object. It is a map from a string name (e.g. parameter name) to a number array.
   * The name should be one of Base.paramsNameOrderArray[] elements.
   *
   * @param {object} this.out
   *   An object which has the following data members: sourceHeight, sourceWidth, sourceChannelCount, stepCountRequested,
   * pointwise1ChannelCountRate, depthwiseFilterHeight, nActivationId, nActivationIdAtBlockEnd, nWhetherShuffleChannel,
   * bKeepInputTensor, outputHeight, outputWidth.
   *
   * @param {number} weightsElementOffsetBegin
   *   Offset how many elements (4 bytes per element) at the beginning of the result weightsFloat32Array.
   * The this.in.byteOffsetBegin will be ( 4 * weightsElementOffsetBegin ).
   *
   * @return {Base}
   *   Return this object self.
   */
  set_By_ParamsNumberArrayMap_ParamsOut( weightsElementOffsetBegin = 0 ) {
    let blockParams = this.out;

    // Fill in outputHeight, outputWidth.
    Block.Params.set_outputHeight_outputWidth_by_sourceHeight_sourceWidth.call( blockParams, blockParams.sourceHeight, blockParams.sourceWidth );

    let stepParamsMaker = Block.Base.create_Params_to_PointDepthPointParams( blockParams );
    stepParamsMaker.determine_stepCount_depthwiseFilterHeight_Default_Last();

    this.stepsArray.length = stepParamsMaker.stepCount;
    let paramsNameOrderArray = Base.paramsNameOrderArray_Basic.slice(); // Shallow copy.

    let paramsNumberArrayObject = {};
    Object.assign( paramsNumberArrayObject, this.in.paramsNumberArrayObject ); // Shallow copy.

    let channelShuffler;
    for ( let i = 0; i < stepParamsMaker.stepCount; ++i ) { // Step0, 1, 2, 3, ..., StepLast.

      if ( 0 == i ) { // Step0.
        stepParamsMaker.configTo_beforeStep0();
      }

      if ( ( this.stepsArray.length - 1 ) == i ) { // StepLast. (Note: Step0 may also be StepLast.)
        stepParamsMaker.configTo_beforeStepLast();
      }

      // If channelShuffler is not null, keep it so that its tensors could be released.
      if ( stepParamsMaker.channelShuffler ) {
        channelShuffler = stepParamsMaker.channelShuffler;
      }

      let stepName = `step${i}`;
      paramsNameOrderArray.push( stepName ); // Place every step's parameters in sequence.

      let stepTestParams = new PointDepthPoint_TestParams.Base( this.id );
      stepTestParams.set_By_ParamsScattered(
        stepParamsMaker.channelCount0_pointwise1Before,
        stepParamsMaker.channelCount1_pointwise1Before,
        stepParamsMaker.pointwise1ChannelCount, stepParamsMaker.bPointwise1Bias, stepParamsMaker.pointwise1ActivationId,
        stepParamsMaker.depthwise_AvgMax_Or_ChannelMultiplier, stepParamsMaker.depthwiseFilterHeight, stepParamsMaker.depthwiseStridesPad,
        stepParamsMaker.bDepthwiseBias, stepParamsMaker.depthwiseActivationId,
        stepParamsMaker.pointwise21ChannelCount, stepParamsMaker.bPointwise21Bias, stepParamsMaker.pointwise21ActivationId,
        stepParamsMaker.bOutput1Requested,
        stepParamsMaker.bKeepInputTensor
      );

      this.stepsArray[ i ] = stepTestParams;
      paramsNumberArrayObject[ stepName ] = stepTestParams.in.inputFloat32Array;

      if ( 0 == i ) { // After step0 (i.e. for step1, 2, 3, ...)
        stepParamsMaker.configTo_afterStep0();
      }
    }

    // Here (i.e. in Block_TestParams), the channelShuffler is not used. Just release it for avoiding memory leak.
    if ( channelShuffler ) {
      channelShuffler.disposeTensors();
      channelShuffler = null;
    }

    let Float32Array_ByteOffsetBegin = new NameNumberArrayObject_To_Float32Array.Base();
    Float32Array_ByteOffsetBegin.setByConcat( paramsNameOrderArray, paramsNumberArrayObject, weightsElementOffsetBegin );

    this.in.inputFloat32Array = Float32Array_ByteOffsetBegin.weightsFloat32Array;
    this.in.byteOffsetBegin = Float32Array_ByteOffsetBegin.weightsByteOffsetBegin;

    return this;
  }

  /**
   * @override
   */
  onBefore_Yield() {

    // For testing not start at the offset 0.
    let weightsElementOffsetBegin = RandTools.getRandomIntInclusive( 0, 3 ); // Skip a random un-used element count.

    this.set_By_ParamsNumberArrayMap_ParamsOut( weightsElementOffsetBegin );
  }

  /**
   * @override
   */
  onAfter_Yield() {
    this.stepsArray.length = 0; // Clear steps' parameters.
  }

  /**
   * Responsible for generating testing paramters combinations.
   *
   * @param {number} sourceHeight
   *   Only test the height of input image.
   *
   * @param {number} sourceWidth
   *   Only test the width of input image.
   *
   * @param {number} sourceChannelCount
   *   Only test the depth of input image.
   *
   * @yield {Base}
   *   Yield this object itself. The returned object (it is this object itself) should not be modified because it will be re-used.
   */
  * ParamsGenerator( sourceHeight, sourceWidth, sourceChannelCount ) {
    this.sourceHeight = sourceHeight;
    this.sourceWidth = sourceWidth;
    this.sourceChannelCount = sourceChannelCount;

    // Restrict some parameter's large kinds. Otherwise, too many combination will be generated.
    this.valueOutMinMax = {
      sourceHeight: [ this.sourceHeight, this.sourceHeight ], //5,
      sourceWidth:  [ this.sourceWidth,  this.sourceWidth  ], //5,
      sourceChannelCount: [ sourceChannelCount, sourceChannelCount ],

      stepCountRequested: [
        Block.Params.stepCountRequested.valueDesc.range.min,
        Block.Params.stepCountRequested.valueDesc.range.min + 5
      ],

      pointwise1ChannelCountRate: undefined,
      depthwiseFilterHeight: undefined,

      // Because the logic of activation function is simpler than other, it is just randomly tested once
      // for speeding up testing.
      nActivationId: undefined,
//       [
//         ValueDesc.ActivationFunction.Singleton.range.min,
//         ValueDesc.ActivationFunction.Singleton.range.min + 0
//       ],

      nActivationIdAtBlockEnd: undefined,
//       [
//         ValueDesc.ActivationFunction.Singleton.range.min,
//         ValueDesc.ActivationFunction.Singleton.range.min + 0
//       ],

      nWhetherShuffleChannel: undefined,
      bKeepInputTensor: undefined,
    };

    // All the parameters to be tried.
    //
    // Note: The order of these element could be adjusted to change testing order. The last element will be tested (changed) first.
    let paramDescConfigArray = [
      new TestParams.ParamDescConfig( Block.Params.sourceHeight,               this.valueOutMinMax.sourceHeight ),
      new TestParams.ParamDescConfig( Block.Params.sourceWidth,                this.valueOutMinMax.sourceWidth ),
      new TestParams.ParamDescConfig( Block.Params.sourceChannelCount,         this.valueOutMinMax.sourceChannelCount ),
      new TestParams.ParamDescConfig( Block.Params.stepCountRequested,         this.valueOutMinMax.stepCountRequested ),
      new TestParams.ParamDescConfig( Block.Params.pointwise1ChannelCountRate, this.valueOutMinMax.pointwise1ChannelCountRate ),
      new TestParams.ParamDescConfig( Block.Params.depthwiseFilterHeight,      this.valueOutMinMax.depthwiseFilterHeight ),
      new TestParams.ParamDescConfig( Block.Params.nActivationId,              this.valueOutMinMax.nActivationId ),
      new TestParams.ParamDescConfig( Block.Params.nActivationIdAtBlockEnd,    this.valueOutMinMax.nActivationIdAtBlockEnd ),
      new TestParams.ParamDescConfig( Block.Params.nWhetherShuffleChannel,     this.valueOutMinMax.nWhetherShuffleChannel ),
      new TestParams.ParamDescConfig( Block.Params.bKeepInputTensor,           this.valueOutMinMax.bKeepInputTensor ),
    ];

    yield *Base.ParamsGenerator.call( this, paramDescConfigArray );
  }

}

/**
 * The order when generate weightsFloat32Array[].
 *
 * This order could not be changed arbitrarily. It must be the same as the parameter extracting order of Block.initer().
 */
Base.paramsNameOrderArray_Basic = [
  Block.Params.sourceHeight.paramName,
  Block.Params.sourceWidth.paramName,
  Block.Params.sourceChannelCount.paramName,
  Block.Params.stepCountRequested.paramName,
  Block.Params.pointwise1ChannelCountRate.paramName,
  Block.Params.depthwiseFilterHeight.paramName,
  Block.Params.nActivationId.paramName,
  Block.Params.nActivationIdAtBlockEnd.paramName,
  Block.Params.nWhetherShuffleChannel.paramName,
  Block.Params.bKeepInputTensor.paramName,
];
<|endoftext|>