<commit_before>/**
 *
Copyright (c) 2012 by Appcelerator, Inc. All Rights Reserved.
 * Please see the LICENSE file for information about licensing.

 *
 * Processes Titanium APIs for the code processor
 *
 * @module plugins/TiAPIProcessor
 * @author Bryan Hughes <bhughes@appcelerator.com>
 */

var fs = require("fs"),
	path = require("path"),
	util = require("util"),

	Base = require(path.join(global.nodeCodeProcessorLibDir, "Base")),
	Runtime = require(path.join(global.nodeCodeProcessorLibDir, "Runtime")),
	Exceptions = require(path.join(global.nodeCodeProcessorLibDir, "Exceptions")),
	CodeProcessor = require(path.join(global.nodeCodeProcessorLibDir, "CodeProcessor")),

	jsca,
	platform,

	api = { children: {} };

// ******** Plugin API Methods ********

/**
 * Creates an instance of the ti api processor plugin
 *
 * @classdesc Injects a stub of the Titanium Mobile API into the global namespace
 *
 * @constructor
 * @name module:plugins/TiAPIProcessor
 */
module.exports = function(options) {
	jsca = JSON.parse(fs.readFileSync(path.join(options.sdkPath, "api.jsca")));
	platform = options.platform;
};

/**
 * Initializes the plugin
 *
 * @method
 * @name module:plugins/TiAPIProcessor#init
 */
module.exports.prototype.init = function init() {

	// Iterate through the json object and inject all the APIs
	var typesToInsert = {},
		globalObject = Runtime.getGlobalObject(),
		types = jsca.types,
		type,
		aliases = jsca.aliases,
		alias,
		i, j,
		len,
		name,
		root,
		obj;

	// Create the API tree
	for (i = 0, len = types.length; i < len; i++) {
		type = types[i];
		root = api;
		name = type.name.split('.');
		for(j = 0; j < name.length; j++) {
			root.children[name[j]] || (root.children[name[j]] = { children: {} });
			root = root.children[name[j]];
		}
		root.node = type;
	}

	// Create the list of aliases and global objects
	for(i = 0, aliases.length; i < len; i++) {
		alias = aliases[i];
		if (alias) {
			type = alias.type;
			typesToInsert[type] || (typesToInsert[type] = []);
			typesToInsert[type].push(alias.name)
		}
	}

	// Inject the global objects
	for(p in typesToInsert) {
		obj = createObject(api.children[p]);
		globalObject.put(p, obj, false, true);
		for(i = 0, len = typesToInsert[p].length; i < len; i++) {
			globalObject.put(typesToInsert[p][i], obj, false, true);
		}
	}
};

/**
 * Gets the results of the plugin
 *
 * @method
 * @name module:plugins/TiAPIProcessor#getResults
 * @returns {Object} An empty object.
 */
module.exports.prototype.getResults = function getResults() {
	return {};
};

// ******** Function Type ********

/**
 * @classdesc Specialized function that returns information based on the JSCA
 *
 * @constructor
 * @private
 * @param {Array[String]|undefined} returnTypes An array of return types, or undefined
 * @param {String} [className] The name of the class, defaults to "Function." This parameter should only be used by a
 *		constructor for an object extending this one.
 */
function TiFunction(returnTypes, className) {
	Base.ObjectType.call(this, className || "Function");
	this._returnTypes = returnTypes;
}
util.inherits(TiFunction, Base.FunctionType);

/**
 * Calls the require function
 *
 * @method
 * @param {module:Base.BaseType} thisVal The value of this of the function
 * @param (Array[{@link module:Base.BaseType}]} args The set of arguments passed in to the function call
 * @returns {module:Base.BaseType} The return value from the function
 * @see ECMA-262 Spec Chapter 13.2.1
 */
TiFunction.prototype.call = function call(thisVal, args) {
	var returnType,
		root = api,
		parent,
		i, len;
	if (this._returnTypes && this._returnTypes.length === 1) {
		returnType = this._returnTypes[0].type.split('.');
		for(i = 0, len = returnType.length; i < len; i++) {
			root = root && root.children[returnType[i]];
		}
		if (root && root.node) {
			value = createObject(root)
			Runtime.fireEvent("tiPropertyReferenced", "Property '" + p + "' was referenced" + p, {
				name: this._returnTypes[0].type,
				node: root.node
			});
		} else {

		}
		return value;
	} else {
		return new Base.UndefinedType();
	}
};

// ******** Object Type ********

/**
 * @classdesc A custom object implementation that hooks into get, put, and delete so it can fire the appropriate Ti events
 *
 * @constructor
 * @private
 * @extends module:Base.ObjectType
 * @param {Object} api The api describing the object
 * @param {Object} api.node The JSCA node for the object
 * @param {Object} api.children Any children of this object (i.e. separate JSCA types that are properties)
 */
exports.TiObjectType = TiObjectType;
function TiObjectType(api, className) {
	this._api = api;
	Base.ObjectType.call(this, className || "Object");
}
util.inherits(TiObjectType, Base.ObjectType);

/**
 * Indicates that a titanium property was referenced (i.e. read).
 *
 * @name module:plugins/TiAPIProcessor.TiObjectType#tiPropertyReferenced
 * @event
 * @param {String} name The name of the property that was referenced
 * @param {{@link module:Base.DataPropertyDescriptor}|{@link module:Base.AccessorPropertyDescriptor}|undefined} The
 *		descriptor fetched, if it could be found.
 */
/**
 * ECMA-262 Spec: Returns the value of the named property.
 *
 * @method
 * @param {String} p The name of the property to fetch
 * @returns {{@link module:Base.BaseType}} The value of the property, or a new instance of
 *		{@link module:Base.UndefinedType} if the property does not exist
 * @see ECMA-262 Spec Chapter 8.12.3
 */
exports.TiObjectType.prototype.get = function get(p) {
	var value = Base.ObjectType.prototype.get.apply(this, arguments),
		node = value._api ? value._api.node : value._property ? value._property : value._function;
	if (node) {
		Runtime.fireEvent("tiPropertyReferenced", "Property '" + p + "' was referenced" + p, {
			name: this._api.node.name + '.' + p,
			node: node
		});
	}
	return value;
};

/**
 * Indicates that a titanium property was set (i.e. written).
 *
 * @name module:plugins/TiAPIProcessor.TiObjectType#tiPropertySet
 * @event
 * @param {String} name The name of the property that was set
 * @param {module:Base.BaseType} value The value that was set
 */
/**
 * ECMA-262 Spec: Sets the specified named property to the value of the second parameter. The flag controls failure
 * handling.
 *
 * @method
 * @param {String} p The name of the parameter to set the value as
 * @param {module:Base.BaseType} v The value to set
 * @param {Boolean} throwFlag Whether or not to throw an exception on error (related to strict mode)
 * @param {Boolean} suppressEvent Suppresses the "propertySet" event (used when setting prototypes)
 * @throws {{@link module:Exceptions.TypeError}} Thrown when the property cannot be put and throwFlag is true
 * @see ECMA-262 Spec Chapter 8.12.5
 */
exports.TiObjectType.prototype.put = function put(p, v, throwFlag, suppressEvent) {
	Base.ObjectType.prototype.put.apply(this, arguments);
	if (!suppressEvent) {
		Runtime.fireEvent("tiPropertySet", "Property '" + p + "' was set", {
			name: this._api.node.name + '.' + p,
			node: v._api ? v._api.node : v._property ? v._property : v._function
		});
	}
};

/**
 * Indicates that a titanium property was deleted
 *
 * @name module:plugins/TiAPIProcessor.TiObjectType#tiPropertyDeleted
 * @event
 * @param {String} name The name of the property referenced
 */
/**
 * ECMA-262 Spec: Removes the specified named own property from the object. The flag controls failure handling.
 *
 * @method
 * @param {String} p The name of the parameter to delete
 * @param {Boolean} throwFlag Whether or not to throw an exception on error (related to strict mode)
 * @returns {Boolean} Whether or not the object was deleted succesfully
 * @throws {{@link module:Exceptions.TypeError}} Thrown when the property cannot be deleted and throwFlag is true
 * @see ECMA-262 Spec Chapter 8.12.7
 */
exports.TiObjectType.prototype.delete = function objDelete(p, throwFlag) {
	var success = Base.ObjectType.prototype["delete"].apply(this, arguments);
	Runtime.fireEvent("tiPropertyDeleted", "Property '" + p + "' was deleted", {
		name: this._api.node.name + '.' + p,
		success: success
	});
	return success;
};

/**
 * @classdesc Customized require() function that doesn't actually execute code in the interpreter, but rather does it here.
 *
 * @constructor
 * @private
 * @param {String} [className] The name of the class, defaults to "Function." This parameter should only be used by a
 *		constructor for an object extending this one.
 */
function IncludeFunction(className) {
	Base.ObjectType.call(this, className || "Function");
}
util.inherits(IncludeFunction, Base.FunctionType);

/**
 * Calls the require function
 *
 * @method
 * @param {module:Base.BaseType} thisVal The value of this of the function
 * @param (Array[{@link module:Base.BaseType}]} args The set of arguments passed in to the function call
 * @returns {module:Base.BaseType} The return value from the function
 * @see ECMA-262 Spec Chapter 13.2.1
 */
IncludeFunction.prototype.call = function call(thisVal, args) {
	var file = args && Base.getValue(args[0]),
		evalFunc,
		root,
		module,
		result = new Base.UnknownType();

	// Validate the file
	if (!file) {
		file = new Base.UndefinedType();
	}
	if (Base.type(file) === "Unknown") {

		eventDescription = "A value that could not be evaluated was passed to Ti.include";
		Runtime.fireEvent("requireUnresolved", eventDescription, {
			name: "<Could not evaluate Ti.include path>"
		});
		Runtime.reportWarning("requireUnresolved", eventDescription, {
			name: "<Could not evaluate Ti.include path>"
		});
		return result;
	}
	file = Base.toString(file).value;
	file = path.resolve(path.join(path.dirname(file[0] !== "." ? Runtime.getEntryPointFile() : Runtime.getCurrentFile()), file));

	// Make sure the file exists
	console.log(path.resolve(file));
	if (fs.existsSync(file)) {

		// Fire the parsing begin event
		Runtime.fireEvent("fileProcessingBegin", "Processing is beginning for file '" + file + "'", {
			file: file
		});

		// Set the current file
		Runtime.setCurrentFile(file);

		// Eval the code
		evalFunc = Runtime.getGlobalObject().get('eval');
		evalFunc.call(thisVal, [new Base.StringType(fs.readFileSync(file).toString())]);

		// Restore the previous file
		Runtime.popCurrentFile();

		// Fire the parsing end event
		Runtime.fireEvent("fileProcessingEnd", "Processing finished for file '" + file + "'", {
			file: file
		});

	} else {
		throw new Error("Could not load file '" + file + "'");
	}
	return result;
};

// ******** Helper Methods ********

/**
 * Creates a titanium object from an API node
 *
 * @private
 * @method
 */
function createObject(apiNode) {
	var obj = new TiObjectType(apiNode),
		properties = apiNode.node.properties,
		property,
		functions = apiNode.node.functions,
		func,
		children = apiNode.children,
		child,
		value,
		name,
		type,
		p, i, len;

	// Add the properties
	for(i = 0, len = properties.length; i < len; i++) {
		property = properties[i];
		name = property.name;
		type = property.type;
		if (name === 'osname' && apiNode.node.name === 'Titanium.Platform') {
			value = new Base.StringType(platform);
		} else if (type in api.children) {
			value = createObject(api.children[type]);
		} else {
			value = new Base.UnknownType();
		}
		value._property = property;
		obj.put(name, value, false, true);
	}

	// Add the methods
	for(i = 0, len = functions.length; i < len; i++) {
		func = functions[i];
		if (func.name === 'include' && apiNode.node.name === 'Titanium') {
			value = new IncludeFunction();
		} else {
			value = new TiFunction(func.returnTypes);
		}
		value._function = func;
		obj.put(func.name, value, false, true);
	}

	// Add the children
	for(p in children) {
		obj.put(p, createObject(children[p]))
	}

	// Return the newly created object
	return obj;
}<commit_msg>[TIMOB-11333] Added better checking for non-ti props<commit_after>/**
 *
Copyright (c) 2012 by Appcelerator, Inc. All Rights Reserved.
 * Please see the LICENSE file for information about licensing.

 *
 * Processes Titanium APIs for the code processor
 *
 * @module plugins/TiAPIProcessor
 * @author Bryan Hughes <bhughes@appcelerator.com>
 */

var fs = require("fs"),
	path = require("path"),
	util = require("util"),

	Base = require(path.join(global.nodeCodeProcessorLibDir, "Base")),
	Runtime = require(path.join(global.nodeCodeProcessorLibDir, "Runtime")),
	Exceptions = require(path.join(global.nodeCodeProcessorLibDir, "Exceptions")),
	CodeProcessor = require(path.join(global.nodeCodeProcessorLibDir, "CodeProcessor")),

	jsca,
	platform,

	api = { children: {} };

// ******** Plugin API Methods ********

/**
 * Creates an instance of the ti api processor plugin
 *
 * @classdesc Injects a stub of the Titanium Mobile API into the global namespace
 *
 * @constructor
 * @name module:plugins/TiAPIProcessor
 */
module.exports = function(options) {
	jsca = JSON.parse(fs.readFileSync(path.join(options.sdkPath, "api.jsca")));
	platform = options.platform;
};

/**
 * Initializes the plugin
 *
 * @method
 * @name module:plugins/TiAPIProcessor#init
 */
module.exports.prototype.init = function init() {

	// Iterate through the json object and inject all the APIs
	var typesToInsert = {},
		globalObject = Runtime.getGlobalObject(),
		types = jsca.types,
		type,
		aliases = jsca.aliases,
		alias,
		i, j,
		len,
		name,
		root,
		obj;

	// Create the API tree
	for (i = 0, len = types.length; i < len; i++) {
		type = types[i];
		root = api;
		name = type.name.split('.');
		for(j = 0; j < name.length; j++) {
			root.children[name[j]] || (root.children[name[j]] = { children: {} });
			root = root.children[name[j]];
		}
		root.node = type;
	}

	// Create the list of aliases and global objects
	for(i = 0, aliases.length; i < len; i++) {
		alias = aliases[i];
		if (alias) {
			type = alias.type;
			typesToInsert[type] || (typesToInsert[type] = []);
			typesToInsert[type].push(alias.name)
		}
	}

	// Inject the global objects
	for(p in typesToInsert) {
		obj = createObject(api.children[p]);
		globalObject.put(p, obj, false, true);
		for(i = 0, len = typesToInsert[p].length; i < len; i++) {
			globalObject.put(typesToInsert[p][i], obj, false, true);
		}
	}
};

/**
 * Gets the results of the plugin
 *
 * @method
 * @name module:plugins/TiAPIProcessor#getResults
 * @returns {Object} An empty object.
 */
module.exports.prototype.getResults = function getResults() {
	return {};
};

// ******** Function Type ********

/**
 * @classdesc Specialized function that returns information based on the JSCA
 *
 * @constructor
 * @private
 * @param {Array[String]|undefined} returnTypes An array of return types, or undefined
 * @param {String} [className] The name of the class, defaults to "Function." This parameter should only be used by a
 *		constructor for an object extending this one.
 */
function TiFunction(returnTypes, className) {
	Base.ObjectType.call(this, className || "Function");
	this._returnTypes = returnTypes;
}
util.inherits(TiFunction, Base.FunctionType);

/**
 * Calls the require function
 *
 * @method
 * @param {module:Base.BaseType} thisVal The value of this of the function
 * @param (Array[{@link module:Base.BaseType}]} args The set of arguments passed in to the function call
 * @returns {module:Base.BaseType} The return value from the function
 * @see ECMA-262 Spec Chapter 13.2.1
 */
TiFunction.prototype.call = function call(thisVal, args) {
	var returnType,
		root = api,
		parent,
		i, len;
	if (this._returnTypes && this._returnTypes.length === 1) {
		returnType = this._returnTypes[0].type.split('.');
		for(i = 0, len = returnType.length; i < len; i++) {
			root = root && root.children[returnType[i]];
		}
		if (root && root.node) {
			value = createObject(root)
			Runtime.fireEvent("tiPropertyReferenced", "Property '" + p + "' was referenced", {
				name: this._returnTypes[0].type,
				node: root.node
			});
		} else {
			Runtime.fireEvent('nonTiPropertyReference', 'Property "' + p + '" was referenced but is not part of the API', {
				name: this._api.node.name + '.' + p
			}));
		}
		return value;
	} else {
		return new Base.UndefinedType();
	}
};

// ******** Object Type ********

/**
 * @classdesc A custom object implementation that hooks into get, put, and delete so it can fire the appropriate Ti events
 *
 * @constructor
 * @private
 * @extends module:Base.ObjectType
 * @param {Object} api The api describing the object
 * @param {Object} api.node The JSCA node for the object
 * @param {Object} api.children Any children of this object (i.e. separate JSCA types that are properties)
 */
exports.TiObjectType = TiObjectType;
function TiObjectType(api, className) {
	this._api = api;
	Base.ObjectType.call(this, className || "Object");
}
util.inherits(TiObjectType, Base.ObjectType);

/**
 * Indicates that a titanium property was referenced (i.e. read).
 *
 * @name module:plugins/TiAPIProcessor.TiObjectType#tiPropertyReferenced
 * @event
 * @param {String} name The name of the property that was referenced
 * @param {{@link module:Base.DataPropertyDescriptor}|{@link module:Base.AccessorPropertyDescriptor}|undefined} The
 *		descriptor fetched, if it could be found.
 */
/**
 * ECMA-262 Spec: Returns the value of the named property.
 *
 * @method
 * @param {String} p The name of the property to fetch
 * @returns {{@link module:Base.BaseType}} The value of the property, or a new instance of
 *		{@link module:Base.UndefinedType} if the property does not exist
 * @see ECMA-262 Spec Chapter 8.12.3
 */
exports.TiObjectType.prototype.get = function get(p) {
	var value = Base.ObjectType.prototype.get.apply(this, arguments),
		node = value._api ? value._api.node : value._property ? value._property : value._function;
	if (node) {
		Runtime.fireEvent("tiPropertyReferenced", "Property '" + p + "' was referenced", {
			name: this._api.node.name + '.' + p,
			node: node
		});
	} else {
		Runtime.fireEvent('nonTiPropertyReference', 'Property "' + p + '" was referenced but is not part of the API', {
			name: this._api.node.name + '.' + p
		}));
	}
	return value;
};

/**
 * Indicates that a titanium property was set (i.e. written).
 *
 * @name module:plugins/TiAPIProcessor.TiObjectType#tiPropertySet
 * @event
 * @param {String} name The name of the property that was set
 * @param {module:Base.BaseType} value The value that was set
 */
/**
 * ECMA-262 Spec: Sets the specified named property to the value of the second parameter. The flag controls failure
 * handling.
 *
 * @method
 * @param {String} p The name of the parameter to set the value as
 * @param {module:Base.BaseType} v The value to set
 * @param {Boolean} throwFlag Whether or not to throw an exception on error (related to strict mode)
 * @param {Boolean} suppressEvent Suppresses the "propertySet" event (used when setting prototypes)
 * @throws {{@link module:Exceptions.TypeError}} Thrown when the property cannot be put and throwFlag is true
 * @see ECMA-262 Spec Chapter 8.12.5
 */
exports.TiObjectType.prototype.put = function put(p, v, throwFlag, suppressEvent) {
	var node = v._api ? v._api.node : v._property ? v._property : v._function;
	Base.ObjectType.prototype.put.apply(this, arguments);
	if (!suppressEvent) {
		if (node) {
			Runtime.fireEvent("tiPropertySet", "Property '" + p + "' was set", {
				name: this._api.node.name + '.' + p,
				node: node
			});
		} else {
			Runtime.fireEvent('nonTiPropertySet', 'Property "' + p + '" was set but is not part of the API', {
				name: this._api.node.name + '.' + p
			}));
		}
	}
};

/**
 * Indicates that a titanium property was deleted
 *
 * @name module:plugins/TiAPIProcessor.TiObjectType#tiPropertyDeleted
 * @event
 * @param {String} name The name of the property referenced
 */
/**
 * ECMA-262 Spec: Removes the specified named own property from the object. The flag controls failure handling.
 *
 * @method
 * @param {String} p The name of the parameter to delete
 * @param {Boolean} throwFlag Whether or not to throw an exception on error (related to strict mode)
 * @returns {Boolean} Whether or not the object was deleted succesfully
 * @throws {{@link module:Exceptions.TypeError}} Thrown when the property cannot be deleted and throwFlag is true
 * @see ECMA-262 Spec Chapter 8.12.7
 */
exports.TiObjectType.prototype.delete = function objDelete(p, throwFlag) {
	var success = Base.ObjectType.prototype["delete"].apply(this, arguments);
	Runtime.fireEvent("tiPropertyDeleted", "Property '" + p + "' was deleted", {
		name: this._api.node.name + '.' + p,
		success: success
	});
	return success;
};

/**
 * @classdesc Customized require() function that doesn't actually execute code in the interpreter, but rather does it here.
 *
 * @constructor
 * @private
 * @param {String} [className] The name of the class, defaults to "Function." This parameter should only be used by a
 *		constructor for an object extending this one.
 */
function IncludeFunction(className) {
	Base.ObjectType.call(this, className || "Function");
}
util.inherits(IncludeFunction, Base.FunctionType);

/**
 * Calls the require function
 *
 * @method
 * @param {module:Base.BaseType} thisVal The value of this of the function
 * @param (Array[{@link module:Base.BaseType}]} args The set of arguments passed in to the function call
 * @returns {module:Base.BaseType} The return value from the function
 * @see ECMA-262 Spec Chapter 13.2.1
 */
IncludeFunction.prototype.call = function call(thisVal, args) {
	var file = args && Base.getValue(args[0]),
		evalFunc,
		root,
		module,
		result = new Base.UnknownType();

	// Validate the file
	if (!file) {
		file = new Base.UndefinedType();
	}
	if (Base.type(file) === "Unknown") {

		eventDescription = "A value that could not be evaluated was passed to Ti.include";
		Runtime.fireEvent("requireUnresolved", eventDescription, {
			name: "<Could not evaluate Ti.include path>"
		});
		Runtime.reportWarning("requireUnresolved", eventDescription, {
			name: "<Could not evaluate Ti.include path>"
		});
		return result;
	}
	file = Base.toString(file).value;
	file = path.resolve(path.join(path.dirname(file[0] !== "." ? Runtime.getEntryPointFile() : Runtime.getCurrentFile()), file));

	// Make sure the file exists
	console.log(path.resolve(file));
	if (fs.existsSync(file)) {

		// Fire the parsing begin event
		Runtime.fireEvent("fileProcessingBegin", "Processing is beginning for file '" + file + "'", {
			file: file
		});

		// Set the current file
		Runtime.setCurrentFile(file);

		// Eval the code
		evalFunc = Runtime.getGlobalObject().get('eval');
		evalFunc.call(thisVal, [new Base.StringType(fs.readFileSync(file).toString())]);

		// Restore the previous file
		Runtime.popCurrentFile();

		// Fire the parsing end event
		Runtime.fireEvent("fileProcessingEnd", "Processing finished for file '" + file + "'", {
			file: file
		});

	} else {
		throw new Error("Could not load file '" + file + "'");
	}
	return result;
};

// ******** Helper Methods ********

/**
 * Creates a titanium object from an API node
 *
 * @private
 * @method
 */
function createObject(apiNode) {
	var obj = new TiObjectType(apiNode),
		properties = apiNode.node.properties,
		property,
		functions = apiNode.node.functions,
		func,
		children = apiNode.children,
		child,
		value,
		name,
		type,
		p, i, len;

	// Add the properties
	for(i = 0, len = properties.length; i < len; i++) {
		property = properties[i];
		name = property.name;
		type = property.type;
		if (name === 'osname' && apiNode.node.name === 'Titanium.Platform') {
			value = new Base.StringType(platform);
		} else if (type in api.children) {
			value = createObject(api.children[type]);
		} else {
			value = new Base.UnknownType();
		}
		value._property = property;
		obj.put(name, value, false, true);
	}

	// Add the methods
	for(i = 0, len = functions.length; i < len; i++) {
		func = functions[i];
		if (func.name === 'include' && apiNode.node.name === 'Titanium') {
			value = new IncludeFunction();
		} else {
			value = new TiFunction(func.returnTypes);
		}
		value._function = func;
		obj.put(func.name, value, false, true);
	}

	// Add the children
	for(p in children) {
		obj.put(p, createObject(children[p]))
	}

	// Return the newly created object
	return obj;
}<|endoftext|>


<commit_before>// ==UserScript==
// @id iitc-plugin-ingressportalcsvexport@zetaphor
// @name IITC Plugin: Ingress Portal CSV Export
// @category Information
// @version 0.0.1
// @namespace http://github.com/Zetaphor/IITC-Ingress-Portal-CSV-Export
// @updateURL http://github.com/Zetaphor/IITC-Ingress-Portal-CSV-Export/raw/master/ingress_export.js
// @downloadURL http://github.com/Zetaphor/IITC-Ingress-Portal-CSV-Export/raw/master/ingress_export.js
// @description Exports portals to a CSV list
// @include https://www.ingress.com/intel*
// @include http://www.ingress.com/intel*
// @match https://www.ingress.com/intel*
// @match http://www.ingress.com/intel*
// @grant none
// ==/UserScript==
/*global $:false */
/*global map:false */
/*global L:false */
function wrapper() {
    // in case IITC is not available yet, define the base plugin object
    if (typeof window.plugin !== "function") {
        window.plugin = function() {};
    }

    // base context for plugin
    window.plugin.portal_csv_export = function() {};
    var self = window.plugin.portal_csv_export;

    window.master_portal_list = {};
    window.portal_scraper_enabled = false;

    self.portalInScreen = function portalInScreen(p) {
        return map.getBounds().contains(p.getLatLng());
    };

    //  adapted from
    //+ Jonas Raoni Soares Silva
    //@ http://jsfromhell.com/math/is-point-in-poly [rev. #0]
    self.portalInPolygon = function portalInPolygon(polygon, portal) {
        var poly = polygon.getLatLngs();
        var pt = portal.getLatLng();
        var c = false;
        for (var i = -1, l = poly.length, j = l - 1; ++i < l; j = i) {
            ((poly[i].lat <= pt.lat && pt.lat < poly[j].lat) || (poly[j].lat <= pt.lat && pt.lat < poly[i].lat)) && (pt.lng < (poly[j].lng - poly[i].lng) * (pt.lat - poly[i].lat) / (poly[j].lat - poly[i].lat) + poly[i].lng) && (c = !c);
        }
        return c;
    };

    // return if the portal is within the drawtool objects.
    // Polygon and circles are available, and circles are implemented
    // as round polygons.
    self.portalInForm = function(layer) {
        if (layer instanceof L.Rectangle) {
            return true;
        }
        if (layer instanceof L.Circle) {
            return true;
        }
        return false;
    };

    self.portalInGeo = function(layer) {
        if (layer instanceof L.GeodesicPolygon) {
            return true;
        }
        if (layer instanceof L.GeodesicCircle) {
            return true;
        }
        return false;
    };

    self.portalInDrawnItems = function(portal) {
        var c = false;

        window.plugin.drawTools.drawnItems.eachLayer(function(layer) {
            if (!(self.portalInForm(layer) || self.portalInGeo(layer))) {
                return false;
            }

            if (self.portalInPolygon(layer, portal)) {
                c = true;
            }
        });
        return c;
    };
    self.inBounds = function(portal) {
        if (window.plugin.drawTools && window.plugin.drawTools.drawnItems.getLayers().length) {
            return self.portalInDrawnItems(portal);
        } else {
            return self.portalInScreen(portal);
        }
    };
    self.genStr = function genStr(title, image, lat, lng, portalGuid) {
        var href = lat + "," + lng;
        var str= "";
        str = title;
        str = str.replace(/\"/g, "\\\"");
        str = str.replace(";", " ");
        str = str + ", " + href + ", " + image;
        if (window.plugin.keys && (typeof window.portals[portalGuid] !== "undefined")) {
            var keyCount =window.plugin.keys.keys[portalGuid] || 0;
            str = str + ";" + keyCount;
        }
        return str;
    };

    self.genStrFromPortal = function genStrFromPortal(portal, portalGuid) {
        var lat = portal._latlng.lat,
            lng = portal._latlng.lng,
            title = portal.options.data.title || "untitled portal";
            image = portal.options.data.image || ""

        return self.genStr(title, image, lat, lng, portalGuid);
    };

    self.addPortalToExportList = function(portalStr, portalGuid) {
        if (typeof window.master_portal_list[portalGuid] == 'undefined') {
            window.master_portal_list[portalGuid] = portalStr;
            var totalScrapedPortals = parseInt($('#totalScrapedPortals').html())
            $('#totalScrapedPortals').html(totalScrapedPortals + 1);
        }
    };

    self.drawRectangle = function() {
        var bounds = window.map.getBounds();

        var rectangle = new google.maps.Rectangle({
            strokeColor: '#FF0000',
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: '#FF0000',
            fillOpacity: 0.35,
            map: window.map,
            bounds: {
                north: bounds._northEast.lat,
                south: bounds._southWest.lat,
                east: bounds._northEast.lng,
                west: bounds._southWest.lng,
            }
        });
    };

    self.managePortals = function managePortals(obj, portal, x) {
        if (self.inBounds(portal)) {
            var str = self.genStrFromPortal(portal, x);
            obj.list.push(str);
            obj.count += 1;
            self.addPortalToExportList(str, x);
        }
        self.drawRectangle();
        return obj;

    };

    self.checkPortals = function checkPortals(portals) {
        var obj = {
            list: [],
            count: 0
        };
        for (var x in portals) {
            if (typeof window.portals[x] !== "undefined") {
                self.managePortals(obj, window.portals[x], x);
            }
        }
        return obj;

    };

    self.generateCsvData = function() {
        var csvData = 'Name, Latitude, Longitude, Image' + "\n";
        $.each(window.master_portal_list, function(key, value) {
            csvData += (value + "\n");
        });

        return csvData;
    };

    self.downloadCSV = function() {
        var csvData = self.generateCsvData();
        var link = document.createElement("a");
        link.download = 'Portal_Export.csv';
        link.href = "data:text/csv," + escape(csvData);
        link.click();
    }

    self.showDialog = function showDialog(o) {
        var csvData = self.generateCsvData();

        var data = `
        <form name='maxfield' action='#' method='post' target='_blank'>

                    <textarea class='form_area'
                        name='portal_list_area'
                        rows='30'
                        placeholder='Zoom level must be 15 or higher for portal data to load'
                        style="width: 100%; white-space: nowrap;">${csvData}</textarea>

        </form>
        `;

        var dia = window.dialog({
            title: "Portal CSV Export",
            html: data
        }).parent();
        $(".ui-dialog-buttonpane", dia).remove();
        dia.css("width", "600px").css("top", ($(window).height() - dia.height()) / 2).css("left", ($(window).width() - dia.width()) / 2);
        return dia;
    };

    self.gen = function gen() {
        var dialog = self.showDialog(window.master_portal_list);
        return dialog;
    };

    self.setZoomLevel = function() {
        window.map.setZoom(15);
        $('#currentZoomLevel').html('15');
        self.updateZoomStatus();
    };

    self.updateZoomStatus = function() {
        var zoomLevel = window.map.getZoom();
        $('#currentZoomLevel').html(window.map.getZoom());
        if (zoomLevel != 15) {
            $('#currentZoomLevel').css('color', 'red');
            if (window.portal_scraper_enabled) $('#scraperStatus').html('Invalid Zoom Level').css('color', 'yellow');
        }
        else $('#currentZoomLevel').css('color', 'green');
    };

    self.updateTimer = function() {
        self.updateZoomStatus();
        if (window.portal_scraper_enabled) {
            if (window.map.getZoom() == 15) {
                if ($('#innerstatus > span.map > span').html() === 'done') {
                    self.checkPortals(window.portals);
                    $('#scraperStatus').html('Running').css('color', 'green');
                } else {
                    $('#scraperStatus').html('Waiting For Map Data').css('color', 'yellow');
                }
            }
        }
    };

    self.panMap = function() {
        window.map.getBounds();
        window.map.panTo({lat: 40.974379, lng: -85.624982});
    };

    self.toggleStatus = function() {
        if (window.portal_scraper_enabled) {
            window.portal_scraper_enabled = false;
            $('#scraperStatus').html('Stopped').css('color', 'red');
            $('#startScraper').show();
            $('#stopScraper').hide();
            $('#csvControlsBox').hide();
            $('#totalPortals').hide();
        } else {
            window.portal_scraper_enabled = true;
            $('#scraperStatus').html('Running').css('color', 'green');
            $('#startScraper').hide();
            $('#stopScraper').show();
            $('#csvControlsBox').show();
            $('#totalPortals').show();
        }

    };

    // setup function called by IITC
    self.setup = function init() {
        // add controls to toolbox
        var link = $("");
        $("#toolbox").append(link);

        var csvToolbox = `

Portal CSV Exporter

            Start
            Stop

                Current Zoom Level: 0
                Set Zoom Level

Scraper Status: Stopped

Total Portals Scraped: 0

                View Data
                Download CSV

        `;

        $(csvToolbox).insertAfter('#toolbox');

        window.csvUpdateTimer = window.setInterval(self.updateTimer, 800);

        // delete self to ensure init can't be run again
        delete self.init;
    };
    // IITC plugin setup
    if (window.iitcLoaded && typeof self.setup === "function") {
        self.setup();
    } else if (window.bootPlugins) {
        window.bootPlugins.push(self.setup);
    } else {
        window.bootPlugins = [self.setup];
    }
}
// inject plugin into page
var script = document.createElement("script");
script.appendChild(document.createTextNode("(" + wrapper + ")();"));
(document.body || document.head || document.documentElement)
.appendChild(script);
<commit_msg>Rectangle now draws around scraped areas<commit_after>// ==UserScript==
// @id iitc-plugin-ingressportalcsvexport@zetaphor
// @name IITC Plugin: Ingress Portal CSV Export
// @category Information
// @version 0.0.1
// @namespace http://github.com/Zetaphor/IITC-Ingress-Portal-CSV-Export
// @updateURL http://github.com/Zetaphor/IITC-Ingress-Portal-CSV-Export/raw/master/ingress_export.js
// @downloadURL http://github.com/Zetaphor/IITC-Ingress-Portal-CSV-Export/raw/master/ingress_export.js
// @description Exports portals to a CSV list
// @include https://www.ingress.com/intel*
// @include http://www.ingress.com/intel*
// @match https://www.ingress.com/intel*
// @match http://www.ingress.com/intel*
// @grant none
// ==/UserScript==
/*global $:false */
/*global map:false */
/*global L:false */
function wrapper() {
    // in case IITC is not available yet, define the base plugin object
    if (typeof window.plugin !== "function") {
        window.plugin = function() {};
    }

    // base context for plugin
    window.plugin.portal_csv_export = function() {};
    var self = window.plugin.portal_csv_export;

    window.master_portal_list = {};
    window.portal_scraper_enabled = false;
    window.current_area_scraped = false;

    self.portalInScreen = function portalInScreen(p) {
        return map.getBounds().contains(p.getLatLng());
    };

    //  adapted from
    //+ Jonas Raoni Soares Silva
    //@ http://jsfromhell.com/math/is-point-in-poly [rev. #0]
    self.portalInPolygon = function portalInPolygon(polygon, portal) {
        var poly = polygon.getLatLngs();
        var pt = portal.getLatLng();
        var c = false;
        for (var i = -1, l = poly.length, j = l - 1; ++i < l; j = i) {
            ((poly[i].lat <= pt.lat && pt.lat < poly[j].lat) || (poly[j].lat <= pt.lat && pt.lat < poly[i].lat)) && (pt.lng < (poly[j].lng - poly[i].lng) * (pt.lat - poly[i].lat) / (poly[j].lat - poly[i].lat) + poly[i].lng) && (c = !c);
        }
        return c;
    };

    // return if the portal is within the drawtool objects.
    // Polygon and circles are available, and circles are implemented
    // as round polygons.
    self.portalInForm = function(layer) {
        if (layer instanceof L.Rectangle) {
            return true;
        }
        if (layer instanceof L.Circle) {
            return true;
        }
        return false;
    };

    self.portalInGeo = function(layer) {
        if (layer instanceof L.GeodesicPolygon) {
            return true;
        }
        if (layer instanceof L.GeodesicCircle) {
            return true;
        }
        return false;
    };

    self.portalInDrawnItems = function(portal) {
        var c = false;

        window.plugin.drawTools.drawnItems.eachLayer(function(layer) {
            if (!(self.portalInForm(layer) || self.portalInGeo(layer))) {
                return false;
            }

            if (self.portalInPolygon(layer, portal)) {
                c = true;
            }
        });
        return c;
    };
    self.inBounds = function(portal) {
        if (window.plugin.drawTools && window.plugin.drawTools.drawnItems.getLayers().length) {
            return self.portalInDrawnItems(portal);
        } else {
            return self.portalInScreen(portal);
        }
    };
    self.genStr = function genStr(title, image, lat, lng, portalGuid) {
        var href = lat + "," + lng;
        var str= "";
        str = title;
        str = str.replace(/\"/g, "\\\"");
        str = str.replace(";", " ");
        str = str + ", " + href + ", " + image;
        if (window.plugin.keys && (typeof window.portals[portalGuid] !== "undefined")) {
            var keyCount =window.plugin.keys.keys[portalGuid] || 0;
            str = str + ";" + keyCount;
        }
        return str;
    };

    self.genStrFromPortal = function genStrFromPortal(portal, portalGuid) {
        var lat = portal._latlng.lat,
            lng = portal._latlng.lng,
            title = portal.options.data.title || "untitled portal";
            image = portal.options.data.image || ""

        return self.genStr(title, image, lat, lng, portalGuid);
    };

    self.addPortalToExportList = function(portalStr, portalGuid) {
        if (typeof window.master_portal_list[portalGuid] == 'undefined') {
            window.master_portal_list[portalGuid] = portalStr;
            // var totalScrapedPortals = parseInt($('#totalScrapedPortals').html())
            self.updateTotalScrapedCount()
        }
    };

    self.updateTotalScrapedCount = function() {
        $('#totalScrapedPortals').html(Object.keys(window.master_portal_list).length);
    };

    self.drawRectangle = function() {
        var bounds = window.map.getBounds();
        var bounds = [[bounds._southWest.lat, bounds._southWest.lng], [bounds._northEast.lat, bounds._northEast.lng]];
        L.rectangle(bounds, {color: "#00ff11", weight: 1, opacity: 0.9}).addTo(window.map);
    };

    self.managePortals = function managePortals(obj, portal, x) {
        if (self.inBounds(portal)) {
            var str = self.genStrFromPortal(portal, x);
            obj.list.push(str);
            obj.count += 1;
            self.addPortalToExportList(str, x);
        }
        return obj;

    };

    self.checkPortals = function checkPortals(portals) {
        var obj = {
            list: [],
            count: 0
        };
        for (var x in portals) {
            if (typeof window.portals[x] !== "undefined") {
                self.managePortals(obj, window.portals[x], x);
            }
        }
        return obj;

    };

    self.generateCsvData = function() {
        var csvData = 'Name, Latitude, Longitude, Image' + "\n";
        $.each(window.master_portal_list, function(key, value) {
            csvData += (value + "\n");
        });

        return csvData;
    };

    self.downloadCSV = function() {
        var csvData = self.generateCsvData();
        var link = document.createElement("a");
        link.download = 'Portal_Export.csv';
        link.href = "data:text/csv," + escape(csvData);
        link.click();
    }

    self.showDialog = function showDialog(o) {
        var csvData = self.generateCsvData();

        var data = `
        <form name='maxfield' action='#' method='post' target='_blank'>

                    <textarea class='form_area'
                        name='portal_list_area'
                        rows='30'
                        placeholder='Zoom level must be 15 or higher for portal data to load'
                        style="width: 100%; white-space: nowrap;">${csvData}</textarea>

        </form>
        `;

        var dia = window.dialog({
            title: "Portal CSV Export",
            html: data
        }).parent();
        $(".ui-dialog-buttonpane", dia).remove();
        dia.css("width", "600px").css("top", ($(window).height() - dia.height()) / 2).css("left", ($(window).width() - dia.width()) / 2);
        return dia;
    };

    self.gen = function gen() {
        var dialog = self.showDialog(window.master_portal_list);
        return dialog;
    };

    self.setZoomLevel = function() {
        window.map.setZoom(15);
        $('#currentZoomLevel').html('15');
        self.updateZoomStatus();
    };

    self.updateZoomStatus = function() {
        var zoomLevel = window.map.getZoom();
        $('#currentZoomLevel').html(window.map.getZoom());
        if (zoomLevel != 15) {
            window.current_area_scraped = false;
            $('#currentZoomLevel').css('color', 'red');
            if (window.portal_scraper_enabled) $('#scraperStatus').html('Invalid Zoom Level').css('color', 'yellow');
        }
        else $('#currentZoomLevel').css('color', 'green');
    };

    self.updateTimer = function() {
        self.updateZoomStatus();
        if (window.portal_scraper_enabled) {
            if (window.map.getZoom() == 15) {
                if ($('#innerstatus > span.map > span').html() === 'done') {
                    if (!window.current_area_scraped) {
                        self.checkPortals(window.portals);
                        window.current_area_scraped = true;
                        $('#scraperStatus').html('Running').css('color', 'green');
                        self.drawRectangle();
                    } else {
                        $('#scraperStatus').html('Area Scraped').css('color', 'green');
                    }
                } else {
                    current_area_scraped = false;
                    $('#scraperStatus').html('Waiting For Map Data').css('color', 'yellow');
                }
            }
        }
    };

    self.panMap = function() {
        window.map.getBounds();
        window.map.panTo({lat: 40.974379, lng: -85.624982});
    };

    self.toggleStatus = function() {
        if (window.portal_scraper_enabled) {
            window.portal_scraper_enabled = false;
            $('#scraperStatus').html('Stopped').css('color', 'red');
            $('#startScraper').show();
            $('#stopScraper').hide();
            $('#csvControlsBox').hide();
            $('#totalPortals').hide();
        } else {
            window.portal_scraper_enabled = true;
            $('#scraperStatus').html('Running').css('color', 'green');
            $('#startScraper').hide();
            $('#stopScraper').show();
            $('#csvControlsBox').show();
            $('#totalPortals').show();
            self.updateTotalScrapedCount();
        }

    };

    // setup function called by IITC
    self.setup = function init() {
        // add controls to toolbox
        var link = $("");
        $("#toolbox").append(link);

        var csvToolbox = `

Portal CSV Exporter

            Start
            Stop

                Current Zoom Level: 0
                Set Zoom Level

Scraper Status: Stopped

Total Portals Scraped: 0

                View Data
                Download CSV

        `;

        $(csvToolbox).insertAfter('#toolbox');

        window.csvUpdateTimer = window.setInterval(self.updateTimer, 500);

        // delete self to ensure init can't be run again
        delete self.init;
    };
    // IITC plugin setup
    if (window.iitcLoaded && typeof self.setup === "function") {
        self.setup();
    } else if (window.bootPlugins) {
        window.bootPlugins.push(self.setup);
    } else {
        window.bootPlugins = [self.setup];
    }
}
// inject plugin into page
var script = document.createElement("script");
script.appendChild(document.createTextNode("(" + wrapper + ")();"));
(document.body || document.head || document.documentElement)
.appendChild(script);
<|endoftext|>


<commit_before>// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Generation of reference from protos

'use strict';

const protobufjs = require('protobufjs');
const fs = require('fs');
const path = require('path');
const argv = require('yargs').argv

const PROJECT_ROOT =
    path.dirname(path.dirname(path.dirname(path.dirname(__filename))));

const visited = {};

// Removes \n due to 80col wrapping and preserves only end-of-sentence line
// breaks.
function singleLineComment(comment) {
  comment = comment || '';
  comment = comment.trim();
  comment = comment.replace(/[.:?!]\n/g, '
');
  comment = comment.replace(/[|]/g, '`');
  comment = comment.replace(/\n/g, ' ');
  return comment;
}

function getFullName(pType) {
  let cur = pType;
  let name = pType.name;
  while (cur && cur.parent != cur && cur.parent instanceof protobufjs.Type) {
    name = `${cur.parent.name}.${name}`;
    cur = cur.parent;
  }
  return name;
}

function genType(pType, depth) {
  depth = depth || 0;
  console.assert(pType instanceof protobufjs.ReflectionObject);
  const fullName = getFullName(pType);
  if (fullName in visited)
    return '';
  visited[fullName] = true;

  const heading = '#' +
      '#'.repeat(Math.min(depth, 2));
  const anchor = depth > 0 ? `{#${fullName}} ` : '';
  let md = `${heading} ${anchor}${fullName}`;
  md += '\n';
  const fileName = path.basename(pType.filename);
  const relPath = path.relative(PROJECT_ROOT, pType.filename);

  // Remove Next id: NN lines.
  md += `${(pType.comment || '').replace(/(\n)?^\s*next.*\bid:.*$/img, '')}`;
  md += `\n\nDefined in [${fileName}](/${relPath})\n\n`;

  const subTypes = [];

  if (pType instanceof protobufjs.Enum) {
    md += '#### Enum values:\n';
    md += 'Name | Value | Description\n';
    md += '---- | ----- | -----------\n';
    for (const enumName of Object.keys(pType.values)) {
      const enumVal = pType.values[enumName];
      const comment = singleLineComment(pType.comments[enumName]);
      md += `${enumName} | ${enumVal} | ${comment}\n`
    }
  } else {
    md += '#### Fields:\n';
    md += 'Field | Type | Description\n';
    md += '----- | ---- | -----------\n';

    for (const fieldName in pType.fields) {
      const field = pType.fields[fieldName];
      let type = field.type;
      if (field.repeated) {
        type = `${type}[]`;
      }
      if (field.resolvedType) {
        // The TraceConfig proto is linked from the TracePacket reference.
        // Instead of recursing and generating the TraceConfig types all over
        // again, just link to the dedicated TraceConfig reference page.
        if (getFullName(field.resolvedType) === 'TraceConfig') {
          type = `[${type}](/docs/reference/trace-config-proto.autogen)`;
        } else {
          subTypes.push(field.resolvedType);
          type = `[${type}](#${getFullName(field.resolvedType)})`;
        }
      }
      md += `${fieldName} | ${type} | ${singleLineComment(field.comment)}\n`
    }
  }
  md += '\n\n\n\n';

  for (const subType of subTypes)
    md += genType(subType, depth + 1);

  return md;
}

function main() {
  const inProtoFile = argv['i'];
  const protoName = argv['p'];
  const outFile = argv['o'];
  if (!inProtoFile || !protoName) {
    console.error('Usage: -i input.proto -p protos.RootType [-o out.md]');
    process.exit(1);
  }

  const parser = new protobufjs.Root();
  parser.resolvePath = (_, target) => {
    if (target == inProtoFile) {
      // The root proto file passed from the cmdline will be relative to the
      // root_build_dir (out/xxx) (e.g.: ../../protos/config)
      return inProtoFile;
    }
    // All the other imports, instead, will be relative to the project root
    // (e.g. protos/config/...)
    return path.join(PROJECT_ROOT, target);
  };

  const cfg = parser.loadSync(
      inProtoFile, {alternateCommentMode: true, keepCase: true});
  cfg.resolveAll();
  const traceConfig = cfg.lookup(protoName);
  const generatedMd = genType(traceConfig);
  if (outFile) {
    fs.writeFileSync(outFile, generatedMd);
  } else {
    console.log(generatedMd);
  }
  process.exit(0);
}

main();
<commit_msg>Docs: more small improvements to markdown renderer for proto reference. am: 8ddf5ae4b8 am: 821f45903c am: b6f630f3ee<commit_after>// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Generation of reference from protos

'use strict';

const protobufjs = require('protobufjs');
const fs = require('fs');
const path = require('path');
const argv = require('yargs').argv

const PROJECT_ROOT =
    path.dirname(path.dirname(path.dirname(path.dirname(__filename))));

const visited = {};

// This function is used to escape:
// - The message-level comment, which becomes a full paragraph.
// - The per-field comments, rendered as as table.
function escapeCommentCommon(comment) {
  comment = comment || '';

  // Remove Next id: NN lines.
  comment = comment.replace(/(\n)?^\s*next.*\bid:.*$/img, '');

  // Hide our little dirty secrets.
  comment = comment.replace(/(\n)?^\s*TODO\(\w+\):.*$/img, '');

  // Turn |variable| references into `variable`.
  comment = comment.replace(/[|](\w+?)[|]/g, '`$1`');
  return comment;
}

// This is used to escape only the per-field comments.
// Removes \n due to 80col wrapping and preserves only end-of-sentence line
// breaks.
function singleLineComment(comment) {
  comment = escapeCommentCommon(comment);
  comment = comment.trim();
  comment = comment.replace(/([.:?!])\n/g, '$1
');
  comment = comment.replace(/\n/g, ' ');
  return comment;
}

function getFullName(pType) {
  let cur = pType;
  let name = pType.name;
  while (cur && cur.parent != cur && cur.parent instanceof protobufjs.Type) {
    name = `${cur.parent.name}.${name}`;
    cur = cur.parent;
  }
  return name;
}

function genType(pType, depth) {
  depth = depth || 0;
  console.assert(pType instanceof protobufjs.ReflectionObject);
  const fullName = getFullName(pType);
  if (fullName in visited)
    return '';
  visited[fullName] = true;

  const heading = '#' +
      '#'.repeat(Math.min(depth, 2));
  const anchor = depth > 0 ? `{#${fullName}} ` : '';
  let md = `${heading} ${anchor}${fullName}`;
  md += '\n';
  const fileName = path.basename(pType.filename);
  const relPath = path.relative(PROJECT_ROOT, pType.filename);

  md += escapeCommentCommon(pType.comment);
  md += `\n\nDefined in [${fileName}](/${relPath})\n\n`;

  const subTypes = [];

  if (pType instanceof protobufjs.Enum) {
    md += '#### Enum values:\n';
    md += 'Name | Value | Description\n';
    md += '---- | ----- | -----------\n';
    for (const enumName of Object.keys(pType.values)) {
      const enumVal = pType.values[enumName];
      const comment = singleLineComment(pType.comments[enumName]);
      md += `${enumName} | ${enumVal} | ${comment}\n`
    }
  } else {
    md += '#### Fields:\n';
    md += 'Field | Type | Description\n';
    md += '----- | ---- | -----------\n';

    for (const fieldName in pType.fields) {
      const field = pType.fields[fieldName];
      let type = field.type;
      if (field.repeated) {
        type = `${type}[]`;
      }
      if (field.resolvedType) {
        // The TraceConfig proto is linked from the TracePacket reference.
        // Instead of recursing and generating the TraceConfig types all over
        // again, just link to the dedicated TraceConfig reference page.
        if (getFullName(field.resolvedType) === 'TraceConfig') {
          type = `[${type}](/docs/reference/trace-config-proto.autogen)`;
        } else {
          subTypes.push(field.resolvedType);
          type = `[${type}](#${getFullName(field.resolvedType)})`;
        }
      }
      md += `${fieldName} | ${type} | ${singleLineComment(field.comment)}\n`
    }
  }
  md += '\n\n\n\n';

  for (const subType of subTypes)
    md += genType(subType, depth + 1);

  return md;
}

function main() {
  const inProtoFile = argv['i'];
  const protoName = argv['p'];
  const outFile = argv['o'];
  if (!inProtoFile || !protoName) {
    console.error('Usage: -i input.proto -p protos.RootType [-o out.md]');
    process.exit(1);
  }

  const parser = new protobufjs.Root();
  parser.resolvePath = (_, target) => {
    if (target == inProtoFile) {
      // The root proto file passed from the cmdline will be relative to the
      // root_build_dir (out/xxx) (e.g.: ../../protos/config)
      return inProtoFile;
    }
    // All the other imports, instead, will be relative to the project root
    // (e.g. protos/config/...)
    return path.join(PROJECT_ROOT, target);
  };

  const cfg = parser.loadSync(
      inProtoFile, {alternateCommentMode: true, keepCase: true});
  cfg.resolveAll();
  const traceConfig = cfg.lookup(protoName);
  const generatedMd = genType(traceConfig);
  if (outFile) {
    fs.writeFileSync(outFile, generatedMd);
  } else {
    console.log(generatedMd);
  }
  process.exit(0);
}

main();
<|endoftext|>


<commit_before>(function($) {

  var SlickFormatter = {

    ///////////////////////////////////////////////////////////////////////////
    // Helpers
    ///////////////////////////////////////////////////////////////////////////

    applyStyle: function(value, styleClass = '', style = '') {
      return value === null ? "" : "" + value + "";
    },

    parseDateTime: function(dateTimeStr) {
      try {
        var REGEX_DATE = '(\\d{2})\\/(\\d{2})\\/(\\d{4})'; // 'yyyy-mm-dd'
        var REGEX_TIME = '(\\d{2}):(\\d{2})'; // 'hh:mm'
        var matchedArr = dateTimeStr.match(new RegExp('^' + REGEX_DATE + '[ \\t]' + REGEX_TIME + '$'));

        return {
          day: matchedArr[1],
          month: matchedArr[2],
          year: matchedArr[3],
          hour: matchedArr[4],
          minute: matchedArr[5]
        };
      } catch (err) {
        return null;
      }
    },

    ///////////////////////////////////////////////////////////////////////////
    // Formatters
    ///////////////////////////////////////////////////////////////////////////

    BaseFormatter: function(row, cell, value, columnDef, dataContext) {
      var source = columnDef.source;
      var inner_formatter = columnDef.inner_formatter;

      // Retrive info for relation columns
      if (source && typeof value === 'object') {
        value = value[source];
      }

      // Apply format for relation columns
      if (inner_formatter) {
        if (inner_formatter == 'boolean') {
          value = TextBoolCellFormatter(row, cell, eval(value), columnDef, dataContext);
        } else if (typeof(window[inner_formatter]) == 'function') {
          value = window[inner_formatter](row, cell, value, columnDef, dataContext);
        }
      }

      // Filter `null` value for 'has_many' columns
      value = (columnDef.type === 'has_many' && value === 'null') ? '' : value;

      // Set default text-align
      var textAlign, default_style;
      if (columnDef.type == 'datetime' ||
        columnDef.type == 'date' ||
        columnDef.type == 'time') {
        textAlign = 'center';
      }
      default_style = textAlign ? 'text-align:' + textAlign : ''

      // Apply style
      return applyStyle(value, columnDef.style_class, columnDef.style || default_style);
    },

    MoneyFormatter: function(row, cell, value, columnDef, dataContext) {
      var currency = columnDef.currency || "$";
      var text = (value === null || value === undefined || value === '') ? '' : parseFloat(value).toMoney(2, '.', ',') + ' ' + currency;
      return applyStyle(text, columnDef.style_class, columnDef.style || 'text-align:right');
    },

    TextBoolCellFormatter: function(row, cell, value, columnDef, dataContext) {
      var text = value === null ? "" : (value ? 'Yes' : 'No');
      return applyStyle(text, columnDef.style_class, columnDef.style || 'text-align:center');
    },

    GraphicBoolCellFormatter: function(row, cell, value, columnDef, dataContext) {
      var checked = value ? 'checked="checked"' : '';
      var html = '<input disabled type="checkbox" class="filled-in" ' +
        checked + ' id="show-checkbox-' + row + '" />' +
        '';
      return applyStyle(html, columnDef.style_class, columnDef.style || 'text-align:center');
    },

    ZeroFormatter: function(row, cell, value, columnDef, dataContext) {
      var text = value === 0 ? "" : value;
      return applyStyle(text, columnDef.style_class, columnDef.style || 'text-align:right');
    },

    TooltipFormatter: function(row, cell, value, columnDef, dataContext) {
      return "
" + applyStyle(value, columnDef.style_class, columnDef.style || 'text-align:center') + "
";
    },

    // Support image tag on grid
    ImageFormatter: function(row, cell, value, columnDef, dataContext) {
      if (value == null) { return ""; }

      var style = columnDef.style || 'text-align:center';
      return "

";
    }
  };

  $.extend(window, SlickFormatter);

})(jQuery);
<commit_msg>BUG #63 - Make cucumber pass by avoiding ES6<commit_after>(function($) {

  var SlickFormatter = {

    ///////////////////////////////////////////////////////////////////////////
    // Helpers
    ///////////////////////////////////////////////////////////////////////////

    applyStyle: function(value, styleClass, style) {
      return value === null ? "" : "" + value + "";
    },

    parseDateTime: function(dateTimeStr) {
      try {
        var REGEX_DATE = '(\\d{2})\\/(\\d{2})\\/(\\d{4})'; // 'yyyy-mm-dd'
        var REGEX_TIME = '(\\d{2}):(\\d{2})'; // 'hh:mm'
        var matchedArr = dateTimeStr.match(new RegExp('^' + REGEX_DATE + '[ \\t]' + REGEX_TIME + '$'));

        return {
          day: matchedArr[1],
          month: matchedArr[2],
          year: matchedArr[3],
          hour: matchedArr[4],
          minute: matchedArr[5]
        };
      } catch (err) {
        return null;
      }
    },

    ///////////////////////////////////////////////////////////////////////////
    // Formatters
    ///////////////////////////////////////////////////////////////////////////

    BaseFormatter: function(row, cell, value, columnDef, dataContext) {
      var source = columnDef.source;
      var inner_formatter = columnDef.inner_formatter;

      // Retrive info for relation columns
      if (source && typeof value === 'object') {
        value = value[source];
      }

      // Apply format for relation columns
      if (inner_formatter) {
        if (inner_formatter == 'boolean') {
          value = TextBoolCellFormatter(row, cell, eval(value), columnDef, dataContext);
        } else if (typeof(window[inner_formatter]) == 'function') {
          value = window[inner_formatter](row, cell, value, columnDef, dataContext);
        }
      }

      // Filter `null` value for 'has_many' columns
      value = (columnDef.type === 'has_many' && value === 'null') ? '' : value;

      // Set default text-align
      var textAlign, default_style;
      if (columnDef.type == 'datetime' ||
        columnDef.type == 'date' ||
        columnDef.type == 'time') {
        textAlign = 'center';
      }
      default_style = textAlign ? 'text-align:' + textAlign : ''

      // Apply style
      return applyStyle(value, columnDef.style_class, columnDef.style || default_style);
    },

    MoneyFormatter: function(row, cell, value, columnDef, dataContext) {
      var currency = columnDef.currency || "$";
      var text = (value === null || value === undefined || value === '') ? '' : parseFloat(value).toMoney(2, '.', ',') + ' ' + currency;
      return applyStyle(text, columnDef.style_class, columnDef.style || 'text-align:right');
    },

    TextBoolCellFormatter: function(row, cell, value, columnDef, dataContext) {
      var text = value === null ? "" : (value ? 'Yes' : 'No');
      return applyStyle(text, columnDef.style_class, columnDef.style || 'text-align:center');
    },

    GraphicBoolCellFormatter: function(row, cell, value, columnDef, dataContext) {
      var checked = value ? 'checked="checked"' : '';
      var html = '<input disabled type="checkbox" class="filled-in" ' +
        checked + ' id="show-checkbox-' + row + '" />' +
        '';
      return applyStyle(html, columnDef.style_class, columnDef.style || 'text-align:center');
    },

    ZeroFormatter: function(row, cell, value, columnDef, dataContext) {
      var text = value === 0 ? "" : value;
      return applyStyle(text, columnDef.style_class, columnDef.style || 'text-align:right');
    },

    TooltipFormatter: function(row, cell, value, columnDef, dataContext) {
      return "
" + applyStyle(value, columnDef.style_class, columnDef.style || 'text-align:center') + "
";
    },

    // Support image tag on grid
    ImageFormatter: function(row, cell, value, columnDef, dataContext) {
      if (value == null) { return ""; }

      var style = columnDef.style || 'text-align:center';
      return "

";
    }
  };

  $.extend(window, SlickFormatter);

})(jQuery);
<|endoftext|>


<commit_before>YUI.add('aui-form-validator-tests', function(Y) {

    //--------------------------------------------------------------------------
    // AUI Form Validator Unit Tests
    //--------------------------------------------------------------------------

    var suite = new Y.Test.Suite('aui-form-validator'),
        formValidator;

    formValidator = new Y.FormValidator({
        boundingBox: '#myForm',
        fieldStrings: {
            email: {
                required: 'Type your email in this field.'
            },
            name: {
                required: 'Please provide your name.'
            }
        },
        rules: {
            age: {
                required: true
            },
            email: {
                email: true,
                required: true
            },
            emailConfirmation: {
                email: true,
                equalTo: '#email',
                required: true
            },
            gender: {
                required: true
            },
            name: {
                rangeLength: [2, 50],
                required: true
            },
            picture: {
                acceptFiles: 'jpg, gif, png',
                required: true
            },
            read: {
                required: true
            },
            url: {
                required: true,
                url: true
            }
        },
        showAllMessages: true
    });

    //--------------------------------------------------------------------------
    // Test Case for invalid fields
    //--------------------------------------------------------------------------

    suite.add(new Y.Test.Case({

        name: 'AUI Form Submit Form Tests',

        /*
         * Check if on submit all fields are marked as invalid
         * Tests: AUI-965
         */
        'test submit form': function() {
            var buttonSubmit,
                elementWithoutError,
                form;

            form = Y.one('#myForm');

            form.simulate('submit');

            elementWithoutError = Y.one('.control-group:not(.error)');

            Y.Assert.isNull(elementWithoutError, 'There shouldn\'t be any element without class error');
        },

        /*
         * Check if validator nodes render after the input and lable's textNode
         * Tests: AUI-965
         */
        'test error message displayed after label': function() {
            var instance = this;

            instance._assertValidatorNextLabel('input[value=male]');

            instance._assertValidatorNextLabel('input[name=read]');
        },

        _assertValidatorNextLabel: function(input) {
            var inputNode,
                textNode;

            inputNode = Y.one(input);

            textNode = inputNode.get('nextSibling');

            Y.Assert.isTrue(textNode.get('nodeType') === 3, 'Next to the input should be a text node');

            Y.Assert.isTrue(
                textNode.next().hasClass('form-validator-stack'),
                'Next to the input should be form validator');
        }
    }));

    Y.Test.Runner.add(suite);

}, '', {
    requires: ['test', 'aui-form-validator', 'node-event-simulate']
});
<commit_msg>AUI-1204 Adding tests<commit_after>YUI.add('aui-form-validator-tests', function(Y) {

    //--------------------------------------------------------------------------
    // AUI Form Validator Unit Tests
    //--------------------------------------------------------------------------

    var suite = new Y.Test.Suite('aui-form-validator'),
        formValidator;

    formValidator = new Y.FormValidator({
        boundingBox: '#myForm',
        fieldStrings: {
            email: {
                required: 'Type your email in this field.'
            },
            name: {
                required: 'Please provide your name.'
            }
        },
        rules: {
            age: {
                required: true
            },
            email: {
                email: true,
                required: true
            },
            emailConfirmation: {
                email: true,
                equalTo: '#email',
                required: true
            },
            gender: {
                required: true
            },
            name: {
                rangeLength: [2, 50],
                required: true
            },
            picture: {
                acceptFiles: 'jpg, gif, png',
                required: true
            },
            read: {
                required: true
            },
            url: {
                required: true,
                url: true
            }
        },
        showAllMessages: true
    });

    //--------------------------------------------------------------------------
    // Test Case for invalid fields
    //--------------------------------------------------------------------------

    suite.add(new Y.Test.Case({

        name: 'AUI Form Submit Form Tests',

        /*
         * Check if on submit all fields are marked as invalid
         * Tests: AUI-965
         */
        'test submit form': function() {
            var buttonSubmit,
                elementWithoutError,
                form;

            form = Y.one('#myForm');

            form.simulate('submit');

            elementWithoutError = Y.one('.control-group:not(.error)');

            Y.Assert.isNull(elementWithoutError, 'There shouldn\'t be any element without class error');
        },

        /*
         * Check if validator nodes render after the input and lable's textNode
         * Tests: AUI-965
         */
        'test error message displayed after label': function() {
            var instance = this;

            instance._assertValidatorNextLabel('input[value=male]');

            instance._assertValidatorNextLabel('input[name=read]');
        },

        /*
         * Check if validator correctly validates <select> html fields
         * Tests: AUI-1204
         */
        'test submit empty select': function() {
            var form = Y.Node.create('<form><select name="gender"></select></form>');

            var select = form.one('select');

            var emptyOption = Y.Node.create('<option value=""></option>').appendTo(select);

            var validOption = Y.Node.create('<option value=\"male\">Male</option>').appendTo(select);

            var validator = new Y.FormValidator(
                {
                    boundingBox: form,
                    rules: {
                        gender: {
                            required: true
                        }
                    }
                }
            );

            form.simulate('submit');

            Y.Assert.isTrue(validator.hasErrors());

            validOption.attr('selected', 'selected');

            form.simulate('submit');

            Y.Assert.isFalse(validator.hasErrors());
        },

        _assertValidatorNextLabel: function(input) {
            var inputNode,
                textNode;

            inputNode = Y.one(input);

            textNode = inputNode.get('nextSibling');

            Y.Assert.isTrue(textNode.get('nodeType') === 3, 'Next to the input should be a text node');

            Y.Assert.isTrue(
                textNode.next().hasClass('form-validator-stack'),
                'Next to the input should be form validator');
        }
    }));

    Y.Test.Runner.add(suite);

}, '', {
    requires: ['test', 'aui-form-validator', 'node-event-simulate']
});
<|endoftext|>


<commit_before>import "../legacy/d3/d3v5Min.js";
import "../legacy/CXGN/Dataset.js";

/**
 * WizardDownloads - Creates a new WizardDownloads object.
 *
 * @class
 * @classdesc links to a wizard and manages showing relavant related data
 * @param  {type} main_id div to draw within
 * @param  {type} wizard wizard to link to
 * @returns {Object}
 */

function openWindowWithPost(url, data) {
  var form = document.createElement("form");
  form.target = "_blank";
  form.method = "POST";
  form.action = url;
  form.style.display = "none";

  for (var key in data) {
    var input = document.createElement("input");
    input.type = "hidden";
    input.name = key;
    input.value = data[key];
    form.appendChild(input);
  }

  document.body.appendChild(form);
  form.submit();
  document.body.removeChild(form);
}

export function WizardDownloads(main_id,wizard){
  var main = d3.select(main_id);
  var datasets = new CXGN.Dataset();

  var categories = [];
  var selections = {};
  var operations = {};
  wizard.on_change((c,s,o)=>{
    categories = c;
    selections = s;
    operations = o;

    // Genotype downloads
    var accessions = categories.indexOf("accessions")!=-1?
      selections["accessions"]:
      [];
    var traits = categories.indexOf("traits")!=-1?
      selections["traits"]:
      [];
    var protocols = categories.indexOf("genotyping_protocols")!=-1?
      selections["genotyping_protocols"]:
      [];
    main.select(".wizard-download-genotypes-info")
      .attr("value",`${accessions.length||"Too few"} accessions, ${
        protocols.length==1?"selected protocol":
        protocols.length>1?"too many protocols selected":
        "default protocol"
      }`);
    main.selectAll(".wizard-download-genotypes")
      .attr("disabled",!!accessions.length&&protocols.length<=1?null:true)
      .on("click",()=>{
        event.preventDefault();
        var accession_ids = accessions.map(d=>d.id);
        var trial_ids = (selections["trials"]||[]).map(d=>d.id);
        var protocol_id = protocols.length==1?protocols[0].id:'';
        var chromosome_number = d3.select(".wizard-download-genotypes-chromosome-number").node().value;
        var start_position = d3.select(".wizard-download-genotypes-start-position").node().value;
        var end_position = d3.select(".wizard-download-genotypes-end-position").node().value;
        var download_format = d3.select(".wizard-download-genotypes-format").node().value;
        var compute_from_parents = d3.select(".wizard-download-genotypes-parents-compute").property("checked");
        var include_duplicate_genotypes = d3.select(".wizard-download-genotypes-duplicates-include").property("checked");
        var marker_set_list_id = d3.select(".wizard-download-genotypes-marker-set-list-id").node().value;
        if(chromosome_number && marker_set_list_id) {
            alert(`Please indicate either chromosome or markerset, not both.`);
            d3.select(this).attr("disabled",null);
            return;
        }
        var url = document.location.origin+'/breeders/download_gbs_action';
        openWindowWithPost(url, {
            ids: accession_ids.join(","),
            protocol_id: protocol_id,
            format: accession_ids,
            chromosome_number: chromosome_number,
            start_position: start_position,
            end_position: end_position,
            trial_ids: trial_ids.join(","),
            download_format: download_format,
            compute_from_parents: compute_from_parents,
            marker_set_list_id: marker_set_list_id,
            include_duplicate_genotypes: include_duplicate_genotypes,
        });
        // window.open(url,'_blank');
      });
    main.selectAll(".wizard-download-genetic-relationship-matrix")
      .attr("disabled",!!accessions.length&&protocols.length<=1?null:true)
      .on("click",()=>{
        event.preventDefault();
        var accession_ids = accessions.map(d=>d.id);
        var trial_ids = (selections["trials"]||[]).map(d=>d.id);
        var protocol_id = protocols.length==1?protocols[0].id:'';
        var download_format = d3.select(".wizard-download-genotypes-grm-format").node().value;
        var maf = d3.select(".wizard-download-genotypes-grm-maf").node().value;
        var marker_filter = d3.select(".wizard-download-genotypes-grm-marker-filter").node().value;
        var individuals_filter = d3.select(".wizard-download-genotypes-grm-individuals-filter").node().value;
        var compute_from_parents = d3.select(".wizard-download-genotypes-parents-compute").property("checked");
        var url = document.location.origin+'/breeders/download_grm_action';
        openWindowWithPost(url, {
            ids: accession_ids.join(","),
            protocol_id: protocol_id,
            format: accession_ids,
            trial_ids: trial_ids.join(","),
            download_format: download_format,
            compute_from_parents: compute_from_parents,
            minor_allele_frequency: maf,
            marker_filter: marker_filter,
            individuals_filter: individuals_filter,
        });
        // window.open(url,'_blank');
      });
    main.selectAll(".wizard-download-gwas")
        .attr("disabled",!!traits.length&&accessions.length&&protocols.length<=1?null:true)
        .on("click",()=>{
          event.preventDefault();
          var accession_ids = accessions.map(d=>d.id);
          var trait_ids = traits.map(d=>d.id);
          var protocol_id = protocols.length==1?protocols[0].id:'';
          var maf = d3.select(".wizard-download-genotypes-grm-maf").node().value;
          var marker_filter = d3.select(".wizard-download-genotypes-grm-marker-filter").node().value;
          var individuals_filter = d3.select(".wizard-download-genotypes-grm-individuals-filter").node().value;
          var download_format = d3.select(".wizard-download-genotypes-gwas-format").node().value;
          var repeated_measurements = d3.select(".wizard-download-genotypes-gwas-repeated-measurements").node().value;
          var compute_from_parents = d3.select(".wizard-download-genotypes-parents-compute").property("checked");
          var url = document.location.origin+'/breeders/download_gwas_action';
          openWindowWithPost(url, {
            ids: accession_ids.join(","),
            protocol_id: protocol_id,
            format: accession_ids,
            trait_ids: trait_ids.join(","),
            compute_from_parents: compute_from_parents,
            minor_allele_frequency: maf,
            marker_filter: marker_filter,
            individuals_filter: individuals_filter,
            download_format: download_format,
            traits_are_repeated_measurements: repeated_measurements,
          });
          // window.open(url,'_blank');
      });
    // Download Trial Metadata
    var trials = categories.indexOf("trials")!=-1 ? selections["trials"] : [];
    main.selectAll(".wizard-download-tmetadata-info")
      .attr("value",`${trials.length||"Too few"} trials`);
    main.selectAll(".wizard-download-tmetadata")
      .attr("disabled",trials.length>0?null:true)
      .on("click",()=>{
        var t_ids = JSON.stringify(trials.map(d=>d.id));
        var format = d3.select(".wizard-download-tmetadata-format").node().value;
        var url = document.location.origin+'/breeders/trials/phenotype/download';
        openWindowWithPost(url, {
            trial_list: t_ids,
            format: format,
            dataLevel: 'metadata'
        });
        // window.open(url,'_blank');
      });

    // Download Trial Phenotypes
    var trials = categories.indexOf("trials")!=-1 ? selections["trials"] : [];
    var traits = categories.indexOf("traits")!=-1 ? selections["traits"] : [];
    var comps = categories.indexOf("trait_components")!=-1 ? selections["trait_components"] : [];
    var plots = categories.indexOf("plots")!=-1 ? selections["plots"] : [];
    var plants = categories.indexOf("plants")!=-1 ? selections["plants"] : [];
    var locations = categories.indexOf("locations")!=-1 ? selections["locations"] : [];
    var years = categories.indexOf("years")!=-1 ? selections["years"] : [];

    main.selectAll(".wizard-download-phenotypes-info")
      .attr("value",`${trials.length||"Too few"} trials`);
    main.selectAll(".wizard-download-phenotypes")
      .attr("disabled",trials.length>0?null:true)
      .on("click",()=>{
        var trial_ids = JSON.stringify(trials.map(d=>d.id));
        var trait_ids = JSON.stringify(traits.map(d=>d.id));
        var comp_ids = JSON.stringify(comps.map(d=>d.id));
        var accession_ids = JSON.stringify(accessions.map(d=>d.id));
        var plot_ids = JSON.stringify(plots.map(d=>d.id));
        var plant_ids = JSON.stringify(plants.map(d=>d.id));
        var location_ids = JSON.stringify(locations.map(d=>d.id));
        var year_ids = JSON.stringify(years.map(d=>d.id));

        var speed = d3.select(".wizard-download-phenotypes-speed").node().value;
        var format = d3.select(".wizard-download-phenotypes-format").node().value;
        var level = d3.select(".wizard-download-phenotypes-level").node().value;
        var timestamp = d3.selectAll('.wizard-download-phenotypes-timestamp').property('checked')?1:0;
        var entry_numbers = d3.selectAll('.wizard-download-phenotypes-entry-numbers').property('checked')?1:0;
        var outliers = d3.selectAll('.wizard-download-phenotypes-outliers').property('checked')?1:0;
        var names = JSON.stringify(d3.select(".wizard-download-phenotypes-name").node().value.split(","));
        var min = d3.select(".wizard-download-phenotypes-min").node().value;
        var max = d3.select(".wizard-download-phenotypes-max").node().value;

        var url = document.location.origin+'/breeders/trials/phenotype/download';
        openWindowWithPost(url, {
            trial_list: trial_ids,
            speed: speed,
            format: format,
            trait_list: trait_ids,
            trait_component_list: comp_ids,
            accession_list: accession_ids,
            plot_list: plot_ids,
            plant_list: plant_ids,
            location_list: location_ids,
            year_list: year_ids,
            dataLevel: level,
            phenotype_min_value: min,
            phenotype_max_value: max,
            timestamp: timestamp,
            entry_numbers: entry_numbers,
            trait_contains: names,
            include_row_and_column_numbers: 1,
            exclude_phenotype_outlier: outliers,
            include_pedigree_parents: 0,
        });
        // window.open(url,'_blank');
      });
});

}
<commit_msg>remove old window opens<commit_after>import "../legacy/d3/d3v5Min.js";
import "../legacy/CXGN/Dataset.js";

/**
 * WizardDownloads - Creates a new WizardDownloads object.
 *
 * @class
 * @classdesc links to a wizard and manages showing relavant related data
 * @param  {type} main_id div to draw within
 * @param  {type} wizard wizard to link to
 * @returns {Object}
 */

function openWindowWithPost(url, data) {
  var form = document.createElement("form");
  form.target = "_blank";
  form.method = "POST";
  form.action = url;
  form.style.display = "none";

  for (var key in data) {
    var input = document.createElement("input");
    input.type = "hidden";
    input.name = key;
    input.value = data[key];
    form.appendChild(input);
  }

  document.body.appendChild(form);
  form.submit();
  document.body.removeChild(form);
}

export function WizardDownloads(main_id,wizard){
  var main = d3.select(main_id);
  var datasets = new CXGN.Dataset();

  var categories = [];
  var selections = {};
  var operations = {};
  wizard.on_change((c,s,o)=>{
    categories = c;
    selections = s;
    operations = o;

    // Genotype downloads
    var accessions = categories.indexOf("accessions")!=-1?
      selections["accessions"]:
      [];
    var traits = categories.indexOf("traits")!=-1?
      selections["traits"]:
      [];
    var protocols = categories.indexOf("genotyping_protocols")!=-1?
      selections["genotyping_protocols"]:
      [];
    main.select(".wizard-download-genotypes-info")
      .attr("value",`${accessions.length||"Too few"} accessions, ${
        protocols.length==1?"selected protocol":
        protocols.length>1?"too many protocols selected":
        "default protocol"
      }`);
    main.selectAll(".wizard-download-genotypes")
      .attr("disabled",!!accessions.length&&protocols.length<=1?null:true)
      .on("click",()=>{
        event.preventDefault();
        var accession_ids = accessions.map(d=>d.id);
        var trial_ids = (selections["trials"]||[]).map(d=>d.id);
        var protocol_id = protocols.length==1?protocols[0].id:'';
        var chromosome_number = d3.select(".wizard-download-genotypes-chromosome-number").node().value;
        var start_position = d3.select(".wizard-download-genotypes-start-position").node().value;
        var end_position = d3.select(".wizard-download-genotypes-end-position").node().value;
        var download_format = d3.select(".wizard-download-genotypes-format").node().value;
        var compute_from_parents = d3.select(".wizard-download-genotypes-parents-compute").property("checked");
        var include_duplicate_genotypes = d3.select(".wizard-download-genotypes-duplicates-include").property("checked");
        var marker_set_list_id = d3.select(".wizard-download-genotypes-marker-set-list-id").node().value;
        if(chromosome_number && marker_set_list_id) {
            alert(`Please indicate either chromosome or markerset, not both.`);
            d3.select(this).attr("disabled",null);
            return;
        }
        var url = document.location.origin+'/breeders/download_gbs_action';
        openWindowWithPost(url, {
            ids: accession_ids.join(","),
            protocol_id: protocol_id,
            format: accession_ids,
            chromosome_number: chromosome_number,
            start_position: start_position,
            end_position: end_position,
            trial_ids: trial_ids.join(","),
            download_format: download_format,
            compute_from_parents: compute_from_parents,
            marker_set_list_id: marker_set_list_id,
            include_duplicate_genotypes: include_duplicate_genotypes,
        });
      });
    main.selectAll(".wizard-download-genetic-relationship-matrix")
      .attr("disabled",!!accessions.length&&protocols.length<=1?null:true)
      .on("click",()=>{
        event.preventDefault();
        var accession_ids = accessions.map(d=>d.id);
        var trial_ids = (selections["trials"]||[]).map(d=>d.id);
        var protocol_id = protocols.length==1?protocols[0].id:'';
        var download_format = d3.select(".wizard-download-genotypes-grm-format").node().value;
        var maf = d3.select(".wizard-download-genotypes-grm-maf").node().value;
        var marker_filter = d3.select(".wizard-download-genotypes-grm-marker-filter").node().value;
        var individuals_filter = d3.select(".wizard-download-genotypes-grm-individuals-filter").node().value;
        var compute_from_parents = d3.select(".wizard-download-genotypes-parents-compute").property("checked");
        var url = document.location.origin+'/breeders/download_grm_action';
        openWindowWithPost(url, {
            ids: accession_ids.join(","),
            protocol_id: protocol_id,
            format: accession_ids,
            trial_ids: trial_ids.join(","),
            download_format: download_format,
            compute_from_parents: compute_from_parents,
            minor_allele_frequency: maf,
            marker_filter: marker_filter,
            individuals_filter: individuals_filter,
        });
      });
    main.selectAll(".wizard-download-gwas")
        .attr("disabled",!!traits.length&&accessions.length&&protocols.length<=1?null:true)
        .on("click",()=>{
          event.preventDefault();
          var accession_ids = accessions.map(d=>d.id);
          var trait_ids = traits.map(d=>d.id);
          var protocol_id = protocols.length==1?protocols[0].id:'';
          var maf = d3.select(".wizard-download-genotypes-grm-maf").node().value;
          var marker_filter = d3.select(".wizard-download-genotypes-grm-marker-filter").node().value;
          var individuals_filter = d3.select(".wizard-download-genotypes-grm-individuals-filter").node().value;
          var download_format = d3.select(".wizard-download-genotypes-gwas-format").node().value;
          var repeated_measurements = d3.select(".wizard-download-genotypes-gwas-repeated-measurements").node().value;
          var compute_from_parents = d3.select(".wizard-download-genotypes-parents-compute").property("checked");
          var url = document.location.origin+'/breeders/download_gwas_action';
          openWindowWithPost(url, {
            ids: accession_ids.join(","),
            protocol_id: protocol_id,
            format: accession_ids,
            trait_ids: trait_ids.join(","),
            compute_from_parents: compute_from_parents,
            minor_allele_frequency: maf,
            marker_filter: marker_filter,
            individuals_filter: individuals_filter,
            download_format: download_format,
            traits_are_repeated_measurements: repeated_measurements,
          });
      });
    // Download Trial Metadata
    var trials = categories.indexOf("trials")!=-1 ? selections["trials"] : [];
    main.selectAll(".wizard-download-tmetadata-info")
      .attr("value",`${trials.length||"Too few"} trials`);
    main.selectAll(".wizard-download-tmetadata")
      .attr("disabled",trials.length>0?null:true)
      .on("click",()=>{
        var t_ids = JSON.stringify(trials.map(d=>d.id));
        var format = d3.select(".wizard-download-tmetadata-format").node().value;
        var url = document.location.origin+'/breeders/trials/phenotype/download';
        openWindowWithPost(url, {
            trial_list: t_ids,
            format: format,
            dataLevel: 'metadata'
        });
      });

    // Download Trial Phenotypes
    var trials = categories.indexOf("trials")!=-1 ? selections["trials"] : [];
    var traits = categories.indexOf("traits")!=-1 ? selections["traits"] : [];
    var comps = categories.indexOf("trait_components")!=-1 ? selections["trait_components"] : [];
    var plots = categories.indexOf("plots")!=-1 ? selections["plots"] : [];
    var plants = categories.indexOf("plants")!=-1 ? selections["plants"] : [];
    var locations = categories.indexOf("locations")!=-1 ? selections["locations"] : [];
    var years = categories.indexOf("years")!=-1 ? selections["years"] : [];

    main.selectAll(".wizard-download-phenotypes-info")
      .attr("value",`${trials.length||"Too few"} trials`);
    main.selectAll(".wizard-download-phenotypes")
      .attr("disabled",trials.length>0?null:true)
      .on("click",()=>{
        var trial_ids = JSON.stringify(trials.map(d=>d.id));
        var trait_ids = JSON.stringify(traits.map(d=>d.id));
        var comp_ids = JSON.stringify(comps.map(d=>d.id));
        var accession_ids = JSON.stringify(accessions.map(d=>d.id));
        var plot_ids = JSON.stringify(plots.map(d=>d.id));
        var plant_ids = JSON.stringify(plants.map(d=>d.id));
        var location_ids = JSON.stringify(locations.map(d=>d.id));
        var year_ids = JSON.stringify(years.map(d=>d.id));

        var speed = d3.select(".wizard-download-phenotypes-speed").node().value;
        var format = d3.select(".wizard-download-phenotypes-format").node().value;
        var level = d3.select(".wizard-download-phenotypes-level").node().value;
        var timestamp = d3.selectAll('.wizard-download-phenotypes-timestamp').property('checked')?1:0;
        var entry_numbers = d3.selectAll('.wizard-download-phenotypes-entry-numbers').property('checked')?1:0;
        var outliers = d3.selectAll('.wizard-download-phenotypes-outliers').property('checked')?1:0;
        var names = JSON.stringify(d3.select(".wizard-download-phenotypes-name").node().value.split(","));
        var min = d3.select(".wizard-download-phenotypes-min").node().value;
        var max = d3.select(".wizard-download-phenotypes-max").node().value;

        var url = document.location.origin+'/breeders/trials/phenotype/download';
        openWindowWithPost(url, {
            trial_list: trial_ids,
            speed: speed,
            format: format,
            trait_list: trait_ids,
            trait_component_list: comp_ids,
            accession_list: accession_ids,
            plot_list: plot_ids,
            plant_list: plant_ids,
            location_list: location_ids,
            year_list: year_ids,
            dataLevel: level,
            phenotype_min_value: min,
            phenotype_max_value: max,
            timestamp: timestamp,
            entry_numbers: entry_numbers,
            trait_contains: names,
            include_row_and_column_numbers: 1,
            exclude_phenotype_outlier: outliers,
            include_pedigree_parents: 0,
        });
      });
});

}
<|endoftext|>


<commit_before>var findOne = require("mongo-client/findOne")
var mapReduce = require("mongo-client/mapReduce")
var expand = require("reducers/expand")

module.exports = incrementalMapReduce

function incrementalMapReduce(col, opts) {
    var timestampPath = opts.timestampPath || "timestamp"
    var lastTimestampPath = opts.lastTimestampPath || "timestamp"

    var lastValue = findOne(opts.reducedCollection, {}, {
        sort: [["value." + lastTimestampPath, -1]]
    })

    var result = expand(lastValue, function (doc) {
        var lastTimestamp = doc && doc.value && doc.value[lastTimestampPath]
        var options = opts.options || {}

        if (lastTimestamp) {
            options.query = options.query || {}
            options.query[timestampPath] = {
                $gt: lastTimestamp
            }
        }

        return mapReduce(col, opts.map, opts.reduce, options)
    })

    return result
}
<commit_msg>add a small batchSize<commit_after>var findOne = require("mongo-client/findOne")
var mapReduce = require("mongo-client/mapReduce")
var expand = require("reducers/expand")

module.exports = incrementalMapReduce

function incrementalMapReduce(col, opts) {
    var timestampPath = opts.timestampPath || "timestamp"
    var lastTimestampPath = opts.lastTimestampPath || "timestamp"

    var lastValue = findOne(opts.reducedCollection, {}, {
        sort: [["value." + lastTimestampPath, -1]],
        batchSize: 10
    })

    var result = expand(lastValue, function (doc) {
        var lastTimestamp = doc && doc.value && doc.value[lastTimestampPath]
        var options = opts.options || {}

        if (lastTimestamp) {
            options.query = options.query || {}
            options.query[timestampPath] = {
                $gt: lastTimestamp
            }
        }

        return mapReduce(col, opts.map, opts.reduce, options)
    })

    return result
}
<|endoftext|>


<commit_before>function runTest()
{
    FBTest.sysout("index.START");
    FBTest.openNewTab(basePath + "console/completion/index/index.html", function(win)
    {
        FBTest.openFirebug();
        FBTest.enableConsolePanel(function(win)
        {
            var panel = FW.Firebug.chrome.selectPanel("console");

            var tests = [
                ["qqq", true, "window[\"qqq--\"]"],
                ["qqa", true, "window[\"qqa'\\\"\\\\\"]"],
                ["window.qqq", true, "window[\"qqq--\"]"],
                ["window['", true],
                ["window['qqq", true],
                ["window[\"qqq", true],
                ["window[\"qqa'", true, "window[\"qqa'\\\"\\\\\"]"],
                ["window['qqa\\'", true, "window['qqa\\'\"\\\\']"],
                ["-", false],
                ["\"", false],
                ["\\\"", false],
                ["[\"", false],
                ["qqq-", false],
                ["window.qqa'", false],
                ["window[", false],
                ["window['qqa'", false],
                ["window[/qq", false]
            ];

            var tasks = new FBTest.TaskList();
            for (var i = 0; i < tests.length; ++i) {
                var test = tests[i];
                tasks.push(testExpression, win, test[0], test[1], test[2]);
            }

            tasks.run(function()
            {
                var doc = FW.Firebug.chrome.window.document;
                var cmdLine = doc.getElementById("fbCommandLine");
                cmdLine.value = "";

                FBTest.testDone("index.DONE");
            });
        });
    });
}

// ************************************************************************************************
// xxxHonza: This should be polished and moved into FBTest namespace.

function testExpression(callback, win, expr, shouldComplete, completeTo)
{
    var doc = FW.Firebug.chrome.window.document;
    var cmdLine = doc.getElementById("fbCommandLine");

    cmdLine.value = "";
    FBTest.typeCommand(expr);
    FBTest.synthesizeKey("VK_TAB", null, win);

    var changed = (cmdLine.value !== expr);
    FBTest.compare(shouldComplete, changed,
        "Completions should " + (shouldComplete ? "" : "not ") +
        "appear for: " + expr);

    if (completeTo)
    {
        FBTest.compare(completeTo, cmdLine.value,
            expr + " should be completed into " + completeTo);
    }

    setTimeout(callback);
}
<commit_msg>FBTest: better logging<commit_after>function runTest()
{
    FBTest.sysout("index.START");
    FBTest.openNewTab(basePath + "console/completion/index/index.html", function(win)
    {
        FBTest.openFirebug();
        FBTest.enableConsolePanel(function(win)
        {
            var panel = FW.Firebug.chrome.selectPanel("console");

            var tests = [
                ["qqq", true, "window[\"qqq--\"]"],
                ["qqa", true, "window[\"qqa'\\\"\\\\\"]"],
                ["window.qqq", true, "window[\"qqq--\"]"],
                ["window['", true],
                ["window['qqq", true],
                ["window[\"qqq", true],
                ["window[\"qqa'", true, "window[\"qqa'\\\"\\\\\"]"],
                ["window['qqa\\'", true, "window['qqa\\'\"\\\\']"],
                ["-", false],
                ["\"", false],
                ["\\\"", false],
                ["[\"", false],
                ["qqq-", false],
                ["window.qqa'", false],
                ["window[", false],
                ["window['qqa'", false],
                ["window[/qq", false]
            ];

            var tasks = new FBTest.TaskList();
            for (var i = 0; i < tests.length; ++i) {
                var test = tests[i];
                tasks.push(testExpression, win, test[0], test[1], test[2]);
            }

            tasks.run(function()
            {
                var doc = FW.Firebug.chrome.window.document;
                var cmdLine = doc.getElementById("fbCommandLine");
                cmdLine.value = "";

                FBTest.testDone("index.DONE");
            });
        });
    });
}

// ************************************************************************************************
// xxxHonza: This should be polished and moved into FBTest namespace.

function testExpression(callback, win, expr, shouldComplete, completeTo)
{
    var doc = FW.Firebug.chrome.window.document;
    var cmdLine = doc.getElementById("fbCommandLine");

    cmdLine.value = "";
    FBTest.typeCommand(expr);
    FBTest.synthesizeKey("VK_TAB", null, win);

    var changed = (cmdLine.value !== expr);
    FBTest.compare(shouldComplete, changed,
        "Completions should " + (shouldComplete ? "" : "not ") +
        "appear for: " + expr + " (cmd line: " + cmdLine.value + ")");

    if (completeTo)
    {
        FBTest.compare(completeTo, cmdLine.value,
            expr + " should be completed into " + completeTo);
    }

    setTimeout(callback);
}
<|endoftext|>


<commit_before>// This is the configuration for the documentation gitbook
module.exports = {
    "version": "2.x.x",
    "links": {
        "sidebar": {
            "Contribute to these docs": "https://github.com/mozilla/webmaker-app",
            "File an issue": "https://github.com/mozilla/webmaker-app/issues",
            "Download": "https://www.gitbook.com/download/pdf/book/k88hudson/webmaker-mobile-guide"
        }
    },
    "plugins": ["youtube"]
};
<commit_msg>gitbook<commit_after>// This is the configuration for the documentation gitbook
module.exports = {
    "gitbook": "2.x.x",
    "links": {
        "sidebar": {
            "Contribute to these docs": "https://github.com/mozilla/webmaker-app",
            "File an issue": "https://github.com/mozilla/webmaker-app/issues",
            "Download": "https://www.gitbook.com/download/pdf/book/k88hudson/webmaker-mobile-guide"
        }
    },
    "plugins": ["youtube"]
};
<|endoftext|>