<commit_before>// Javascript for Jamoma: assemble the gui component
// By Timothy Place, Copyright  2005
// License: GNU LGPL

/*******************************************************************
 * SETUP
 *******************************************************************/

// CONSTANTS
const HEIGHT_1U = 60;						// pixel dimensions
const WIDTH_HALF = 255;						// ...
const NUM_DEFAULT_INLETS_AND_OUTLETS = 32;	// number of these in the jmod.gui

// GLOBALS
var attr_module_type = "audio";
var attr_skin = "default";
var attr_option_no_panel = false;
var attr_num_inputs = 1;
var attr_num_outputs = 1;
var attr_meter_toggle = 1;
var attr_preview = 1;
var attr_bypass = 0;
var attr_mute = 0;
var attr_freeze = 0;
var local_token = 0;
var	num_channels;
var attr_size = "1Uh";
var height = 1;
var width = "half";
var	p = this.patcher;
var offset_x = 0;
var offset_y = 0;
var has_run = 0;				// flag indicating that this module has previously been built

// CONFIGURATION
inlets = 1;
outlets = 5;

// INITIALIZATION
function init()
{
	// set up assistance strings
	setinletassist(0, "set attributes, etc.");
	setoutletassist(0, "connect to a thispatcher object");
	setoutletassist(1, "connect to a bg pictctrl");
	setoutletassist(2, "connect to the audio control panel");
	setoutletassist(3, "connect to the module's umenu");
	setoutletassist(4, "messages to be sent to the module's hub");

	// Process Arguments
	if(jsarguments.length > 1)
		local_token = jsarguments[1];
	else
		post("WARNING: jmod.gui.constructor requires a localized token!\n");
}
init.local = 1;		// hide the init function
init();				// run the init function

/*******************************************************************
 * METHODS
 *******************************************************************/

/* BANG: build the gui component
 *
 *	There are some things here that may not seem very elegant.  As of
 *	Max 4.5.4, New items scripted into a patch, that is loaded in a
 *	bpatcher within a bpatcher (such as jmod.gui), are scripted into place
 *	using the coordinates of the patcher window - not the bpatcher's
 *	viewable region.  This means that a number of objects are pre-included
 *	in the jmod.gui patch and then deleted or moved dynamically, rather than
 *	creating what is needed.
 */
function bang()
{
	// Choose the skin, if needed
	if(attr_skin == "default"){
		if(attr_module_type == "audio")
			attr_skin = "metal.black";
		else if(attr_module_type == "video")
			attr_skin = "metal";
		else if(attr_module_type == "control")
			attr_skin = "metal.blue";
	}

	// Change the background graphic to match the skin (object autosizes to match it)
	outlet(1, "picture", "jmod.bg." + attr_skin + "." + attr_size + ".pct");

	if(attr_module_type == "audio"){

		// send the num_channels to the audio_component patch
		//	that patch will then script in the jmod.gain~ and connect it

		if(has_run == 0){
//			outlet(2, num_channels);	// send the number of channels to the controls
// JUST MOVED DOWN BELOW

			// move the controls if neccessary
			if(width == 1)
				outlet(0, "script", "offset", "controls", -255, 0);

			// delete extra inlets and outlets
			for(i=num_channels*2;i<NUM_DEFAULT_INLETS_AND_OUTLETS;i++){
				outlet(0, "script", "delete", "inlet_"+(i+1));
				outlet(0, "script", "delete", "outlet_"+(i+1));
			}

			// delete the video preview window
			outlet(0, "script", "delete", "pwindow");

			// connect inlets and outlets
			for(i=0; i<num_channels; i++){
				outlet(0, "script", "hidden", "connect", "inlet_"+(i+1), 0, "outlet_"+(i+1), 0);
				outlet(0, "script", "hidden", "connect", "controls", i, "outlet_"+(num_channels+i+1), 0);
			}

			// handle any relevant options
			if(attr_option_no_panel)
				outlet(0, "script", "delete", "controls");

			// Setup the Menu
			outlet(3, "clear");
			outlet(3, "append", "Defeat Signal Meters");
			outlet(3, "append", "Clear Signal Meters");
			outlet(3, "append", "-");
			outlet(3, "append", "Load Settings...");
			outlet(3, "append", "Save Settings...");
			outlet(3, "append", "Restore Default Settings");
			outlet(3, "append", "-");
			outlet(3, "append", "Open Online Reference");
			outlet(3, "append", "View Internal Components");

			outlet(2, num_channels);	// send the number of channels to the controls
		}
	}
	else if(attr_module_type == "video"){
		if(has_run == 0){
			// Create the standard messages
			outlet(0, "script", "hidden", "new", "param_preview", "jmod.parameter.mxt", local_token, "preview");
			outlet(0, "script", "hidden", "new", "param_bypass", "jmod.parameter.mxt", local_token, "bypass");
			outlet(0, "script", "hidden", "new", "param_freeze", "jmod.parameter.mxt", local_token, "freeze");
			outlet(0, "script", "hidden", "new", "param_mute", "jmod.parameter.mxt", local_token, "mute");

			// Delete the audio controls
			outlet(0, "script", "delete", "controls");

			// delete extra inlets and outlets
			for(i=num_channels;i<NUM_DEFAULT_INLETS_AND_OUTLETS;i++){
				outlet(0, "script", "delete", "inlet_"+(i+1));
				outlet(0, "script", "delete", "outlet_"+(i+1));
			}

			// move the preview window if neccessary
			if(width == 1)
				outlet(0, "script", "offset", "pwindow", -255, 0);

			// Setup the Menu
			outlet(3, "clear");
			outlet(3, "append", "Preview Output");
			outlet(3, "append", "Force a Frame of Output");
			outlet(3, "append", "-");
			outlet(3, "append", "Bypass");
			outlet(3, "append", "Freeze");
			outlet(3, "append", "Mute");
			outlet(3, "append", "-");
			outlet(3, "append", "Load Settings...");
			outlet(3, "append", "Save Settings...");
			outlet(3, "append", "Restore Default Settings");
			outlet(3, "append", "-");
			outlet(3, "append", "Open Online Reference");
			outlet(3, "append", "View Internal Components");
		}
	}
	else{	// attr_module_type == "control"
		if(has_run == 0){

			// Delete the audio controls
			outlet(0, "script", "delete", "controls");

			// delete the video preview window
			outlet(0, "script", "delete", "pwindow");

			// Delete the inlets and outlets
			for(i=0;i<NUM_DEFAULT_INLETS_AND_OUTLETS;i++){
				outlet(0, "script", "delete", "inlet_"+(i+1));
				outlet(0, "script", "delete", "outlet_"+(i+1));
			}

			// Setup the Menu
			outlet(3, "clear");
			outlet(3, "append", "Load Settings...");
			outlet(3, "append", "Save Settings...");
			outlet(3, "append", "Restore Default Settings");
			outlet(3, "append", "-");
			outlet(3, "append", "Open Online Reference");
			outlet(3, "append", "View Internal Components");
		}
	}

	// make sure everything is visible
	outlet(0, "script", "sendtoback", "background");
	outlet(0, "script", "sendtoback", "menu");
	outlet(0, "script", "sendtoback", "param_reference");

	has_run = 1;
}

// Method: INT - input from the menu!
function msg_int(value)
{
	if(attr_module_type == "audio"){
		switch(value){
			case 0:
				if(attr_meter_toggle == 1) attr_meter_toggle = 0;
				else if(attr_meter_toggle == 0) attr_meter_toggle = 1;
				outlet(4, "defeat_meters", !attr_meter_toggle);
				outlet(3, "checkitem", 0, !attr_meter_toggle);
				break;
			case 1: outlet(4, "clear_meters"); break;
			case 3: outlet(4, "load_settings"); break;
			case 4: outlet(4, "save_settings"); break;
			case 5: outlet(4, "restore_defaults"); break;
			case 7: outlet(4, "help"); break;
			case 8: outlet(4, "view_internals"); break;
		}
	}
	else if(attr_module_type == "video"){
		switch(value){
			case 0:
				if(attr_preview == 1) attr_preview = 0;
				else if(attr_preview == 0) attr_preview = 1;
				outlet(4, "preview", attr_preview);
				outlet(3, "checkitem", 0, attr_preview);
				break;
			case 1: outlet(4, "force"); break;
			case 3:
				if(attr_bypass == 1) attr_bypass = 0;
				else if(attr_bypass == 0){
					attr_bypass = 1;
					attr_freeze = 0;
					attr_mute = 0;
				}
				outlet(4, "bypass", attr_bypass);
				break;
			case 4:
				if(attr_freeze == 1) attr_freeze = 0;
				else if(attr_freeze == 0){
					attr_bypass = 0;
					attr_freeze = 1;
					attr_mute = 0;
				}
				outlet(4, "freeze", attr_freeze);
				break;
			case 5:
				if(attr_mute == 1) attr_mute = 0;
				else if(attr_mute == 0){
					attr_bypass = 0;
					attr_freeze = 0;
					attr_mute = 1;
				}
				outlet(4, "mute", attr_mute);
				break;
			case 7: outlet(4, "load_settings"); break;
			case 8: outlet(4, "save_settings"); break;
			case 9: outlet(4, "restore_defaults"); break;
			case 11: outlet(4, "help"); break;
			case 12: outlet(4, "view_internals"); break;
		}
		outlet(3, "checkitem", 3, attr_bypass);
		outlet(3, "checkitem", 4, attr_freeze);
		outlet(3, "checkitem", 5, attr_mute);
	}
	else if(attr_module_type == "control"){
		switch(value){
			case 0: outlet(4, "load_settings"); break;
			case 1: outlet(4, "save_settings"); break;
			case 2: outlet(4, "restore_defaults"); break;
			case 4: outlet(4, "help"); break;
			case 5: outlet(4, "view_internals"); break;
		}
	}
}

// Set attribute
function module_type(message)
{
	attr_module_type = message;
}

// Set attribute
function options(message)
{
	if(message == "no_panel")
		attr_option_no_panel = true
}

// Set attribute
function skin(message)
{
	attr_skin = message;
}

// Set attribute
function size(message)
{
	attr_size = message;
// DO SOME SORT OF PATTERN MATCHING HERE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	height = 60;  // make this dynamic!

	if(attr_size.match(/-half/))
		width = 1;
	else
		width = 2;
}

// Set attribute
function num_inputs(message)
{
	attr_num_inputs = message;
	set_num_channels();
}

// Set attribute
function num_outputs(message)
{
	attr_num_outputs = message;
	set_num_channels();
}

// Sets the number of channels based on the number of inputs and outputs
function set_num_channels()
{
	if(attr_num_outputs > attr_num_inputs)
		num_channels = attr_num_outputs;
	else
		num_channels = attr_num_inputs;
}

function anything()
{
	;
}

<commit_msg>fixed bugs in the js constructor that caused the standard video parameters to not be instantiated correctly in the gui<commit_after>// Javascript for Jamoma: assemble the gui component
// By Timothy Place, Copyright  2005
// License: GNU LGPL

/*******************************************************************
 * SETUP
 *******************************************************************/

// CONSTANTS
const HEIGHT_1U = 60;						// pixel dimensions
const WIDTH_HALF = 255;						// ...
const NUM_DEFAULT_INLETS_AND_OUTLETS = 32;	// number of these in the jmod.gui

// GLOBALS
var attr_module_type = "audio";
var attr_skin = "default";
var attr_option_no_panel = false;
var attr_num_inputs = 1;
var attr_num_outputs = 1;
var attr_meter_toggle = 1;
var attr_preview = 1;
var attr_bypass = 0;
var attr_mute = 0;
var attr_freeze = 0;
var local_token = 0;
var	num_channels;
var attr_size = "1Uh";
var height = 1;
var width = "half";
var	p = this.patcher;
var offset_x = 0;
var offset_y = 0;
var has_run = 0;				// flag indicating that this module has previously been built

// CONFIGURATION
inlets = 1;
outlets = 5;

// INITIALIZATION
function init()
{
	// set up assistance strings
	setinletassist(0, "set attributes, etc.");
	setoutletassist(0, "connect to a thispatcher object");
	setoutletassist(1, "connect to a bg pictctrl");
	setoutletassist(2, "connect to the audio control panel");
	setoutletassist(3, "connect to the module's umenu");
	setoutletassist(4, "messages to be sent to the module's hub");

	// Process Arguments
	if(jsarguments.length > 1)
		local_token = jsarguments[1];
	else
		post("WARNING: jmod.gui.constructor requires a localized token!\n");
}
init.local = 1;		// hide the init function
init();				// run the init function

/*******************************************************************
 * METHODS
 *******************************************************************/

/* BANG: build the gui component
 *
 *	There are some things here that may not seem very elegant.  As of
 *	Max 4.5.4, New items scripted into a patch, that is loaded in a
 *	bpatcher within a bpatcher (such as jmod.gui), are scripted into place
 *	using the coordinates of the patcher window - not the bpatcher's
 *	viewable region.  This means that a number of objects are pre-included
 *	in the jmod.gui patch and then deleted or moved dynamically, rather than
 *	creating what is needed.
 */
function bang()
{
	// Choose the skin, if needed
	if(attr_skin == "default"){
		if(attr_module_type == "audio")
			attr_skin = "metal.black";
		else if(attr_module_type == "video")
			attr_skin = "metal";
		else if(attr_module_type == "control")
			attr_skin = "metal.blue";
	}

	// Change the background graphic to match the skin (object autosizes to match it)
	outlet(1, "picture", "jmod.bg." + attr_skin + "." + attr_size + ".pct");

	if(attr_module_type == "audio"){

		// send the num_channels to the audio_component patch
		//	that patch will then script in the jmod.gain~ and connect it

		if(has_run == 0){
//			outlet(2, num_channels);	// send the number of channels to the controls
// JUST MOVED DOWN BELOW

			// move the controls if neccessary
			if(width == 1)
				outlet(0, "script", "offset", "controls", -255, 0);

			// delete extra inlets and outlets
			for(i=num_channels*2;i<NUM_DEFAULT_INLETS_AND_OUTLETS;i++){
				outlet(0, "script", "delete", "inlet_"+(i+1));
				outlet(0, "script", "delete", "outlet_"+(i+1));
			}

			// delete the video preview window
			outlet(0, "script", "delete", "pwindow");

			// connect inlets and outlets
			for(i=0; i<num_channels; i++){
				outlet(0, "script", "hidden", "connect", "inlet_"+(i+1), 0, "outlet_"+(i+1), 0);
				outlet(0, "script", "hidden", "connect", "controls", i, "outlet_"+(num_channels+i+1), 0);
			}

			// handle any relevant options
			if(attr_option_no_panel)
				outlet(0, "script", "delete", "controls");

			// Setup the Menu
			outlet(3, "clear");
			outlet(3, "append", "Defeat Signal Meters");
			outlet(3, "append", "Clear Signal Meters");
			outlet(3, "append", "-");
			outlet(3, "append", "Load Settings...");
			outlet(3, "append", "Save Settings...");
			outlet(3, "append", "Restore Default Settings");
			outlet(3, "append", "-");
			outlet(3, "append", "Open Online Reference");
			outlet(3, "append", "View Internal Components");

			outlet(2, num_channels);	// send the number of channels to the controls
		}
	}
	else if(attr_module_type == "video"){
		if(has_run == 0){
			// Delete the audio controls
			outlet(0, "script", "delete", "controls");

			// Create the standard messages
			outlet(0, "script", "hidden", "new", "param_preview", "newex", 67, 278, 291, 196617,
				"jmod.parameter.mxt", local_token, "preview");
			outlet(0, "script", "hidden", "new", "param_bypass", "newex", 67, 278, 291, 196617,
				"jmod.parameter.mxt", local_token, "bypass");
			outlet(0, "script", "hidden", "new", "param_freeze", "newex", 67, 278, 291, 196617,
				"jmod.parameter.mxt", local_token, "freeze");
			outlet(0, "script", "hidden", "new", "param_mute", "newex", 67, 278, 291, 196617,
				"jmod.parameter.mxt", local_token, "mute");

			// delete extra inlets and outlets
			for(i=num_channels;i<NUM_DEFAULT_INLETS_AND_OUTLETS;i++){
				outlet(0, "script", "delete", "inlet_"+(i+1));
				outlet(0, "script", "delete", "outlet_"+(i+1));
			}

			// move the preview window if neccessary
			if(width == 1)
				outlet(0, "script", "offset", "pwindow", -255, 0);

			// Setup the Menu
			outlet(3, "clear");
			outlet(3, "append", "Preview Output");
			outlet(3, "append", "Force a Frame of Output");
			outlet(3, "append", "-");
			outlet(3, "append", "Bypass");
			outlet(3, "append", "Freeze");
			outlet(3, "append", "Mute");
			outlet(3, "append", "-");
			outlet(3, "append", "Load Settings...");
			outlet(3, "append", "Save Settings...");
			outlet(3, "append", "Restore Default Settings");
			outlet(3, "append", "-");
			outlet(3, "append", "Open Online Reference");
			outlet(3, "append", "View Internal Components");
		}
	}
	else{	// attr_module_type == "control"
		if(has_run == 0){

			// Delete the audio controls
			outlet(0, "script", "delete", "controls");

			// delete the video preview window
			outlet(0, "script", "delete", "pwindow");

			// Delete the inlets and outlets
			for(i=0;i<NUM_DEFAULT_INLETS_AND_OUTLETS;i++){
				outlet(0, "script", "delete", "inlet_"+(i+1));
				outlet(0, "script", "delete", "outlet_"+(i+1));
			}

			// Setup the Menu
			outlet(3, "clear");
			outlet(3, "append", "Load Settings...");
			outlet(3, "append", "Save Settings...");
			outlet(3, "append", "Restore Default Settings");
			outlet(3, "append", "-");
			outlet(3, "append", "Open Online Reference");
			outlet(3, "append", "View Internal Components");
		}
	}

	// make sure everything is visible
	outlet(0, "script", "sendtoback", "background");
	outlet(0, "script", "sendtoback", "menu");
	outlet(0, "script", "sendtoback", "param_reference");

	has_run = 1;
}

// Method: INT - input from the menu!
function msg_int(value)
{
	if(attr_module_type == "audio"){
		switch(value){
			case 0:
				if(attr_meter_toggle == 1) attr_meter_toggle = 0;
				else if(attr_meter_toggle == 0) attr_meter_toggle = 1;
				outlet(4, "defeat_meters", !attr_meter_toggle);
				outlet(3, "checkitem", 0, !attr_meter_toggle);
				break;
			case 1: outlet(4, "clear_meters"); break;
			case 3: outlet(4, "load_settings"); break;
			case 4: outlet(4, "save_settings"); break;
			case 5: outlet(4, "restore_defaults"); break;
			case 7: outlet(4, "help"); break;
			case 8: outlet(4, "view_internals"); break;
		}
	}
	else if(attr_module_type == "video"){
		switch(value){
			case 0:
				if(attr_preview == 1) attr_preview = 0;
				else if(attr_preview == 0) attr_preview = 1;
				outlet(4, "preview", attr_preview);
				outlet(3, "checkitem", 0, attr_preview);
				break;
			case 1: outlet(4, "force"); break;
			case 3:
				if(attr_bypass == 1) attr_bypass = 0;
				else if(attr_bypass == 0){
					attr_bypass = 1;
					attr_freeze = 0;
					attr_mute = 0;
				}
				outlet(4, "bypass", attr_bypass);
				break;
			case 4:
				if(attr_freeze == 1) attr_freeze = 0;
				else if(attr_freeze == 0){
					attr_bypass = 0;
					attr_freeze = 1;
					attr_mute = 0;
				}
				outlet(4, "freeze", attr_freeze);
				break;
			case 5:
				if(attr_mute == 1) attr_mute = 0;
				else if(attr_mute == 0){
					attr_bypass = 0;
					attr_freeze = 0;
					attr_mute = 1;
				}
				outlet(4, "mute", attr_mute);
				break;
			case 7: outlet(4, "load_settings"); break;
			case 8: outlet(4, "save_settings"); break;
			case 9: outlet(4, "restore_defaults"); break;
			case 11: outlet(4, "help"); break;
			case 12: outlet(4, "view_internals"); break;
		}
		outlet(3, "checkitem", 3, attr_bypass);
		outlet(3, "checkitem", 4, attr_freeze);
		outlet(3, "checkitem", 5, attr_mute);
	}
	else if(attr_module_type == "control"){
		switch(value){
			case 0: outlet(4, "load_settings"); break;
			case 1: outlet(4, "save_settings"); break;
			case 2: outlet(4, "restore_defaults"); break;
			case 4: outlet(4, "help"); break;
			case 5: outlet(4, "view_internals"); break;
		}
	}
}

// Set attribute
function module_type(message)
{
	attr_module_type = message;
}

// Set attribute
function options(message)
{
	if(message == "no_panel")
		attr_option_no_panel = true
}

// Set attribute
function skin(message)
{
	attr_skin = message;
}

// Set attribute
function size(message)
{
	attr_size = message;
// DO SOME SORT OF PATTERN MATCHING HERE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	height = 60;  // make this dynamic!

	if(attr_size.match(/-half/))
		width = 1;
	else
		width = 2;
}

// Set attribute
function num_inputs(message)
{
	attr_num_inputs = message;
	set_num_channels();
}

// Set attribute
function num_outputs(message)
{
	attr_num_outputs = message;
	set_num_channels();
}

// Sets the number of channels based on the number of inputs and outputs
function set_num_channels()
{
	if(attr_num_outputs > attr_num_inputs)
		num_channels = attr_num_outputs;
	else
		num_channels = attr_num_inputs;
}

function anything()
{
	;
}

<|endoftext|>


<commit_before>/**
 *  KitScript - A User Script Manager For Safari
 *
 *  Greasemonkey.js - Javascript file containing Greasemonkey classes
 *  (by Prototype.js) used globally in the extension & implementing core
 *  Greasemonkey API.
 *
 *  @author Seraf Dos Santos <webmaster@cyb3r.ca>
 *  @copyright 2011-2012 Seraf Dos Santos - All rights reserved.
 *  @license MIT License
 *  @version 0.1
 */

//"use strict";

/**
 *  KSGMException (KitScript Greasemonkey Exception Class)
 */
var KSGMException = Class.create({

    initialize: function (msg) {

        this._msg = msg;
    },
    getMessage: function () {

        return this._msg;
    }
});

/**
 *  KSGreasemonkeyMetadata (KitScript Greasemonkey Metadata Class)
 */
var KSGreasemonkeyMetadata = Class.create(_Utils, {

    initialize: function ($super) {

        $super();

        this._isHeaderValid = false;
        this._script = "";

        this._md_name = '';
        this._md_namespace = '';
        this._md_description = '';
        this._md_requires = [];
        this._md_includes = [];
        this._md_excludes = [];
        this._md_version = '';
        this._md_runat = KSGreasemonkeyMetadata.RUNAT_END;
    },
    loadScript: function (scriptStr) {

        this._script = scriptStr;

        if (!this.isHeaderValid())
            throw new KSGMException("User script metadata block is invalid.");
        else
            this.parseMetadataBlock();
    },
    isHeaderValid: function () {

        this._isValid = /[\/]{2} ==UserScript==[^=]*==[\/]{1}UserScript==/m.test(this._script);

        return this._isValid;
    },
    parseMetadataBlock: function () {

        var _matches = /[\/]{2} ==UserScript==([^=]*)==[\/]{1}UserScript==/m.exec(this._script);

        var _lines = _matches[1].split("\n");

        for (var i=0; i<_lines.length; i++) {
            var _line = _lines[i].trim();

            if (/[\/]{2} \@name (.*)/gi.test(_line) === true) {

                this._md_name = /[\/]{2} \@name (.*)/gi.exec(_line)[1].trim();
            } else if (/[\/]{2} \@namespace (.*)/gi.test(_line) === true) {

                this._md_namespace = /[\/]{2} \@namespace (.*)/gi.exec(_line)[1].trim();
            } else if (/[\/]{2} \@description (.*)/gi.test(_line) === true) {

                this._md_description = /[\/]{2} \@description (.*)/gi.exec(_line)[1].trim();
            } else if (/[\/]{2} \@require (.*)/gi.test(_line) === true) {

                this._md_requires.push(/[\/]{2} \@require (.*)/gi.exec(_line)[1].trim());
            } else if (/[\/]{2} \@include (.*)/gi.test(_line) === true) {

                this._md_includes.push(/[\/]{2} \@include (.*)/gi.exec(_line)[1].trim());
            } else if (/[\/]{2} \@exclude (.*)/gi.test(_line) === true) {

                this._md_excludes.push(/[\/]{2} \@exclude (.*)/gi.exec(_line)[1].trim());
            } else if (/[\/]{2} \@version (.*)/gi.test(_line) === true) {

                this._md_version = /[\/]{2} \@version (.*)/gi.exec(_line)[1].trim();
            } else if (/[\/]{2} \@run\-at (.*)/gi.test(_line) === true) {

                this._md_runat = /[\/]{2} \@run\-at (.*)/gi.exec(_line)[1].trim();
            }
        }
    },

    /**
     *  =========================== SUPPORTED IN v0.1 ==========================
     *  === v === v === v === v === v === v === v === v === v === v === v === v
     */

    /**
     *  @name string – KS Mandatory
     *
     *  - The combination of namespace and name is the unique identifier for a Greasemonkey script.
     *
     *  @returns String
     */
    getName: function () {

        return this._md_name;
    },
    /**
     *  @namespace string – KS Mandatory
     *
     *  - The combination of namespace and name is the unique identifier for a Greasemonkey script.
     *
     *  @returns String
     */
    getNamespace: function () {

        return this._md_namespace;
    },
    /**
     *  @description string – KS Mandatory
     *
     *  @returns String
     */
    getDescription: function () {

        return this._md_description;
    },
    /**
     *  @requires url – Optional
     *
     *  @returns Array
     */
    getRequires: function () {

        return this._md_requires;
    },
    /**
     *  @includes pattern – Optional
     *
     *  - There can be any number of @include rules in a script.
     *  - If no include rule is provided, @include * is assumed.
     *
     *  @returns Array
     */
    getIncludes: function () {

        return this._md_includes;
    },
    /**
     *  @excludes pattern – Optional
     *
     *  - There can be any number of @exclude rules in a script.
     *
     *  @returns Array
     */
    getExcludes: function () {

        return this._md_excludes;
    },
    /**
     *  @version float – Optional
     *
     *  - This is the version of the script, which should be treated like a
     *      firefox extension version, and maintain the same syntax.
     *
     *  KS v0.1:
     *  - No auto-update implemented
     *
     *  @returns String
     */
    getVersion: function () {

        return this._md_version;
    },
    /**
     *  @run-at "document-end" | "document-start"
     *
     *  - Supports two values: document-end and document-start.
     *  - "document-end" is the standard behavior that Greasemonkey has always had.
     *
     *  @returns String
     */
    getRunAt: function () {

        return this._md_runat;
    },

    /**
     *  ========================================================================
     *  ===================== SUPPORTED IN FUTUR VERSIONS ======================
     *  ========================================================================
     */

    /**
     *  @icon url
     *
     *  @returns String
     */
    getIcon: function () {

        var matches = /[\/]{2} \@icon (.*)/gi.exec(this._script);

        return matches[1];
    },
    /**
     *  @match pattern
     *
     *  @returns Array
     */
    getMatches: function () {

        var _matches = [];

        var matches = /[\/]{2} \@match (.*)/gi.exec(this._script);

        for (var i = 1; i < matches.length; i++) {

            _matches.push(matches[i]);
        }

        return _matches;
    },
    /**
     *  @resource url
     *
     *  @returns Array
     */
    getResources: function () {

        var _resources = [];

        var matches = /[\/]{2} \@resource (.*) (.*)/gi.exec(this._script);

        for (var i = 1; i < matches.length; i++) {

            _resources.push(new Array(matches[i], matches[i+1]));
        }

        return _resources;
    },
    /**
     *  @unwrap void
     *
     *  - This key is strongly recommended to only be used for debugging purposes.
     *
     *  @returns Boolean
     */
    hasUnwrap: function () {

        var _hasUnwrap = /[\/]{2} \@unwrap (.*)/gi.test(this._script);

        return _hasUnwrap;
    }
});

KSGreasemonkeyMetadata.RUNAT_END = 'document-end';
KSGreasemonkeyMetadata.RUNAT_START = 'document-start';

/**
 *  KSGreasemonkeyAPI (KitScript Greasemonkey API Class)
 */
var KSGreasemonkeyAPI = Class.create(_Utils, {

    initialize: function ($super) {

        $super();
    }
});

/**
 *  ============================================================================
 *  ======================== Greasemonkey API Functions ========================
 *  ======================== Supported In Futur Versions =======================
 *  ============================================================================
 */

/**
 *  @param string name
 */
function GM_deleteValue(name) {

}

/**
 *  @param string name
 *  @param mixed defaultVal Default result to be returned
 */
function GM_getValue(name, defaultVal) {

}

function GM_listValues() {

}

/**
 *  @param string name
 *  @param string value
 */
function GM_setValues(name, value) {

}

/**
 *  @param string resource Resource name
 */
function GM_getResourceText(resource) {

}

/**
 *  @param string resource Resource name
 */
function GM_getResourceURL(resource) {

}

/**
 *  @param string css String of CSS
 */
function GM_addStyle(css) {

}

/**
 *  @param boolean binary
 *  @param string data
 *  @param object headers
 *  @param string method
 *  @param function onAbort
 *  @param function onError
 *  @param function onLoad
 *  @param function onProgress
 *  @param function onReadyStateChange
 *  @param string overideMimeType
 *  @param string password
 *  @param boolean synchronous
 *  @param object upload
 *  @param string url
 *  @param string user
 */
function GM_xmlhttpRequest(binary,data,headers,method,onAbort,onError,onLoad,onProgress,onReadyStateChange,overideMimeType,password,synchronous,upload,url,user) {

}

/**
 *  @param string message
 */
function GM_log(message) {

}

/**
 *  @param string url
 */
function GM_openInTab(url) {

}

/**
 *  @param string caption
 *  @param function commandFunc
 *  @param string accessKey
 */
function GMregisterMenuCommand(caption,commandFunc,accessKey) {

}
<commit_msg>Better patterns for header returns<commit_after>/**
 *  KitScript - A User Script Manager For Safari
 *
 *  Greasemonkey.js - Javascript file containing Greasemonkey classes
 *  (by Prototype.js) used globally in the extension & implementing core
 *  Greasemonkey API.
 *
 *  @author Seraf Dos Santos <webmaster@cyb3r.ca>
 *  @copyright 2011-2012 Seraf Dos Santos - All rights reserved.
 *  @license MIT License
 *  @version 0.1
 */

//"use strict";

/**
 *  KSGMException (KitScript Greasemonkey Exception Class)
 */
var KSGMException = Class.create({

    initialize: function (msg) {

        this._msg = msg;
    },
    getMessage: function () {

        return this._msg;
    }
});

/**
 *  KSGreasemonkeyMetadata (KitScript Greasemonkey Metadata Class)
 */
var KSGreasemonkeyMetadata = Class.create(_Utils, {

    initialize: function ($super) {

        $super();

        this._isHeaderValid = false;
        this._script = "";

        this._md_name = '';
        this._md_namespace = '';
        this._md_description = '';
        this._md_requires = [];
        this._md_includes = [];
        this._md_excludes = [];
        this._md_version = '';
        this._md_runat = KSGreasemonkeyMetadata.RUNAT_END;
    },
    loadScript: function (scriptStr) {

        this._script = scriptStr;

        if (!this.isHeaderValid())
            throw new KSGMException("User script metadata block is invalid.");
        else
            this.parseMetadataBlock();
    },
    isHeaderValid: function () {

        this._isValid = /[\/]{2} ==UserScript==[^=]*==[\/]{1}UserScript==/m.test(this._script);

        return this._isValid;
    },
    parseMetadataBlock: function () {

        var _matches = /[\/]{2} ==UserScript==([^=]*)==[\/]{1}UserScript==/m.exec(this._script);

        var _lines = _matches[1].split("\n");

        for (var i=0; i<_lines.length; i++) {
            var _line = _lines[i].trim();

            if (/^[\/]{2} \@name (.*)$/gi.test(_line) === true) {

                this._md_name = /^[\/]{2} \@name (.*)$/gi.exec(_line)[1].trim();
            } else if (/^[\/]{2} \@namespace (.*)$/gi.test(_line) === true) {

                this._md_namespace = /^[\/]{2} \@namespace (.*)$/gi.exec(_line)[1].trim();
            } else if (/^[\/]{2} \@description (.*)$/gi.test(_line) === true) {

                this._md_description = /^[\/]{2} \@description (.*)$/gi.exec(_line)[1].trim();
            } else if (/^[\/]{2} \@require (.*)$/gi.test(_line) === true) {

                this._md_requires.push(/^[\/]{2} \@require (.*)$/gi.exec(_line)[1].trim());
            } else if (/^[\/]{2} \@include (.*)$/gi.test(_line) === true) {

                this._md_includes.push(/^[\/]{2} \@include (.*)$/gi.exec(_line)[1].trim());
            } else if (/^[\/]{2} \@exclude (.*)$/gi.test(_line) === true) {

                this._md_excludes.push(/^[\/]{2} \@exclude (.*)$/gi.exec(_line)[1].trim());
            } else if (/^[\/]{2} \@version (.*)$/gi.test(_line) === true) {

                this._md_version = /^[\/]{2} \@version (.*)$/gi.exec(_line)[1].trim();
            } else if (/^[\/]{2} \@run\-at (.*)$/gi.test(_line) === true) {

                this._md_runat = /^[\/]{2} \@run\-at (.*)$/gi.exec(_line)[1].trim();
            }
        }
    },

    /**
     *  =========================== SUPPORTED IN v0.1 ==========================
     *  === v === v === v === v === v === v === v === v === v === v === v === v
     */

    /**
     *  @name string – KS Mandatory
     *
     *  - The combination of namespace and name is the unique identifier for a Greasemonkey script.
     *
     *  @returns String
     */
    getName: function () {

        return this._md_name;
    },
    /**
     *  @namespace string – KS Mandatory
     *
     *  - The combination of namespace and name is the unique identifier for a Greasemonkey script.
     *
     *  @returns String
     */
    getNamespace: function () {

        return this._md_namespace;
    },
    /**
     *  @description string – KS Mandatory
     *
     *  @returns String
     */
    getDescription: function () {

        return this._md_description;
    },
    /**
     *  @requires url – Optional
     *
     *  @returns Array
     */
    getRequires: function () {

        return this._md_requires;
    },
    /**
     *  @includes pattern – Optional
     *
     *  - There can be any number of @include rules in a script.
     *  - If no include rule is provided, @include * is assumed.
     *
     *  @returns Array
     */
    getIncludes: function () {

        if (this._md_includes.length > 0)
            return this._md_includes;
        else
            return ['*'];
    },
    /**
     *  @excludes pattern – Optional
     *
     *  - There can be any number of @exclude rules in a script.
     *
     *  @returns Array
     */
    getExcludes: function () {

        return this._md_excludes;
    },
    /**
     *  @version float – Optional
     *
     *  - This is the version of the script, which should be treated like a
     *      firefox extension version, and maintain the same syntax.
     *
     *  KS v0.1:
     *  - No auto-update implemented
     *
     *  @returns String
     */
    getVersion: function () {

        return this._md_version;
    },
    /**
     *  @run-at "document-end" | "document-start"
     *
     *  - Supports two values: document-end and document-start.
     *  - "document-end" is the standard behavior that Greasemonkey has always had.
     *
     *  @returns String
     */
    getRunAt: function () {

        if (this._md_runat.length > 0 && (this._md_runat.toLowerCase() == KSGreasemonkeyMetadata.RUNAT_END.toLowerCase() || this._md_runat.toLowerCase() == KSGreasemonkeyMetadata.RUNAT_START.toLowerCase()))
            return this._md_runat;
        else
            return KSGreasemonkeyMetadata.RUNAT_END;
    },

    /**
     *  ========================================================================
     *  ===================== SUPPORTED IN FUTUR VERSIONS ======================
     *  ========================================================================
     */

    /**
     *  @icon url
     *
     *  @returns String
     */
    getIcon: function () {

        var matches = /[\/]{2} \@icon (.*)/gi.exec(this._script);

        return matches[1];
    },
    /**
     *  @match pattern
     *
     *  @returns Array
     */
    getMatches: function () {

        var _matches = [];

        var matches = /[\/]{2} \@match (.*)/gi.exec(this._script);

        for (var i = 1; i < matches.length; i++) {

            _matches.push(matches[i]);
        }

        return _matches;
    },
    /**
     *  @resource url
     *
     *  @returns Array
     */
    getResources: function () {

        var _resources = [];

        var matches = /[\/]{2} \@resource (.*) (.*)/gi.exec(this._script);

        for (var i = 1; i < matches.length; i++) {

            _resources.push(new Array(matches[i], matches[i+1]));
        }

        return _resources;
    },
    /**
     *  @unwrap void
     *
     *  - This key is strongly recommended to only be used for debugging purposes.
     *
     *  @returns Boolean
     */
    hasUnwrap: function () {

        var _hasUnwrap = /[\/]{2} \@unwrap (.*)/gi.test(this._script);

        return _hasUnwrap;
    }
});

KSGreasemonkeyMetadata.RUNAT_END = 'document-end';
KSGreasemonkeyMetadata.RUNAT_START = 'document-start';

/**
 *  KSGreasemonkeyAPI (KitScript Greasemonkey API Class)
 */
var KSGreasemonkeyAPI = Class.create(_Utils, {

    initialize: function ($super) {

        $super();
    }
});

/**
 *  ============================================================================
 *  ======================== Greasemonkey API Functions ========================
 *  ======================== Supported In Futur Versions =======================
 *  ============================================================================
 */

/**
 *  @param string name
 */
function GM_deleteValue(name) {

}

/**
 *  @param string name
 *  @param mixed defaultVal Default result to be returned
 */
function GM_getValue(name, defaultVal) {

}

function GM_listValues() {

}

/**
 *  @param string name
 *  @param string value
 */
function GM_setValues(name, value) {

}

/**
 *  @param string resource Resource name
 */
function GM_getResourceText(resource) {

}

/**
 *  @param string resource Resource name
 */
function GM_getResourceURL(resource) {

}

/**
 *  @param string css String of CSS
 */
function GM_addStyle(css) {

}

/**
 *  @param boolean binary
 *  @param string data
 *  @param object headers
 *  @param string method
 *  @param function onAbort
 *  @param function onError
 *  @param function onLoad
 *  @param function onProgress
 *  @param function onReadyStateChange
 *  @param string overideMimeType
 *  @param string password
 *  @param boolean synchronous
 *  @param object upload
 *  @param string url
 *  @param string user
 */
function GM_xmlhttpRequest(binary,data,headers,method,onAbort,onError,onLoad,onProgress,onReadyStateChange,overideMimeType,password,synchronous,upload,url,user) {

}

/**
 *  @param string message
 */
function GM_log(message) {

}

/**
 *  @param string url
 */
function GM_openInTab(url) {

}

/**
 *  @param string caption
 *  @param function commandFunc
 *  @param string accessKey
 */
function GMregisterMenuCommand(caption,commandFunc,accessKey) {

}
<|endoftext|>


<commit_before>var $ = require('../internals/export');
var getPrototypeOf = require('../internals/object-get-prototype-of');
var setPrototypeOf = require('../internals/object-set-prototype-of');
var create = require('../internals/object-create');
var createPropertyDescriptor = require('../internals/create-property-descriptor');
var iterate = require('../internals/iterate');
var createNonEnumerableProperty = require('../internals/create-non-enumerable-property');
var anObject = require('../internals/an-object');

var $AggregateError = function AggregateError(errors, message) {
  var that = this;
  if (!(that instanceof $AggregateError)) return new $AggregateError(errors, message);
  if (setPrototypeOf) {
    that = setPrototypeOf(new Error(message), getPrototypeOf(that));
  }
  var errorsArray = [];
  iterate(errors, errorsArray.push, errorsArray);
  createNonEnumerableProperty(that, 'errors', errorsArray);
  if (message !== undefined) createNonEnumerableProperty(that, 'message', String(message));
  return that;
};

$AggregateError.prototype = create(Error.prototype, {
  constructor: createPropertyDescriptor(5, $AggregateError),
  name: createPropertyDescriptor(5, 'AggregateError'),
  toString: createPropertyDescriptor(5, function toString() {
    var name = anObject(this).name;
    name = name === undefined ? 'AggregateError' : String(name);
    var message = this.message;
    message = message === undefined ? '' : String(message);
    return name + ': ' + message;
  })
});

$({ global: true }, {
  AggregateError: $AggregateError
});
<commit_msg>add `AggregateError#message`<commit_after>var $ = require('../internals/export');
var getPrototypeOf = require('../internals/object-get-prototype-of');
var setPrototypeOf = require('../internals/object-set-prototype-of');
var create = require('../internals/object-create');
var createPropertyDescriptor = require('../internals/create-property-descriptor');
var iterate = require('../internals/iterate');
var createNonEnumerableProperty = require('../internals/create-non-enumerable-property');
var anObject = require('../internals/an-object');

var $AggregateError = function AggregateError(errors, message) {
  var that = this;
  if (!(that instanceof $AggregateError)) return new $AggregateError(errors, message);
  if (setPrototypeOf) {
    that = setPrototypeOf(new Error(message), getPrototypeOf(that));
  }
  var errorsArray = [];
  iterate(errors, errorsArray.push, errorsArray);
  createNonEnumerableProperty(that, 'errors', errorsArray);
  if (message !== undefined) createNonEnumerableProperty(that, 'message', String(message));
  return that;
};

$AggregateError.prototype = create(Error.prototype, {
  constructor: createPropertyDescriptor(5, $AggregateError),
  message: createPropertyDescriptor(5, ''),
  name: createPropertyDescriptor(5, 'AggregateError'),
  toString: createPropertyDescriptor(5, function toString() {
    var name = anObject(this).name;
    name = name === undefined ? 'AggregateError' : String(name);
    var message = this.message;
    message = message === undefined ? '' : String(message);
    return name + ': ' + message;
  })
});

$({ global: true }, {
  AggregateError: $AggregateError
});
<|endoftext|>


<commit_before>define(function(require, exports, module) {
    "use strict";

    main.consumes = ["cdn.build"];
    return main;

    function main(options, imports, register) {
        var build = imports["cdn.build"];

        var fs = require("fs");
        var path = require("path");
        var mkdirp = require("mkdirp");
        var async = require("async");

        var root = path.join(build.cacheDir, build.version);

        var cache = {};
        build.setCache(cache);

        build.getPathConfig(build.version, function(err, pathConfig) {
            if (err) return done(err);
            var pending = 1;

            if (options.skin && options.config) {
                build.buildSkin(options.config, options.skin, pathConfig, save(["skin", options.config, options.skin + ".css"]));
            } else if (options.config) {
                var configs = options.config.split(/,\s*/);
                var configCache = options.skipDuplicates && {duplicates: []};
                var usedPlugins = options.copyStaticResources && Object.create(null);

                (function buildConfig() {
                    var config = configs.shift();
                    if (!config) {
                        var series = [];
                        if (usedPlugins)
                            series.push(copyStaticResources.bind(null, usedPlugins, pathConfig));
                        if (configCache && configCache.duplicates.length)
                            series.push(fs.writeFile.bind(fs, path.join(root, "config", "duplicates"), configCache.duplicates.join(" "), "utf8"));
                        series.push(done.bind(null, null));
                        return async.series(series);
                    }
                    var skins = options.withSkins;
                    if (skins === true || skins === "all")
                        skins = ["dark", "light", "dark-gray", "light-gray", "flat-light"];
                    else
                        skins = skins ? skins.split(/,\s*/) : [];

                    build.buildConfig(config, pathConfig, save(["config", path.basename(config) + ".js"], function next() {
                        var skin = skins.pop();
                        if (!skin) return buildConfig();
                        build.buildSkin(config, skin, pathConfig, save(["skin", config, skin + ".css"], next));
                    }), function(configName, data) {
                        var pluginPaths = data.map(function(p) {
                            return typeof p == "string" ? p : p.packagePath;
                        }).filter(Boolean).sort();

                        if (usedPlugins) {
                            pluginPaths.forEach(function(p) {
                                usedPlugins[p] = true;
                            });
                        }

                        if (!configCache) return;

                        if (!configCache.defaultConfig) {
                            configCache.defaultConfig = Object.create(null);
                            pluginPaths.forEach(function(p) {
                                configCache.defaultConfig[p] = true;
                            });
                            return false;
                        }

                        var isDuplicate = pluginPaths.every(function(p) {
                            return configCache.defaultConfig[p];
                        });

                        if (!isDuplicate) return false;

                        configCache.duplicates.push(configName);
                        process.nextTick(buildConfig);
                        return true;
                    });
                })();

            } else if (options.worker) {
                build.buildWorker(options.worker, pathConfig, save(["worker", options.worker + ".js"]));
            } else if (options.module) {
                if (options.module === "ace") {
                    listAceModules(pathConfig, function(module, next) {
                        if (next) pending++;
                        build.buildAce(module, pathConfig, function(err, result) {
                            save(["modules", module + ".js"], function(err) {
                                warn(err);
                                done();
                            })(err, result);
                            if (next) process.nextTick(next); // start building next without waiting for write
                        });
                    });
                } else if (options.module.match(/^ace\//)) {
                    build.buildAce(options.module, pathConfig, save(["modules", options.module + ".js"]));
                } else {
                    build.buildModule(options.module, pathConfig, save(["modules", options.module + ".js"]));
                }
            } else {
                done(new Error("unknown action"));
            }

            function warn(err) {
                if (err) console.warn(err);
            }

            function save(nameParts, cb) {
                return function(err, result) {
                    if (err) return cb(err);
                    var code = result.code;
                    nameParts.unshift(root);

                    writeFile(nameParts, code, cb || done);

                    if (result.sources && options.compressOutputDirPrefix) {
                        // compress and save in parallel
                        pending++;
                        var compress = require("architect-build/compress");
                        code = compress.withCache(result.sources, {
                            cache: cache,
                            obfuscate: options.obfuscate,
                            exclude: /(jsoniq|xquery)\.js$/
                        }).code;
                        nameParts[0] += "/" + options.compressOutputDirPrefix;
                        writeFile(nameParts, code, done);
                    }
                };
            }

            function writeFile(filename, code, cb) {
                if (typeof filename != "string")
                    filename = path.join.apply(path, filename);
                mkdirp(path.dirname(filename), function(err) {
                    if (err) return cb(err);
                    fs.writeFile(filename, code, "utf8", function(err) {
                        if (err) return cb(err);
                        console.log("file saved at", filename);
                        cb && cb();
                    });
                });
            }

            function done(err) {
                if (err) {
                    console.error(err);
                    process.exit(1);
                }
                pending--;
                if (pending <= 0)
                    process.exit();
            }
        });
        function listAceModules(pathConfig, cb) {
            // build async loaded ace modules
            var aceModules = ["vim", "emacs", "sublime"].map(function(x) {
                return "plugins/c9.ide.ace.keymaps/" + x + "/keymap";
            });
            var paths = {
                ace: __dirname + "/../../node_modules/ace/lib/ace",
                plugins: __dirname + "/../../plugins",
            };
            function addAceModules(path, excludePattern) {
                var parts = path.split("/");
                if (parts[0] == "ace") {
                    if (parts[1] == "modes" || parts[1] == "themes")
                        parts[1] = parts[1].slice(0, -1);
                }
                parts[0] = paths[parts[0]];
                var fsPath = parts.join("/");
                try {
                    var files = fs.readdirSync(fsPath);
                    files.filter(function(p) {
                        return !excludePattern.test(p) && !/[\s#]/.test(p) && /.*\.js$/.test(p);
                    }).forEach(function(p) {
                        aceModules.push(path + "/" + p.slice(0, -3));
                    });
                } catch(e) {}
            }

            var aceModulePaths = [
                "ace",
                "plugins/c9.ide.salesforce/salesforce.language"
            ];
            aceModulePaths.forEach(function(p) {
                addAceModules(p + "/modes", /_highlight_rules|_test|_worker|xml_util|_outdent|behaviour|completions/);
                addAceModules(p + "/themes", /_test/);
                addAceModules(p + "/ext", /_test/);
                addAceModules(p + "/snippets", /_test/);
            });

            function take() {
                var p = aceModules.pop();
                console.log("building ", p, aceModules.length);
                cb(p, aceModules.length && take);
            }
            take();
        }
        function copyStaticResources(usedPlugins, pathConfig, next) {
            var moduleDeps = require("architect-build/module-deps");
            var copy = require('architect-build/copy');
            // todo: use usedPlugins to filter out some of unneeded deps
            var roots = pathConfig.pathMap;
            Object.keys(roots).filter(function(p) {
                return !/(c9.docker|docs|smith|vfs-socket|engine.io|msgpack.js)$/.test(p);
            }).forEach(function(p) {
                var absPath = moduleDeps.resolveModulePath(p, pathConfig.pathMap);
                if (/^\/lib\/ace/.test(p))
                    return;
                copy(absPath, root + "/static/" + p, {
                    include: /^(libmarkdown.js|runners_list.js|builders_list.js|bootstrap.js)$/,
                    exclude: function(name, dir) {
                        if (/\.css$/.test(name)) {
                            if (!cache.files[dir + "/" + name]) {
                                console.log("\x1b [1A\x1b[0K", "adding file ", dir + "/" + name);
                                return false;
                            }
                        }
                        return /\.(jsx?|css|less|xml|ejs|prv|pub|sh)$|(^|[/])^(mock|example|\.[^/]*|package.json)[/]?$/.test(name);
                    },
                    onDir: function(e) { console.log("\x1b [1A\x1b[0K" + e) }
                });
            });
            next();
        }
    }
});
<commit_msg>Refactor language module loading<commit_after>define(function(require, exports, module) {
    "use strict";

    main.consumes = ["cdn.build"];
    return main;

    function main(options, imports, register) {
        var build = imports["cdn.build"];

        var fs = require("fs");
        var path = require("path");
        var mkdirp = require("mkdirp");
        var async = require("async");

        var root = path.join(build.cacheDir, build.version);

        var cache = {};
        build.setCache(cache);

        build.getPathConfig(build.version, function(err, pathConfig) {
            if (err) return done(err);
            var pending = 1;

            if (options.skin && options.config) {
                build.buildSkin(options.config, options.skin, pathConfig, save(["skin", options.config, options.skin + ".css"]));
            } else if (options.config) {
                var configs = options.config.split(/,\s*/);
                var configCache = options.skipDuplicates && {duplicates: []};
                var usedPlugins = options.copyStaticResources && Object.create(null);

                (function buildConfig() {
                    var config = configs.shift();
                    if (!config) {
                        var series = [];
                        if (usedPlugins)
                            series.push(copyStaticResources.bind(null, usedPlugins, pathConfig));
                        if (configCache && configCache.duplicates.length)
                            series.push(fs.writeFile.bind(fs, path.join(root, "config", "duplicates"), configCache.duplicates.join(" "), "utf8"));
                        series.push(done.bind(null, null));
                        return async.series(series);
                    }
                    var skins = options.withSkins;
                    if (skins === true || skins === "all")
                        skins = ["dark", "light", "dark-gray", "light-gray", "flat-light"];
                    else
                        skins = skins ? skins.split(/,\s*/) : [];

                    build.buildConfig(config, pathConfig, save(["config", path.basename(config) + ".js"], function next() {
                        var skin = skins.pop();
                        if (!skin) return buildConfig();
                        build.buildSkin(config, skin, pathConfig, save(["skin", config, skin + ".css"], next));
                    }), function(configName, data) {
                        var pluginPaths = data.map(function(p) {
                            return typeof p == "string" ? p : p.packagePath;
                        }).filter(Boolean).sort();

                        if (usedPlugins) {
                            pluginPaths.forEach(function(p) {
                                usedPlugins[p] = true;
                            });
                        }

                        if (!configCache) return;

                        if (!configCache.defaultConfig) {
                            configCache.defaultConfig = Object.create(null);
                            pluginPaths.forEach(function(p) {
                                configCache.defaultConfig[p] = true;
                            });
                            return false;
                        }

                        var isDuplicate = pluginPaths.every(function(p) {
                            return configCache.defaultConfig[p];
                        });

                        if (!isDuplicate) return false;

                        configCache.duplicates.push(configName);
                        process.nextTick(buildConfig);
                        return true;
                    });
                })();

            } else if (options.worker) {
                build.buildWorker(options.worker, pathConfig, save(["worker", options.worker + ".js"]));
            } else if (options.module) {
                if (options.module === "ace") {
                    listAceModules(pathConfig, function(module, next) {
                        if (next) pending++;
                        build.buildAce(module, pathConfig, function(err, result) {
                            save(["modules", module + ".js"], function(err) {
                                warn(err);
                                done();
                            })(err, result);
                            if (next) process.nextTick(next); // start building next without waiting for write
                        });
                    });
                } else if (options.module.match(/^ace\//)) {
                    build.buildAce(options.module, pathConfig, save(["modules", options.module + ".js"]));
                } else {
                    build.buildModule(options.module, pathConfig, save(["modules", options.module + ".js"]));
                }
            } else {
                done(new Error("unknown action"));
            }

            function warn(err) {
                if (err) console.warn(err);
            }

            function save(nameParts, cb) {
                return function(err, result) {
                    if (err) return cb(err);
                    var code = result.code;
                    nameParts.unshift(root);

                    writeFile(nameParts, code, cb || done);

                    if (result.sources && options.compressOutputDirPrefix) {
                        // compress and save in parallel
                        pending++;
                        var compress = require("architect-build/compress");
                        code = compress.withCache(result.sources, {
                            cache: cache,
                            obfuscate: options.obfuscate,
                            exclude: /(jsoniq|xquery)\.js$/
                        }).code;
                        nameParts[0] += "/" + options.compressOutputDirPrefix;
                        writeFile(nameParts, code, done);
                    }
                };
            }

            function writeFile(filename, code, cb) {
                if (typeof filename != "string")
                    filename = path.join.apply(path, filename);
                mkdirp(path.dirname(filename), function(err) {
                    if (err) return cb(err);
                    fs.writeFile(filename, code, "utf8", function(err) {
                        if (err) return cb(err);
                        console.log("file saved at", filename);
                        cb && cb();
                    });
                });
            }

            function done(err) {
                if (err) {
                    console.error(err);
                    process.exit(1);
                }
                pending--;
                if (pending <= 0)
                    process.exit();
            }
        });

        function listAceModules(pathConfig, cb) {
            var result = [
                "plugins/c9.ide.ace.keymaps/vim/keymap",
                "plugins/c9.ide.ace.keymaps/emacs/keymap",
                "plugins/c9.ide.ace.keymaps/sublime/keymap",
            ];

            // FIXME: this could be resolved via pathConfig:
            var pathMap = {
                "ace": __dirname + "/../../node_modules/ace/lib/ace",
                "plugins": __dirname + "/../../plugins",
            };

            var packages = [
                "ace",
                "plugins/c9.ide.salesforce/salesforce.language",
            ];

            function readPackage(name, type, excludePattern) {
                var targetPath = path.join(name, type);

                var parts = targetPath.split("/");
                var prefix = parts[0];

                if (!pathMap[prefix])
                    throw new Error("Cannot map prefix " + prefix + " for path " + targetPath);

                var sourcePath = path.resolve(pathMap[prefix], path.relative(prefix, targetPath));

                if (!fs.existsSync(sourcePath))
                    return;

                var files = fs
                    .readdirSync(sourcePath)
                    .filter(function(p) {
                        return !excludePattern.test(p)
                            && !/[\s#]/.test(p)
                            && /.*\.js$/.test(p);
                    });

                files.map(function(p) {
                    result.push(path.join(targetPath, path.basename(p, ".js")));
                });
            }

            packages.forEach(function(name) {
                var isAce = (name === "ace");
                readPackage(name, (isAce ? "mode" : "modes"), /_highlight_rules|_test|_worker|xml_util|_outdent|behaviour|completions/);
                readPackage(name, (isAce ? "theme" : "themes"), /_test/);
                readPackage(name, "ext", /_test/);
                readPackage(name, "snippets", /_test/);
            });

            function take() {
                var p = result.pop();
                console.log("building ", p, result.length);
                cb(p, result.length && take);
            }
            take();
        }

        function copyStaticResources(usedPlugins, pathConfig, next) {
            var moduleDeps = require("architect-build/module-deps");
            var copy = require('architect-build/copy');
            // todo: use usedPlugins to filter out some of unneeded deps
            var roots = pathConfig.pathMap;
            Object.keys(roots).filter(function(p) {
                return !/(c9.docker|docs|smith|vfs-socket|engine.io|msgpack.js)$/.test(p);
            }).forEach(function(p) {
                var absPath = moduleDeps.resolveModulePath(p, pathConfig.pathMap);
                if (/^\/lib\/ace/.test(p))
                    return;
                copy(absPath, root + "/static/" + p, {
                    include: /^(libmarkdown.js|runners_list.js|builders_list.js|bootstrap.js)$/,
                    exclude: function(name, dir) {
                        if (/\.css$/.test(name)) {
                            if (!cache.files[dir + "/" + name]) {
                                console.log("\x1b [1A\x1b[0K", "adding file ", dir + "/" + name);
                                return false;
                            }
                        }
                        return /\.(jsx?|css|less|xml|ejs|prv|pub|sh)$|(^|[/])^(mock|example|\.[^/]*|package.json)[/]?$/.test(name);
                    },
                    onDir: function(e) { console.log("\x1b [1A\x1b[0K" + e) }
                });
            });
            next();
        }
    }
});
<|endoftext|>


<commit_before>(function(window) {
	var Sparky = window.Sparky;

	function wrap(i, min, max) {
		return i < min ? max - (min - i) :
			i >= max ? min + (i - max) :
			i ;
	}

	function Throttle(fn, time) {
		var flag = false;
		var context, args;

		function update() {
			fn.apply(context, args);
			flag = false;
		}

		return function() {
			context = this;
			args = arguments;

			if (flag) { return; }
			flag = true;

			setTimeout(update, time);
		};
	}

	var request = Throttle(function request(url, tip, node) {
		jQuery
		.ajax(url)
		.then(function(data) {
			if (!data || data.length === 0) { return; }
			tip.scope(Collection(data));

			var elem = tip.tojQuery();

			window.requestAnimationFrame(function() {
				elem.trigger({ type: 'activate', relatedTarget: node });

				var inputs = elem.find('input');

				var i = 0;

				inputs.eq(i).addClass('focus');

				node.addEventListener('keydown', function(e) {
					if (e.keyCode === 38) {
						e.preventDefault();
						console.log('UP');
						inputs.eq(i).removeClass('focus');
						i = wrap(i - 1, 0, inputs.length);
						inputs.eq(i).addClass('focus');
					}
					else if (e.keyCode === 40) {
						e.preventDefault();
						console.log('DOWN');
						inputs.eq(i).removeClass('focus');
						i = wrap(i + 1, 0, inputs.length);
						inputs.eq(i).addClass('focus');
					}
					else if (e.keyCode === 13) {
						e.preventDefault();
						console.log('RETURN');
						inputs.eq(i)[0].checked = true;
						Sparky.dom.trigger(inputs.eq(i)[0], 'valuechange');
					}
				});
			});
		});
	}, 320);

	Sparky.fn.suggest = function(node) {
		if (Sparky.dom.tag(node) !== 'input') {
			console.warn('Sparky: data-fn="suggest" can only be applied to an <input>.');
			return;
		}

		var id    = node.getAttribute('data-suggest-template');
		var url   = node.getAttribute('data-suggest-url');
		var value = node.getAttribute('data-suggest-value');
		var fn    = node.getAttribute('data-suggest-fn');
		var minlength = parseInt(node.getAttribute('data-suggest-minlength') || 3, 10);

		fn = this.data[fn];

		if (!id || !url) {
			console.warn('Sparky: data-fn="suggest" requires attributes data-suggest-template and data-suggest-url.', node);
			return;
		}

		var tip = Sparky(id);

		var scope;

		function listen(tip) {
			function update(data) {
				jQuery(tip).trigger('deactivate');

				if (value) {
					node.value = Sparky.render(value, data);
					Sparky.dom.trigger(node, 'valuechange');
				}

				if (fn) {
					fn(node, scope, data);
				}

				window.requestAnimationFrame(function() {
					// Refocus the original input
					node.focus();
				});
			}

			function change(e) {
				if (!e.target.checked) { return; }
				update(Sparky.getScope(e.target));
			}

			tip.addEventListener('change', change);
			tip.addEventListener('valuechange', change);
		}

		Sparky.dom.append(document.body, tip);

		listen(tip.filter(Sparky.dom.isElementNode)[0]);

		node.addEventListener('input', function(e) {
			var text = e.target.value;

			if (text.length < minlength) {
				jQuery(tip).trigger('deactivate');
				return;
			}

			request(url + text, tip, node);
		});

		this.on('scope', function(sparky, newscope) {
			scope = newscope;
		});

		node.addEventListener('blur', function(e) {
			jQuery(tip).trigger('deactivate');
		});
	};
})(this);
<commit_msg>Suggest<commit_after>(function(window) {
	var assign = Object.assign;
	var Sparky = window.Sparky;

	function wrap(i, min, max) {
		return i < min ? max - (min - i) :
			i >= max ? min + (i - max) :
			i ;
	}

	function Throttle(fn, time) {
		var flag = false;
		var context, args;

		function update() {
			fn.apply(context, args);
			flag = false;
		}

		return function() {
			context = this;
			args = arguments;

			if (flag) { return; }
			flag = true;

			setTimeout(update, time);
		};
	}

	var request = Throttle(function request(url, tip, node) {

		jQuery
		.ajax(url, { cache: true })
		.then(function(data) {
			if (!data || data.length === 0) { return; }
			tip.scope(Collection(data));

			var elem = tip.tojQuery();

			window.requestAnimationFrame(function() {
				elem.trigger({ type: 'activate', relatedTarget: node });

				var inputs = elem.find('input');
				var i = 0;

				inputs.eq(i).addClass('focus');

				node.addEventListener('keydown', function(e) {
					if (e.keyCode === 38) {
						e.preventDefault();
						console.log('UP');
						inputs.eq(i).removeClass('focus');
						i = wrap(i - 1, 0, inputs.length);
						inputs.eq(i).addClass('focus');
					}
					else if (e.keyCode === 40) {
						e.preventDefault();
						console.log('DOWN');
						inputs.eq(i).removeClass('focus');
						i = wrap(i + 1, 0, inputs.length);
						inputs.eq(i).addClass('focus');
					}
					else if (e.keyCode === 13) {
						e.preventDefault();
						console.log('RETURN');
						inputs.eq(i)[0].checked = true;
						Sparky.dom.trigger(inputs.eq(i)[0], 'valuechange');
					}
				});
			});
		});
	}, 320);

	assign(Sparky.fn, {
		suggest: function(node) {
			if (Sparky.dom.tag(node) !== 'input') {
				console.warn('Sparky: data-fn="suggest" can only be applied to an <input>.');
				return;
			}

			var id    = node.getAttribute('data-suggest-template');
			var url   = node.getAttribute('data-suggest-url');
			var value = node.getAttribute('data-suggest-value');
			var fn    = node.getAttribute('data-suggest-fn');
			var minlength = parseInt(node.getAttribute('data-suggest-minlength') || 3, 10);

			fn = this.data[fn];

			if (!id || !url) {
				console.warn('Sparky: data-fn="suggest" requires attributes data-suggest-template and data-suggest-url.', node);
				return;
			}

			var tip = Sparky(id);

			var scope;

			function listen(tip) {
				function update(data) {
					jQuery(tip).trigger('deactivate');

					if (value) {
						node.value = Sparky.render(value, data);
						Sparky.dom.trigger(node, 'valuechange');
					}

					if (fn) {
						fn(node, scope, data);
					}

					window.requestAnimationFrame(function() {
						// Refocus the original input
						node.focus();
					});
				}

				function change(e) {
					if (!e.target.checked) { return; }
					update(Sparky.getScope(e.target));
				}

				tip.addEventListener('change', change);
				tip.addEventListener('valuechange', change);
			}

			Sparky.dom.append(document.body, tip);

			listen(tip.filter(Sparky.dom.isElementNode)[0]);

			node.addEventListener('input', function(e) {
				var text = e.target.value;

				if (text.length < minlength) {
					jQuery(tip).trigger('deactivate');
					return;
				}

				request(url + text, tip, node);
			});

			this.on('scope', function(sparky, newscope) {
				scope = newscope;
			});

			node.addEventListener('blur', function(e) {
				jQuery(tip).trigger('deactivate');
			});
		},

		'click-suggest': function(node) {

			var id    = node.getAttribute('data-suggest-template');
			var url   = node.getAttribute('data-suggest-url');
			var value = node.getAttribute('data-suggest-value');
			var fn    = node.getAttribute('data-suggest-fn');
			var minlength = parseInt(node.getAttribute('data-suggest-minlength') || 3, 10);

			fn = this.data[fn];

			if (!id || !url) {
				console.warn('Sparky: data-fn="suggest" requires attributes data-suggest-template and data-suggest-url.', node);
				return;
			}

			var tip = Sparky(id);

			var scope;

			function listen(tip) {
				function update(data) {
					jQuery(tip).trigger('deactivate');

					if (value) {
						node.value = Sparky.render(value, data);
						Sparky.dom.trigger(node, 'valuechange');
					}

					if (fn) {
						fn(node, scope, data);
					}

					window.requestAnimationFrame(function() {
						// Refocus the original input
						node.focus();
					});
				}

				function change(e) {
					if (!e.target.checked) { return; }
					update(Sparky.getScope(e.target));
				}

				tip.addEventListener('change', change);
				tip.addEventListener('valuechange', change);
			}

			Sparky.dom.append(document.body, tip);

			listen(tip.filter(Sparky.dom.isElementNode)[0]);

			requestAnimationFrame(function functionName() {
	console.log('HEY', node);
				node.addEventListener('click', function(e) {
					var text = e.target.value || '';
	console.log('CLICK');
					//if (text.length < minlength) {
					//	jQuery(tip).trigger('deactivate');
					//	return;
					//}

					request(url + text, tip, node);
				});
			});

			this.on('scope', function(sparky, newscope) {
				scope = newscope;
			});

			node.addEventListener('blur', function(e) {
				jQuery(tip).trigger('deactivate');
			});
		}
	});
})(this);
<|endoftext|>


<commit_before>/**
 * @fileOverview G6 Mapper Plugin base on d3 tech stack
 * d3-scale  https://github.com/d3/d3-scale
 * d3-legend https://github.com/susielu/d3-legend
 * @author shiwu.wyy@antfin.com
 */
const G6 = require('@antv/g6');
const { Legend } = require('@antv/component/lib');
const { Color, CircleSize, Category } = Legend;
// const Legend = require('@antv/g2/src/component/legend');
// const Color = require('@antv/g2/src/component/legend/color');
// const Size = require('@antv/g2/src/component/legend/size');
const Attr = require('@antv/attr');
const Scale = require('@antv/scale');
const { Util, G } = G6;

class Plugin {
  constructor(itemType, dim, channel, range, otherCfg) {
    Util.mix(this, {
      /**
       * the type of the item, 'node'/'edge'
       * @type  {String}
       */
      itemType: null,

      /**
       * 数据纬度
       * @type  {String}
       */
      dim: null,

      /**
       * 映射域
       * @type  {Array}
       */
      range: [ 0, 1 ],

      /**
       * 视觉通道
       * @type  {String}
       */
      channel: null,

      /**
       * 度量配置
       * @type  {object}
       */
      scaleCfg: {},

      /**
       * 图例配置
       * @type  {object}
       */
      legendCfg: {
        title: {
          fill: '#333'
        },
        layout: 'horizontal' // horizontal or vertical
      },

      /**
       * 是否数据对齐
       * @type  {boolean}
       */
      nice: true,
      curRange: [ 0, 100 ]
    }, {
      itemType,
      dim,
      channel,
      range
    }, otherCfg);
  }
  init() {
    const graph = this.graph;
    graph.on('beforechange', ev => {
      if (ev.action === 'changeData') {
        const {
          data
        } = ev;
        this._createScale(graph.parseSource(data));
        this._mapping();
        this.legendCfg && this._createLegend(graph.parseSource(data));
      }
    });
  }
  _trainCategoryScale(itemType, data) {
    const dim = this.dim;
    const domainMap = {};
    const domain = [];
    data.forEach(model => {
      if (!domainMap[model[dim]]) {
        domainMap[model[dim]] = true;
        domain.push(model[dim]);
      }
    });
    return domain;
  }
  _trainNumberScale(itemType, data) {
    const dim = this.dim;
    const domain = [ Infinity, -Infinity ];
    data.forEach(model => {
      if (domain[0] > model[dim]) {
        domain[0] = model[dim];
      }
      if (domain[1] < model[dim]) {
        domain[1] = model[dim];
      }
    });
    return domain;
  }
  _getScaleType(data) {
    const dim = this.dim;
    const scaleCfg = this.scaleCfg;
    if (!scaleCfg.type) {
      if (Util.isNumber(data[0][dim])) {
        scaleCfg.type = 'linear';
      } else {
        scaleCfg.type = 'category';
      }
    }
    return Util.upperFirst(scaleCfg.type);
  }
  _scaleConsSelector(scaleType, scaleCfg) {
    switch (scaleType) {
      case 'Linear':
        return new Scale.Linear(scaleCfg);
      case 'Log':
        return new Scale.Log(scaleCfg);
      case 'Pow':
        return new Scale.Pow(scaleCfg);
      default:
        return new Scale.Linear(scaleCfg);
    }
  }
  _createScale(sourceData) {
    const itemType = this.itemType;
    const data = sourceData[itemType + 's'];
    const scaleCfg = this.scaleCfg;
    const scaleType = this._getScaleType(data);
    const scale = this._scaleConsSelector(scaleType, scaleCfg);
    const range = this.range;
    scale.nice = scaleCfg.nice;
    let domain = scaleCfg.domain;
    scale.range = range;
    if (!domain) {
      if (scaleType === 'Category') {
        domain = this._trainCategoryScale(itemType, data);
      } else {
        domain = this._trainNumberScale(itemType, data);
      }
    }
    const domainLength = domain.length;
    if (domainLength === 2 && domain[0] === domain[1]) {
      if (domain[0] > 0) {
        domain[0] = 0;
      } else if (domain[0] < 0) {
        domain[1] = 0;
      } else {
        domain[0] = -1;
      }
    }
    scale.values = domain;
    scale.min = domain[0];
    scale.max = domain[domain.length - 1];
    Util.isFunction(scaleCfg.callback) && scaleCfg.callback(scale, domain);
    this.scale = scale;

  }
  _createLegend(sourceData) {
    const itemType = this.itemType;
    const data = sourceData[itemType + 's'];
    const scaleType = this._getScaleType(data);
    const channel = this.channel;
    const graph = this.graph;

    const containerId = this.legendCfg.containerId;
    let legendContainer = this.legendCfg.container;
    if (legendContainer === undefined) {
      if (containerId === undefined) {
        legendContainer = Util.createDOM('

');
        const container = graph.getGraphContainer();
        container.appendChild(legendContainer);
      } else {
        legendContainer = document.getElementById(containerId);
        if (legendContainer === undefined || legendContainer === null) {
          throw new Error('please set the container for the graph !');
        }
      }
    }
    const canvas = new G.Canvas({
      containerId, // dom_id,
      containerDOM: legendContainer,
      width: 500,
      height: 500
    });
    let legend;
    const domain = this.scale.values;
    const dim = this.dim;
    if (scaleType === 'Category') {
      legend = this._createCatLegend(canvas);
      // the listener for category legend to filter nodes and edges
      graph.addFilter(item => {
        if (this.curRange[0] === 0 && this.curRange[1] === 100) {
          return true;
        }
        if (item.isNode) {
          const val = item.model[dim];
          let visible = true;
          Util.each(this.curRange, r => {
            const checked = r.get('checked');
            const name = r.get('value');
            if (!checked && name === val) {
              visible = false;
            }
          });
          return visible;
        } else if (item.isEdge) {
          const sourceVal = item.source.model[dim];
          let sourceVisible = true;
          const targetVal = item.target.model[dim];
          let targetVisible = true;
          Util.each(this.curRange, r => {
            const checked = r.get('checked');
            const name = r.get('value');
            if (!checked && name === sourceVal) {
              sourceVisible = false;
            }
            if (!checked && name === targetVal) {
              targetVisible = false;
            }
          });
          if (!sourceVisible || !targetVisible) return false;
          return true;
        }
      });
      legend.on('itemclick', () => {
        const itemsGroup = legend.get('itemsGroup');
        this.curRange = itemsGroup.get('children');
        graph.filter();
        legend.get('canvas').draw();
      });
    } else {
      if (channel === 'color') {
        legend = this._createContinuousColorLegend(canvas);
      } else {
        legend = this._createContinuousSizeLegend(canvas);
      }
      // the listener to filter nodes and edges
      const slider = legend.get('slider');
      graph.addFilter(item => {
        if (item.isNode) {
          const val = item.model[dim];
          const percent = 100 * (val - domain[0]) / (domain[domain.length - 1] - domain[0]);
          if (percent > this.curRange[1] || percent < this.curRange[0]) {
            return false;
          }
          return true;
        } else if (item.isEdge) {
          const sourceVal = item.source.model[dim];
          const sourcePercent = 100 * (sourceVal - domain[0]) / (domain[domain.length - 1] - domain[0]);
          const sourceVisible = (sourcePercent <= this.curRange[1] && sourcePercent >= this.curRange[0]);
          const targetVal = item.target.model[dim];
          const targetPercent = 100 * (targetVal - domain[0]) / (domain[domain.length - 1] - domain[0]);
          const targetVisible = (targetPercent <= this.curRange[1] && targetPercent >= this.curRange[0]);
          if (!sourceVisible || !targetVisible) return false;
          return true;
        }
      });

      legend.get('slidable') && slider.on('sliderchange', Util.throttle(ev => {
        this.curRange = ev.range;
        graph.filter();
      }, 100));
    }
    const bbox = legend.get('group').getBBox();
    const padding = 6;
    const legendWidth = bbox.maxX - bbox.minX;
    const legendHeight = bbox.maxY - bbox.minY;
    legend.move(-bbox.minX + padding, -bbox.minY + padding);
    canvas.changeSize(legendWidth + 2 * padding, legendHeight + 2 * padding);
    this.legend = legend;
    this.legendCanvas = canvas;
    canvas.draw();
  }
  _createCatLegend(canvas) {
    const scale = this.scale;
    const range = scale.range;
    const domain = scale.values;
    const items = [];
    Util.each(range, (val, i) => {
      items.push({
        value: domain[i], // marker text
        marker: {
          symbol: 'circle',
          radius: 5,
          fill: val // marker color
        },
        checked: true
      });
    });
    const cfg = Util.mix({
      items,
      checkable: true,
      clickable: true,
      container: canvas
    }, this.legendCfg);
    const legend = new Category(cfg);
    return legend;
  }
  _getLegendCfg(defaultCfg) {
    const legendCfg = this.legendCfg;
    if (Util.isNil(legendCfg.width) && Util.isNil(legendCfg.height)) {
      if (legendCfg.layout === 'horizontal') {
        legendCfg.width = 150;
        legendCfg.height = 15;
      } else {
        legendCfg.width = 15;
        legendCfg.height = 150;
      }
    }
    if (!Util.isNil(legendCfg.width) && Util.isNil(legendCfg.height)) {
      if (legendCfg.layout === 'horizontal') {
        legendCfg.height = legendCfg.width / 10;
      } else {
        legendCfg.height = legendCfg.width * 10;
      }
    } else if (Util.isNil(legendCfg.width) && !Util.isNil(legendCfg.height)) {
      if (legendCfg.layout === 'horizontal') {
        legendCfg.width = legendCfg.height * 10;
      } else {
        legendCfg.width = legendCfg.height / 10;
      }
    }
    return Util.mix(true, {}, defaultCfg, legendCfg);
  }
  _createContinuousColorLegend(canvas) {
    const scale = this.scale;
    const range = scale.range;
    const domain = scale.values;
    const domainStep = (domain[domain.length - 1] - domain[0]) / (range.length - 1);
    const items = [];
    Util.each(range, (val, i) => {
      const itemText = domain[0] + domainStep * i;
      const percentage = (itemText - domain[0]) / (domain[domain.length - 1] - domain[0]);
      items.push({
        color: val,
        value: itemText, // the number label of the slider
        percentage
      });
    });
    const cfg = this._getLegendCfg({
      items,
      container: canvas,
      title: {
        text: this.dim
      }
    });
    const legend = new Color(cfg);
    // const legend = canvas.addGroup(Color, cfg);
    return legend;
  }
  _createContinuousSizeLegend(canvas) {
    const scale = this.scale;
    const range = scale.range;
    const domain = scale.values;
    const domainStep = (domain[domain.length - 1] - domain[0]) / (range.length - 1);

    const items = [];
    Util.each(range, (val, i) => {
      const dom = domain[0] + domainStep * i;
      items.push({
        attrValue: val,
        value: dom // the number label of the slider
      });
    });
    const cfg = this._getLegendCfg({
      items,
      container: canvas,
      attrType: 'size',
      title: {
        text: this.dim
      }
    });
    const legend = new CircleSize(cfg);
    return legend;
  }
  _mapping() {
    const graph = this.graph;
    const dim = this.dim;
    const itemType = this.itemType;
    const scale = this.scale;
    const channel = this.channel;

    const domain = scale.values;
    const range = scale.range;
    let color;
    if (channel === 'color') {
      const colorScale = this._scaleSelector(Util.upperFirst(scale.type), domain);
      color = new Attr.Color({
        scales: [ colorScale ],
        values: range
      });
    }
    graph[itemType]()[channel](model => {
      if (itemType === 'node' && channel === 'size') {
        return scale.scale(model[dim]);
      } else if (channel === 'color') {
        return color.mapping(model[dim])[0];
      }
      return scale.scale(model[dim]);
    });
  }
  _scaleSelector(type, domain) {
    const params = {
      min: domain[0],
      max: domain[domain.length - 1]
    };
    switch (type) {
      case 'Category':
        return Scale.cat({
          values: domain
        });
      default:
        return Scale.linear(params);
    }
  }
  destroy() {
    this.legendCanvas && this.legendCanvas.destroy();
  }
}

G6.Plugins['tool.mapper'] = Plugin;
module.exports = Plugin;
<commit_msg>fix:delete unnecessary notes<commit_after>/**
 * @fileOverview G6 Mapper Plugin base on d3 tech stack
 * d3-scale  https://github.com/d3/d3-scale
 * d3-legend https://github.com/susielu/d3-legend
 * @author shiwu.wyy@antfin.com
 */
const G6 = require('@antv/g6');
const { Legend } = require('@antv/component/lib');
const { Color, CircleSize, Category } = Legend;
const Attr = require('@antv/attr');
const Scale = require('@antv/scale');
const { Util, G } = G6;

class Plugin {
  constructor(itemType, dim, channel, range, otherCfg) {
    Util.mix(this, {
      /**
       * the type of the item, 'node'/'edge'
       * @type  {String}
       */
      itemType: null,

      /**
       * 数据纬度
       * @type  {String}
       */
      dim: null,

      /**
       * 映射域
       * @type  {Array}
       */
      range: [ 0, 1 ],

      /**
       * 视觉通道
       * @type  {String}
       */
      channel: null,

      /**
       * 度量配置
       * @type  {object}
       */
      scaleCfg: {},

      /**
       * 图例配置
       * @type  {object}
       */
      legendCfg: {
        title: {
          fill: '#333'
        },
        layout: 'horizontal' // horizontal or vertical
      },

      /**
       * 是否数据对齐
       * @type  {boolean}
       */
      nice: true,
      curRange: [ 0, 100 ]
    }, {
      itemType,
      dim,
      channel,
      range
    }, otherCfg);
  }
  init() {
    const graph = this.graph;
    graph.on('beforechange', ev => {
      if (ev.action === 'changeData') {
        const {
          data
        } = ev;
        this._createScale(graph.parseSource(data));
        this._mapping();
        this.legendCfg && this._createLegend(graph.parseSource(data));
      }
    });
  }
  _trainCategoryScale(itemType, data) {
    const dim = this.dim;
    const domainMap = {};
    const domain = [];
    data.forEach(model => {
      if (!domainMap[model[dim]]) {
        domainMap[model[dim]] = true;
        domain.push(model[dim]);
      }
    });
    return domain;
  }
  _trainNumberScale(itemType, data) {
    const dim = this.dim;
    const domain = [ Infinity, -Infinity ];
    data.forEach(model => {
      if (domain[0] > model[dim]) {
        domain[0] = model[dim];
      }
      if (domain[1] < model[dim]) {
        domain[1] = model[dim];
      }
    });
    return domain;
  }
  _getScaleType(data) {
    const dim = this.dim;
    const scaleCfg = this.scaleCfg;
    if (!scaleCfg.type) {
      if (Util.isNumber(data[0][dim])) {
        scaleCfg.type = 'linear';
      } else {
        scaleCfg.type = 'category';
      }
    }
    return Util.upperFirst(scaleCfg.type);
  }
  _scaleConsSelector(scaleType, scaleCfg) {
    switch (scaleType) {
      case 'Linear':
        return new Scale.Linear(scaleCfg);
      case 'Log':
        return new Scale.Log(scaleCfg);
      case 'Pow':
        return new Scale.Pow(scaleCfg);
      default:
        return new Scale.Linear(scaleCfg);
    }
  }
  _createScale(sourceData) {
    const itemType = this.itemType;
    const data = sourceData[itemType + 's'];
    const scaleCfg = this.scaleCfg;
    const scaleType = this._getScaleType(data);
    const scale = this._scaleConsSelector(scaleType, scaleCfg);
    const range = this.range;
    scale.nice = scaleCfg.nice;
    let domain = scaleCfg.domain;
    scale.range = range;
    if (!domain) {
      if (scaleType === 'Category') {
        domain = this._trainCategoryScale(itemType, data);
      } else {
        domain = this._trainNumberScale(itemType, data);
      }
    }
    const domainLength = domain.length;
    if (domainLength === 2 && domain[0] === domain[1]) {
      if (domain[0] > 0) {
        domain[0] = 0;
      } else if (domain[0] < 0) {
        domain[1] = 0;
      } else {
        domain[0] = -1;
      }
    }
    scale.values = domain;
    scale.min = domain[0];
    scale.max = domain[domain.length - 1];
    Util.isFunction(scaleCfg.callback) && scaleCfg.callback(scale, domain);
    this.scale = scale;

  }
  _createLegend(sourceData) {
    const itemType = this.itemType;
    const data = sourceData[itemType + 's'];
    const scaleType = this._getScaleType(data);
    const channel = this.channel;
    const graph = this.graph;

    const containerId = this.legendCfg.containerId;
    let legendContainer = this.legendCfg.container;
    if (legendContainer === undefined) {
      if (containerId === undefined) {
        legendContainer = Util.createDOM('

');
        const container = graph.getGraphContainer();
        container.appendChild(legendContainer);
      } else {
        legendContainer = document.getElementById(containerId);
        if (legendContainer === undefined || legendContainer === null) {
          throw new Error('please set the container for the graph !');
        }
      }
    }
    const canvas = new G.Canvas({
      containerId, // dom_id,
      containerDOM: legendContainer,
      width: 500,
      height: 500
    });
    let legend;
    const domain = this.scale.values;
    const dim = this.dim;
    if (scaleType === 'Category') {
      legend = this._createCatLegend(canvas);
      // the listener for category legend to filter nodes and edges
      graph.addFilter(item => {
        if (this.curRange[0] === 0 && this.curRange[1] === 100) {
          return true;
        }
        if (item.isNode) {
          const val = item.model[dim];
          let visible = true;
          Util.each(this.curRange, r => {
            const checked = r.get('checked');
            const name = r.get('value');
            if (!checked && name === val) {
              visible = false;
            }
          });
          return visible;
        } else if (item.isEdge) {
          const sourceVal = item.source.model[dim];
          let sourceVisible = true;
          const targetVal = item.target.model[dim];
          let targetVisible = true;
          Util.each(this.curRange, r => {
            const checked = r.get('checked');
            const name = r.get('value');
            if (!checked && name === sourceVal) {
              sourceVisible = false;
            }
            if (!checked && name === targetVal) {
              targetVisible = false;
            }
          });
          if (!sourceVisible || !targetVisible) return false;
          return true;
        }
      });
      legend.on('itemclick', () => {
        const itemsGroup = legend.get('itemsGroup');
        this.curRange = itemsGroup.get('children');
        graph.filter();
        legend.get('canvas').draw();
      });
    } else {
      if (channel === 'color') {
        legend = this._createContinuousColorLegend(canvas);
      } else {
        legend = this._createContinuousSizeLegend(canvas);
      }
      // the listener to filter nodes and edges
      const slider = legend.get('slider');
      graph.addFilter(item => {
        if (item.isNode) {
          const val = item.model[dim];
          const percent = 100 * (val - domain[0]) / (domain[domain.length - 1] - domain[0]);
          if (percent > this.curRange[1] || percent < this.curRange[0]) {
            return false;
          }
          return true;
        } else if (item.isEdge) {
          const sourceVal = item.source.model[dim];
          const sourcePercent = 100 * (sourceVal - domain[0]) / (domain[domain.length - 1] - domain[0]);
          const sourceVisible = (sourcePercent <= this.curRange[1] && sourcePercent >= this.curRange[0]);
          const targetVal = item.target.model[dim];
          const targetPercent = 100 * (targetVal - domain[0]) / (domain[domain.length - 1] - domain[0]);
          const targetVisible = (targetPercent <= this.curRange[1] && targetPercent >= this.curRange[0]);
          if (!sourceVisible || !targetVisible) return false;
          return true;
        }
      });

      legend.get('slidable') && slider.on('sliderchange', Util.throttle(ev => {
        this.curRange = ev.range;
        graph.filter();
      }, 100));
    }
    const bbox = legend.get('group').getBBox();
    const padding = 6;
    const legendWidth = bbox.maxX - bbox.minX;
    const legendHeight = bbox.maxY - bbox.minY;
    legend.move(-bbox.minX + padding, -bbox.minY + padding);
    canvas.changeSize(legendWidth + 2 * padding, legendHeight + 2 * padding);
    this.legend = legend;
    this.legendCanvas = canvas;
    canvas.draw();
  }
  _createCatLegend(canvas) {
    const scale = this.scale;
    const range = scale.range;
    const domain = scale.values;
    const items = [];
    Util.each(range, (val, i) => {
      items.push({
        value: domain[i], // marker text
        marker: {
          symbol: 'circle',
          radius: 5,
          fill: val // marker color
        },
        checked: true
      });
    });
    const cfg = Util.mix({
      items,
      checkable: true,
      clickable: true,
      container: canvas
    }, this.legendCfg);
    const legend = new Category(cfg);
    return legend;
  }
  _getLegendCfg(defaultCfg) {
    const legendCfg = this.legendCfg;
    if (Util.isNil(legendCfg.width) && Util.isNil(legendCfg.height)) {
      if (legendCfg.layout === 'horizontal') {
        legendCfg.width = 150;
        legendCfg.height = 15;
      } else {
        legendCfg.width = 15;
        legendCfg.height = 150;
      }
    }
    if (!Util.isNil(legendCfg.width) && Util.isNil(legendCfg.height)) {
      if (legendCfg.layout === 'horizontal') {
        legendCfg.height = legendCfg.width / 10;
      } else {
        legendCfg.height = legendCfg.width * 10;
      }
    } else if (Util.isNil(legendCfg.width) && !Util.isNil(legendCfg.height)) {
      if (legendCfg.layout === 'horizontal') {
        legendCfg.width = legendCfg.height * 10;
      } else {
        legendCfg.width = legendCfg.height / 10;
      }
    }
    return Util.mix(true, {}, defaultCfg, legendCfg);
  }
  _createContinuousColorLegend(canvas) {
    const scale = this.scale;
    const range = scale.range;
    const domain = scale.values;
    const domainStep = (domain[domain.length - 1] - domain[0]) / (range.length - 1);
    const items = [];
    Util.each(range, (val, i) => {
      const itemText = domain[0] + domainStep * i;
      const percentage = (itemText - domain[0]) / (domain[domain.length - 1] - domain[0]);
      items.push({
        color: val,
        value: itemText, // the number label of the slider
        percentage
      });
    });
    const cfg = this._getLegendCfg({
      items,
      container: canvas,
      title: {
        text: this.dim
      }
    });
    const legend = new Color(cfg);
    // const legend = canvas.addGroup(Color, cfg);
    return legend;
  }
  _createContinuousSizeLegend(canvas) {
    const scale = this.scale;
    const range = scale.range;
    const domain = scale.values;
    const domainStep = (domain[domain.length - 1] - domain[0]) / (range.length - 1);

    const items = [];
    Util.each(range, (val, i) => {
      const dom = domain[0] + domainStep * i;
      items.push({
        attrValue: val,
        value: dom // the number label of the slider
      });
    });
    const cfg = this._getLegendCfg({
      items,
      container: canvas,
      attrType: 'size',
      title: {
        text: this.dim
      }
    });
    const legend = new CircleSize(cfg);
    return legend;
  }
  _mapping() {
    const graph = this.graph;
    const dim = this.dim;
    const itemType = this.itemType;
    const scale = this.scale;
    const channel = this.channel;

    const domain = scale.values;
    const range = scale.range;
    let color;
    if (channel === 'color') {
      const colorScale = this._scaleSelector(Util.upperFirst(scale.type), domain);
      color = new Attr.Color({
        scales: [ colorScale ],
        values: range
      });
    }
    graph[itemType]()[channel](model => {
      if (itemType === 'node' && channel === 'size') {
        return scale.scale(model[dim]);
      } else if (channel === 'color') {
        return color.mapping(model[dim])[0];
      }
      return scale.scale(model[dim]);
    });
  }
  _scaleSelector(type, domain) {
    const params = {
      min: domain[0],
      max: domain[domain.length - 1]
    };
    switch (type) {
      case 'Category':
        return Scale.cat({
          values: domain
        });
      default:
        return Scale.linear(params);
    }
  }
  destroy() {
    this.legendCanvas && this.legendCanvas.destroy();
  }
}

G6.Plugins['tool.mapper'] = Plugin;
module.exports = Plugin;
<|endoftext|>