<commit_before>var dragview = function (dragview) {
    var savedX, savedY, moving, offsetWidth;
    var { page, menu } = dragview;
    preventOverflowScrolling(page);
    moveupon(page, {
        start(event) {
            savedX = event.clientX;
            savedY = event.clientY;
            offsetWidth = menu.offsetWidth;
            var { target } = event;
            moving = null;
            if (/(input|textarea)/i.test(target.tagName)) {
                moving = false;
            } else {
                var { childNodes } = target;
                for (var cx = 0, dx = childNodes.length; cx < dx; cx++) {
                    var child = childNodes[cx];
                    if (child.nodeType === 3) {
                        moving = false;
                        break;
                    }
                }
                if (moving !== false) do {
                    var contentEditbale = target.getAttribute("contenteditable") !== null;
                    if (contentEditbale) {
                        moving = false;
                        break;
                    }
                    target = target.parentNode;
                } while (target.nodeType == 1);
            }
        },
        move(event) {
            if (moving === false) return;
            if (event.moveLocked) return;
            if (
                /resize/i.test(getComputedStyle(document.body).cursor)
            ) return;
            var deltaX = savedX - event.clientX;
            var deltaY = savedY - event.clientY;
            if (!moving) {
                if (Math.abs(deltaX) < MOVELOCK_DELTA && Math.abs(deltaY) < MOVELOCK_DELTA) return;
                if (Math.abs(deltaY) >= Math.abs(deltaX)) {
                    moving = -1;
                } else {
                    moving = {
                        restX: freeOffset(page.style.left || 0) - savedX
                    };
                    page.style.transition = 'none';
                }
            }
            if (moving === -1) return;

            event.moveLocked = true;
            moving.deltaX = deltaX;
            var left = event.clientX + moving.restX;
            page.style.left = fromOffset(left);
        },
        end() {
            page.style.transition = '';
            if (moving && moving !== -1) {
                var left = freeOffset(page.style.left || 0);
                if (moving.deltaX < 0 && left > offsetWidth * 0.3 || moving.deltaX > 0 && left > offsetWidth * 0.7 || !moving.deltaX && left > offsetWidth >> 1) {
                    page.style.left = 0;
                    dragview.toRight();
                } else {
                    dragview.toLeft();
                    page.style.left = 0;
                }
            }
        }
    });
}

/**
 * 左侧为菜单
 * 菜单在小屏上收起，可以点击按钮打开
 */
function main(mainPath, historyName = "") {
    var layer = div();
    layer.innerHTML = glance;
    if (mainPath instanceof Object) {
        var { left: leftPath, top: topPath, main: mainPath } = mainPath;
    }
    var [leftLayer, topLayer] = layer.children;
    on("append")(layer, function () {
        var index = 2;
        zimoli.switch(historyName, layer, mainPath);
        var hook = function () {
            if (--index !== 0) return;
            if (leftPath) {
                var page = zimoli.create(leftPath);
                page.setAttribute('layer', 'left');
                appendChild.replace(leftLayer, page);
                leftLayer = page;
                dragview({ page: layer, toLeft: layer.closeLeft, toRight: layer.openLeft, menu: leftLayer });
            }
            if (topPath) {
                var page = zimoli.create(topPath);
                page.setAttribute('layer', 'top');
                appendChild.replace(topLayer, page);
                topLayer = page;
            }
            zimoli();
        };
        if (leftPath) {
            zimoli.prepare(leftPath, hook);
        } else hook();
        if (topPath) {
            zimoli.prepare(topPath, hook);
        } else hook();
    });
    var closed = false;
    var isClosed = function () {
        var computed = getScreenPosition(leftLayer);
        var delta = computed.left + computed.width;
        return delta <= 0;
    };
    var bindClass = function () {
        if (closed) {
            var collapse = layer.clientLeft === 0;
            addClass(layer, 'close');
            removeClass(layer, 'open');
            css(layer, `margin-left:0`);
            if (collapse) {
                removeClass(layer, 'close open');
            }
        } else {
            addClass(layer, 'open');
            removeClass(layer, 'close');
            css(layer, `margin-left:${fromOffset(leftLayer.offsetWidth)}`);
            setTimeout(function () {
                var collapse = layer.clientLeft === 0;
                if (!collapse) {
                    css(layer, 'margin-left:0');
                }
            }, 20);
        }
    };
    on("transitionend")(layer, function (event) {
        if (event.target !== this) return;
        dispatch(window, 'render');
    });
    layer.closeLeft = function () {
        closed = true;
        bindClass();
    };
    layer.openLeft = function () {
        closed = false;
        bindClass();
    };
    layer.switchLeft = function () {
        closed = !isClosed();
        bindClass();
    };
    return layer;
}<commit_msg>左侧和顶部支持传入组件构造函数<commit_after>var dragview = function (dragview) {
    var savedX, savedY, moving, offsetWidth;
    var { page, menu } = dragview;
    preventOverflowScrolling(page);
    moveupon(page, {
        start(event) {
            savedX = event.clientX;
            savedY = event.clientY;
            offsetWidth = menu.offsetWidth;
            var { target } = event;
            moving = null;
            if (/(input|textarea)/i.test(target.tagName)) {
                moving = false;
            } else {
                var { childNodes } = target;
                for (var cx = 0, dx = childNodes.length; cx < dx; cx++) {
                    var child = childNodes[cx];
                    if (child.nodeType === 3) {
                        moving = false;
                        break;
                    }
                }
                if (moving !== false) do {
                    var contentEditbale = target.getAttribute("contenteditable") !== null;
                    if (contentEditbale) {
                        moving = false;
                        break;
                    }
                    target = target.parentNode;
                } while (target.nodeType == 1);
            }
        },
        move(event) {
            if (moving === false) return;
            if (event.moveLocked) return;
            if (
                /resize/i.test(getComputedStyle(document.body).cursor)
            ) return;
            var deltaX = savedX - event.clientX;
            var deltaY = savedY - event.clientY;
            if (!moving) {
                if (Math.abs(deltaX) < MOVELOCK_DELTA && Math.abs(deltaY) < MOVELOCK_DELTA) return;
                if (Math.abs(deltaY) >= Math.abs(deltaX)) {
                    moving = -1;
                } else {
                    moving = {
                        restX: freeOffset(page.style.left || 0) - savedX
                    };
                    page.style.transition = 'none';
                }
            }
            if (moving === -1) return;

            event.moveLocked = true;
            moving.deltaX = deltaX;
            var left = event.clientX + moving.restX;
            page.style.left = fromOffset(left);
        },
        end() {
            page.style.transition = '';
            if (moving && moving !== -1) {
                var left = freeOffset(page.style.left || 0);
                if (moving.deltaX < 0 && left > offsetWidth * 0.3 || moving.deltaX > 0 && left > offsetWidth * 0.7 || !moving.deltaX && left > offsetWidth >> 1) {
                    page.style.left = 0;
                    dragview.toRight();
                } else {
                    dragview.toLeft();
                    page.style.left = 0;
                }
            }
        }
    });
}

/**
 * 左侧为菜单
 * 菜单在小屏上收起，可以点击按钮打开
 */
function main(mainPath, historyName = "") {
    var layer = div();
    layer.innerHTML = glance;
    if (mainPath instanceof Object) {
        var { left: leftPath, top: topPath, main: mainPath } = mainPath;
    }
    var [leftLayer, topLayer] = layer.children;
    on("append")(layer, function () {
        var index = 2;
        zimoli.switch(historyName, layer, mainPath);
        var hook = function () {
            if (--index !== 0) return;
            if (leftPath) {
                var page = zimoli.create(leftPath);
                page.setAttribute('layer', 'left');
                appendChild.replace(leftLayer, page);
                leftLayer = page;
                dragview({ page: layer, toLeft: layer.closeLeft, toRight: layer.openLeft, menu: leftLayer });
            }
            if (topPath) {
                var page = zimoli.create(topPath);
                page.setAttribute('layer', 'top');
                appendChild.replace(topLayer, page);
                topLayer = page;
            }
            zimoli();
        };
        if (typeof leftPath === 'string') {
            zimoli.prepare(leftPath, hook);
        } else hook();
        if (typeof topPath === 'string') {
            zimoli.prepare(topPath, hook);
        } else hook();
    });
    var closed = false;
    var isClosed = function () {
        var computed = getScreenPosition(leftLayer);
        var delta = computed.left + computed.width;
        return delta <= 0;
    };
    var bindClass = function () {
        if (closed) {
            var collapse = layer.clientLeft === 0;
            addClass(layer, 'close');
            removeClass(layer, 'open');
            css(layer, `margin-left:0`);
            if (collapse) {
                removeClass(layer, 'close open');
            }
        } else {
            addClass(layer, 'open');
            removeClass(layer, 'close');
            css(layer, `margin-left:${fromOffset(leftLayer.offsetWidth)}`);
            setTimeout(function () {
                var collapse = layer.clientLeft === 0;
                if (!collapse) {
                    css(layer, 'margin-left:0');
                }
            }, 20);
        }
    };
    on("transitionend")(layer, function (event) {
        if (event.target !== this) return;
        dispatch(window, 'render');
    });
    layer.closeLeft = function () {
        closed = true;
        bindClass();
    };
    layer.openLeft = function () {
        closed = false;
        bindClass();
    };
    layer.switchLeft = function () {
        closed = !isClosed();
        bindClass();
    };
    return layer;
}<|endoftext|>


<commit_before>QUnit.module('views');

QUnit.test('ok.View()', function (assert) {
	var view = new ok.View();
	assert.ok(view instanceof ok.View, 'Can create views');
	assert.deepEqual(view.classNames, ['ok-view'], 'Views have "ok-view" class by default');
	assert.deepEqual(ok.toArray(view.el.classList), ['ok-view'], 'Classes are applied to view element');
	assert.equal(view.tagName, 'div', 'Views are divs by default');
	assert.equal(view.el.tagName.toLowerCase(), 'div', 'Views elements are divs by default');
	var custom = new ok.View({
		tagName: 'p',
		classNames: 'custom-paragraph'
	});
	assert.equal(custom.tagName, 'p', 'Tag name property is set on init');
	assert.equal(custom.el.tagName.toLowerCase(), 'p', 'Can make views a tag other than div');
	assert.deepEqual(custom.classNames, ['ok-view', 'custom-paragraph'], 'Classes can be set on views');
	assert.deepEqual(ok.toArray(custom.el.classList), ['ok-view', 'custom-paragraph'], 'Classes can be set on view elements');
});<commit_msg>Test view `isStarted` property<commit_after>QUnit.module('views');

QUnit.test('ok.View()', function (assert) {
	var view = new ok.View();
	assert.ok(view instanceof ok.View, 'Can create views');
	assert.deepEqual(view.classNames, ['ok-view'], 'Views have "ok-view" class by default');
	assert.deepEqual(ok.toArray(view.el.classList), ['ok-view'], 'Classes are applied to view element');
	assert.equal(view.tagName, 'div', 'Views are divs by default');
	assert.equal(view.el.tagName.toLowerCase(), 'div', 'Views elements are divs by default');
	var custom = new ok.View({
		tagName: 'p',
		classNames: 'custom-paragraph'
	});
	assert.equal(custom.tagName, 'p', 'Tag name property is set on init');
	assert.equal(custom.el.tagName.toLowerCase(), 'p', 'Can make views a tag other than div');
	assert.deepEqual(custom.classNames, ['ok-view', 'custom-paragraph'], 'Classes can be set on views');
	assert.deepEqual(ok.toArray(custom.el.classList), ['ok-view', 'custom-paragraph'], 'Classes can be set on view elements');
});

QUnit.test('ok.View#isStarted', function (assert) {
	var view = new ok.View();
	assert.equal(view.isStarted, false, 'Views are not started by default');
	view.start();
	assert.equal(view.isStarted, true, 'View can be started');
	view.stop();
	assert.equal(view.isStarted, false, 'View can be stopped');
});
<|endoftext|>


<commit_before>"use strict";

if(!Object.keys)
{
	Object.keys = (function()
	{
		var hop = Object.prototype.hasOwnProperty,
			hasDontEnumBug = !({toString: null}).propertyIsEnumerable("toString"),
			dontEnums = [ "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "constructor" ],
			dontEnumsLength = dontEnums.length;

		return function (obj)
		{
			if(typeof obj!=="object" && typeof obj!=="function" || obj === null)
				throw new TypeError("Object.keys called on non-object");

			var result = [];

			for(var prop in obj)
			{
				if(hop.call(obj, prop))
					result.push(prop);
			}

			if(hasDontEnumBug)
			{
				for(var i=0;i<dontEnumsLength;i++)
				{
					if(hop.call(obj, dontEnums[i]))
						result.push(dontEnums[i]);
				}
			}

			return result;
		};
	})();
}

if(!Object.values)
{
	Object.values = function(obj)
	{
		var result = [];

		Object.keys(obj).forEach(function(key)
		{
			result.push(obj[key]);
		});

		return result;
	};
}

if(!Object.forEach)
{
	Object.forEach = function(obj, cb)
	{
		if(!cb)
			return;

		Object.keys(obj).forEach(function(key, i)
		{
			cb(key, obj[key], i);
		});
	};
}

if(!Object.every)
{
	Object.every = function(obj, cb)
	{
		if(!cb)
			return true;

		var matches = true;
		Object.keys(obj).forEach(function(key, i)
		{
			matches = cb(key, obj[key], i);
		});

		return matches;
	};
}

if(!Object.mutate)
{
	Object.mutate = function(obj, cb, startResult)
	{
		if(!cb)
			return;

		var result = ((typeof startResult!=="undefined") ? startResult : undefined);

		Object.keys(obj).forEach(function(key)
		{
			result = cb(key, obj[key], result);
		});

		return result;
	};
}

if(!Object.merge)
{
	Object.merge = function(o1, o2, dupHandler, onlyKeys)
	{
		var hop = Object.prototype.hasOwnProperty;

		Object.forEach(o2, function(key)
		{
			if(onlyKeys && onlyKeys.indexOf(key)===-1)
				return;

			if(!hop.call(o1, key) || !dupHandler)
				o1[key] = o2[key];
			else
				o1[key] = dupHandler(o1[key], o2[key]);
		});

		return o1;
	};
}

if(!Object.map)
{
	Object.map = function(obj, cb)
	{
		if(!cb)
			return obj;

		var result = {};

		Object.forEach(obj, function(key, value)
		{
			var r = cb(key, value);
			result[r[0]] = r[1];
		});

		return result;
	};
}

if(!Object.isObject)
{
	Object.isObject = function (arg)
	{
		return arg!==null && !Array.isArray(arg) && typeof arg==="object";
	};
}
<commit_msg>Some minor changes<commit_after>"use strict";

if(!Object.keys)
{
	Object.keys = (function()
	{
		var hop = Object.prototype.hasOwnProperty,
			hasDontEnumBug = !({toString: null}).propertyIsEnumerable("toString"),
			dontEnums = [ "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "constructor" ],
			dontEnumsLength = dontEnums.length;

		return function (obj)
		{
			if(typeof obj!=="object" && typeof obj!=="function" || obj === null)
				throw new TypeError("Object.keys called on non-object");

			var result = [];

			for(var prop in obj)
			{
				if(hop.call(obj, prop))
					result.push(prop);
			}

			if(hasDontEnumBug)
			{
				for(var i=0;i<dontEnumsLength;i++)
				{
					if(hop.call(obj, dontEnums[i]))
						result.push(dontEnums[i]);
				}
			}

			return result;
		};
	})();
}

if(!Object.values)
{
	Object.values = function(obj)
	{
		var result = [];

		Object.keys(obj).forEach(function(key)
		{
			result.push(obj[key]);
		});

		return result;
	};
}

if(!Object.forEach)
{
	Object.forEach = function(obj, cb)
	{
		if(!cb)
			return;

		Object.keys(obj).forEach(function(key, i)
		{
			cb(key, obj[key], i);
		});
	};
}

if(!Object.every)
{
	Object.every = function(obj, cb)
	{
		if(!cb)
			return true;

		var matches = true;
		Object.keys(obj).forEach(function(key, i)
		{
			matches = cb(key, obj[key], i);
		});

		return matches;
	};
}

if(!Object.mutate)
{
	Object.mutate = function(obj, cb, startResult)
	{
		if(!cb)
			return;

		var result = ((typeof startResult!=="undefined") ? startResult : undefined);

		Object.keys(obj).forEach(function(key)
		{
			result = cb(key, obj[key], result);
		});

		return result;
	};
}

if(!Object.merge)
{
	Object.merge = function(o1, o2, dupHandler, onlyKeys)
	{
		var hop = Object.prototype.hasOwnProperty;

		Object.forEach(o2, function(key)
		{
			if(onlyKeys && onlyKeys.indexOf(key)===-1)
				return;

			if(!hop.call(o1, key) || !dupHandler)
				o1[key] = o2[key];
			else
				o1[key] = dupHandler(o1[key], o2[key], key);
		});

		return o1;
	};
}

if(!Object.map)
{
	Object.map = function(obj, cb)
	{
		if(!cb)
			return obj;

		var result = {};

		Object.forEach(obj, function(key, value)
		{
			var r = cb(key, value);
			if(!Array.isArray(r))
				result[key] = r;
			else if(r.length===1)
				result[key] = r[0];
			else
				result[r[0]] = r[1];
		});

		return result;
	};
}

if(!Object.isObject)
{
	Object.isObject = function (arg)
	{
		return arg!==null && !Array.isArray(arg) && typeof arg==="object";
	};
}
<|endoftext|>


<commit_before>/**
 * Function that returns default values.
 * Used because Object.assign does a shallow instead of a deep copy.
 * Using [].push will add to the base array, so a require will alter
 * the base array output.
 */
'use strict';

const path = require('path');
const srcPath = path.join(__dirname, '/../src');
const dfltPort = 8000;

/**
 * Get the default modules object for webpack
 * @return {Object}
 */
function getDefaultModules() {
  return {
    preLoaders: [
      {
        test: /\.(js|jsx)$/,
        include: srcPath,
        loader: 'eslint-loader'
      }
    ],
    loaders: [
      {
        test: /\.css$/,
        loader: 'style-loader!css-loader'
      },
      {
        test: /\.sass/,
        loader: 'style-loader!css-loader!sass-loader?outputStyle=expanded&indentedSyntax'
      },
      {
        test: /\.scss/,
        loader: 'style-loader!css-loader!sass-loader?outputStyle=expanded'

      },
      {
        test: /\.less/,
        loader: 'style-loader!css-loader!less-loader'
      },
      {
        test: /\.styl/,
        loader: 'style-loader!css-loader!stylus-loader'
      },
      {
        test: /\.(png|jpg|gif|woff|woff2|eot|ttf|svg)$/,
        loader: 'url-loader?limit=8192'
      },
      {
        test: /\.json$/,
        loader: 'json-loader'
      },
      {
        test: /\.(mp4|ogg|svg)$/,
        loader: 'file-loader'
      }
    ]
  };
}

module.exports = {
  srcPath: srcPath,
  publicPath: 'assets/',
  port: dfltPort,
  getDefaultModules: getDefaultModules
};
<commit_msg>修复BUG<commit_after>/**
 * Function that returns default values.
 * Used because Object.assign does a shallow instead of a deep copy.
 * Using [].push will add to the base array, so a require will alter
 * the base array output.
 */
'use strict';

const path = require('path');
const srcPath = path.join(__dirname, '/../src');
const dfltPort = 8000;

/**
 * Get the default modules object for webpack
 * @return {Object}
 */
function getDefaultModules() {
  return {
    preLoaders: [
      {
        test: /\.(js|jsx)$/,
        include: srcPath,
        loader: 'eslint-loader'
      }
    ],
    loaders: [
      {
        test: /\.css$/,
        loader: 'style-loader!css-loader'
      },
      {
        test: /\.sass/,
        loader: 'style-loader!css-loader!sass-loader?outputStyle=expanded&indentedSyntax'
      },
      {
        test: /\.scss/,
        loader: 'style-loader!css-loader!sass-loader?outputStyle=expanded'

      },
      {
        test: /\.less/,
        loader: 'style-loader!css-loader!less-loader'
      },
      {
        test: /\.styl/,
        loader: 'style-loader!css-loader!stylus-loader'
      },
      {
        test: /\.(png|jpg|gif|woff|woff2|eot|ttf|svg)$/,
        loader: 'url-loader?limit=8192'
      },
      {
        test: /\.json$/,
        loader: 'json-loader'
      },
      {
        test: /\.(mp4|ogg|svg)$/,
        loader: 'file-loader'
      }
    ]
  };
}

module.exports = {
  srcPath: srcPath,
  publicPath: '/assets/',
  port: dfltPort,
  getDefaultModules: getDefaultModules
};
<|endoftext|>


<commit_before>/**
 *  Copyright 2015 Jaime Pajuelo
 *
 *  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.
 */

"use strict";

/**
 * @namespace
 */
var forms = {};

forms.BaseField = (function () {

    /**
     * @constructor
     * @param {Object.<String, *>} [options]
     */
    var BaseField = function BaseField(options) {
        var defaultOptions = {
            'maxLength': 1024,
            'minLength': 0,
            'pattern': null,
            'required': true
        };

        var defaultProps = {
            'label': null
        };

        defaultOptions = utils.updateObject(defaultOptions, options);
        defaultProps = utils.updateObject(defaultProps, options);

        this.label = defaultProps.label;
        this.initialValue = null;

        this.name = null;
        this.element = _createControl.call(this);
        this.validators = buildValidators(defaultOptions);

        this.helpText = null;
        this.errorMessage = document.createElement('p');
        this.errorMessage.className = "control-error";
    };

    /**
     * @abstract
     * @returns {HTMLElement}
     */
    BaseField.member('createControl', function createControl() {
        return null;
    });

    /**
     * @returns {BaseField} The instance on which this method was called.
     */
    BaseField.member('clean', function clean() {
        this.errorMessage.textContent = "";

        return this;
    });

    /**
     * @throws {TypeError}
     * @returns {String} The element value cleaned.
     */
    BaseField.member('getValue', function getValue() {

        if (!(this.element instanceof HTMLElement)) {
            throw new TypeError("The element is not instance of HTMLElement.");
        }

        return this.element.value.trim();
    });

    /**
     * @returns {Boolean} If the element value an error.
     */
    BaseField.member('hasError', function hasError() {
        var cleanedValue, found, i;

        cleanedValue = this.clean().getValue();

        for (found = false, i = 0; !found && i < this.validators.length; i++) {
            try {
                this.validators[i].validate(cleanedValue);
            } catch (e) {
                if (e instanceof validators.ValidationError) {
                    this.errorMessage.textContent = e.message;
                    found = true;
                }
            }
        }

        return found;
    });

    /**
     * @returns {BaseField} The instance on which this method was called.
     */
    BaseField.member('setName', function setName(fieldName) {

        if (!(this.element instanceof HTMLElement)) {
            throw new TypeError("The element is not instance of HTMLElement.");
        }

        this.name = fieldName;
        this.element.setAttribute('name', fieldName);

        return this;
    });

    var _createControl = function _createControl() {
        var newControl = this.createControl();

        if (!(newControl instanceof HTMLElement)) {
            throw new TypeError("The element is not instance of HTMLElement.");
        }

        newControl.addEventListener('input', function (event) {
            this.hasError();
        }.bind(this));

        return newControl;
    };

    var buildValidators = function buildValidators(options) {
        var validatorList = [];

        if (options.required) {
            validatorList.push(new validators.RequiredValidator());
        }

        if (options.minLength > 0) {
            validatorList.push(new validators.MinLengthValidator(options.minLength));
        }

        if (options.maxLength > options.minLength) {
            validatorList.push(new validators.MaxLengthValidator(options.maxLength));
        }

        if (options.pattern != null) {
            validatorList.push(new validators.RegexValidator(options.pattern));
        }

        return validatorList;
    };

    return BaseField;

})();

forms.TextField = (function () {

    /**
     * @constructor
     * @extends {BaseField}
     * @param {Object.<String, *>} [options]
     */
    var TextField = function TextField(options) {
        var defaultOptions = {
            'placeholder': null,
            'type': "text"
        };

        defaultOptions = utils.updateObject(defaultOptions, options);

        this.type = defaultOptions.type;
        this.placeholder = defaultOptions.placeholder;
        this.callParent(options);
    };

    TextField.inherit(forms.BaseField);

    /**
     * @override
     * @returns {HTMLElement}
     */
    TextField.member('createControl', function createControl() {
        var element;

        element = document.createElement('input');
        element.className = "form-control";
        element.type = this.type;

        if (this.placeholder != null) {
            element.placeholder = this.placeholder;
        }

        return element;
    });

    return TextField;

})();

forms.PasswordField = (function () {

    /**
     * @constructor
     * @extends {TextField}
     * @param {Object.<String, *>} [options]
     */
    var PasswordField = function PasswordField(options) {
        options = utils.updateObject(options);
        options.type = "password";

        this.callParent(options);
    };

    PasswordField.inherit(forms.TextField);

    return PasswordField;

})();

forms.LongTextField = (function () {

    /**
     * @constructor
     * @extends {BaseField}
     * @param {Object.<String, *>} [options]
     */
    var LongTextField = function LongTextField(options) {
        this.callParent(options);
    };

    LongTextField.inherit(forms.BaseField);

    /**
     * @override
     * @returns {HTMLElement}
     */
    LongTextField.member('createControl', function createControl() {
        var element;

        element = document.createElement('textarea');
        element.className = "form-control";

        return element;
    });

    return LongTextField;

})();
<commit_msg>Add a first method to build a HTML field<commit_after>/**
 *  Copyright 2015 Jaime Pajuelo
 *
 *  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.
 */

"use strict";

/**
 * @namespace
 */
var forms = {};

forms.BaseField = (function () {

    /**
     * @constructor
     * @param {Object.<String, *>} [options]
     */
    var BaseField = function BaseField(options) {
        var defaultOptions = {
            'maxLength': 1024,
            'minLength': 0,
            'pattern': null,
            'required': true
        };

        var defaultProps = {
            'label': null
        };

        defaultOptions = utils.updateObject(defaultOptions, options);
        defaultProps = utils.updateObject(defaultProps, options);

        this.label = defaultProps.label;
        this.initialValue = null;

        this.name = null;
        this.element = _createControl.call(this);
        this.validators = buildValidators(defaultOptions);

        this.helpText = null;
        this.errorMessage = document.createElement('p');
        this.errorMessage.className = "control-error";
    };

    /**
     * @abstract
     * @returns {HTMLElement}
     */
    BaseField.member('createControl', function createControl() {
        return null;
    });

    /**
     * @returns {HTMLElement}
     */
    BaseField.member('build', function build() {
        var fieldGroup, labelControl;

        fieldGroup = document.createElement('div');
        fieldGroup.className = "form-group";

        if (this.label) {
            labelControl = document.createElement('label');
            labelControl.className = "control-label";
            labelControl.textContent = this.label;

            fieldGroup.appendChild(labelControl);
        }

        fieldGroup.appendChild(this.element);
        fieldGroup.appendChild(this.errorMessage);

        return fieldGroup;
    });

    /**
     * @returns {BaseField} The instance on which this method was called.
     */
    BaseField.member('clean', function clean() {
        this.errorMessage.textContent = "";

        return this;
    });

    /**
     * @throws {TypeError}
     * @returns {String} The element value cleaned.
     */
    BaseField.member('getValue', function getValue() {

        if (!(this.element instanceof HTMLElement)) {
            throw new TypeError("The element is not instance of HTMLElement.");
        }

        return this.element.value.trim();
    });

    /**
     * @returns {Boolean} If the element value an error.
     */
    BaseField.member('hasError', function hasError() {
        var cleanedValue, found, i;

        cleanedValue = this.clean().getValue();

        for (found = false, i = 0; !found && i < this.validators.length; i++) {
            try {
                this.validators[i].validate(cleanedValue);
            } catch (e) {
                if (e instanceof validators.ValidationError) {
                    this.errorMessage.textContent = e.message;
                    found = true;
                }
            }
        }

        return found;
    });

    /**
     * @returns {BaseField} The instance on which this method was called.
     */
    BaseField.member('setName', function setName(fieldName) {

        if (!(this.element instanceof HTMLElement)) {
            throw new TypeError("The element is not instance of HTMLElement.");
        }

        this.name = fieldName;
        this.element.setAttribute('name', fieldName);

        return this;
    });

    var _createControl = function _createControl() {
        var newControl = this.createControl();

        if (!(newControl instanceof HTMLElement)) {
            throw new TypeError("The element is not instance of HTMLElement.");
        }

        newControl.addEventListener('input', function (event) {
            this.hasError();
        }.bind(this));

        return newControl;
    };

    var buildValidators = function buildValidators(options) {
        var validatorList = [];

        if (options.required) {
            validatorList.push(new validators.RequiredValidator());
        }

        if (options.minLength > 0) {
            validatorList.push(new validators.MinLengthValidator(options.minLength));
        }

        if (options.maxLength > options.minLength) {
            validatorList.push(new validators.MaxLengthValidator(options.maxLength));
        }

        if (options.pattern != null) {
            validatorList.push(new validators.RegexValidator(options.pattern));
        }

        return validatorList;
    };

    return BaseField;

})();

forms.TextField = (function () {

    /**
     * @constructor
     * @extends {BaseField}
     * @param {Object.<String, *>} [options]
     */
    var TextField = function TextField(options) {
        var defaultOptions = {
            'placeholder': null,
            'type': "text"
        };

        defaultOptions = utils.updateObject(defaultOptions, options);

        this.type = defaultOptions.type;
        this.placeholder = defaultOptions.placeholder;
        this.callParent(options);
    };

    TextField.inherit(forms.BaseField);

    /**
     * @override
     * @returns {HTMLElement}
     */
    TextField.member('createControl', function createControl() {
        var element;

        element = document.createElement('input');
        element.className = "form-control";
        element.type = this.type;

        if (this.placeholder != null) {
            element.placeholder = this.placeholder;
        }

        return element;
    });

    return TextField;

})();

forms.PasswordField = (function () {

    /**
     * @constructor
     * @extends {TextField}
     * @param {Object.<String, *>} [options]
     */
    var PasswordField = function PasswordField(options) {
        options = utils.updateObject(options);
        options.type = "password";

        this.callParent(options);
    };

    PasswordField.inherit(forms.TextField);

    return PasswordField;

})();

forms.LongTextField = (function () {

    /**
     * @constructor
     * @extends {BaseField}
     * @param {Object.<String, *>} [options]
     */
    var LongTextField = function LongTextField(options) {
        this.callParent(options);
    };

    LongTextField.inherit(forms.BaseField);

    /**
     * @override
     * @returns {HTMLElement}
     */
    LongTextField.member('createControl', function createControl() {
        var element;

        element = document.createElement('textarea');
        element.className = "form-control";

        return element;
    });

    return LongTextField;

})();
<|endoftext|>


<commit_before>var assert = require('assert')
var scripts = require('../src/scripts')

var Address = require('../src/address')
var ECKey = require('../src/eckey')
var Transaction = require('../src/transaction')
var Script = require('../src/script')

var fixtures = require('./fixtures/transaction')

describe('Transaction', function() {
  function fromRaw(raw) {
    var tx = new Transaction()
    tx.version = raw.version
    tx.locktime = raw.locktime

    raw.ins.forEach(function(txIn) {
      var txHash = new Buffer(txIn.hash, 'hex')
      var script = txIn.script ? Script.fromASM(txIn.script) : undefined

      tx.addInput(txHash, txIn.index, txIn.sequence, script)
    })

    raw.outs.forEach(function(txOut) {
      tx.addOutput(Script.fromASM(txOut.script), txOut.value)
    })

    return tx
  }

  describe('fromBuffer/fromHex', function() {
    fixtures.valid.forEach(function(f) {
      it('imports ' + f.id + ' correctly', function() {
        var actual = Transaction.fromHex(f.hex)

        assert.deepEqual(actual.toHex(), f.hex)
      })
    })

    fixtures.invalid.fromBuffer.forEach(function(f) {
      it('throws on ' + f.exception, function() {
        assert.throws(function() {
          Transaction.fromHex(f.hex)
        }, new RegExp(f.exception))
      })
    })
  })

  describe('toBuffer/toHex', function() {
    fixtures.valid.forEach(function(f) {
      it('exports ' + f.id + ' correctly', function() {
        var actual = fromRaw(f.raw)

        assert.deepEqual(actual.toHex(), f.hex)
      })
    })
  })

  describe('addInput', function() {
    // FIXME: not as pretty as could be
    // Probably a bit representative of the API
    var prevTxHash, prevTxId, prevTx
    beforeEach(function() {
      var f = fixtures.valid[0]
      prevTx = Transaction.fromHex(f.hex)
      prevTxHash = prevTx.getHash()
      prevTxId = prevTx.getId()
    })

    it('accepts a transaction id', function() {
      var tx = new Transaction()
      tx.addInput(prevTxId, 0)

      assert.deepEqual(tx.ins[0].hash, prevTxHash)
    })

    it('accepts a transaction hash', function() {
      var tx = new Transaction()
      tx.addInput(prevTxHash, 0)

      assert.deepEqual(tx.ins[0].hash, prevTxHash)
    })

    it('accepts a Transaction object', function() {
      var tx = new Transaction()
      tx.addInput(prevTx, 0)

      assert.deepEqual(tx.ins[0].hash, prevTxHash)
    })

    it('returns an index', function() {
      var tx = new Transaction()
      assert.equal(tx.addInput(prevTxHash, 0), 0)
      assert.equal(tx.addInput(prevTxHash, 0), 1)
    })

    it('defaults to DEFAULT_SEQUENCE', function() {
      var tx = new Transaction()
      tx.addInput(prevTxHash, 0)

      assert.equal(tx.ins[0].sequence, Transaction.DEFAULT_SEQUENCE)
    })

    it('defaults to empty script', function() {
      var tx = new Transaction()
      tx.addInput(prevTxHash, 0)

      assert.equal(tx.ins[0].script, Script.EMPTY)
    })

    fixtures.valid.forEach(function(f) {
      it('should add the inputs for ' + f.id + ' correctly', function() {
        var tx = new Transaction()

        f.raw.ins.forEach(function(txIn, i) {
          var txHash = new Buffer(txIn.hash, 'hex')
          var script = txIn.script ? Script.fromASM(txIn.script) : undefined
          var j = tx.addInput(txHash, txIn.index, txIn.sequence, script)
          var sequence = txIn.sequence
          if (sequence === undefined || sequence === null ) {
            sequence = Transaction.DEFAULT_SEQUENCE
          }

          assert.equal(i, j)
          assert.equal(tx.ins[i].hash.toString('hex'), txIn.hash)
          assert.equal(tx.ins[i].index, txIn.index)
          assert.equal(tx.ins[i].sequence, sequence)
          assert.deepEqual(tx.ins[i].script, script || Script.EMPTY)
        })
      })
    })

    fixtures.invalid.addInput.forEach(function(f) {
      it('throws on ' + f.exception, function() {
        var tx = new Transaction()
        var hash = new Buffer(f.hash, 'hex')

        assert.throws(function() {
          tx.addInput(hash, f.index)
        }, new RegExp(f.exception))
      })
    })
  })

  describe('addOutput', function() {
    // FIXME: not as pretty as could be
    // Probably a bit representative of the API
    var destAddressB58, destAddress, destScript
    beforeEach(function() {
      destAddressB58 = '15mMHKL96tWAUtqF3tbVf99Z8arcmnJrr3'
      destAddress = Address.fromBase58Check(destAddressB58)
      destScript = destAddress.toOutputScript()
    })

    it('accepts an address string', function() {
      var tx = new Transaction()
      tx.addOutput(destAddressB58, 40000)

      assert.deepEqual(tx.outs[0].script, destScript)
      assert.equal(tx.outs[0].value, 40000)
    })

    it('accepts an Address', function() {
      var tx = new Transaction()
      tx.addOutput(destAddress, 40000)

      assert.deepEqual(tx.outs[0].script, destScript)
      assert.equal(tx.outs[0].value, 40000)
    })

    it('accepts a scriptPubKey', function() {
      var tx = new Transaction()
      tx.addOutput(destScript, 40000)

      assert.deepEqual(tx.outs[0].script, destScript)
      assert.equal(tx.outs[0].value, 40000)
    })

    it('returns an index', function() {
      var tx = new Transaction()
      assert.equal(tx.addOutput(destScript, 40000), 0)
      assert.equal(tx.addOutput(destScript, 40000), 1)
    })

    fixtures.valid.forEach(function(f) {
      it('should add the outputs for ' + f.id + ' correctly', function() {
        var tx = new Transaction()

        f.raw.outs.forEach(function(txOut, i) {
          var scriptPubKey = Script.fromASM(txOut.script)
          var j = tx.addOutput(scriptPubKey, txOut.value)

          assert.equal(i, j)
          assert.equal(tx.outs[i].script, scriptPubKey)
          assert.equal(tx.outs[i].value, txOut.value)
        })
      })
    })
  })

  describe('clone', function() {
    fixtures.valid.forEach(function(f) {
      var actual, expected

      beforeEach(function() {
        expected = Transaction.fromHex(f.hex)
        actual = expected.clone()
      })

      it('should have value equality', function() {
        assert.deepEqual(actual, expected)
      })

      it('should not have reference equality', function() {
        assert.notEqual(actual, expected)
      })
    })
  })

  describe('getId', function() {
    fixtures.valid.forEach(function(f) {
      it('should return the id for ' + f.id, function() {
        var tx = Transaction.fromHex(f.hex)
        var actual = tx.getId()

        assert.equal(actual, f.id)
      })
    })
  })

  describe('getHash', function() {
    fixtures.valid.forEach(function(f) {
      it('should return the hash for ' + f.id, function() {
        var tx = Transaction.fromHex(f.hex)
        var actual = tx.getHash().toString('hex')

        assert.equal(actual, f.hash)
      })
    })
  })

  // TODO:
  //  hashForSignature: [Function],

  // FIXME: remove in 2.x.y
  describe('signInput/validateInput', function() {
    it('works for multi-sig redeem script', function() {
      var tx = new Transaction()
      tx.addInput('d6f72aab8ff86ff6289842a0424319bf2ddba85dc7c52757912297f948286389', 0)
      tx.addOutput('mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r', 1)

      var privKeys = [
        '5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf',
        '5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAvUcVfH'
      ].map(function(wif) {
        return ECKey.fromWIF(wif)
      })
      var pubKeys = privKeys.map(function(eck) { return eck.pub })
      var redeemScript = scripts.multisigOutput(2, pubKeys)

      var signatures = privKeys.map(function(privKey) {
        return tx.signInput(0, redeemScript, privKey)
      })

      var redeemScriptSig = scripts.multisigInput(signatures)
      var scriptSig = scripts.scriptHashInput(redeemScriptSig, redeemScript)
      tx.setInputScript(0, scriptSig)

      signatures.forEach(function(sig, i){
        assert(tx.validateInput(0, redeemScript, privKeys[i].pub, sig))
      })

      var expected = '010000000189632848f99722915727c5c75da8db2dbf194342a0429828f66ff88fab2af7d600000000fd1b0100483045022100e5be20d440b2bbbc886161f9095fa6d0bca749a4e41d30064f30eb97adc7a1f5022061af132890d8e4e90fedff5e9365aeeb77021afd8ef1d5c114d575512e9a130a0147304402205054e38e9d7b5c10481b6b4991fde5704cd94d49e344406e3c2ce4d18a43bf8e022051d7ba8479865b53a48bee0cce86e89a25633af5b2918aa276859489e232f51c014c8752410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52aeffffffff0101000000000000001976a914751e76e8199196d454941c45d1b3a323f1433bd688ac00000000'
      assert.equal(tx.toHex(), expected)
    })
  })
})
<commit_msg>tests: transaction.add* better tested by raw functions<commit_after>var assert = require('assert')
var scripts = require('../src/scripts')

var Address = require('../src/address')
var ECKey = require('../src/eckey')
var Transaction = require('../src/transaction')
var Script = require('../src/script')

var fixtures = require('./fixtures/transaction')

describe('Transaction', function() {
  function fromRaw(raw) {
    var tx = new Transaction()
    tx.version = raw.version
    tx.locktime = raw.locktime

    raw.ins.forEach(function(txIn) {
      var txHash = new Buffer(txIn.hash, 'hex')
      var script = txIn.script ? Script.fromASM(txIn.script) : undefined

      tx.addInput(txHash, txIn.index, txIn.sequence, script)
    })

    raw.outs.forEach(function(txOut) {
      tx.addOutput(Script.fromASM(txOut.script), txOut.value)
    })

    return tx
  }

  describe('fromBuffer/fromHex', function() {
    fixtures.valid.forEach(function(f) {
      it('imports ' + f.id + ' correctly', function() {
        var actual = Transaction.fromHex(f.hex)

        assert.deepEqual(actual.toHex(), f.hex)
      })
    })

    fixtures.invalid.fromBuffer.forEach(function(f) {
      it('throws on ' + f.exception, function() {
        assert.throws(function() {
          Transaction.fromHex(f.hex)
        }, new RegExp(f.exception))
      })
    })
  })

  describe('toBuffer/toHex', function() {
    fixtures.valid.forEach(function(f) {
      it('exports ' + f.id + ' correctly', function() {
        var actual = fromRaw(f.raw)

        assert.deepEqual(actual.toHex(), f.hex)
      })
    })
  })

  describe('addInput', function() {
    // FIXME: not as pretty as could be
    // Probably a bit representative of the API
    var prevTxHash, prevTxId, prevTx
    beforeEach(function() {
      var f = fixtures.valid[0]
      prevTx = Transaction.fromHex(f.hex)
      prevTxHash = prevTx.getHash()
      prevTxId = prevTx.getId()
    })

    it('accepts a transaction id', function() {
      var tx = new Transaction()
      tx.addInput(prevTxId, 0)

      assert.deepEqual(tx.ins[0].hash, prevTxHash)
    })

    it('accepts a transaction hash', function() {
      var tx = new Transaction()
      tx.addInput(prevTxHash, 0)

      assert.deepEqual(tx.ins[0].hash, prevTxHash)
    })

    it('accepts a Transaction object', function() {
      var tx = new Transaction()
      tx.addInput(prevTx, 0)

      assert.deepEqual(tx.ins[0].hash, prevTxHash)
    })

    it('returns an index', function() {
      var tx = new Transaction()
      assert.equal(tx.addInput(prevTxHash, 0), 0)
      assert.equal(tx.addInput(prevTxHash, 0), 1)
    })

    it('defaults to DEFAULT_SEQUENCE', function() {
      var tx = new Transaction()
      tx.addInput(prevTxHash, 0)

      assert.equal(tx.ins[0].sequence, Transaction.DEFAULT_SEQUENCE)
    })

    it('defaults to empty script', function() {
      var tx = new Transaction()
      tx.addInput(prevTxHash, 0)

      assert.equal(tx.ins[0].script, Script.EMPTY)
    })

    fixtures.invalid.addInput.forEach(function(f) {
      it('throws on ' + f.exception, function() {
        var tx = new Transaction()
        var hash = new Buffer(f.hash, 'hex')

        assert.throws(function() {
          tx.addInput(hash, f.index)
        }, new RegExp(f.exception))
      })
    })
  })

  describe('addOutput', function() {
    // FIXME: not as pretty as could be
    // Probably a bit representative of the API
    var destAddressB58, destAddress, destScript
    beforeEach(function() {
      destAddressB58 = '15mMHKL96tWAUtqF3tbVf99Z8arcmnJrr3'
      destAddress = Address.fromBase58Check(destAddressB58)
      destScript = destAddress.toOutputScript()
    })

    it('accepts an address string', function() {
      var tx = new Transaction()
      tx.addOutput(destAddressB58, 40000)

      assert.deepEqual(tx.outs[0].script, destScript)
      assert.equal(tx.outs[0].value, 40000)
    })

    it('accepts an Address', function() {
      var tx = new Transaction()
      tx.addOutput(destAddress, 40000)

      assert.deepEqual(tx.outs[0].script, destScript)
      assert.equal(tx.outs[0].value, 40000)
    })

    it('accepts a scriptPubKey', function() {
      var tx = new Transaction()
      tx.addOutput(destScript, 40000)

      assert.deepEqual(tx.outs[0].script, destScript)
      assert.equal(tx.outs[0].value, 40000)
    })

    it('returns an index', function() {
      var tx = new Transaction()
      assert.equal(tx.addOutput(destScript, 40000), 0)
      assert.equal(tx.addOutput(destScript, 40000), 1)
    })
  })

  describe('clone', function() {
    fixtures.valid.forEach(function(f) {
      var actual, expected

      beforeEach(function() {
        expected = Transaction.fromHex(f.hex)
        actual = expected.clone()
      })

      it('should have value equality', function() {
        assert.deepEqual(actual, expected)
      })

      it('should not have reference equality', function() {
        assert.notEqual(actual, expected)
      })
    })
  })

  describe('getId', function() {
    fixtures.valid.forEach(function(f) {
      it('should return the id for ' + f.id, function() {
        var tx = Transaction.fromHex(f.hex)
        var actual = tx.getId()

        assert.equal(actual, f.id)
      })
    })
  })

  describe('getHash', function() {
    fixtures.valid.forEach(function(f) {
      it('should return the hash for ' + f.id, function() {
        var tx = Transaction.fromHex(f.hex)
        var actual = tx.getHash().toString('hex')

        assert.equal(actual, f.hash)
      })
    })
  })

  // TODO:
  //  hashForSignature: [Function],

  // FIXME: remove in 2.x.y
  describe('signInput/validateInput', function() {
    it('works for multi-sig redeem script', function() {
      var tx = new Transaction()
      tx.addInput('d6f72aab8ff86ff6289842a0424319bf2ddba85dc7c52757912297f948286389', 0)
      tx.addOutput('mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r', 1)

      var privKeys = [
        '5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf',
        '5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAvUcVfH'
      ].map(function(wif) {
        return ECKey.fromWIF(wif)
      })
      var pubKeys = privKeys.map(function(eck) { return eck.pub })
      var redeemScript = scripts.multisigOutput(2, pubKeys)

      var signatures = privKeys.map(function(privKey) {
        return tx.signInput(0, redeemScript, privKey)
      })

      var redeemScriptSig = scripts.multisigInput(signatures)
      var scriptSig = scripts.scriptHashInput(redeemScriptSig, redeemScript)
      tx.setInputScript(0, scriptSig)

      signatures.forEach(function(sig, i){
        assert(tx.validateInput(0, redeemScript, privKeys[i].pub, sig))
      })

      var expected = '010000000189632848f99722915727c5c75da8db2dbf194342a0429828f66ff88fab2af7d600000000fd1b0100483045022100e5be20d440b2bbbc886161f9095fa6d0bca749a4e41d30064f30eb97adc7a1f5022061af132890d8e4e90fedff5e9365aeeb77021afd8ef1d5c114d575512e9a130a0147304402205054e38e9d7b5c10481b6b4991fde5704cd94d49e344406e3c2ce4d18a43bf8e022051d7ba8479865b53a48bee0cce86e89a25633af5b2918aa276859489e232f51c014c8752410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52aeffffffff0101000000000000001976a914751e76e8199196d454941c45d1b3a323f1433bd688ac00000000'
      assert.equal(tx.toHex(), expected)
    })
  })
})
<|endoftext|>


<commit_before>var test = require('tap').test;
var Blocks = require('../../src/engine/blocks');

test('spec', function (t) {
    var b = new Blocks();

    t.type(Blocks, 'function');
    t.type(b, 'object');
    t.ok(b instanceof Blocks);

    t.type(b._blocks, 'object');
    t.type(b._stacks, 'object');
    t.ok(Array.isArray(b._stacks));

    t.type(b.createBlock, 'function');
    t.type(b.moveBlock, 'function');
    t.type(b.changeBlock, 'function');
    t.type(b.deleteBlock, 'function');

    t.end();
});

test('create', function (t) {
    var b = new Blocks();
    b.createBlock({
        id: 'foo',
        opcode: 'TEST_BLOCK',
        next: null,
        fields: {},
        inputs: {},
        topLevel: true
    });

    t.type(b._blocks['foo'], 'object');
    t.equal(b._blocks['foo'].opcode, 'TEST_BLOCK');
    t.notEqual(b._stacks.indexOf('foo'), -1);
    t.end();
});

test('move', function (t) {
    var b = new Blocks();
    b.createBlock({
        id: 'foo',
        opcode: 'TEST_BLOCK',
        next: null,
        fields: {},
        inputs: {},
        topLevel: true
    });
    b.createBlock({
        id: 'bar',
        opcode: 'TEST_BLOCK',
        next: null,
        fields: {},
        inputs: {},
        topLevel: true
    });

    // Attach 'bar' to the end of 'foo'
    b.moveBlock({
        id: 'bar',
        newParent: 'foo'
    });
    t.equal(b._stacks.length, 1);
    t.equal(Object.keys(b._blocks).length, 2);
    t.equal(b._blocks['foo'].next, 'bar');

    // Detach 'bar' from 'foo'
    b.moveBlock({
        id: 'bar',
        oldParent: 'foo'
    });
    t.equal(b._stacks.length, 2);
    t.equal(Object.keys(b._blocks).length, 2);
    t.equal(b._blocks['foo'].next, null);

    t.end();
});

test('delete', function (t) {
    var b = new Blocks();
    b.createBlock({
        id: 'foo',
        opcode: 'TEST_BLOCK',
        next: null,
        fields: {},
        inputs: {},
        topLevel: true
    });
    b.deleteBlock({
        id: 'foo'
    });

    t.type(b._blocks['foo'], 'undefined');
    t.equal(b._stacks.indexOf('foo'), -1);
    t.end();
});
<commit_msg>Add blocks delete chain test<commit_after>var test = require('tap').test;
var Blocks = require('../../src/engine/blocks');

test('spec', function (t) {
    var b = new Blocks();

    t.type(Blocks, 'function');
    t.type(b, 'object');
    t.ok(b instanceof Blocks);

    t.type(b._blocks, 'object');
    t.type(b._stacks, 'object');
    t.ok(Array.isArray(b._stacks));

    t.type(b.createBlock, 'function');
    t.type(b.moveBlock, 'function');
    t.type(b.changeBlock, 'function');
    t.type(b.deleteBlock, 'function');

    t.end();
});

test('create', function (t) {
    var b = new Blocks();
    b.createBlock({
        id: 'foo',
        opcode: 'TEST_BLOCK',
        next: null,
        fields: {},
        inputs: {},
        topLevel: true
    });

    t.type(b._blocks['foo'], 'object');
    t.equal(b._blocks['foo'].opcode, 'TEST_BLOCK');
    t.notEqual(b._stacks.indexOf('foo'), -1);
    t.end();
});

test('move', function (t) {
    var b = new Blocks();
    b.createBlock({
        id: 'foo',
        opcode: 'TEST_BLOCK',
        next: null,
        fields: {},
        inputs: {},
        topLevel: true
    });
    b.createBlock({
        id: 'bar',
        opcode: 'TEST_BLOCK',
        next: null,
        fields: {},
        inputs: {},
        topLevel: true
    });

    // Attach 'bar' to the end of 'foo'
    b.moveBlock({
        id: 'bar',
        newParent: 'foo'
    });
    t.equal(b._stacks.length, 1);
    t.equal(Object.keys(b._blocks).length, 2);
    t.equal(b._blocks['foo'].next, 'bar');

    // Detach 'bar' from 'foo'
    b.moveBlock({
        id: 'bar',
        oldParent: 'foo'
    });
    t.equal(b._stacks.length, 2);
    t.equal(Object.keys(b._blocks).length, 2);
    t.equal(b._blocks['foo'].next, null);

    t.end();
});

test('delete', function (t) {
    var b = new Blocks();
    b.createBlock({
        id: 'foo',
        opcode: 'TEST_BLOCK',
        next: null,
        fields: {},
        inputs: {},
        topLevel: true
    });
    b.deleteBlock({
        id: 'foo'
    });

    t.type(b._blocks['foo'], 'undefined');
    t.equal(b._stacks.indexOf('foo'), -1);
    t.end();
});

test('delete chain', function (t) {
    // Create a chain of connected blocks and delete the top one.
    // All of them should be deleted.
    var b = new Blocks();
    b.createBlock({
        id: 'foo',
        opcode: 'TEST_BLOCK',
        next: 'foo2',
        fields: {},
        inputs: {},
        topLevel: true
    });
    b.createBlock({
        id: 'foo2',
        opcode: 'TEST_BLOCK',
        next: 'foo3',
        fields: {},
        inputs: {},
        topLevel: false
    });
    b.createBlock({
        id: 'foo3',
        opcode: 'TEST_BLOCK',
        next: null,
        fields: {},
        inputs: {},
        topLevel: false
    });
    b.deleteBlock({
        id: 'foo'
    });
    t.type(b._blocks['foo'], 'undefined');
    t.type(b._blocks['foo2'], 'undefined');
    t.type(b._blocks['foo3'], 'undefined');
    t.equal(b._stacks.indexOf('foo'), -1);
    t.equal(Object.keys(b._blocks).length, 0);
    t.equal(b._stacks.length, 0);
    t.end();
});
<|endoftext|>


<commit_before>angular.module('gettext').filter('translate', function (gettextCatalog) {
    return function (input) {
        return gettextCatalog.getString(input);
    };
});
<commit_msg>Mark filter as stateful such that it works with Angular 1.3rc2.<commit_after>angular.module('gettext').filter('translate', function (gettextCatalog) {
    function filter(input) {
        return gettextCatalog.getString(input);
    }
    filter.$stateful = true;
    return filter;
});
<|endoftext|>


<commit_before>// set up the map
var map = new L.Map('map');

// create the tile layer with correct attribution
var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib='Map data © OpenStreetMap contributors';
var osm = new L.TileLayer(osmUrl, {minZoom: 10, maxZoom: 20, attribution: osmAttrib});

// start the map in Karlsruhe, Germany
map.setView(new L.LatLng(49.00, 8.40), 15);
map.addLayer(osm);

// markers for containers
var clothesMarker = L.AwesomeMarkers.icon({
  prefix: 'ion',
  icon: 'tshirt',
  markerColor: 'cadetblue'
});

var glassMarker = L.AwesomeMarkers.icon({
  prefix: 'ion',
  icon: 'wineglass',
  markerColor: 'blue'
});

// OverPassAPI overlays
var clothesLayer = new L.OverPassLayer({
  query: "node['amenity'='recycling']['recycling:clothes'='yes']({{bbox}});out;",
  markerIcon: clothesMarker,
});

var glassLayer = new L.OverPassLayer({
  query: "node['amenity'='recycling']['recycling:glass'='yes']({{bbox}});out;",
  markerIcon: glassMarker,
});

map.addLayer(clothesLayer);
map.addLayer(glassLayer);

// Layer control (switch on/off layers)
var baseMap = {
    "base": osm
};

var overlayMaps = {
    "clothes": clothesLayer,
    "glass": glassLayer
};

L.control.layers(baseMap, overlayMaps).addTo(map);
<commit_msg>Show batteries containers<commit_after>// set up the map
var map = new L.Map('map');

// create the tile layer with correct attribution
var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib='Map data © OpenStreetMap contributors';
var osm = new L.TileLayer(osmUrl, {minZoom: 10, maxZoom: 20, attribution: osmAttrib});

// start the map in Karlsruhe, Germany
map.setView(new L.LatLng(49.00, 8.40), 15);
map.addLayer(osm);

// markers for containers
var clothesMarker = L.AwesomeMarkers.icon({
  prefix: 'ion',
  icon: 'tshirt',
  markerColor: 'cadetblue'
});

var glassMarker = L.AwesomeMarkers.icon({
  prefix: 'ion',
  icon: 'wineglass',
  markerColor: 'blue'
});

var batteriesMarker = L.AwesomeMarkers.icon({
  prefix: 'ion',
  icon: 'battery-low',
  markerColor: 'orange'
});

// OverPassAPI overlays
var clothesLayer = new L.OverPassLayer({
  query: "node['amenity'='recycling']['recycling:clothes'='yes']({{bbox}});out;",
  markerIcon: clothesMarker,
});

var glassLayer = new L.OverPassLayer({
  query: "node['amenity'='recycling']['recycling:glass'='yes']({{bbox}});out;",
  markerIcon: glassMarker,
});

var batteriesLayer = new L.OverPassLayer({
  query: "node['amenity'='recycling']['recycling:batteries'='yes']({{bbox}});out;",
  markerIcon: batteriesMarker,
});

map.addLayer(clothesLayer);
map.addLayer(glassLayer);
map.addLayer(batteriesLayer);

// Layer control (switch on/off layers)
var baseMap = {
    "Base": osm
};

var overlayMaps = {
    "Clothes": clothesLayer,
    "Glass": glassLayer,
    "Batteries": batteriesLayer
};

L.control.layers(baseMap, overlayMaps).addTo(map);
<|endoftext|>


<commit_before>const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: {
    index: [
      'babel-polyfill',
      './src/index.js'
    ]
  },
  output: {
    path: path.join(__dirname, 'build'),
    filename: '[name].js'
  },
  target: 'web',
  module: {
    loaders: [{
      loader: 'babel-loader',
      include: [path.resolve(__dirname, 'src')],
      exclude: /node_modules/,
      test: /\.js$/,
      query: {
        presets: ['react', 'es2015', 'stage-0']
      }
    }, {
      loader: 'json-loader',
      test: /\.json$/
    }, {
      loader: ExtractTextPlugin.extract('style', 'css?modules&localIdentName=[local]__[hash:base64:5]'),
      test: /\.css$/,
      exclude: /node_modules/
    }]
  },
  resolve: {
    modulesDirectories: [
      './node_modules',
      './src'
    ]
  },
  plugins: [
    new ExtractTextPlugin('styles.css')
  ]
}
<commit_msg>add changes :minibus:<commit_after>const path = require('path')
const ExtractTextPlugin = require('extract-text-webpack-plugin')

module.exports = {
  entry: {
    index: [
      'babel-polyfill',
      './src/index.js'
    ]
  },
  output: {
    path: path.join(__dirname, 'build'),
    filename: '[name].js'
  },
  target: 'web',
  module: {
    loaders: [{
      loader: 'babel-loader',
      include: [path.resolve(__dirname, 'src')],
      exclude: /node_modules/,
      test: /\.js$/,
      query: {
        presets: ['react', 'es2015', 'stage-0']
      }
    }, {
      loader: 'json-loader',
      test: /\.json$/
    }, {
      loader: ExtractTextPlugin.extract('style', 'css?modules&localIdentName=[local]__[hash:base64:5]'),
      test: /\.css$/,
      exclude: /node_modules/
    }]
  },
  resolve: {
    modulesDirectories: [
      './node_modules',
      './src'
    ]
  },
  plugins: [
    new ExtractTextPlugin('styles.css')
  ]
}
<|endoftext|>


<commit_before>/**
 * Copyright 2013-2020 the original author or authors from the JHipster project.
 *
 * This file is part of the JHipster project, see https://www.jhipster.tech/
 * for more information.
 *
 * 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.
 */
const chalk = require('chalk');

module.exports = {
    askPipeline,
    askIntegrations,
};

function askPipeline() {
    if (this.abort) return;
    if (this.autoconfigureTravis) {
        this.log('Auto-configuring Travis CI');
        this.pipeline = 'travis';
        return;
    }
    if (this.autoconfigureJenkins) {
        this.log('Auto-configuring Jenkins');
        this.pipeline = 'jenkins';
        this.sendBuildToGitlab = false;
        this.insideDocker = false;
        return;
    }

    if (this.autoconfigureGitlab) {
        this.log('Auto-configuring Gitlab');
        this.pipeline = 'gitlab';
        this.sendBuildToGitlab = true;
        this.insideDocker = true;
        return;
    }

    if (this.autoconfigureAzure) {
        this.log('Auto-configuring Azure');
        this.pipeline = 'azure';
        return;
    }

    if (this.autoconfigureGithub) {
        this.log('Auto-configuring GitHub Actions');
        this.pipeline = 'github';
        return;
    }

    if (this.autoconfigureCircleCI) {
        this.log('Auto-configuring CircleCI');
        this.pipeline = 'circle';
        return;
    }

    const done = this.async();
    const prompts = [
        {
            type: 'list',
            name: 'pipeline',
            message: 'What CI/CD pipeline do you want to generate?',
            default: 'jenkins',
            choices: [
                { name: 'Jenkins pipeline', value: 'jenkins' },
                { name: 'Azure Pipelines', value: 'azure' },
                { name: 'GitLab CI', value: 'gitlab' },
                { name: 'GitHub Actions', value: 'github' },
                { name: 'Travis CI', value: 'travis' },
                { name: 'CircleCI', value: 'circle' },
            ],
        },
    ];
    this.prompt(prompts).then(props => {
        this.pipeline = props.pipeline;
        done();
    });
}

function askIntegrations() {
    if (this.abort || !this.pipeline || this.pipeline === 'azure') return;
    if (this.autoconfigureTravis) {
        this.cicdIntegrations = [];
        return;
    }
    if (this.autoconfigureJenkins) {
        this.cicdIntegrations = [];
        this.sendBuildToGitlab = false;
        this.insideDocker = false;
        return;
    }

    if (this.autoconfigureGitlab) {
        this.cicdIntegrations = [];
        this.sendBuildToGitlab = true;
        this.insideDocker = true;
        return;
    }

    if (this.autoconfigureAzure) {
        this.log('Auto-configuring Azure');
        this.pipeline = 'azure';
        return;
    }

    if (this.autoconfigureGithub) {
        this.log('Auto-configuring GitHub Actions');
        this.pipeline = 'github';
        return;
    }

    if (this.autoconfigureCircleCI) {
        this.log('Auto-configuring CircleCI');
        this.pipeline = 'circle';
        return;
    }

    const integrationChoices = [];
    if (['jenkins', 'gitlab', 'github'].includes(this.pipeline)) {
        integrationChoices.push({ name: `Deploy your application to an ${chalk.yellow('*Artifactory*')}`, value: 'deploy' });
    }
    if (['jenkins', 'gitlab', 'travis', 'github'].includes(this.pipeline)) {
        integrationChoices.push({ name: `Analyze your code with ${chalk.yellow('*Sonar*')}`, value: 'sonar' });
    }
    if (['jenkins', 'github'].includes(this.pipeline)) {
        integrationChoices.push({ name: `Build and publish a ${chalk.yellow('*Docker*')} image`, value: 'publishDocker' });
    }
    if (['jenkins', 'gitlab', 'travis', 'github', 'circle'].includes(this.pipeline)) {
        integrationChoices.push({
            name: `Deploy to ${chalk.yellow('*Heroku*')} (requires HEROKU_API_KEY set on CI service)`,
            value: 'heroku',
        });
    }
    const defaultDockerImage = `jhipster/${this.dasherizedBaseName}`;

    const done = this.async();
    const prompts = [
        {
            when: this.pipeline === 'jenkins',
            type: 'confirm',
            name: 'insideDocker',
            message: 'Would you like to perform the build in a Docker container ?',
            default: false,
        },
        {
            when: this.pipeline === 'gitlab',
            type: 'confirm',
            name: 'insideDocker',
            message: 'In GitLab CI, perform the build in a docker container (hint: GitLab.com uses Docker container) ?',
            default: false,
        },
        {
            when: this.pipeline === 'jenkins',
            type: 'confirm',
            name: 'sendBuildToGitlab',
            message: 'Would you like to send build status to GitLab ?',
            default: false,
        },
        {
            when: integrationChoices.length > 0,
            type: 'checkbox',
            name: 'cicdIntegrations',
            message: 'What tasks/integrations do you want to include ?',
            default: [],
            choices: integrationChoices,
        },
        {
            when: response => response.cicdIntegrations.includes('deploy'),
            type: 'input',
            name: 'artifactorySnapshotsId',
            message: `${chalk.yellow('*Artifactory*')}: what is the ID of distributionManagement for snapshots ?`,
            default: 'snapshots',
        },
        {
            when: response => response.cicdIntegrations.includes('deploy'),
            type: 'input',
            name: 'artifactorySnapshotsUrl',
            message: `${chalk.yellow('*Artifactory*')}: what is the URL of distributionManagement for snapshots ?`,
            default: 'http://artifactory:8081/artifactory/libs-snapshot',
        },
        {
            when: response => response.cicdIntegrations.includes('deploy'),
            type: 'input',
            name: 'artifactoryReleasesId',
            message: `${chalk.yellow('*Artifactory*')}: what is the ID of distributionManagement for releases ?`,
            default: 'releases',
        },
        {
            when: response => response.cicdIntegrations.includes('deploy'),
            type: 'input',
            name: 'artifactoryReleasesUrl',
            message: `${chalk.yellow('*Artifactory*')}: what is the URL of distributionManagement for releases ?`,
            default: 'http://artifactory:8081/artifactory/libs-release',
        },
        {
            when: response => this.pipeline === 'jenkins' && response.cicdIntegrations.includes('sonar'),
            type: 'input',
            name: 'sonarName',
            message: `${chalk.yellow('*Sonar*')}: what is the name of the Sonar server ?`,
            default: 'sonar',
        },
        {
            when: response => this.pipeline !== 'jenkins' && response.cicdIntegrations.includes('sonar'),
            type: 'input',
            name: 'sonarUrl',
            message: `${chalk.yellow('*Sonar*')}: what is the URL of the Sonar server ?`,
            default: 'https://sonarcloud.io',
        },
        {
            when: response => this.pipeline !== 'jenkins' && response.cicdIntegrations.includes('sonar'),
            type: 'input',
            name: 'sonarOrga',
            message: `${chalk.yellow('*Sonar*')}: what is the Organization of the Sonar server ?`,
            default: '',
        },
        {
            when: response => this.pipeline === 'github' && response.cicdIntegrations.includes('publishDocker'),
            type: 'input',
            name: 'dockerImage',
            message: `${chalk.yellow('*Docker*')}: what is the name of the image ?`,
            default: defaultDockerImage,
        },
        {
            when: response => response.cicdIntegrations.includes('heroku'),
            type: 'input',
            name: 'herokuAppName',
            message: `${chalk.yellow('*Heroku*')}: name of your Heroku Application ?`,
            default: `${this.herokuAppName}`,
        },
    ];
    this.prompt(prompts).then(props => {
        this.cicdIntegrations = props.cicdIntegrations;

        this.artifactorySnapshotsId = props.artifactorySnapshotsId;
        this.artifactorySnapshotsUrl = props.artifactorySnapshotsUrl;
        this.artifactoryReleasesId = props.artifactoryReleasesId;
        this.artifactoryReleasesUrl = props.artifactoryReleasesUrl;

        this.sonarName = props.sonarName;
        this.sonarUrl = props.sonarUrl;
        this.sonarOrga = props.sonarOrga;

        this.publishDocker = props.publishDocker;
        this.dockerImage = props.dockerImage;

        this.insideDocker = props.insideDocker;

        this.sendBuildToGitlab = props.sendBuildToGitlab;

        done();
    });
}
<commit_msg>chore: convert ci-cd prompts to async<commit_after>/**
 * Copyright 2013-2020 the original author or authors from the JHipster project.
 *
 * This file is part of the JHipster project, see https://www.jhipster.tech/
 * for more information.
 *
 * 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.
 */
const chalk = require('chalk');

module.exports = {
    askPipeline,
    askIntegrations,
};

async function askPipeline() {
    if (this.abort) return;
    if (this.autoconfigureTravis) {
        this.log('Auto-configuring Travis CI');
        this.pipeline = 'travis';
        return;
    }
    if (this.autoconfigureJenkins) {
        this.log('Auto-configuring Jenkins');
        this.pipeline = 'jenkins';
        this.sendBuildToGitlab = false;
        this.insideDocker = false;
        return;
    }

    if (this.autoconfigureGitlab) {
        this.log('Auto-configuring Gitlab');
        this.pipeline = 'gitlab';
        this.sendBuildToGitlab = true;
        this.insideDocker = true;
        return;
    }

    if (this.autoconfigureAzure) {
        this.log('Auto-configuring Azure');
        this.pipeline = 'azure';
        return;
    }

    if (this.autoconfigureGithub) {
        this.log('Auto-configuring GitHub Actions');
        this.pipeline = 'github';
        return;
    }

    if (this.autoconfigureCircleCI) {
        this.log('Auto-configuring CircleCI');
        this.pipeline = 'circle';
        return;
    }

    const prompts = [
        {
            type: 'list',
            name: 'pipeline',
            message: 'What CI/CD pipeline do you want to generate?',
            default: 'jenkins',
            choices: [
                { name: 'Jenkins pipeline', value: 'jenkins' },
                { name: 'Azure Pipelines', value: 'azure' },
                { name: 'GitLab CI', value: 'gitlab' },
                { name: 'GitHub Actions', value: 'github' },
                { name: 'Travis CI', value: 'travis' },
                { name: 'CircleCI', value: 'circle' },
            ],
        },
    ];
    const props = await this.prompt(prompts);
    this.pipeline = props.pipeline;
}

function askIntegrations() {
    if (this.abort || !this.pipeline || this.pipeline === 'azure') return;
    if (this.autoconfigureTravis) {
        this.cicdIntegrations = [];
        return;
    }
    if (this.autoconfigureJenkins) {
        this.cicdIntegrations = [];
        this.sendBuildToGitlab = false;
        this.insideDocker = false;
        return;
    }

    if (this.autoconfigureGitlab) {
        this.cicdIntegrations = [];
        this.sendBuildToGitlab = true;
        this.insideDocker = true;
        return;
    }

    if (this.autoconfigureAzure) {
        this.log('Auto-configuring Azure');
        this.pipeline = 'azure';
        return;
    }

    if (this.autoconfigureGithub) {
        this.log('Auto-configuring GitHub Actions');
        this.pipeline = 'github';
        return;
    }

    if (this.autoconfigureCircleCI) {
        this.log('Auto-configuring CircleCI');
        this.pipeline = 'circle';
        return;
    }

    const integrationChoices = [];
    if (['jenkins', 'gitlab', 'github'].includes(this.pipeline)) {
        integrationChoices.push({ name: `Deploy your application to an ${chalk.yellow('*Artifactory*')}`, value: 'deploy' });
    }
    if (['jenkins', 'gitlab', 'travis', 'github'].includes(this.pipeline)) {
        integrationChoices.push({ name: `Analyze your code with ${chalk.yellow('*Sonar*')}`, value: 'sonar' });
    }
    if (['jenkins', 'github'].includes(this.pipeline)) {
        integrationChoices.push({ name: `Build and publish a ${chalk.yellow('*Docker*')} image`, value: 'publishDocker' });
    }
    if (['jenkins', 'gitlab', 'travis', 'github', 'circle'].includes(this.pipeline)) {
        integrationChoices.push({
            name: `Deploy to ${chalk.yellow('*Heroku*')} (requires HEROKU_API_KEY set on CI service)`,
            value: 'heroku',
        });
    }
    const defaultDockerImage = `jhipster/${this.dasherizedBaseName}`;

    const done = this.async();
    const prompts = [
        {
            when: this.pipeline === 'jenkins',
            type: 'confirm',
            name: 'insideDocker',
            message: 'Would you like to perform the build in a Docker container ?',
            default: false,
        },
        {
            when: this.pipeline === 'gitlab',
            type: 'confirm',
            name: 'insideDocker',
            message: 'In GitLab CI, perform the build in a docker container (hint: GitLab.com uses Docker container) ?',
            default: false,
        },
        {
            when: this.pipeline === 'jenkins',
            type: 'confirm',
            name: 'sendBuildToGitlab',
            message: 'Would you like to send build status to GitLab ?',
            default: false,
        },
        {
            when: integrationChoices.length > 0,
            type: 'checkbox',
            name: 'cicdIntegrations',
            message: 'What tasks/integrations do you want to include ?',
            default: [],
            choices: integrationChoices,
        },
        {
            when: response => response.cicdIntegrations.includes('deploy'),
            type: 'input',
            name: 'artifactorySnapshotsId',
            message: `${chalk.yellow('*Artifactory*')}: what is the ID of distributionManagement for snapshots ?`,
            default: 'snapshots',
        },
        {
            when: response => response.cicdIntegrations.includes('deploy'),
            type: 'input',
            name: 'artifactorySnapshotsUrl',
            message: `${chalk.yellow('*Artifactory*')}: what is the URL of distributionManagement for snapshots ?`,
            default: 'http://artifactory:8081/artifactory/libs-snapshot',
        },
        {
            when: response => response.cicdIntegrations.includes('deploy'),
            type: 'input',
            name: 'artifactoryReleasesId',
            message: `${chalk.yellow('*Artifactory*')}: what is the ID of distributionManagement for releases ?`,
            default: 'releases',
        },
        {
            when: response => response.cicdIntegrations.includes('deploy'),
            type: 'input',
            name: 'artifactoryReleasesUrl',
            message: `${chalk.yellow('*Artifactory*')}: what is the URL of distributionManagement for releases ?`,
            default: 'http://artifactory:8081/artifactory/libs-release',
        },
        {
            when: response => this.pipeline === 'jenkins' && response.cicdIntegrations.includes('sonar'),
            type: 'input',
            name: 'sonarName',
            message: `${chalk.yellow('*Sonar*')}: what is the name of the Sonar server ?`,
            default: 'sonar',
        },
        {
            when: response => this.pipeline !== 'jenkins' && response.cicdIntegrations.includes('sonar'),
            type: 'input',
            name: 'sonarUrl',
            message: `${chalk.yellow('*Sonar*')}: what is the URL of the Sonar server ?`,
            default: 'https://sonarcloud.io',
        },
        {
            when: response => this.pipeline !== 'jenkins' && response.cicdIntegrations.includes('sonar'),
            type: 'input',
            name: 'sonarOrga',
            message: `${chalk.yellow('*Sonar*')}: what is the Organization of the Sonar server ?`,
            default: '',
        },
        {
            when: response => this.pipeline === 'github' && response.cicdIntegrations.includes('publishDocker'),
            type: 'input',
            name: 'dockerImage',
            message: `${chalk.yellow('*Docker*')}: what is the name of the image ?`,
            default: defaultDockerImage,
        },
        {
            when: response => response.cicdIntegrations.includes('heroku'),
            type: 'input',
            name: 'herokuAppName',
            message: `${chalk.yellow('*Heroku*')}: name of your Heroku Application ?`,
            default: `${this.herokuAppName}`,
        },
    ];
    this.prompt(prompts).then(props => {
        this.cicdIntegrations = props.cicdIntegrations;

        this.artifactorySnapshotsId = props.artifactorySnapshotsId;
        this.artifactorySnapshotsUrl = props.artifactorySnapshotsUrl;
        this.artifactoryReleasesId = props.artifactoryReleasesId;
        this.artifactoryReleasesUrl = props.artifactoryReleasesUrl;

        this.sonarName = props.sonarName;
        this.sonarUrl = props.sonarUrl;
        this.sonarOrga = props.sonarOrga;

        this.publishDocker = props.publishDocker;
        this.dockerImage = props.dockerImage;

        this.insideDocker = props.insideDocker;

        this.sendBuildToGitlab = props.sendBuildToGitlab;

        done();
    });
}
<|endoftext|>


<commit_before>'use strict';
const Base = require('yeoman-generator').Base;
const path = require('path');
const yeoman = require('yeoman-environment');

function toPluginRepo(url, useSSH) {
  const match = url.match(/(github:)?([\w\d-_]+\/)?([\w\d-_]+)(#.+)?/);
  const repo = match ? `${match[4] ? `-b ${match[4].slice(1)} ` : ''}${useSSH ? 'git@github.com:' : 'https://github.com/'}${match[2] || ''}${match[3]}.git` : '';
  return {
    name: match ? match[3] : url,
    url,
    repo
  };
}

class Generator extends Base {
  constructor(args, options) {
    super(args, options);

    this.argument('pkgs', {
      description: 'the packages to install',
      type: Array,
      required: true
    });

    this.option('for', {
      type: String,
      description: 'the plugin for which should the package be registered',
      alias: 'for'
    });

    this.option('ssh', {
      alias: 's',
      defaults: false,
      type: Boolean
    });

    this.option('type', {
      type: String,
      default: 'lib',
      description: 'dependency type lib|plugin',
      alias: 't'
    });

    this.plugin = null;
    this.plugins = [];
  }

  _yo(generator, options) {
    // call yo internally
    const env = yeoman.createEnv([], {
      cwd: this.cwd
    }, this.env.adapter);
    env.register(require.resolve('../' + generator), 'phovea:' + generator);
    return new Promise((resolve, reject) => {
      try {
        this.log('running yo phovea:' + generator);
        env.run('phovea:' + generator, options || {}, () => {
          // wait a second after running yo to commit the files correctly
          setTimeout(() => resolve(), 500);
        });
      } catch (e) {
        console.error('error', e, e.stack);
        reject(e);
      }
    });
  }

  default() {
    this.plugin = this.options.for;

    if (this.fs.exists(this.destinationPath('../.yo-rc-workspace.json'))) {
      // we are in a workspace
      this.plugin = path.basename(this.destinationRoot());
      this.log('switch to workspace for install dependencies but keep ' + this.plugin, 'in mind');
      process.chdir('../');
    }
    if (this.options.type.startsWith('p')) {
      this.plugins = this.pkgs.map((url) => {
        const p = toPluginRepo(url, this.options.ssh);
        if (!p.repo) {
          this.log('can resolve repository for ' + url);
          return null;
        }
        this.log(`cloning git clone ${p.repo}`);
        this.spawnCommandSync('git', ['clone'].concat(p.repo.split(' ')));
        return p;
      }).filter((n) => Boolean(n));
      this.log('updating workspace');
      return this._yo('workspace').then(() => {
        this.log('running npm install');
        this.npmInstall();
      });
    }
    this.log('installing: ', this.pkgs.join(' '));
    this.npmInstall(this.pkgs, {save: true});
  }

  end() {
    if (this.plugin && this.fs.exists(this.destinationPath(`package.json`))) {
      // also store the dependency in the plugin
      const child = {dependencies: {}};
      if (this.options.type.startsWith('p')) {
        this.plugins.forEach((p) => {
          child.dependencies[p.name] = p.url;
        });
      } else {
        // copy from package json
        const parent = this.fs.readJSON(this.destinationPath('../package.json'));
        this.pkgs.forEach((p) => {
          const pp = parent.dependencies[p];
          if (pp) {
            child.dependencies[p] = pp;
          }
        });
      }
      this.fs.extendJSON(this.destinationPath(`package.json`), child);
    }
  }
}

module.exports = Generator;
<commit_msg>try to fix #121 install doesn't copy dependency<commit_after>'use strict';
const Base = require('yeoman-generator').Base;
const path = require('path');
const yeoman = require('yeoman-environment');

function toPluginRepo(url, useSSH) {
  const match = url.match(/(github:)?([\w\d-_]+\/)?([\w\d-_]+)(#.+)?/);
  const repo = match ? `${match[4] ? `-b ${match[4].slice(1)} ` : ''}${useSSH ? 'git@github.com:' : 'https://github.com/'}${match[2] || ''}${match[3]}.git` : '';
  return {
    name: match ? match[3] : url,
    url,
    repo
  };
}

class Generator extends Base {
  constructor(args, options) {
    super(args, options);

    this.argument('pkgs', {
      description: 'the packages to install',
      type: Array,
      required: true
    });

    this.option('for', {
      type: String,
      description: 'the plugin for which should the package be registered',
      alias: 'for'
    });

    this.option('ssh', {
      alias: 's',
      defaults: false,
      type: Boolean
    });

    this.option('type', {
      type: String,
      default: 'lib',
      description: 'dependency type lib|plugin',
      alias: 't'
    });

    this.plugin = null;
    this.plugins = [];
  }

  _yo(generator, options) {
    // call yo internally
    const env = yeoman.createEnv([], {
      cwd: this.cwd
    }, this.env.adapter);
    env.register(require.resolve('../' + generator), 'phovea:' + generator);
    return new Promise((resolve, reject) => {
      try {
        this.log('running yo phovea:' + generator);
        env.run('phovea:' + generator, options || {}, () => {
          // wait a second after running yo to commit the files correctly
          setTimeout(() => resolve(), 500);
        });
      } catch (e) {
        console.error('error', e, e.stack);
        reject(e);
      }
    });
  }

  default() {
    this.plugin = this.options.for;

    if (this.fs.exists(this.destinationPath('../.yo-rc-workspace.json'))) {
      // we are in a workspace
      this.plugin = path.basename(this.destinationRoot());
      this.log('switch to workspace for install dependencies but keep ' + this.plugin, 'in mind');
      process.chdir('../');
    }
    if (!this.options.type.startsWith('p')) {
      // regular dependency
      this.before = this.fs.readJSON(this.destinationPath('../package.json'));
      this.log('installing: ', this.pkgs.join(' '));
      this.npmInstall(this.pkgs, {save: true});
    }

    this.plugins = this.pkgs.map((url) => {
      const p = toPluginRepo(url, this.options.ssh);
      if (!p.repo) {
        this.log('can resolve repository for ' + url);
        return null;
      }
      this.log(`cloning git clone ${p.repo}`);
      this.spawnCommandSync('git', ['clone'].concat(p.repo.split(' ')));
      return p;
    }).filter((n) => Boolean(n));
    this.log('updating workspace');
    return this._yo('workspace').then(() => {
      this.log('running npm install');
      this.npmInstall();
    });
  }

  end() {
    if (this.plugin && this.fs.exists(this.destinationPath(`package.json`))) {
      // also store the dependency in the plugin
      const child = {dependencies: {}};
      if (this.options.type.startsWith('p')) {
        this.plugins.forEach((p) => {
          child.dependencies[p.name] = p.url;
        });
      } else {
        // copy from package json
        const before = this.before.dependencies;
        const after = this.fs.readJSON(this.destinationPath('../package.json'));
        const changes = after.dependencies;
        Object.keys(before).forEach((k) => delete changes[k]); // delete old entries
        // integrate new ones
        Object.assign(child.dependencies, changes);
      }
      this.fs.extendJSON(this.destinationPath(`package.json`), child);
    }
  }
}

module.exports = Generator;
<|endoftext|>