<commit_before>// htmlCanvas is a DSL that we use to add elements to the DOM using a HTML looking syntax.
//
// The basic metaphor used is one of painting on a canvas using brushes. The canvas is the
// DOM and the brushes HTML 'tags'.
//
// _NOTE:_ It has nothing to do with the HTML5 canvas tag
//
// _Usage:_
//
// A htmlCanvas is created on a jQuery object:
//
//		var html = htmlCanvas($('BODY'));
//
// We write HTML using standard tags:
//
//		html.h1('Hello World!');
//
//	and standard attributes:
//
//		html.a('Google').id('id').href('http://www.google.se');
//
//	Attributes can also be set from an object litteral:
//
//		html.a({id: 'id', href: 'http://www.google.se'}, 'Google');
//
//  Callbacks can be attached to events:
//
//		html.a('Click me!').click(function() { alert('Hello World!')});
//
//	Tags can be nested:
//
//		html.div({'class' : 'outer_div'},
//			html.div({'class' : 'inner_div'},
//				html.span('Some text')
//			)
//		);
//
// Parts can be assigned to variables:
//
//		var homeButton = html.a('Home').href('/');
//		if(showAlert) {
//			homeButton.click(function() { alert('Hello'); });
//		}
//

/*
* HTML Canvas
* Copyright 2011 Nicolas Petton <nico@objectfusion.fr>
* This file is released under MIT.
*/

define(
	[
		'jquery'
	],

	function (jQuery) {

		// - - -

		// ### htmlCanvas
		// htmlCanvas provides a HTML-looking-syntax interface for appending content to the The Document Object Model (DOM).
		//
		// _Usage_:
		//
		//		var html = htmlCanvas($('BODY'));
		//		html.div(html.h1('title'));
		//
		// The canvas is created on the first element matched by aJQuery (eg. $('BODY') above). A brush for that element is created
		// and set as the root object.
		//
		// All other brushes (eg. html.div() above) are added to that root brush. Brushes added as children of a
		// brush (eg. html.h1('title') above) are however added to their parent brush which gives us the ability to nest
		// brushes and create a tree.
		//
		var htmlCanvas = function (aJQuery) {
			var that = {};

			// Supported HTML 'tags'
			var tags = ('a abbr acronym address area article aside audio b bdi bdo big ' +
				'blockquote body br button canvas caption cite code col colgroup command ' +
				'datalist dd del details dfn div dl dt em embed fieldset figcaption figure ' +
				'footer form frame frameset h1 h2 h3 h4 h5 h6 hr head header hgroup html i ' +
				'iframe img input ins kbd keygen label legend li link map mark meta meter ' +
				'nav noscript object ol optgroup option output p param pre progress q rp rt' +
				'ruby samp script section select small source span strong style sub summary' +
				'sup table tbody td textarea tfoot th thead time title tr track tt ul var' +
				'video wbr').split(' ');

			// #### Public API

			// The root object. It's element is set to first element matched by aJQuery
			that.root = tagBrush({ canvas: that, jQuery: aJQuery });

			// Creates a new tag brush and adds it to root brush. The element is a
			// new element in partent brush element, created using the 'tag' (eg. H1).
			that.tag = function (tag, children) {
				var t = tagBrush({ canvas: that, tag: tag, children: children });
				that.root.addBrush(t);
				return t;
			};

			// Tag brush functions are added dynamically on object creation.
			// Each 'tag' in Supported HTML 'tags' is added as a public method on htmlCanvas
			//
			// _Example:_
			//
			//		html.h1('hello');
			//		html.span('world');
			//
			function createTagBrush(tagname) {
				return function () {
					var args = Array.prototype.slice.call(arguments);
					return that.tag(tagname, args);
				};
			}
			for (var tagIndex = 0; tagIndex < tags.length; tagIndex++) {
				that[tags[tagIndex]] = createTagBrush(tags[tagIndex]);
			}

			// Render anObject on the root tag brush. See `tagBrush.render()`
			that.render = function (anObject) {
				that.root.render(anObject);
			};

			return that;
		};

		// - - -

		// ### tagBrush
		// A tag brush object represents a DOM element, built on a canvas. The element can
		// be created from a 'tag' or an element matched using 'jQuery'.
		//
		// _Usage:_ create from 'tag'
		//
		//		var h1 = tagBrush({tag : 'h1', canvas : html});
		//
		// A h1 element is created and appended to ´canvas.root´.
		//
		// _Usage:_ create from matched jQuery
		//
		//		var h1 = tagBrush({jQuery : '#heading', canvas : html});
		//
		// A brush is created for first element that match jQuery.
		//
		// _Usage:_ create from with children
		//
		//		tagBrush({jQuery : '#heading', canvas : html, children : [headingBrush, bodyBrush, footerBrush]});
		//
		//	Children are appended to brush one-by-one.
		//
		// _Note:_ Each tag brush should be only used once.
		var tagBrush = function (spec) {
			var that = {};

			// Supported HTML events
			var attributes = 'href for id media rel src style title type'.split(' ');

			// Supported HTML attributes
			var events = ('blur focus focusin focusout load resize scroll unload ' +
				'click dblclick mousedown mouseup mousemove mouseover ' +
				'mouseout mouseenter mouseleave change select submit ' +
				'keydown keypress keyup error').split(' ');

			var jquery = spec.jQuery;
			var elementTagName = spec.tag;
			var children = spec.children;
			var canvas = spec.canvas;

			// DOM element - Is set on initilization to first DOM element matched by
			// 'jquery'. if no jQuery is given, element is created from tag name.
			var element;

			function createElement(tagName) {
				return document.createElement(tagName);
			}

			// Appends objects to the brush element. A tag brush knows how to append:
			//
			// - strings
			// - functions (that take a htmlCanvas as argument)
			// - other brushes and widgets (that implements `appendToBrush()`)
			// - map / object literal with attributes (eg. {id: 'aId', 'class' : 'aClass'})
			// - array of valid objects (see above)
			//
			// all other objects are appended using:
			// `jQuery(element).append(object);`
			//
			function append(object) {
				if (typeof(object) === 'undefined' || object === null) {
					throw 'cannot append null or undefined to brush';
				}

				if (typeof object === "object" && object.constructor === Array) {
					for (var i = 0; i < object.length; i++) {
						append(object[i]);
					}
				}
				else if (typeof object === "string") {
					appendString(object);
				} else if (typeof object === "function") {
					appendFunction(object);
				} else if (typeof object === "object" &&
					object.appendToBrush /* eg. widget and tagBrush implement appendToBrush */) {
					object.appendToBrush(that); // double dispatch
				}
				else if (typeof object === "object") {
					that.attr(object); // assume attributes if none of above
				} else {
					jQuery(element).append(object); // default to jquery
				}
			}

			// Appends DOM node as child of element or concatenate with
			// text if element can't have children.
			function appendChild(child) {
				if (element.canHaveChildren !== false) {
					element.appendChild(child);
				} else {
					element.text = element.text + child.innerHTML;
				}
			}

			// Appends element of brush as last child of this element
			function appendBrush(aTagBrush) {
				appendChild(aTagBrush.element());
			}

			// Append text or HTML text to element
			function appendString(string) {
				jQuery(element).append(string);
			}

			// Append function by executing function with this element as canvas.
			function appendFunction(fn) {
				var root = canvas.root;
				canvas.root = that;
				fn(canvas);
				canvas.root = root;
			}

			// #### Public API

			// Returns DOM element created by brush.
			that.element = function () {
				return element;
			};

			// Renders objects using `append()`. Can take a single or several arguments.
			//
			// _Usage:_
			//
			//		html.h1().render(
			//			'hello',
			//			html.span('world',
			//				function(html) {
			//					html.img().src('foo.img');
			//				}
			//			)
			//		);
			that.render = function () {
				var args = Array.prototype.slice.call(arguments);
				for (var i = 0; i < args.length; i++) {
					append(args[i]);
				}
				return that;
			};

			// Implemention for `appendToBrush()` to allow a brush to be
            // appended to another brush.
            //
            // Basicly it allows us to do:
            //
            //		var h1Brush = html.span('test');
            //      html.div(h1Brush);
            //
			that.appendToBrush = function (aTagBrush) {
				aTagBrush.addBrush(that);
			};

			// Appends brush `element()` to this element.
			that.addBrush = appendBrush;

			// Events are delegated to jQuery
			//
			// _Usage:_
			//
			//		html.a('click me').on('click', function() {
			//			alert('click');
			//		});
			that.on = function (event, callback) {
				that.asJQuery().bind(event, callback);
				return that;
			};

			// Event functions are added dynamically on object creation.
			// Each supported event is added as a public method on brush
			//
			// _Example:_
			//
			//		aBrush.click(function() { .. });
			//		aBrush.blur(function() { .. });
			//		aBrush.load(function() { .. });
			//
			function createEvent(eventname) {
				return function (callback) {
					that.on(eventname, callback);
					return that;
				};
			}
			for (var eventIndex = 0; eventIndex < events.length; eventIndex++) {
				that[events[eventIndex]] = createEvent(events[eventIndex]);
			}

			// Attribute accessors are added dynamically on object creation.
			// Each supported attribute is added as a public method on brush
			//
			// _Example:_
			//
			//		aBrush.id('id');
			//		aBrush.src('javascript:0');
			//		aBrush.href('#');
			//
			function createAttrubute(attributename) {
				return function (value) {
					that.setAttribute(attributename, value);
					return that;
				};
			}
			for (var attributeIndex = 0; attributeIndex < attributes.length; attributeIndex++) {
				that[attributes[attributeIndex]] = createAttrubute(attributes[attributeIndex]);
			}

			// Sets element attribute with key to value
			that.setAttribute = function (key, value) {
				element.setAttribute(key, value);
				return that;
			};

			// Set element style with key/value or object literal.
			//
			// _Usage:_
			//
			//		html.h1().css('display', 'block');
			//		html.h1().css({'display' : 'block', 'color' : 'red'});
			//
			that.css = function (key, value) {
				if (typeof key === "string") {
					that.asJQuery().css(key, value);
				}
				else {
					that.asJQuery().css(key); // otherwise assume key is a map (object literal)
				}

				return that;
			};

			// Set attributes using object literal.
			//
			// _Usage:_
			//
			//		html.h1().attr({id : 'myid', 'class' : 'myclass'});
			//
			// _Note:_ Use klass or 'class' with quotation marks as key instead of class since its a reserved word.
			//
			that.attr = function (object) {
				for (var key in object) {
					if (object.hasOwnProperty(key)) {
						if (key === 'klass') {
							that.addClass(object[key]);
						} else {
							that.setAttribute(key, object[key]);
						}
					}
				}

				return that;
			};

			// Appends className to class attribute
			that.addClass = function (className) {
				that.asJQuery().addClass(className);
				return that;
			};

			// Removes className from class attribute
			that.removeClass = function (className) {
				that.asJQuery().removeClass(className);
				return that;
			};

			// Returns jQuery that match element.
			that.asJQuery = function () {
				return jQuery(that.element());
			};

			// #### TagBrush initialization

			// Element is set to first match if a jQuery was given.
			if (jquery && typeof jquery === 'string') {
				jquery = jQuery(jquery);
			}
			if (jquery) {
				element = jquery.get(0);
				if (!element) {
					throw 'jQuery did not match an element';
				}
			}

			// If no jQuery was given, element is created
			// from tag name.
			else {
				element = createElement(elementTagName);
			}

			// Append children to support nesting. _Eg.:_
			//
			//		html.ul(html.li(html.a({href: '#'}, 'home'));
			if (children) {
				for (var childIndex = 0; childIndex < spec.children.length; childIndex++) {
					append(spec.children[childIndex]);
				}
			}

			return that;
		};

        // ### Exports
        // htmlCanvas

		return htmlCanvas;
	}
);<commit_msg>throw errors instead of strings<commit_after>// htmlCanvas is a DSL that we use to add elements to the DOM using a HTML looking syntax.
//
// The basic metaphor used is one of painting on a canvas using brushes. The canvas is the
// DOM and the brushes HTML 'tags'.
//
// _NOTE:_ It has nothing to do with the HTML5 canvas tag
//
// _Usage:_
//
// A htmlCanvas is created on a jQuery object:
//
//		var html = htmlCanvas($('BODY'));
//
// We write HTML using standard tags:
//
//		html.h1('Hello World!');
//
//	and standard attributes:
//
//		html.a('Google').id('id').href('http://www.google.se');
//
//	Attributes can also be set from an object litteral:
//
//		html.a({id: 'id', href: 'http://www.google.se'}, 'Google');
//
//  Callbacks can be attached to events:
//
//		html.a('Click me!').click(function() { alert('Hello World!')});
//
//	Tags can be nested:
//
//		html.div({'class' : 'outer_div'},
//			html.div({'class' : 'inner_div'},
//				html.span('Some text')
//			)
//		);
//
// Parts can be assigned to variables:
//
//		var homeButton = html.a('Home').href('/');
//		if(showAlert) {
//			homeButton.click(function() { alert('Hello'); });
//		}
//

/*
* HTML Canvas
* Copyright 2011 Nicolas Petton <nico@objectfusion.fr>
* This file is released under MIT.
*/

define(
	[
		'jquery'
	],

	function (jQuery) {

		// - - -

		// ### htmlCanvas
		// htmlCanvas provides a HTML-looking-syntax interface for appending content to the The Document Object Model (DOM).
		//
		// _Usage_:
		//
		//		var html = htmlCanvas($('BODY'));
		//		html.div(html.h1('title'));
		//
		// The canvas is created on the first element matched by aJQuery (eg. $('BODY') above). A brush for that element is created
		// and set as the root object.
		//
		// All other brushes (eg. html.div() above) are added to that root brush. Brushes added as children of a
		// brush (eg. html.h1('title') above) are however added to their parent brush which gives us the ability to nest
		// brushes and create a tree.
		//
		var htmlCanvas = function (aJQuery) {
			var that = {};

			// Supported HTML 'tags'
			var tags = ('a abbr acronym address area article aside audio b bdi bdo big ' +
				'blockquote body br button canvas caption cite code col colgroup command ' +
				'datalist dd del details dfn div dl dt em embed fieldset figcaption figure ' +
				'footer form frame frameset h1 h2 h3 h4 h5 h6 hr head header hgroup html i ' +
				'iframe img input ins kbd keygen label legend li link map mark meta meter ' +
				'nav noscript object ol optgroup option output p param pre progress q rp rt' +
				'ruby samp script section select small source span strong style sub summary' +
				'sup table tbody td textarea tfoot th thead time title tr track tt ul var' +
				'video wbr').split(' ');

			// #### Public API

			// The root object. It's element is set to first element matched by aJQuery
			that.root = tagBrush({ canvas: that, jQuery: aJQuery });

			// Creates a new tag brush and adds it to root brush. The element is a
			// new element in partent brush element, created using the 'tag' (eg. H1).
			that.tag = function (tag, children) {
				var t = tagBrush({ canvas: that, tag: tag, children: children });
				that.root.addBrush(t);
				return t;
			};

			// Tag brush functions are added dynamically on object creation.
			// Each 'tag' in Supported HTML 'tags' is added as a public method on htmlCanvas
			//
			// _Example:_
			//
			//		html.h1('hello');
			//		html.span('world');
			//
			function createTagBrush(tagname) {
				return function () {
					var args = Array.prototype.slice.call(arguments);
					return that.tag(tagname, args);
				};
			}
			for (var tagIndex = 0; tagIndex < tags.length; tagIndex++) {
				that[tags[tagIndex]] = createTagBrush(tags[tagIndex]);
			}

			// Render anObject on the root tag brush. See `tagBrush.render()`
			that.render = function (anObject) {
				that.root.render(anObject);
			};

			return that;
		};

		// - - -

		// ### tagBrush
		// A tag brush object represents a DOM element, built on a canvas. The element can
		// be created from a 'tag' or an element matched using 'jQuery'.
		//
		// _Usage:_ create from 'tag'
		//
		//		var h1 = tagBrush({tag : 'h1', canvas : html});
		//
		// A h1 element is created and appended to ´canvas.root´.
		//
		// _Usage:_ create from matched jQuery
		//
		//		var h1 = tagBrush({jQuery : '#heading', canvas : html});
		//
		// A brush is created for first element that match jQuery.
		//
		// _Usage:_ create from with children
		//
		//		tagBrush({jQuery : '#heading', canvas : html, children : [headingBrush, bodyBrush, footerBrush]});
		//
		//	Children are appended to brush one-by-one.
		//
		// _Note:_ Each tag brush should be only used once.
		var tagBrush = function (spec) {
			var that = {};

			// Supported HTML events
			var attributes = 'href for id media rel src style title type'.split(' ');

			// Supported HTML attributes
			var events = ('blur focus focusin focusout load resize scroll unload ' +
				'click dblclick mousedown mouseup mousemove mouseover ' +
				'mouseout mouseenter mouseleave change select submit ' +
				'keydown keypress keyup error').split(' ');

			var jquery = spec.jQuery;
			var elementTagName = spec.tag;
			var children = spec.children;
			var canvas = spec.canvas;

			// DOM element - Is set on initilization to first DOM element matched by
			// 'jquery'. if no jQuery is given, element is created from tag name.
			var element;

			function createElement(tagName) {
				return document.createElement(tagName);
			}

			// Appends objects to the brush element. A tag brush knows how to append:
			//
			// - strings
			// - functions (that take a htmlCanvas as argument)
			// - other brushes and widgets (that implements `appendToBrush()`)
			// - map / object literal with attributes (eg. {id: 'aId', 'class' : 'aClass'})
			// - array of valid objects (see above)
			//
			// all other objects are appended using:
			// `jQuery(element).append(object);`
			//
			function append(object) {
				if (typeof(object) === 'undefined' || object === null) {
					throw new Error('cannot append null or undefined to brush');
				}

				if (typeof object === "object" && object.constructor === Array) {
					for (var i = 0; i < object.length; i++) {
						append(object[i]);
					}
				}
				else if (typeof object === "string") {
					appendString(object);
				} else if (typeof object === "function") {
					appendFunction(object);
				} else if (typeof object === "object" &&
					object.appendToBrush /* eg. widget and tagBrush implement appendToBrush */) {
					object.appendToBrush(that); // double dispatch
				}
				else if (typeof object === "object") {
					that.attr(object); // assume attributes if none of above
				} else {
					jQuery(element).append(object); // default to jquery
				}
			}

			// Appends DOM node as child of element or concatenate with
			// text if element can't have children.
			function appendChild(child) {
				if (element.canHaveChildren !== false) {
					element.appendChild(child);
				} else {
					element.text = element.text + child.innerHTML;
				}
			}

			// Appends element of brush as last child of this element
			function appendBrush(aTagBrush) {
				appendChild(aTagBrush.element());
			}

			// Append text or HTML text to element
			function appendString(string) {
				jQuery(element).append(string);
			}

			// Append function by executing function with this element as canvas.
			function appendFunction(fn) {
				var root = canvas.root;
				canvas.root = that;
				fn(canvas);
				canvas.root = root;
			}

			// #### Public API

			// Returns DOM element created by brush.
			that.element = function () {
				return element;
			};

			// Renders objects using `append()`. Can take a single or several arguments.
			//
			// _Usage:_
			//
			//		html.h1().render(
			//			'hello',
			//			html.span('world',
			//				function(html) {
			//					html.img().src('foo.img');
			//				}
			//			)
			//		);
			that.render = function () {
				var args = Array.prototype.slice.call(arguments);
				for (var i = 0; i < args.length; i++) {
					append(args[i]);
				}
				return that;
			};

			// Implemention for `appendToBrush()` to allow a brush to be
            // appended to another brush.
            //
            // Basicly it allows us to do:
            //
            //		var h1Brush = html.span('test');
            //      html.div(h1Brush);
            //
			that.appendToBrush = function (aTagBrush) {
				aTagBrush.addBrush(that);
			};

			// Appends brush `element()` to this element.
			that.addBrush = appendBrush;

			// Events are delegated to jQuery
			//
			// _Usage:_
			//
			//		html.a('click me').on('click', function() {
			//			alert('click');
			//		});
			that.on = function (event, callback) {
				that.asJQuery().bind(event, callback);
				return that;
			};

			// Event functions are added dynamically on object creation.
			// Each supported event is added as a public method on brush
			//
			// _Example:_
			//
			//		aBrush.click(function() { .. });
			//		aBrush.blur(function() { .. });
			//		aBrush.load(function() { .. });
			//
			function createEvent(eventname) {
				return function (callback) {
					that.on(eventname, callback);
					return that;
				};
			}
			for (var eventIndex = 0; eventIndex < events.length; eventIndex++) {
				that[events[eventIndex]] = createEvent(events[eventIndex]);
			}

			// Attribute accessors are added dynamically on object creation.
			// Each supported attribute is added as a public method on brush
			//
			// _Example:_
			//
			//		aBrush.id('id');
			//		aBrush.src('javascript:0');
			//		aBrush.href('#');
			//
			function createAttrubute(attributename) {
				return function (value) {
					that.setAttribute(attributename, value);
					return that;
				};
			}
			for (var attributeIndex = 0; attributeIndex < attributes.length; attributeIndex++) {
				that[attributes[attributeIndex]] = createAttrubute(attributes[attributeIndex]);
			}

			// Sets element attribute with key to value
			that.setAttribute = function (key, value) {
				element.setAttribute(key, value);
				return that;
			};

			// Set element style with key/value or object literal.
			//
			// _Usage:_
			//
			//		html.h1().css('display', 'block');
			//		html.h1().css({'display' : 'block', 'color' : 'red'});
			//
			that.css = function (key, value) {
				if (typeof key === "string") {
					that.asJQuery().css(key, value);
				}
				else {
					that.asJQuery().css(key); // otherwise assume key is a map (object literal)
				}

				return that;
			};

			// Set attributes using object literal.
			//
			// _Usage:_
			//
			//		html.h1().attr({id : 'myid', 'class' : 'myclass'});
			//
			// _Note:_ Use klass or 'class' with quotation marks as key instead of class since its a reserved word.
			//
			that.attr = function (object) {
				for (var key in object) {
					if (object.hasOwnProperty(key)) {
						if (key === 'klass') {
							that.addClass(object[key]);
						} else {
							that.setAttribute(key, object[key]);
						}
					}
				}

				return that;
			};

			// Appends className to class attribute
			that.addClass = function (className) {
				that.asJQuery().addClass(className);
				return that;
			};

			// Removes className from class attribute
			that.removeClass = function (className) {
				that.asJQuery().removeClass(className);
				return that;
			};

			// Returns jQuery that match element.
			that.asJQuery = function () {
				return jQuery(that.element());
			};

			// #### TagBrush initialization

			// Element is set to first match if a jQuery was given.
			if (jquery && typeof jquery === 'string') {
				jquery = jQuery(jquery);
			}
			if (jquery) {
				element = jquery.get(0);
				if (!element) {
					throw new Error('jQuery did not match an element');
				}
			}

			// If no jQuery was given, element is created
			// from tag name.
			else {
				element = createElement(elementTagName);
			}

			// Append children to support nesting. _Eg.:_
			//
			//		html.ul(html.li(html.a({href: '#'}, 'home'));
			if (children) {
				for (var childIndex = 0; childIndex < spec.children.length; childIndex++) {
					append(spec.children[childIndex]);
				}
			}

			return that;
		};

        // ### Exports
        // htmlCanvas

		return htmlCanvas;
	}
);
<|endoftext|>


<commit_before>const { multiPromisify } = require("./utils");

function shimLegacy(method) {
  return async config => {
    const compile = multiPromisify(method);

    const [contracts, sourceIndexes, compilerInfo] = await compile(config);

    return {
      contracts: shimContracts(contracts),
      sourceIndexes,
      compilerInfo
    };
  };
}

function shimContracts(contracts) {
  // convert to list
  return Object.values(contracts).map(shimContract);
}

function shimContract(contract) {
  const {
    contractName,
    contract_name,
    sourcePath,
    source,
    sourceMap,
    deployedSourceMap,
    legacyAST,
    ast,
    abi,
    metadata,
    bytecode,
    deployedBytecode,
    compiler,
    devdoc,
    userdoc,
    immutableReferences
  } = contract;

  return {
    contractName: contract_name || contractName,
    sourcePath,
    source,
    sourceMap,
    deployedSourceMap,
    legacyAST,
    ast,
    abi,
    metadata,
    bytecode: shimBytecode(bytecode),
    deployedBytecode: shimBytecode(deployedBytecode),
    compiler,
    devdoc,
    userdoc,
    immutableReferences
  };
}

function shimBytecode(bytecode) {
  if (!bytecode) {
    return undefined;
  }
  if (typeof bytecode === "object") {
    return bytecode;
  }

  const linkReferences = [];

  const bytes = bytecode
    .slice(2) // remove 0x prefix
    .replace(/__[^_]+_*/g, (linkReference, characterOffset) => {
      const [, name] = linkReference.match(/__([^_]+)_*/);

      const characterLength = linkReference.length;

      const offset = characterOffset / 2;
      const length = characterLength / 2;

      linkReferences.push({
        offsets: [offset],
        name,
        length
      });

      return "0".repeat(characterLength);
    });

  return { bytes, linkReferences };
}

module.exports = {
  shimLegacy,
  shimContracts,
  shimContract,
  shimBytecode
};
<commit_msg>Update shim method to wrap compilation in an array<commit_after>const { multiPromisify } = require("./utils");

function shimLegacy(method) {
  return async config => {
    const compile = multiPromisify(method);

    const [contracts, sourceIndexes, compilerInfo] = await compile(config);

    return [
      {
        contracts: shimContracts(contracts),
        sourceIndexes,
        compilerInfo
      }
    ];
  };
}

function shimContracts(contracts) {
  // convert to list
  return Object.values(contracts).map(shimContract);
}

function shimContract(contract) {
  const {
    contractName,
    contract_name,
    sourcePath,
    source,
    sourceMap,
    deployedSourceMap,
    legacyAST,
    ast,
    abi,
    metadata,
    bytecode,
    deployedBytecode,
    compiler,
    devdoc,
    userdoc,
    immutableReferences
  } = contract;

  return {
    contractName: contract_name || contractName,
    sourcePath,
    source,
    sourceMap,
    deployedSourceMap,
    legacyAST,
    ast,
    abi,
    metadata,
    bytecode: shimBytecode(bytecode),
    deployedBytecode: shimBytecode(deployedBytecode),
    compiler,
    devdoc,
    userdoc,
    immutableReferences
  };
}

function shimBytecode(bytecode) {
  if (!bytecode) {
    return undefined;
  }
  if (typeof bytecode === "object") {
    return bytecode;
  }

  const linkReferences = [];

  const bytes = bytecode
    .slice(2) // remove 0x prefix
    .replace(/__[^_]+_*/g, (linkReference, characterOffset) => {
      const [, name] = linkReference.match(/__([^_]+)_*/);

      const characterLength = linkReference.length;

      const offset = characterOffset / 2;
      const length = characterLength / 2;

      linkReferences.push({
        offsets: [offset],
        name,
        length
      });

      return "0".repeat(characterLength);
    });

  return { bytes, linkReferences };
}

module.exports = {
  shimLegacy,
  shimContracts,
  shimContract,
  shimBytecode
};
<|endoftext|>


<commit_before>"use strict";

const realFetch = require('isomorphic-fetch/fetch-npm-node.js');
const { fetchDecorator } = require('./../dist/utils');

module.exports = fetchDecorator(realFetch);
<commit_msg>export the same with node & browser<commit_after>"use strict";

const realFetch = require('isomorphic-fetch/fetch-npm-node.js');
const { fetchDecorator } = require('./../dist/utils');

const fetch = fetchDecorator(realFetch);

fetch.fetch = fetch;

module.exports = fetch;
<|endoftext|>


<commit_before>let {
  parseTests,
  parseTestsWithQueryString,
  formatTests,
  relativeTests,
  relativeTests2,
} = require('../third_party/test_cases');
let url = require('../dist');

parseTests = {
  ...parseTests,
  'https://google.com/hello?test=space%20': {
    protocol: 'https:',
    slashes: true,
    host: 'google.com',
    hostname: 'google.com',
    search: '?test=space%20',
    query: 'test=space%20',
    pathname: '/hello',
    path: '/hello?test=space%20',
    href: 'https://google.com/hello?test=space%20',
  },
  '?percent=%25': {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: '?percent=%25',
    query: 'percent=%25',
    pathname: null,
    path: '?percent=%25',
    href: '?percent=%25',
  },
  [`?lf=before${encodeURI('\n')}after`]: {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: '?lf=before%0Aafter',
    query: 'lf=before%0Aafter',
    pathname: null,
    path: '?lf=before%0Aafter',
    href: '?lf=before%0Aafter',
  },
  'https://www.w.org': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'www.w.org',
    port: null,
    hostname: 'www.w.org',
    hash: null,
    search: null,
    query: null,
    pathname: '/',
    path: '/',
    href: 'https://www.w.org/',
  },
  'https://www.wikipedia.org/': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'www.wikipedia.org',
    port: null,
    hostname: 'www.wikipedia.org',
    hash: null,
    search: null,
    query: null,
    pathname: '/',
    path: '/',
    href: 'https://www.wikipedia.org/',
  },
  '/:42': {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: null,
    query: null,
    pathname: '/:42',
    path: '/:42',
    href: '/:42',
  },
  'http://example.com/:42': {
    protocol: 'http:',
    slashes: true,
    auth: null,
    host: 'example.com',
    port: null,
    hostname: 'example.com',
    hash: null,
    search: null,
    query: null,
    pathname: '/:42',
    path: '/:42',
    href: 'http://example.com/:42',
  },
  '/:80': {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: null,
    query: null,
    pathname: '/:80',
    path: '/:80',
    href: '/:80',
  },
  '/:443': {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: null,
    query: null,
    pathname: '/:443',
    path: '/:443',
    href: '/:443',
  },
  'https://example.com/:443': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'example.com',
    port: null,
    hostname: 'example.com',
    hash: null,
    search: null,
    query: null,
    pathname: '/:443',
    path: '/:443',
    href: 'https://example.com/:443',
  },
  'http://hello:80@hello:80/': {
    protocol: 'http:',
    slashes: true,
    auth: 'hello:80',
    host: 'hello:80',
    port: '80',
    hostname: 'hello',
    hash: null,
    search: null,
    query: null,
    pathname: '/',
    path: '/',
    href: 'http://hello:80@hello:80/',
  },
  'https://hello:443@hello:443/': {
    protocol: 'https:',
    slashes: true,
    auth: 'hello:443',
    host: 'hello:443',
    port: '443',
    hostname: 'hello',
    hash: null,
    search: null,
    query: null,
    pathname: '/',
    path: '/',
    href: 'https://hello:443@hello:443/',
  },
  'https://x.x/hello%25world': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'x.x',
    port: null,
    hostname: 'x.x',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello%25world',
    path: '/hello%25world',
    href: 'https://x.x/hello%25world',
  },
  'https://x.x/hello%3Fworld': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'x.x',
    port: null,
    hostname: 'x.x',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello%3Fworld',
    path: '/hello%3Fworld',
    href: 'https://x.x/hello%3Fworld',
  },
  'https://x.x/hello%23world': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'x.x',
    port: null,
    hostname: 'x.x',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello%23world',
    path: '/hello%23world',
    href: 'https://x.x/hello%23world',
  },
  'https://hello/hello%20world/': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'hello',
    port: null,
    hostname: 'hello',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello%20world/',
    path: '/hello%20world/',
    href: 'https://hello/hello%20world/',
  },
  'https://hello/hello%20%20world/': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'hello',
    port: null,
    hostname: 'hello',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello%20%20world/',
    path: '/hello%20%20world/',
    href: 'https://hello/hello%20%20world/',
  },
  'https://x.x/hello%23%20world': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'x.x',
    port: null,
    hostname: 'x.x',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello%23%20world',
    path: '/hello%23%20world',
    href: 'https://x.x/hello%23%20world',
  },
  'http://x/hello%20world%20': {
    protocol: 'http:',
    slashes: true,
    auth: null,
    host: 'x',
    port: null,
    hostname: 'x',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello%20world%20',
    path: '/hello%20world%20',
    href: 'http://x/hello%20world%20',
  },
  'https://x.x/hello!"$%&\'()*+,./:;<=>@[] ^_`{|}~-world': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'x.x',
    port: null,
    hostname: 'x.x',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello!%22$%&%27()*+,./:;%3C=%3E@[]%20%5E_%60%7B%7C%7D~-world',
    path: '/hello!%22$%&%27()*+,./:;%3C=%3E@[]%20%5E_%60%7B%7C%7D~-world',
    href:
      'https://x.x/hello!%22$%&%27()*+,./:;%3C=%3E@[]%20%5E_%60%7B%7C%7D~-world',
  },
  "https://x.x/hello!%22$%25&'()*+,./:;%3C=%3E@%5B%5D%20%5E_%60%7B%7C%7D~-world": {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'x.x',
    port: null,
    hostname: 'x.x',
    hash: null,
    search: null,
    query: null,
    pathname:
      '/hello!%22$%25&%27()*+,./:;%3C=%3E@%5B%5D%20%5E_%60%7B%7C%7D~-world',
    path: '/hello!%22$%25&%27()*+,./:;%3C=%3E@%5B%5D%20%5E_%60%7B%7C%7D~-world',
    href:
      'https://x.x/hello!%22$%25&%27()*+,./:;%3C=%3E@%5B%5D%20%5E_%60%7B%7C%7D~-world',
  },
};

describe('Basic parse and format:', () => {
  Object.keys(parseTests).forEach(function (u) {
    it(`parse(${u}):`, () => {
      const actual = url.parse(u);
      const spaced = url.parse('     \t  ' + u + '\n\t');
      const expected = parseTests[u];
      const reparsed = url.parse(actual);

      Object.keys(actual).forEach((i) => {
        if (expected[i] === undefined && actual[i] === null) {
          expected[i] = null;
        }
      });

      // The parsed object is an instanceof Url
      // Jasmine's toEqual fails when comparing an instance with and object
      expect({ ...actual }).toEqual(expected);
      expect({ ...spaced }).toEqual(expected);
      expect({ ...reparsed }).toEqual(expected);
    });

    it(`format(${u}):`, () => {
      const expected = parseTests[u].href;
      const actual = url.format(parseTests[u]);

      expect(actual).toEqual(expected);
    });
  });
});

parseTestsWithQueryString = {
  ...parseTestsWithQueryString,
  '/example?query=size:10': {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: '?query=size:10',
    query: { query: 'size:10' },
    pathname: '/example',
    path: '/example?query=size:10',
    href: '/example?query=size:10',
  },
};

describe('With querystring:', () => {
  Object.keys(parseTestsWithQueryString).forEach(function (u) {
    it(`parse(${u}):`, () => {
      const actual = url.parse(u, true);
      const expected = parseTestsWithQueryString[u];

      Object.keys(actual).forEach((i) => {
        if (expected[i] === undefined && actual[i] === null) {
          expected[i] = null;
        }
      });

      expect({ ...actual }).toEqual(expected);
    });
  });
});

describe('Test format():', () => {
  Object.keys(formatTests).forEach(function (u) {
    const expected = formatTests[u].href;
    it(`format(${u}):`, () => {
      const actual = url.format(u);

      expect(actual).toBe(expected);
    });

    it(`format(${JSON.stringify(formatTests[u])})`, () => {
      delete formatTests[u].href;
      const actualObj = url.format(formatTests[u]);

      expect(actualObj).toBe(expected);
    });
  });
});

describe('Test resolve():', () => {
  relativeTests.forEach(function (relativeTest) {
    it(`resolve(${relativeTest[0]}, ${relativeTest[1]}):`, () => {
      const actual = url.resolve(relativeTest[0], relativeTest[1]);
      const expected = relativeTest[2];

      expect(actual).toBe(expected);
    });
  });
});

// https://github.com/joyent/node/issues/568
[undefined, null, true, false, 0.0, 0, [], {}].forEach(function (val) {
  describe('Test [undefined, null, true, false, 0.0, 0, [], {}] values:', () => {
    it(`parse(${val})`, () => {
      expect(() => {
        url.parse(val);
      }).toThrow();
    });
  });
});

describe('Test wonky resolves:', () => {
  relativeTests2.forEach(function (relativeTest) {
    it(`resolve(${relativeTest[1]}, ${relativeTest[0]}):`, () => {
      const actual = url.resolve(relativeTest[1], relativeTest[0]);
      const expected = relativeTest[2];

      expect(actual).toBe(expected);
    });
  });
});

describe('Test resolveObject:', () => {
  relativeTests.forEach(function (relativeTest) {
    it(`resolveObject(${relativeTest[0]}, ${relativeTest[1]}):`, () => {
      let actual = url.resolveObject(relativeTest[0], relativeTest[1]);
      let expected = url.parse(relativeTest[2]);

      expect(actual).toEqual(expected);

      expected = relativeTest[2];
      actual = url.format(actual);

      expect(actual).toBe(expected);
    });
  });
});

//format: [to, from, result]
// the test: ['.//g', 'f:/a', 'f://g'] is a fundamental problem
// url.parse('f:/a') does not have a host
// url.resolve('f:/a', './/g') does not have a host because you have moved
// down to the g directory.  i.e. f:     //g, however when this url is parsed
// f:// will indicate that the host is g which is not the case.
// it is unclear to me how to keep this information from being lost
// it may be that a pathname of ////g should collapse to /g but this seems
// to be a lot of work for an edge case.  Right now I remove the test
if (
  relativeTests2[181][0] === './/g' &&
  relativeTests2[181][1] === 'f:/a' &&
  relativeTests2[181][2] === 'f://g'
) {
  relativeTests2.splice(181, 1);
}

describe('Test wonky resolveObject:', () => {
  relativeTests2.forEach(function (relativeTest) {
    it(`resolveObject(${relativeTest[1]}, ${relativeTest[0]}):`, () => {
      let actual = url.resolveObject(
        url.parse(relativeTest[1]),
        relativeTest[0]
      );
      let expected = url.parse(relativeTest[2]);

      expect(actual).toEqual(expected);

      expected = relativeTest[2];
      actual = url.format(actual);

      expect(actual).toBe(expected);
    });
  });
});
<commit_msg>test relative as well<commit_after>let {
  parseTests,
  parseTestsWithQueryString,
  formatTests,
  relativeTests,
  relativeTests2,
} = require('../third_party/test_cases');
let url = require('../dist');

parseTests = {
  ...parseTests,
  'https://google.com/hello?test=space%20': {
    protocol: 'https:',
    slashes: true,
    host: 'google.com',
    hostname: 'google.com',
    search: '?test=space%20',
    query: 'test=space%20',
    pathname: '/hello',
    path: '/hello?test=space%20',
    href: 'https://google.com/hello?test=space%20',
  },
  '?percent=%25': {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: '?percent=%25',
    query: 'percent=%25',
    pathname: null,
    path: '?percent=%25',
    href: '?percent=%25',
  },
  [`?lf=before${encodeURI('\n')}after`]: {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: '?lf=before%0Aafter',
    query: 'lf=before%0Aafter',
    pathname: null,
    path: '?lf=before%0Aafter',
    href: '?lf=before%0Aafter',
  },
  'https://www.w.org': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'www.w.org',
    port: null,
    hostname: 'www.w.org',
    hash: null,
    search: null,
    query: null,
    pathname: '/',
    path: '/',
    href: 'https://www.w.org/',
  },
  'https://www.wikipedia.org/': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'www.wikipedia.org',
    port: null,
    hostname: 'www.wikipedia.org',
    hash: null,
    search: null,
    query: null,
    pathname: '/',
    path: '/',
    href: 'https://www.wikipedia.org/',
  },
  '/:42': {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: null,
    query: null,
    pathname: '/:42',
    path: '/:42',
    href: '/:42',
  },
  'http://example.com/:42': {
    protocol: 'http:',
    slashes: true,
    auth: null,
    host: 'example.com',
    port: null,
    hostname: 'example.com',
    hash: null,
    search: null,
    query: null,
    pathname: '/:42',
    path: '/:42',
    href: 'http://example.com/:42',
  },
  '/:80': {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: null,
    query: null,
    pathname: '/:80',
    path: '/:80',
    href: '/:80',
  },
  '/:443': {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: null,
    query: null,
    pathname: '/:443',
    path: '/:443',
    href: '/:443',
  },
  'https://example.com/:443': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'example.com',
    port: null,
    hostname: 'example.com',
    hash: null,
    search: null,
    query: null,
    pathname: '/:443',
    path: '/:443',
    href: 'https://example.com/:443',
  },
  'http://hello:80@hello:80/': {
    protocol: 'http:',
    slashes: true,
    auth: 'hello:80',
    host: 'hello:80',
    port: '80',
    hostname: 'hello',
    hash: null,
    search: null,
    query: null,
    pathname: '/',
    path: '/',
    href: 'http://hello:80@hello:80/',
  },
  'https://hello:443@hello:443/': {
    protocol: 'https:',
    slashes: true,
    auth: 'hello:443',
    host: 'hello:443',
    port: '443',
    hostname: 'hello',
    hash: null,
    search: null,
    query: null,
    pathname: '/',
    path: '/',
    href: 'https://hello:443@hello:443/',
  },
  'https://x.x/hello%25world': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'x.x',
    port: null,
    hostname: 'x.x',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello%25world',
    path: '/hello%25world',
    href: 'https://x.x/hello%25world',
  },
  'https://x.x/hello%3Fworld': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'x.x',
    port: null,
    hostname: 'x.x',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello%3Fworld',
    path: '/hello%3Fworld',
    href: 'https://x.x/hello%3Fworld',
  },
  'https://x.x/hello%23world': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'x.x',
    port: null,
    hostname: 'x.x',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello%23world',
    path: '/hello%23world',
    href: 'https://x.x/hello%23world',
  },
  'https://hello/hello%20world/': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'hello',
    port: null,
    hostname: 'hello',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello%20world/',
    path: '/hello%20world/',
    href: 'https://hello/hello%20world/',
  },
  'https://hello/hello%20%20world/': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'hello',
    port: null,
    hostname: 'hello',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello%20%20world/',
    path: '/hello%20%20world/',
    href: 'https://hello/hello%20%20world/',
  },
  'https://x.x/hello%23%20world': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'x.x',
    port: null,
    hostname: 'x.x',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello%23%20world',
    path: '/hello%23%20world',
    href: 'https://x.x/hello%23%20world',
  },
  'http://x/hello%20world%20': {
    protocol: 'http:',
    slashes: true,
    auth: null,
    host: 'x',
    port: null,
    hostname: 'x',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello%20world%20',
    path: '/hello%20world%20',
    href: 'http://x/hello%20world%20',
  },
  'https://x.x/hello!"$%&\'()*+,./:;<=>@[] ^_`{|}~-world': {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'x.x',
    port: null,
    hostname: 'x.x',
    hash: null,
    search: null,
    query: null,
    pathname: '/hello!%22$%&%27()*+,./:;%3C=%3E@[]%20%5E_%60%7B%7C%7D~-world',
    path: '/hello!%22$%&%27()*+,./:;%3C=%3E@[]%20%5E_%60%7B%7C%7D~-world',
    href:
      'https://x.x/hello!%22$%&%27()*+,./:;%3C=%3E@[]%20%5E_%60%7B%7C%7D~-world',
  },
  "https://x.x/hello!%22$%25&'()*+,./:;%3C=%3E@%5B%5D%20%5E_%60%7B%7C%7D~-world": {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'x.x',
    port: null,
    hostname: 'x.x',
    hash: null,
    search: null,
    query: null,
    pathname:
      '/hello!%22$%25&%27()*+,./:;%3C=%3E@%5B%5D%20%5E_%60%7B%7C%7D~-world',
    path: '/hello!%22$%25&%27()*+,./:;%3C=%3E@%5B%5D%20%5E_%60%7B%7C%7D~-world',
    href:
      'https://x.x/hello!%22$%25&%27()*+,./:;%3C=%3E@%5B%5D%20%5E_%60%7B%7C%7D~-world',
  },
  '/hello%20world%20': {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: null,
    query: null,
    pathname: '/hello%20world%20',
    path: '/hello%20world%20',
    href: '/hello%20world%20',
  },
};

describe('Basic parse and format:', () => {
  Object.keys(parseTests).forEach(function (u) {
    it(`parse(${u}):`, () => {
      const actual = url.parse(u);
      const spaced = url.parse('     \t  ' + u + '\n\t');
      const expected = parseTests[u];
      const reparsed = url.parse(actual);

      Object.keys(actual).forEach((i) => {
        if (expected[i] === undefined && actual[i] === null) {
          expected[i] = null;
        }
      });

      // The parsed object is an instanceof Url
      // Jasmine's toEqual fails when comparing an instance with and object
      expect({ ...actual }).toEqual(expected);
      expect({ ...spaced }).toEqual(expected);
      expect({ ...reparsed }).toEqual(expected);
    });

    it(`format(${u}):`, () => {
      const expected = parseTests[u].href;
      const actual = url.format(parseTests[u]);

      expect(actual).toEqual(expected);
    });
  });
});

parseTestsWithQueryString = {
  ...parseTestsWithQueryString,
  '/example?query=size:10': {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: '?query=size:10',
    query: { query: 'size:10' },
    pathname: '/example',
    path: '/example?query=size:10',
    href: '/example?query=size:10',
  },
};

describe('With querystring:', () => {
  Object.keys(parseTestsWithQueryString).forEach(function (u) {
    it(`parse(${u}):`, () => {
      const actual = url.parse(u, true);
      const expected = parseTestsWithQueryString[u];

      Object.keys(actual).forEach((i) => {
        if (expected[i] === undefined && actual[i] === null) {
          expected[i] = null;
        }
      });

      expect({ ...actual }).toEqual(expected);
    });
  });
});

describe('Test format():', () => {
  Object.keys(formatTests).forEach(function (u) {
    const expected = formatTests[u].href;
    it(`format(${u}):`, () => {
      const actual = url.format(u);

      expect(actual).toBe(expected);
    });

    it(`format(${JSON.stringify(formatTests[u])})`, () => {
      delete formatTests[u].href;
      const actualObj = url.format(formatTests[u]);

      expect(actualObj).toBe(expected);
    });
  });
});

describe('Test resolve():', () => {
  relativeTests.forEach(function (relativeTest) {
    it(`resolve(${relativeTest[0]}, ${relativeTest[1]}):`, () => {
      const actual = url.resolve(relativeTest[0], relativeTest[1]);
      const expected = relativeTest[2];

      expect(actual).toBe(expected);
    });
  });
});

// https://github.com/joyent/node/issues/568
[undefined, null, true, false, 0.0, 0, [], {}].forEach(function (val) {
  describe('Test [undefined, null, true, false, 0.0, 0, [], {}] values:', () => {
    it(`parse(${val})`, () => {
      expect(() => {
        url.parse(val);
      }).toThrow();
    });
  });
});

describe('Test wonky resolves:', () => {
  relativeTests2.forEach(function (relativeTest) {
    it(`resolve(${relativeTest[1]}, ${relativeTest[0]}):`, () => {
      const actual = url.resolve(relativeTest[1], relativeTest[0]);
      const expected = relativeTest[2];

      expect(actual).toBe(expected);
    });
  });
});

describe('Test resolveObject:', () => {
  relativeTests.forEach(function (relativeTest) {
    it(`resolveObject(${relativeTest[0]}, ${relativeTest[1]}):`, () => {
      let actual = url.resolveObject(relativeTest[0], relativeTest[1]);
      let expected = url.parse(relativeTest[2]);

      expect(actual).toEqual(expected);

      expected = relativeTest[2];
      actual = url.format(actual);

      expect(actual).toBe(expected);
    });
  });
});

//format: [to, from, result]
// the test: ['.//g', 'f:/a', 'f://g'] is a fundamental problem
// url.parse('f:/a') does not have a host
// url.resolve('f:/a', './/g') does not have a host because you have moved
// down to the g directory.  i.e. f:     //g, however when this url is parsed
// f:// will indicate that the host is g which is not the case.
// it is unclear to me how to keep this information from being lost
// it may be that a pathname of ////g should collapse to /g but this seems
// to be a lot of work for an edge case.  Right now I remove the test
if (
  relativeTests2[181][0] === './/g' &&
  relativeTests2[181][1] === 'f:/a' &&
  relativeTests2[181][2] === 'f://g'
) {
  relativeTests2.splice(181, 1);
}

describe('Test wonky resolveObject:', () => {
  relativeTests2.forEach(function (relativeTest) {
    it(`resolveObject(${relativeTest[1]}, ${relativeTest[0]}):`, () => {
      let actual = url.resolveObject(
        url.parse(relativeTest[1]),
        relativeTest[0]
      );
      let expected = url.parse(relativeTest[2]);

      expect(actual).toEqual(expected);

      expected = relativeTest[2];
      actual = url.format(actual);

      expect(actual).toBe(expected);
    });
  });
});
<|endoftext|>


<commit_before>// initializes the application
// and links it with the GUI

'use strict'

// require keybindings
const keybindings = require('../src/keybindings.js')
const printChat = require('../src/core/printChat.js')

// require core modules
// const nodeInfo = require('./src/core/nodeInfo.js')
const core = require('../src/core/core.js')
const hoverNodeInfo = require('../src/core/hoverNodeInfo.js')
const editNode = require('../src/core/editNode.js')
const totalNodes = require('../src/core/totalNodes.js')
// require design modules
const dgn = require('../src/design/design.js')
// require design-state Models
const dgnState = require('../src/design-state/dgnState.js')
// reguire implementation modules
const imp = require('../src/implementation/implementation.js')
// require implementation-state modules
const impState = require('../src/implementation-state/impState.js')

module.exports = function setup (cy) {
  // initial label render
  cy.nodes().addClass('label-nodes')
  cy.edges().addClass('label-edges')

  // global variables, used in cy.on
  let selectedNode = {}
  let oldSelectedNode = {}
  let selectedEdge = {}
  let srcNode = {}
  let trgNode = {}
  let srcNodeCpt = {}
  let trgNodeCpt = {}
  // initialize export variables to prevent undefined errors
  selectedNode.out = {}
  selectedEdge.out = {}
  srcNode.out = {}
  trgNode.out = {}
  srcNodeCpt.out = {}
  trgNodeCpt.out = {}

  // counter variable to create unique sequential node ids in addComponents.js
  const initialCount = cy.nodes().length

  // cy.on does stuff when intrecting with the graph
  // actions when tapping on node
  cy.on('tap', 'node', selection => {
    // removes previous selections
    cy.elements().removeClass('selection')
    cy.elements().removeClass('attention')
    cy.elements().removeClass('protect')
    cy.nodes().removeClass('old-selection')
    oldSelectedNode = selectedNode.out
    selectedNode.out = selection.target[0]
    selectedNode.out.addClass('selection')
    if (Object.keys(oldSelectedNode).length !== 0) {
      oldSelectedNode.addClass('old-selection')
    }
    srcNode.out = trgNode.out // second selection
    trgNode.out = selectedNode.out.data().id
    srcNodeCpt.out = trgNodeCpt.out // second selection
    trgNodeCpt.out = selectedNode.out.data().info.concept
    selectedEdge.out = {} // clear token
    totalNodes(cy) // global module
    editNode.removeElement() // remove the edit node element
  })
  // actions when tapping on an edge
  cy.on('tap', 'edge', selection => {
    // removes previous selections
    cy.elements().removeClass('selection')
    cy.elements().removeClass('attention')
    cy.elements().removeClass('protect')
    cy.nodes().removeClass('old-selection')
    selection.target.addClass('selection')
    selectedNode.out = {} // clear token
    oldSelectedNode = {} // clear token
    selectedEdge.out = selection.target[0]
    totalNodes(cy) // global module
    editNode.removeElement() // remove the edit node element
  })
  // actions when tapping the stage
  cy.on('tap', selection => {
    // checks if only the stage was clicked
    if (selection.target === cy) {
      // removes previous selections
      cy.elements().removeClass('faded')
      cy.elements().removeClass('selection')
      cy.elements().removeClass('attention')
      cy.elements().removeClass('protect')
      cy.nodes().removeClass('old-selection')
      // clear tokens
      selectedNode.out = {}
      oldSelectedNode = {}
      selectedEdge.out = {}
      totalNodes(cy) // global module
      editNode.removeElement() // remove the edit node element
    }
  })
  // right clicking
  cy.on('cxttapend', 'node', selection => {
    selectedNode = selection.target[0]
    editNode.formNode(selectedNode) // global module
  })
  // actions when hovering over a node
  cy.on('mouseover', 'node', event => {
    hoverNodeInfo(event.target[0]) // global module
  })
  // actions when hovering out of a node
  cy.on('mouseout', 'node', event => {
    // hides the hover container
    document.getElementById('container-node-id').style.display = 'none'
  })

  // create the paths of each phase
  const dgnPath = 'design.html'
  const dgnStatePath = 'design-state.html'
  const impPath = 'implementation.html'
  const impStatePath = 'implementation-state.html'

  // store the last word of the window path to make it cross plaform
  // blame chromium and its Posix paths on windows for this ugliness
  const pathLocation = window.location.pathname.split('/').pop()

  // load the buttons for each phase

  // load design phase buttons
  if (pathLocation === dgnPath) {
    dgn.addNode(cy, initialCount)
    dgn.threatVerify(cy)
    dgn.overview(cy)
    dgn.validate(cy)
    dgn.moduleGroup(cy)
    dgn.addEdge(cy, srcNode, trgNode, srcNodeCpt, trgNodeCpt)
    // load design-state buttons
  } else if (pathLocation === dgnStatePath) {
    dgnState.addNode(cy, initialCount)
    dgnState.overview(cy)
    dgnState.validate(cy)
    dgnState.addEdge(cy, srcNode, trgNode, srcNodeCpt, trgNodeCpt)
    // loads implementation phase buttons
  } else if (pathLocation === impPath) {
    imp.addNode(cy, initialCount)
    imp.overview(cy)
    imp.validate(cy)
    imp.threatVerify(cy)
    imp.vulnVerify(cy)
    imp.findVulnerabilities(cy)
    imp.findPattern(cy)
    imp.moduleGroup(cy)
    imp.addEdge(cy, srcNode, trgNode, srcNodeCpt, trgNodeCpt)
    // loads implementation-state buttons
  } else if (pathLocation === impStatePath) {
    impState.addNode(cy, initialCount)
    impState.overview(cy)
    impState.validate(cy)
    impState.addEdge(cy, srcNode, trgNode, srcNodeCpt, trgNodeCpt)
  }

  // declaration of global buttons

  // highlights only the selected node class
  core.selectionNode(cy)
  // cose layout
  core.graphLayout(cy)
  // enable label buttons
  core.labels(cy)
  // save graph
  core.saveGraph(cy)
  // load graph - TODO doesn't work properly
  // core.loadGraph(cy)
  // show the neighbors of a tapped node
  core.showNeighbor(cy, selectedNode)
  // delete elements
  core.deleteButton(cy, selectedNode, selectedEdge)
  // initial node count
  totalNodes(cy)
  // enable keybindings
  keybindings(cy, selectedNode, selectedEdge)

  // test function
  const buttonTest = document.getElementById('test-button')
  buttonTest.addEventListener('click', () => {
    // test code goes here
    printChat('test function\nused for debugging')
  })
}

// toggles side panels
// const toggleUI = () => {
//   const sidebarStatus = document.getElementById('sidebar-id')
//   const actionBarStatus = document.getElementById('action-bar-id')
//   if (sidebarStatus.style.display === 'block') {
//     sidebarStatus.style.display = 'none'
//     actionBarStatus.style.display = 'none'
//   } else {
//     sidebarStatus.style.display = 'block'
//     actionBarStatus.style.display = 'block'
//   }
// }
<commit_msg>:bug: clear tokens when right clicking a node<commit_after>// initializes the application
// and links it with the GUI

'use strict'

// require keybindings
const keybindings = require('../src/keybindings.js')
const printChat = require('../src/core/printChat.js')

// require core modules
// const nodeInfo = require('./src/core/nodeInfo.js')
const core = require('../src/core/core.js')
const hoverNodeInfo = require('../src/core/hoverNodeInfo.js')
const editNode = require('../src/core/editNode.js')
const totalNodes = require('../src/core/totalNodes.js')
// require design modules
const dgn = require('../src/design/design.js')
// require design-state Models
const dgnState = require('../src/design-state/dgnState.js')
// reguire implementation modules
const imp = require('../src/implementation/implementation.js')
// require implementation-state modules
const impState = require('../src/implementation-state/impState.js')

module.exports = function setup (cy) {
  // initial label render
  cy.nodes().addClass('label-nodes')
  cy.edges().addClass('label-edges')

  // global variables, used in cy.on
  let selectedNode = {}
  let oldSelectedNode = {}
  let selectedEdge = {}
  let srcNode = {}
  let trgNode = {}
  let srcNodeCpt = {}
  let trgNodeCpt = {}
  // initialize export variables to prevent undefined errors
  selectedNode.out = {}
  selectedEdge.out = {}
  srcNode.out = {}
  trgNode.out = {}
  srcNodeCpt.out = {}
  trgNodeCpt.out = {}

  // counter variable to create unique sequential node ids in addComponents.js
  const initialCount = cy.nodes().length

  // cy.on does stuff when intrecting with the graph
  // actions when tapping on node
  cy.on('tap', 'node', selection => {
    // removes previous selections
    cy.elements().removeClass('selection')
    cy.elements().removeClass('attention')
    cy.elements().removeClass('protect')
    cy.nodes().removeClass('old-selection')
    oldSelectedNode = selectedNode.out
    selectedNode.out = selection.target[0]
    selectedNode.out.addClass('selection')
    if (Object.keys(oldSelectedNode).length !== 0) {
      oldSelectedNode.addClass('old-selection')
    }
    srcNode.out = trgNode.out // second selection
    trgNode.out = selectedNode.out.data().id
    srcNodeCpt.out = trgNodeCpt.out // second selection
    trgNodeCpt.out = selectedNode.out.data().info.concept
    selectedEdge.out = {} // clear token
    totalNodes(cy) // global module
    editNode.removeElement() // remove the edit node element
  })
  // actions when tapping on an edge
  cy.on('tap', 'edge', selection => {
    // removes previous selections
    cy.elements().removeClass('selection')
    cy.elements().removeClass('attention')
    cy.elements().removeClass('protect')
    cy.nodes().removeClass('old-selection')
    selection.target.addClass('selection')
    selectedNode.out = {} // clear token
    oldSelectedNode = {} // clear token
    selectedEdge.out = selection.target[0]
    totalNodes(cy) // global module
    editNode.removeElement() // remove the edit node element
  })
  // actions when tapping the stage
  cy.on('tap', selection => {
    // checks if only the stage was clicked
    if (selection.target === cy) {
      // removes previous selections
      cy.elements().removeClass('faded')
      cy.elements().removeClass('selection')
      cy.elements().removeClass('attention')
      cy.elements().removeClass('protect')
      cy.nodes().removeClass('old-selection')
      // clear tokens
      selectedNode.out = {}
      oldSelectedNode = {}
      selectedEdge.out = {}
      totalNodes(cy) // global module
      editNode.removeElement() // remove the edit node element
    }
  })
  // right clicking
  cy.on('cxttapend', 'node', selection => {
    selectedNode = selection.target[0]
    editNode.formNode(selectedNode) // global module
    // clear tokens
    selectedNode.out = {}
    oldSelectedNode = {}
    selectedEdge.out = {}
  })
  // actions when hovering over a node
  cy.on('mouseover', 'node', event => {
    hoverNodeInfo(event.target[0]) // global module
  })
  // actions when hovering out of a node
  cy.on('mouseout', 'node', event => {
    // hides the hover container
    document.getElementById('container-node-id').style.display = 'none'
  })

  // create the paths of each phase
  const dgnPath = 'design.html'
  const dgnStatePath = 'design-state.html'
  const impPath = 'implementation.html'
  const impStatePath = 'implementation-state.html'

  // store the last word of the window path to make it cross plaform
  // blame chromium and its Posix paths on windows for this ugliness
  const pathLocation = window.location.pathname.split('/').pop()

  // load the buttons for each phase

  // load design phase buttons
  if (pathLocation === dgnPath) {
    dgn.addNode(cy, initialCount)
    dgn.threatVerify(cy)
    dgn.overview(cy)
    dgn.validate(cy)
    dgn.moduleGroup(cy)
    dgn.addEdge(cy, srcNode, trgNode, srcNodeCpt, trgNodeCpt)
    // load design-state buttons
  } else if (pathLocation === dgnStatePath) {
    dgnState.addNode(cy, initialCount)
    dgnState.overview(cy)
    dgnState.validate(cy)
    dgnState.addEdge(cy, srcNode, trgNode, srcNodeCpt, trgNodeCpt)
    // loads implementation phase buttons
  } else if (pathLocation === impPath) {
    imp.addNode(cy, initialCount)
    imp.overview(cy)
    imp.validate(cy)
    imp.threatVerify(cy)
    imp.vulnVerify(cy)
    imp.findVulnerabilities(cy)
    imp.findPattern(cy)
    imp.moduleGroup(cy)
    imp.addEdge(cy, srcNode, trgNode, srcNodeCpt, trgNodeCpt)
    // loads implementation-state buttons
  } else if (pathLocation === impStatePath) {
    impState.addNode(cy, initialCount)
    impState.overview(cy)
    impState.validate(cy)
    impState.addEdge(cy, srcNode, trgNode, srcNodeCpt, trgNodeCpt)
  }

  // declaration of global buttons

  // highlights only the selected node class
  core.selectionNode(cy)
  // cose layout
  core.graphLayout(cy)
  // enable label buttons
  core.labels(cy)
  // save graph
  core.saveGraph(cy)
  // load graph - TODO doesn't work properly
  // core.loadGraph(cy)
  // show the neighbors of a tapped node
  core.showNeighbor(cy, selectedNode)
  // delete elements
  core.deleteButton(cy, selectedNode, selectedEdge)
  // initial node count
  totalNodes(cy)
  // enable keybindings
  keybindings(cy, selectedNode, selectedEdge)

  // test function
  const buttonTest = document.getElementById('test-button')
  buttonTest.addEventListener('click', () => {
    // test code goes here
    printChat('test function\nused for debugging')
  })
}

// toggles side panels
// const toggleUI = () => {
//   const sidebarStatus = document.getElementById('sidebar-id')
//   const actionBarStatus = document.getElementById('action-bar-id')
//   if (sidebarStatus.style.display === 'block') {
//     sidebarStatus.style.display = 'none'
//     actionBarStatus.style.display = 'none'
//   } else {
//     sidebarStatus.style.display = 'block'
//     actionBarStatus.style.display = 'block'
//   }
// }
<|endoftext|>


<commit_before>import { decorate } from './private/utils';

const CONSOLE_NATIVE = console;

let count = 0;

function handleDescriptor(target, key, descriptor, [prefix = null, konsole = null]) {
  let className = target.constructor.name;
  let fn = descriptor.value;
  const CONSOLE = konsole || CONSOLE_NATIVE;

  if ( prefix === null ) {
    prefix = `${className}.${key}`;
  }

  if (typeof fn !== 'function') {
    throw new SyntaxError(`@instrument can only be used on functions, not: ${fn}`);
  }

  return {
    ...descriptor,
    value() {
      let timeStarted;
      let log = CONSOLE.log ? CONSOLE.log.bind(CONSOLE) : CONSOLE_NATIVE.log.bind(CONSOLE_NATIVE);
      let time = CONSOLE.time ? CONSOLE.time.bind(CONSOLE) : function() {
        timeStarted = new Date();
      };
      let timeEnd = CONSOLE.timeEnd ? CONSOLE.timeEnd.bind(CONSOLE) : function() {
        let timeEnded = new Date();
        let timeTaken = timeEnded - timeStarted;
        log(`${label}: ${timeTaken}ms`);
      };
      let label = `${prefix}-${count}`;
      count++;
      time(label);
      fn.apply(this, arguments);
      timeEnd(label);
    }
  }
}

export default function instrument(...args) {
  return decorate(handleDescriptor, args);
}
<commit_msg>captured and returned value in @instrument<commit_after>import { decorate } from './private/utils';

const CONSOLE_NATIVE = console;

let count = 0;

function handleDescriptor(target, key, descriptor, [prefix = null, konsole = null]) {
  let className = target.constructor.name;
  let fn = descriptor.value;
  const CONSOLE = konsole || CONSOLE_NATIVE;

  if ( prefix === null ) {
    prefix = `${className}.${key}`;
  }

  if (typeof fn !== 'function') {
    throw new SyntaxError(`@instrument can only be used on functions, not: ${fn}`);
  }

  return {
    ...descriptor,
    value() {
      let timeStarted;
      let log = CONSOLE.log ? CONSOLE.log.bind(CONSOLE) : CONSOLE_NATIVE.log.bind(CONSOLE_NATIVE);
      let time = CONSOLE.time ? CONSOLE.time.bind(CONSOLE) : function() {
        timeStarted = new Date();
      };
      let timeEnd = CONSOLE.timeEnd ? CONSOLE.timeEnd.bind(CONSOLE) : function() {
        let timeEnded = new Date();
        let timeTaken = timeEnded - timeStarted;
        log(`${label}: ${timeTaken}ms`);
      };
      let label = `${prefix}-${count}`;
      count++;
      time(label);
      let result = fn.apply(this, arguments);
      timeEnd(label);
      return result;
    }
  }
}

export default function instrument(...args) {
  return decorate(handleDescriptor, args);
}
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import {
  View,
  StyleSheet,
  TouchableHighlight,
  LayoutAnimation,
  AsyncStorage,
  Text
} from 'react-native'

import { connect } from 'react-redux'
import { newRoute } from '../Actions/actions_routing.js'
import routes from '../Utils/routes.js'

import InterestsList from '../Components/InterestsList.js'
// TODO send log out down as a prop function

class Interests extends Component {

  componentWillUnmount () {
    this.setInterests()
  }

  setInterests () {
    const chosenInterests = this.props.chosenInterests
    //set to async storage
    AsyncStorage.setItem('interests', JSON.stringify(chosenInterests))
    //send data to db
    const interestObj = {
      userId: 'ysu:' + this.props.userDetails.email,
      interests: chosenInterests
    }
    // const url = 'http://annafreudhub.herokuapp.com/setinterests'
    const url = 'http://localhost:4000/setinterests'
    fetch(url, {
      method: 'POST',
      body: JSON.stringify(interestObj)
    })
    //change route
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)
  }

  render () {
    return (
      <View style={styles.mainContainer}>
        <TouchableHighlight
          onPress={() => {
            AsyncStorage.clear()
            this.props.newRoute(routes.SIGNUP)
          }}
        >
          <Text>LogOut</Text>
        </TouchableHighlight>
        <InterestsList />
        <TouchableHighlight
          style={styles.menu}
          onPress={() => this.props.newRoute(routes.HUB)}
        >
          <Text style={styles.menuItem}>Submit</Text>
        </TouchableHighlight>
      </View>
    )
  }
}

const mapStateToProps = (state) => ({ ...state })

export default connect(mapStateToProps, { newRoute })(Interests)

const styles = StyleSheet.create({
  mainContainer: {
    backgroundColor: '#fff',
    flex: 1
  },
  menu: {
    justifyContent: 'space-between',
    alignItems: 'center',
    flexDirection: 'row',
    position: 'absolute',
    left: 0,
    right: 0,
    bottom: 60,
    height: 60,
    backgroundColor: '#031f39'
  },
  menuItem: {
    color: '#fff',
    textAlign: 'center',
    fontSize: 15,
    flex: 1
  }
})
<commit_msg>remove logout<commit_after>import React, { Component } from 'react'
import {
  View,
  StyleSheet,
  TouchableHighlight,
  LayoutAnimation,
  AsyncStorage,
  Text
} from 'react-native'

import { connect } from 'react-redux'
import { newRoute } from '../Actions/actions_routing.js'
import routes from '../Utils/routes.js'

import InterestsList from '../Components/InterestsList.js'
// TODO send log out down as a prop function

class Interests extends Component {

  componentWillUnmount () {
    this.setInterests()
  }

  setInterests () {
    const chosenInterests = this.props.chosenInterests
    //set to async storage
    AsyncStorage.setItem('interests', JSON.stringify(chosenInterests))
    //send data to db
    const interestObj = {
      userId: 'ysu:' + this.props.userDetails.email,
      interests: chosenInterests
    }
    // const url = 'http://annafreudhub.herokuapp.com/setinterests'
    const url = 'http://localhost:4000/setinterests'
    fetch(url, {
      method: 'POST',
      body: JSON.stringify(interestObj)
    })
    //change route
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)
  }

  render () {
    return (
      <View style={styles.mainContainer}>
        <InterestsList />
        <TouchableHighlight
          style={styles.menu}
          onPress={() => this.props.newRoute(routes.HUB)}
        >
          <Text style={styles.menuItem}>Submit</Text>
        </TouchableHighlight>
      </View>
    )
  }
}

const mapStateToProps = (state) => ({ ...state })

export default connect(mapStateToProps, { newRoute })(Interests)

const styles = StyleSheet.create({
  mainContainer: {
    backgroundColor: '#fff',
    flex: 1
  },
  menu: {
    justifyContent: 'space-between',
    alignItems: 'center',
    flexDirection: 'row',
    position: 'absolute',
    left: 0,
    right: 0,
    bottom: 60,
    height: 60,
    backgroundColor: '#031f39'
  },
  menuItem: {
    color: '#fff',
    textAlign: 'center',
    fontSize: 15,
    flex: 1
  }
})
<|endoftext|>


<commit_before>#!/usr/bin/env node

const fs = require('fs-extra')
const path = require('path')
const spawnSync = require('child_process').spawnSync

const program = require('commander')

const build = (sourceDir) => {
  // Check that the source directory exists and chdir to it.
  if (!fs.existsSync(sourceDir)) {
    console.error('The source directory: ' + sourceDir + ' does not exist!')
    process.exit(1)
  }
  process.chdir(sourceDir)

  // Make the 'web-build' directory to hold the dockcross script and the CMake
  // build.
  try {
    fs.mkdirSync('web-build')
  } catch (err) {
    if (err.code !== 'EEXIST') throw err
  }

  // Check that we have docker and can run it.
  const dockerVersion = spawnSync('docker', ['--version'], {
    env: process.env,
    stdio: [ 'ignore', 'ignore', 'ignore' ]
  })
  if (dockerVersion.status !== 0) {
    console.error("Could not run the 'docker' command.")
    console.error('This tool requires Docker.')
    console.error('')
    console.error('Please find installation instructions at:')
    console.error('')
    console.error('  https://docs.docker.com/install/')
    console.error('')
    process.exit(dockerVersion.status)
  }

  let dockerImage = 'insighttoolkit/itk-js'
  if (program.commands[0].image) {
    dockerImage = program.commands[0].image
  }

  // Ensure we have the 'dockcross' Docker build environment driver script
  const dockcrossScript = 'web-build/itk-js-build-env'
  try {
    fs.statSync(dockcrossScript)
  } catch (err) {
    if (err.code === 'ENOENT') {
      const output = fs.openSync(dockcrossScript, 'w')
      const dockerCall = spawnSync('docker', ['run', '--rm', dockerImage], {
        env: process.env,
        stdio: [ 'ignore', output, null ]
      })
      if (dockerCall.status !== 0) {
        process.exit(dockerCall.status)
      }
      fs.closeSync(output)
      fs.chmodSync(dockcrossScript, '755')
    } else {
      throw err
    }
  }

  const hypenIndex = program.rawArgs.findIndex((arg) => arg === '--')
  let cmakeArgs = []
  if (hypenIndex !== -1) {
    cmakeArgs = program.rawArgs.slice(hypenIndex + 1)
  }

  const dockerBuild = spawnSync(dockcrossScript, ['web-build'].concat(cmakeArgs), {
    env: process.env,
    stdio: 'inherit'
  })
  process.exit(dockerBuild.status)
}

const test = (sourceDir) => {
  // Check that the source directory exists and chdir to it.
  if (!fs.existsSync(sourceDir)) {
    console.error('The source directory: ' + sourceDir + ' does not exist!')
    process.exit(1)
  }
  process.chdir(sourceDir)

  const dockcrossScript = path.join('web-build/itk-js-build-env')
  try {
    fs.statSync(dockcrossScript)
  } catch (err) {
    console.error('Could not find ' + sourceDir + '/web-build/itk-js-build-env')
    console.error('')
    console.error('Has')
    console.error('')
    console.error('  itk-js build ' + sourceDir)
    console.error('')
    console.error('been executed?')
    process.exit(1)
  }

  const hypenIndex = program.rawArgs.findIndex((arg) => arg === '--')
  let ctestArgs = ''
  if (hypenIndex !== -1) {
    ctestArgs = program.rawArgs.slice(hypenIndex + 1).join(' ')
  }

  const dockerBuild = spawnSync('bash', [dockcrossScript,
    'bash', '-c',
      'cd web-build && ctest ' + ctestArgs],
    {
      env: process.env,
      stdio: 'inherit'
    })
  process.exit(dockerBuild.status)
}

program
  .command('build <sourceDir>')
  .usage('[options] <sourceDir> [-- <cmake arguments>]')
  .description('build the CMake project found in the given source directory')
  .action(build)
  .option('-i, --image <image>', 'build environment Docker image, defaults to insighttoolkit/itk-js')

// todo: needs a wrapper in web_add_test that 1) mount /work into the emscripten filesystem
// and 2) invokes the runtime
// program
//   .command('test <sourceDir>')
//   .usage('[options] <sourceDir> [-- <ctest arguments>]')
//   .description('run ctest on the project previously built from the given source directory')
//   .action(test)

program
  .parse(process.argv)

program.help()
<commit_msg>feat(cli): Use tagged version of default Docker image<commit_after>#!/usr/bin/env node

const fs = require('fs-extra')
const path = require('path')
const spawnSync = require('child_process').spawnSync

const program = require('commander')

const build = (sourceDir) => {
  // Check that the source directory exists and chdir to it.
  if (!fs.existsSync(sourceDir)) {
    console.error('The source directory: ' + sourceDir + ' does not exist!')
    process.exit(1)
  }
  process.chdir(sourceDir)

  // Make the 'web-build' directory to hold the dockcross script and the CMake
  // build.
  try {
    fs.mkdirSync('web-build')
  } catch (err) {
    if (err.code !== 'EEXIST') throw err
  }

  // Check that we have docker and can run it.
  const dockerVersion = spawnSync('docker', ['--version'], {
    env: process.env,
    stdio: [ 'ignore', 'ignore', 'ignore' ]
  })
  if (dockerVersion.status !== 0) {
    console.error("Could not run the 'docker' command.")
    console.error('This tool requires Docker.')
    console.error('')
    console.error('Please find installation instructions at:')
    console.error('')
    console.error('  https://docs.docker.com/install/')
    console.error('')
    process.exit(dockerVersion.status)
  }

  let dockerImage = 'insighttoolkit/itk-js:20190317-5d260e3'
  if (program.commands[0].image) {
    dockerImage = program.commands[0].image
  }

  // Ensure we have the 'dockcross' Docker build environment driver script
  const dockcrossScript = 'web-build/itk-js-build-env'
  try {
    fs.statSync(dockcrossScript)
  } catch (err) {
    if (err.code === 'ENOENT') {
      const output = fs.openSync(dockcrossScript, 'w')
      const dockerCall = spawnSync('docker', ['run', '--rm', dockerImage], {
        env: process.env,
        stdio: [ 'ignore', output, null ]
      })
      if (dockerCall.status !== 0) {
        process.exit(dockerCall.status)
      }
      fs.closeSync(output)
      fs.chmodSync(dockcrossScript, '755')
    } else {
      throw err
    }
  }

  const hypenIndex = program.rawArgs.findIndex((arg) => arg === '--')
  let cmakeArgs = []
  if (hypenIndex !== -1) {
    cmakeArgs = program.rawArgs.slice(hypenIndex + 1)
  }

  const dockerBuild = spawnSync(dockcrossScript, ['web-build'].concat(cmakeArgs), {
    env: process.env,
    stdio: 'inherit'
  })
  process.exit(dockerBuild.status)
}

const test = (sourceDir) => {
  // Check that the source directory exists and chdir to it.
  if (!fs.existsSync(sourceDir)) {
    console.error('The source directory: ' + sourceDir + ' does not exist!')
    process.exit(1)
  }
  process.chdir(sourceDir)

  const dockcrossScript = path.join('web-build/itk-js-build-env')
  try {
    fs.statSync(dockcrossScript)
  } catch (err) {
    console.error('Could not find ' + sourceDir + '/web-build/itk-js-build-env')
    console.error('')
    console.error('Has')
    console.error('')
    console.error('  itk-js build ' + sourceDir)
    console.error('')
    console.error('been executed?')
    process.exit(1)
  }

  const hypenIndex = program.rawArgs.findIndex((arg) => arg === '--')
  let ctestArgs = ''
  if (hypenIndex !== -1) {
    ctestArgs = program.rawArgs.slice(hypenIndex + 1).join(' ')
  }

  const dockerBuild = spawnSync('bash', [dockcrossScript,
    'bash', '-c',
      'cd web-build && ctest ' + ctestArgs],
    {
      env: process.env,
      stdio: 'inherit'
    })
  process.exit(dockerBuild.status)
}

program
  .command('build <sourceDir>')
  .usage('[options] <sourceDir> [-- <cmake arguments>]')
  .description('build the CMake project found in the given source directory')
  .action(build)
  .option('-i, --image <image>', 'build environment Docker image, defaults to insighttoolkit/itk-js')

// todo: needs a wrapper in web_add_test that 1) mount /work into the emscripten filesystem
// and 2) invokes the runtime
// program
//   .command('test <sourceDir>')
//   .usage('[options] <sourceDir> [-- <ctest arguments>]')
//   .description('run ctest on the project previously built from the given source directory')
//   .action(test)

program
  .parse(process.argv)

program.help()
<|endoftext|>


<commit_before>require("colors");

var path = require("path");
var diff = require("diff");
var run  = require(path.join(__dirname, "run-solution"));

module.exports = function(solution, attempt, cb) {

  run(solution, function(err, solutionResult) {

    if(err) {
      console.error(err);
      return cb(false);
    }

    run(attempt, function(err, attemptResult) {

      if(err) {
        if(err.code !== 8) {
          console.error(err);
        }
        return cb(false);
      }

      if(solutionResult === attemptResult) {
        return cb(true);
      }

      cb(false, {
        solution: solutionResult,
        attempt:  attemptResult,
        diff:     generateDiff(solutionResult, attemptResult)
      });

    });

  });

}

function generateDiff(solution, attempt) {

  var parts = diff.diffChars(solution, attempt);

  var result = "";

  parts.forEach(function(part) {

    if(part.added) {
      result += part.value["bgRed"];
    } else if(part.removed) {
      result += part.value["bgGreen"];
    } else {
      result += part.value;
    }

  });

  return result;

}<commit_msg>Fixing empty output problem<commit_after>require("colors");

var path = require("path");
var diff = require("diff");
var run  = require(path.join(__dirname, "run-solution"));

module.exports = function(solution, attempt, cb) {

  run(solution, function(err, solutionResult) {

    if(err) {
      console.error(err);
      return cb(false);
    }

    run(attempt, function(err, attemptResult) {

      if(err && err.code !== 8) {
        console.error(err);
        return cb(false);
      }

      if(solutionResult === attemptResult) {
        return cb(true);
      }

      cb(false, {
        solution: solutionResult,
        attempt:  err || attemptResult,
        diff:     generateDiff(solutionResult, attemptResult)
      });

    });

  });

}

function generateDiff(solution, attempt) {

  var parts = diff.diffChars(solution, attempt);

  var result = "";

  parts.forEach(function(part) {

    if(part.added) {
      result += part.value["bgRed"];
    } else if(part.removed) {
      result += part.value["bgGreen"];
    } else {
      result += part.value;
    }

  });

  return result;

}
<|endoftext|>


<commit_before>function c_a(a, b) {
    "use strict";
    var c, d, obj;
    obj = {
        "difference": [],
        "same_elements": []
    };
    function trim(a) {
        var i = a.length;
        while (i >= 0) {
            if (a[i] === "_*deleted*_") {
                a.splice(i, 1);
            }
            i -= 1;
        }
        return a;
    }
    function process_it(k, l) {
        var same = [];
        l.forEach(function (v, i) {
            k.forEach(function (vv, ii) {
                if (v === vv) {
                    same.push(vv);
                    l.splice(i, 1, "_*deleted*_");
                    k.splice(ii, 1, "_*deleted*_");
                }
            });
        });
        return {
            "difference": trim(l.concat(k)),
            "same_elements": same
        };
    }
    if (a instanceof Array && b instanceof Array) {
        c = a.slice();
        d = b.slice();
        if (c.length >= d.length) {
            obj = process_it(c, d);
        } else {
            obj = process_it(d, c);
        }
    }
    return obj;
}
<commit_msg>Deleted the quotes<commit_after>function c_a(a, b) {
    "use strict";
    var c, d, obj;
    obj = {
        difference: [],
        same_elements: []
    };
    function trim(a) {
        var i = a.length;
        while (i >= 0) {
            if (a[i] === "_*deleted*_") {
                a.splice(i, 1);
            }
            i -= 1;
        }
        return a;
    }
    function process_it(k, l) {
        var same = [];
        l.forEach(function (v, i) {
            k.forEach(function (vv, ii) {
                if (v === vv) {
                    same.push(vv);
                    l.splice(i, 1, "_*deleted*_");
                    k.splice(ii, 1, "_*deleted*_");
                }
            });
        });
        return {
            difference: trim(l.concat(k)),
            same_elements: same
        };
    }
    if (a instanceof Array && b instanceof Array) {
        c = a.slice();
        d = b.slice();
        if (c.length >= d.length) {
            obj = process_it(c, d);
        } else {
            obj = process_it(d, c);
        }
    }
    return obj;
}
<|endoftext|>