<commit_before>'use strict';

var i              = require('es5-ext/lib/Function/i')
  , d              = require('es5-ext/lib/Object/descriptor')
  , startsWith     = require('es5-ext/lib/String/prototype/starts-with')
  , endsWith       = require('es5-ext/lib/String/prototype/ends-with')
  , Plain          = require('./plain')
  , isNamespace    = require('./is-namespace')
  , nameRe         = require('./name-re')
  , RelSetReadOnly = require('./rel-set-read-only')
  , UniqueIndex    = require('./unique-index')
  , dummyNs        = require('./dummy-ns')

  , isArray = Array.isArray
  , defineProperty = Object.defineProperty
  , defineProperties = Object.defineProperties
  , getOwnPropertyNames = Object.getOwnPropertyNames
  , getPrototypeOf = Object.getPrototypeOf
  , isDigit = RegExp.prototype.test.bind(/\d/)

  , Relation, Item, Constructor, define, signal, history, reverse, refresh
  , addTriggers, removeTriggers;

addTriggers = function (rel) {
	var onadd, onremove;
	if (rel.hasOwnProperty('_triggersSetup_')) return;
	rel.triggers.forEach(onadd = function (name) {
		if (!rel.obj['_' + name]) define(rel.obj, name);
		rel.obj['_' + name].on('update', rel._refresh_)
	});
	rel.triggers.on('add', onadd);
	rel.triggers.on('remove', onremove = function (name) {
		rel.obj['-' + name].off('update', rel._refresh_);
	});
	defineProperty(rel, '_triggersSetup_',
		d({ onadd: onadd, onremove: onremove }));
};

removeTriggers = function (rel) {
	var setup = rel.hasOwnProperty('_triggersSetup_') && rel._triggersSetup_;
	if (!setup) return;
	rel.triggers.forEach(function (name) {
		rel.obj['_' + name].off('update', rel._refresh_)
	});
	rel.triggers.off('add', setup.onadd);
	rel.triggers.off('remove', setup.onremove);
	delete rel._triggersSetup_;
};

refresh = function () {
	var nu = this._value, old = this.__value;
	if ((typeof nu === 'function') && !nu._id_) {
		if (nu.length || !this.triggers.count) {
			this.__value = nu;
			if (this.hasOwnProperty('_triggersSetup_')) removeTriggers(this);
			return;
		} else {
			nu = this.__value = this.ns.normalize(nu.call(this.obj));
			if (!this.hasOwnProperty('_triggersSetup_')) addTriggers(this);
		}
	} else {
		nu = this.__value = (nu == null) ? nu : this.ns.normalize(nu);
		if (this.hasOwnProperty('_triggersSetup_')) removeTriggers(this);
	}
	if (old !== nu) this.emit('update', nu, old);
};

module.exports = Relation = Plain.create(function (obj, name, descriptor) {
	defineProperties(this, {
		obj: d('', obj),
		name: d.gs('', function () { return name; }),
		_id_: d('', obj._id_ + ':' + name),
		_foreign_: d('w', null),
		_descriptor_: d('', descriptor),
		__value: d('w', undefined),
		_refresh_: d(refresh.bind(this))
	});
	this._ns.on('update', this._refresh_);
});

Constructor = function (obj, parent) {
	defineProperties(this, {
		obj: d('', obj),
		_id_: d('', obj._id_ + ':' + this.name),
		_foreign_: d('w', null),
		__value: d('w', this.__value),
		_refresh_: d(refresh.bind(this))
	});
	this._ns.on('update', this._refresh_);
	parent.on('update', this._refresh_);
};

defineProperties(Relation.prototype, {
	_id_: d(''),
	_create_: d(function (obj) {
		var rel;
		// Avoid Object.create for performance reasons
		Constructor.prototype = this;
		rel = new Constructor(obj, this);
		if (!this.hasOwnProperty('_children_')) {
			defineProperty(this, '_children_', d('', []));
		}
		this._children_.push(rel);
		return rel;
	}),
	_onOld_: d(function (value) {
		if (this.unique) this._uniqIndex_.remove(this, value);
		if (value && value._id_ && value.ns) reverse.remove(this, value);
	}),
	_onNew_: d(function (value) {
		if (this.unique) this._uniqIndex_.add(this, value);
		if (value && value._id_ && value.ns) reverse.add(this, value);
	}),
	_setVisibility_: d(function (value) {
		if ((value !== undefined) &&
				(!this.obj.hasOwnProperty(this.name) || this._foreign_)) {
			defineProperty(this.obj, this.name, this._descriptor_);
		} else if (!this._foreign_) {
			delete this.obj[this.name];
		}
		if (this._foreign_) this._foreign_ = null;
	}),
	_forEachObject_: d(function (cb) {
		getOwnPropertyNames(this).forEach(function (name) {
			var value;
			if (startsWith.call(name, '__')) {
				value = this[name];
				if (!value._id_) return;
			} else if (isDigit(name[0]) && this.propertyIsEnumerable(name)) {
				value = this[name];
				if (!value || !value._id_ || !endsWith.call(value._id_, '"')) return;
			} else {
				return;
			}
			cb(value, value._id_, this);
		}, this);
	}),
	value: d.gs(function () {
		var value = this.__value;
		if ((typeof value === 'function') && !value._id_) {
			if (value.length) return value;
			value = value.call(this.obj);
			if (this.multiple) return new RelSetReadOnly(this.ns, value);
			return (value == null) ? null : this.ns.normalize(value);
		}
		if (this.multiple) {
			if (!this.hasOwnProperty('_count_')) this._initSet_();
			return this;
		}
		return value;
	}, function self(value) {
		var error = this.validate(value);
		if (error) throw error;
		this.$setMultiValue(value);
	}),
	$setMultiValue: d(function (value) {
		if (this.hasOwnProperty('_count_')) {
			this._reset_(value);
			return;
		}
		if ((value == null) || ((typeof value === 'function') && !value._id_)) {
			this.$setValue(value);
			signal(this, value);
			return;
		}
		if (isArray(value)) {
			this._initSet_();
			this._reset_(value);
			return;
		}
		value = this.ns.is(value) ? value : this.ns.$construct(value);
		this.$setValue(value);
		signal(this, value);
	}),
	$setValue: d(function (value) {
		var oldValue;

		if (!this.hasOwnProperty('_descriptor_')) this._setVisibility_(value);

		oldValue = this.hasOwnProperty('_value') ? this._value : undefined;
		if (value === undefined) {
			if (this.hasOwnProperty('_value')) {
				delete this._value;
				getPrototypeOf(this).on('update', this._refresh_);
			}
		} else if (!this.hasOwnProperty('_value')) {
			defineProperty(this, '_value', d('cw', value));
			getPrototypeOf(this).off('update', this._refresh_);
		} else {
			this._value = value;
		}

		if ((typeof oldValue === 'function') && !oldValue._id_) oldValue = null;
		if ((typeof value === 'function') && !value._id_) value = null;

		if (oldValue !== value) {
			if (oldValue !== null) this._onOld_(oldValue);
			if (value !== null) this._onNew_(value);
		}
		this._refresh_();
	}),
	find: d(function (value) {
		var obj;
		if (!this.hasOwnProperty('_children_')) return null;
		value = this.ns.normalize(value);
		if (value == null) return null;
		this._children_.some(function self(child) {
			if (child._value === value) {
				obj = child.obj;
				return true;
			}
			if (child.hasOwnProperty('_children_')) {
				return child._children_.some(self);
			}
		});
		return obj || null;
	}),
	_validate_: d(function (original) {
		var key, error, ns = this.ns, value;
		if ((typeof original === 'function') && !original._id_) {
			return new TypeError(original + " is not valid " + ns._id_);
		}
		value = ns.coerce(original);
		if (value == null) {
			return new TypeError(original + " is not valid " + ns._id_);
		}
		if ((error = ns.validate(value))) return error;
		if (!(key = ns._serialize_(value))) {
			return new TypeError(original + " is not valid dbjs value");
		}
		if (this.unique && (error = this._uniqIndex_.validate(this, key, value))) {
			return error;
		}
		return null;
	}),
	_validateValues_: d(function (values) {
		var error, errors;
		values.forEach(function (value) {
			if ((error = this._validate_(value))) {
				if (!errors) errors = [];
				errors.push(error);
			}
		}, this);
		return errors;
	}),
	validate: d(function (value) {
		var error, errors;
		if (this.writeOnce && (this._value != null)) {
			return new TypeError("Property is read-only");
		}
		if (value === undefined) {
			if (this.required && (getPrototypeOf(this)._value == null)) {
				return new TypeError((this.label || this.name) + " is required");
			}
			return null;
		}
		if (value === null) {
			if (this.required) {
				return new TypeError((this.label || this.name) + " is required");
			}
			return null;
		}
		if ((typeof value === 'function') && !value._id_) return null;

		if (isArray(value)) {
			if (!this.multiple) {
				return new TypeError(value + " is not valid " + this.ns._id_);
			}
			if (!value.length) {
				if (!this.required) return null;
				return new TypeError(value + " is not valid " + this.ns._id_);
			}
			if ((errors = this._validateValues_(value))) {
				error = new TypeError(value + " contains invalid values");
				error.errors = errors;
				return error;
			}
			return null;
		}
		return this._validate_(value);
	})
});

define = require('./define-basic');

define(Relation.prototype, 'required', false);
define(Relation.prototype, 'multiple', false);
define(Relation.prototype, 'writeOnce', false);

define(Relation.prototype, 'unique', false);
defineProperties(Relation.prototype.__unique, {
	$setValue: d(function (value) {
		if (value) {
			if (!this.hasOwnProperty('_value')) {
				defineProperty(this.obj, 'unique', this._descriptor_);
			}
			if (this._value) {
				this._value = true;
				return;
			}
			this._value = true;
			defineProperty(this.obj, '_uniqIndex_',
				d('c', new UniqueIndex(this.obj)));
		} else {
			if (!this._value) return;
			delete this._value;
			delete this.obj.unique;
			delete this.obj._uniqIndex_;
			if (this.obj.hasOwnProperty('_children_')) {
				this.obj._children_.forEach(function self(child) {
					if (child.unique) {
						defineProperty(child, '_uniqIndex_',
							d('c', new UniqueIndex(child)));
					} else if (child.hasOwnProperty('_children_')) {
						child._children_.forEach(self);
					}
				});
			}
		}
		this._refresh_();
	}),
	validate: d(function (value) {
		if (!value && this._value && !this.hasOwnProperty('_value')) {
			return new Error("Cannot override unique on extended namespace.");
		}
		return null;
	})
});

define(Relation.prototype, 'reverse', null);
defineProperties(Relation.prototype.__reverse, {
	value: d.gs(function () {
		return this.hasOwnProperty('_value') ? this._value : null;
	}, function self(value) {
		var error;
		value = this._normalize(value);
		if ((error = this.validate(value))) throw error;
		this.$setValue(value);
		signal(this, value);
	}),
	_normalize: d(function (value) {
		if (value === true) {
			value = this.obj.obj.ns._id_;
			value = value[0].toLowerCase() + value.slice(1);
		} else if (value) {
			value = String(value);
		}
		return value;
	}),
	$setValue: d(function (name) {
		if (!name) {
			if (this.hasOwnProperty('_value')) {
				reverse.unset(this.obj, this._value);
				delete this.obj.reverse;
				delete this._value;
			}
			return;
		}
		name = String(name);
		if ((name !== this._value) && this.hasOwnProperty('_value')) {
			reverse.unset(this.obj, this._value);
		}
		reverse.set(this.obj, name);
		if (!this.hasOwnProperty('_value')) {
			defineProperty(this.obj, 'reverse', this._descriptor_);
		}
		this._value = name;
	}),
	validate: d(function (name) {
		if (!name) return null;
		if (name === true) {
			name = this.obj.obj.ns._id_;
			name = name[0].toLowerCase() + name.slice(1);
		} else {
			name = String(name);
		}
		if (name === this._value) return null;
		if (!nameRe.test(name)) return new TypeError(name + " is not a valid name");
		return null;
	})
});

define(Relation.prototype, 'ns', dummyNs);
defineProperties(Relation.prototype.__ns, {
	_normalize: d(i),
	$setValue: d(function (value) {
		var old = this._value, newValue, revName;
		if (value === null) value = Relation.prototype.ns;
		newValue = value;
		if (value === undefined) newValue = getPrototypeOf(this)._value;

		revName = this.obj.hasOwnProperty('reverse') && this.obj.reverse;
		if (revName && (old !== newValue)) reverse.unset(this.obj, revName);

		if (value === undefined) {
			delete this.obj.ns;
			delete this._value;
		} else {
			if (!this.hasOwnProperty('_value')) {
				defineProperty(this.obj, 'ns', this._descriptor_);
			}
			this._value = value;
		}

		if (old !== newValue) {
			if (revName) reverse.set(this.obj, revName);
			if (this.obj.unique) this.obj._uniqIndex_.updateNs(this.obj, old);
		}
		this._refresh_();
	}),
	validate: d(function (value) {
		if (value == null) return null;
		if (!isNamespace(value)) {
			return new TypeError(value + " is not a namespace object");
		}
		return null;
	})
});

require('./rel-set');
Item  = require('./rel-set-item');
reverse = require('./rel-reverse');
signal = require('./signal');
history = signal.history;
<commit_msg>Take out '__value' from iteration<commit_after>'use strict';

var i              = require('es5-ext/lib/Function/i')
  , d              = require('es5-ext/lib/Object/descriptor')
  , startsWith     = require('es5-ext/lib/String/prototype/starts-with')
  , endsWith       = require('es5-ext/lib/String/prototype/ends-with')
  , Plain          = require('./plain')
  , isNamespace    = require('./is-namespace')
  , nameRe         = require('./name-re')
  , RelSetReadOnly = require('./rel-set-read-only')
  , UniqueIndex    = require('./unique-index')
  , dummyNs        = require('./dummy-ns')

  , isArray = Array.isArray
  , defineProperty = Object.defineProperty
  , defineProperties = Object.defineProperties
  , getOwnPropertyNames = Object.getOwnPropertyNames
  , getPrototypeOf = Object.getPrototypeOf
  , isDigit = RegExp.prototype.test.bind(/\d/)

  , Relation, Item, Constructor, define, signal, history, reverse, refresh
  , addTriggers, removeTriggers;

addTriggers = function (rel) {
	var onadd, onremove;
	if (rel.hasOwnProperty('_triggersSetup_')) return;
	rel.triggers.forEach(onadd = function (name) {
		if (!rel.obj['_' + name]) define(rel.obj, name);
		rel.obj['_' + name].on('update', rel._refresh_)
	});
	rel.triggers.on('add', onadd);
	rel.triggers.on('remove', onremove = function (name) {
		rel.obj['-' + name].off('update', rel._refresh_);
	});
	defineProperty(rel, '_triggersSetup_',
		d({ onadd: onadd, onremove: onremove }));
};

removeTriggers = function (rel) {
	var setup = rel.hasOwnProperty('_triggersSetup_') && rel._triggersSetup_;
	if (!setup) return;
	rel.triggers.forEach(function (name) {
		rel.obj['_' + name].off('update', rel._refresh_)
	});
	rel.triggers.off('add', setup.onadd);
	rel.triggers.off('remove', setup.onremove);
	delete rel._triggersSetup_;
};

refresh = function () {
	var nu = this._value, old = this.__value;
	if ((typeof nu === 'function') && !nu._id_) {
		if (nu.length || !this.triggers.count) {
			this.__value = nu;
			if (this.hasOwnProperty('_triggersSetup_')) removeTriggers(this);
			return;
		} else {
			nu = this.__value = this.ns.normalize(nu.call(this.obj));
			if (!this.hasOwnProperty('_triggersSetup_')) addTriggers(this);
		}
	} else {
		nu = this.__value = (nu == null) ? nu : this.ns.normalize(nu);
		if (this.hasOwnProperty('_triggersSetup_')) removeTriggers(this);
	}
	if (old !== nu) this.emit('update', nu, old);
};

module.exports = Relation = Plain.create(function (obj, name, descriptor) {
	defineProperties(this, {
		obj: d('', obj),
		name: d.gs('', function () { return name; }),
		_id_: d('', obj._id_ + ':' + name),
		_foreign_: d('w', null),
		_descriptor_: d('', descriptor),
		__value: d('w', undefined),
		_refresh_: d(refresh.bind(this))
	});
	this._ns.on('update', this._refresh_);
});

Constructor = function (obj, parent) {
	defineProperties(this, {
		obj: d('', obj),
		_id_: d('', obj._id_ + ':' + this.name),
		_foreign_: d('w', null),
		__value: d('w', this.__value),
		_refresh_: d(refresh.bind(this))
	});
	this._ns.on('update', this._refresh_);
	parent.on('update', this._refresh_);
};

defineProperties(Relation.prototype, {
	_id_: d(''),
	_create_: d(function (obj) {
		var rel;
		// Avoid Object.create for performance reasons
		Constructor.prototype = this;
		rel = new Constructor(obj, this);
		if (!this.hasOwnProperty('_children_')) {
			defineProperty(this, '_children_', d('', []));
		}
		this._children_.push(rel);
		return rel;
	}),
	_onOld_: d(function (value) {
		if (this.unique) this._uniqIndex_.remove(this, value);
		if (value && value._id_ && value.ns) reverse.remove(this, value);
	}),
	_onNew_: d(function (value) {
		if (this.unique) this._uniqIndex_.add(this, value);
		if (value && value._id_ && value.ns) reverse.add(this, value);
	}),
	_setVisibility_: d(function (value) {
		if ((value !== undefined) &&
				(!this.obj.hasOwnProperty(this.name) || this._foreign_)) {
			defineProperty(this.obj, this.name, this._descriptor_);
		} else if (!this._foreign_) {
			delete this.obj[this.name];
		}
		if (this._foreign_) this._foreign_ = null;
	}),
	_forEachObject_: d(function (cb) {
		getOwnPropertyNames(this).forEach(function (name) {
			var value;
			if (startsWith.call(name, '__')) {
				if (name === '__value') return;
				value = this[name];
				if (!value._id_) return;
			} else if (isDigit(name[0]) && this.propertyIsEnumerable(name)) {
				value = this[name];
				if (!value || !value._id_ || !endsWith.call(value._id_, '"')) return;
			} else {
				return;
			}
			cb(value, value._id_, this);
		}, this);
	}),
	value: d.gs(function () {
		var value = this.__value;
		if ((typeof value === 'function') && !value._id_) {
			if (value.length) return value;
			value = value.call(this.obj);
			if (this.multiple) return new RelSetReadOnly(this.ns, value);
			return (value == null) ? null : this.ns.normalize(value);
		}
		if (this.multiple) {
			if (!this.hasOwnProperty('_count_')) this._initSet_();
			return this;
		}
		return value;
	}, function self(value) {
		var error = this.validate(value);
		if (error) throw error;
		this.$setMultiValue(value);
	}),
	$setMultiValue: d(function (value) {
		if (this.hasOwnProperty('_count_')) {
			this._reset_(value);
			return;
		}
		if ((value == null) || ((typeof value === 'function') && !value._id_)) {
			this.$setValue(value);
			signal(this, value);
			return;
		}
		if (isArray(value)) {
			this._initSet_();
			this._reset_(value);
			return;
		}
		value = this.ns.is(value) ? value : this.ns.$construct(value);
		this.$setValue(value);
		signal(this, value);
	}),
	$setValue: d(function (value) {
		var oldValue;

		if (!this.hasOwnProperty('_descriptor_')) this._setVisibility_(value);

		oldValue = this.hasOwnProperty('_value') ? this._value : undefined;
		if (value === undefined) {
			if (this.hasOwnProperty('_value')) {
				delete this._value;
				getPrototypeOf(this).on('update', this._refresh_);
			}
		} else if (!this.hasOwnProperty('_value')) {
			defineProperty(this, '_value', d('cw', value));
			getPrototypeOf(this).off('update', this._refresh_);
		} else {
			this._value = value;
		}

		if ((typeof oldValue === 'function') && !oldValue._id_) oldValue = null;
		if ((typeof value === 'function') && !value._id_) value = null;

		if (oldValue !== value) {
			if (oldValue !== null) this._onOld_(oldValue);
			if (value !== null) this._onNew_(value);
		}
		this._refresh_();
	}),
	find: d(function (value) {
		var obj;
		if (!this.hasOwnProperty('_children_')) return null;
		value = this.ns.normalize(value);
		if (value == null) return null;
		this._children_.some(function self(child) {
			if (child._value === value) {
				obj = child.obj;
				return true;
			}
			if (child.hasOwnProperty('_children_')) {
				return child._children_.some(self);
			}
		});
		return obj || null;
	}),
	_validate_: d(function (original) {
		var key, error, ns = this.ns, value;
		if ((typeof original === 'function') && !original._id_) {
			return new TypeError(original + " is not valid " + ns._id_);
		}
		value = ns.coerce(original);
		if (value == null) {
			return new TypeError(original + " is not valid " + ns._id_);
		}
		if ((error = ns.validate(value))) return error;
		if (!(key = ns._serialize_(value))) {
			return new TypeError(original + " is not valid dbjs value");
		}
		if (this.unique && (error = this._uniqIndex_.validate(this, key, value))) {
			return error;
		}
		return null;
	}),
	_validateValues_: d(function (values) {
		var error, errors;
		values.forEach(function (value) {
			if ((error = this._validate_(value))) {
				if (!errors) errors = [];
				errors.push(error);
			}
		}, this);
		return errors;
	}),
	validate: d(function (value) {
		var error, errors;
		if (this.writeOnce && (this._value != null)) {
			return new TypeError("Property is read-only");
		}
		if (value === undefined) {
			if (this.required && (getPrototypeOf(this)._value == null)) {
				return new TypeError((this.label || this.name) + " is required");
			}
			return null;
		}
		if (value === null) {
			if (this.required) {
				return new TypeError((this.label || this.name) + " is required");
			}
			return null;
		}
		if ((typeof value === 'function') && !value._id_) return null;

		if (isArray(value)) {
			if (!this.multiple) {
				return new TypeError(value + " is not valid " + this.ns._id_);
			}
			if (!value.length) {
				if (!this.required) return null;
				return new TypeError(value + " is not valid " + this.ns._id_);
			}
			if ((errors = this._validateValues_(value))) {
				error = new TypeError(value + " contains invalid values");
				error.errors = errors;
				return error;
			}
			return null;
		}
		return this._validate_(value);
	})
});

define = require('./define-basic');

define(Relation.prototype, 'required', false);
define(Relation.prototype, 'multiple', false);
define(Relation.prototype, 'writeOnce', false);

define(Relation.prototype, 'unique', false);
defineProperties(Relation.prototype.__unique, {
	$setValue: d(function (value) {
		if (value) {
			if (!this.hasOwnProperty('_value')) {
				defineProperty(this.obj, 'unique', this._descriptor_);
			}
			if (this._value) {
				this._value = true;
				return;
			}
			this._value = true;
			defineProperty(this.obj, '_uniqIndex_',
				d('c', new UniqueIndex(this.obj)));
		} else {
			if (!this._value) return;
			delete this._value;
			delete this.obj.unique;
			delete this.obj._uniqIndex_;
			if (this.obj.hasOwnProperty('_children_')) {
				this.obj._children_.forEach(function self(child) {
					if (child.unique) {
						defineProperty(child, '_uniqIndex_',
							d('c', new UniqueIndex(child)));
					} else if (child.hasOwnProperty('_children_')) {
						child._children_.forEach(self);
					}
				});
			}
		}
		this._refresh_();
	}),
	validate: d(function (value) {
		if (!value && this._value && !this.hasOwnProperty('_value')) {
			return new Error("Cannot override unique on extended namespace.");
		}
		return null;
	})
});

define(Relation.prototype, 'reverse', null);
defineProperties(Relation.prototype.__reverse, {
	value: d.gs(function () {
		return this.hasOwnProperty('_value') ? this._value : null;
	}, function self(value) {
		var error;
		value = this._normalize(value);
		if ((error = this.validate(value))) throw error;
		this.$setValue(value);
		signal(this, value);
	}),
	_normalize: d(function (value) {
		if (value === true) {
			value = this.obj.obj.ns._id_;
			value = value[0].toLowerCase() + value.slice(1);
		} else if (value) {
			value = String(value);
		}
		return value;
	}),
	$setValue: d(function (name) {
		if (!name) {
			if (this.hasOwnProperty('_value')) {
				reverse.unset(this.obj, this._value);
				delete this.obj.reverse;
				delete this._value;
			}
			return;
		}
		name = String(name);
		if ((name !== this._value) && this.hasOwnProperty('_value')) {
			reverse.unset(this.obj, this._value);
		}
		reverse.set(this.obj, name);
		if (!this.hasOwnProperty('_value')) {
			defineProperty(this.obj, 'reverse', this._descriptor_);
		}
		this._value = name;
	}),
	validate: d(function (name) {
		if (!name) return null;
		if (name === true) {
			name = this.obj.obj.ns._id_;
			name = name[0].toLowerCase() + name.slice(1);
		} else {
			name = String(name);
		}
		if (name === this._value) return null;
		if (!nameRe.test(name)) return new TypeError(name + " is not a valid name");
		return null;
	})
});

define(Relation.prototype, 'ns', dummyNs);
defineProperties(Relation.prototype.__ns, {
	_normalize: d(i),
	$setValue: d(function (value) {
		var old = this._value, newValue, revName;
		if (value === null) value = Relation.prototype.ns;
		newValue = value;
		if (value === undefined) newValue = getPrototypeOf(this)._value;

		revName = this.obj.hasOwnProperty('reverse') && this.obj.reverse;
		if (revName && (old !== newValue)) reverse.unset(this.obj, revName);

		if (value === undefined) {
			delete this.obj.ns;
			delete this._value;
		} else {
			if (!this.hasOwnProperty('_value')) {
				defineProperty(this.obj, 'ns', this._descriptor_);
			}
			this._value = value;
		}

		if (old !== newValue) {
			if (revName) reverse.set(this.obj, revName);
			if (this.obj.unique) this.obj._uniqIndex_.updateNs(this.obj, old);
		}
		this._refresh_();
	}),
	validate: d(function (value) {
		if (value == null) return null;
		if (!isNamespace(value)) {
			return new TypeError(value + " is not a namespace object");
		}
		return null;
	})
});

require('./rel-set');
Item  = require('./rel-set-item');
reverse = require('./rel-reverse');
signal = require('./signal');
history = signal.history;
<|endoftext|>


<commit_before>'use strict';

const storageManager = require('./../StorageManager'),
      BlobHttpProperties = require('./../model/BlobHttpProperties');

class CreateBlockBlob {
    constructor() {
    }

    process(req, res, container, blob) {
        const httpProps = this._buildHttpProps(req.headers);
        const metaProps = this._buildMetaProps(req.headers);
        storageManager.createBlockBlob(container, blob, req.body, httpProps, metaProps)
            .then((result) => {
                this._addResponseHeaders(res, result)
                res.status(201).send();
            })
            .catch((e) => {
                if (e.code === 'ENOENT') {
                    console.error(`Container ${container} does not exist.`);
                    res.status(404).send();
                } else if (e.code === 'EACCES') {
                    console.error(`Azurite failed to create blob in local file system due to missing permissions.`);
                    res.status(404).send();
                } else if (e.name === 'md5') {
                    console.error(e.message);
                    res.status(400).send(e.message);
                } else {
                    res.status(500).send();
                    throw e;
                }
            })
    }

    _buildHttpProps(httpHeader) {
        return new BlobHttpProperties(
            null, // ETag will be overwritten by most recent value in DB if this is an update of an existing blob
            null,
            // x-ms-* attributes have precedence over according HTTP-Headers
            httpHeader['x-ms-blob-content-type'] || httpHeader['Content-Type'] || 'application/octet-stream',
            httpHeader['x-ms-blob-content-encoding'] || httpHeader['Content-Encoding'] || 'utf8',
            httpHeader['x-ms-blob-content-language'] || httpHeader['Content-Language'],
            httpHeader['x-ms-blob-content-md5'] || httpHeader['Content-MD5'],
            httpHeader['x-ms-blob-cache-control'] || httpHeader['Cache-Control']);
    }

    _buildMetaProps(httpHeader) {
        let metaProps = {};
        Object.keys(httpHeader).forEach((key) => {
            const value = httpHeader[key];
            if (key.indexOf('x-ms-meta-') !== -1) {
                metaProps[key] = value;
            }
        });
        return metaProps;
    }

    _addResponseHeaders(res, props) {
        res.set({
            'ETag': props.ETag,
            'Last-Modified': props.lastModified,
            'x-ms-version': '2011-08-18',
            'x-ms-request-server-encrypted': false,
            'Content-MD5': props.md5
        });
    }
}

module.exports = new CreateBlockBlob();<commit_msg>fixed http props<commit_after>'use strict';

const storageManager = require('./../StorageManager'),
      BlobHttpProperties = require('./../model/BlobHttpProperties');

class CreateBlockBlob {
    constructor() {
    }

    process(req, res, container, blob) {
        const httpProps = this._buildHttpProps(req.headers);
        const metaProps = this._buildMetaProps(req.headers);
        storageManager.createBlockBlob(container, blob, req.body, httpProps, metaProps)
            .then((result) => {
                this._addResponseHeaders(res, result)
                res.status(201).send();
            })
            .catch((e) => {
                if (e.code === 'ENOENT') {
                    console.error(`Container ${container} does not exist.`);
                    res.status(404).send();
                } else if (e.code === 'EACCES') {
                    console.error(`Azurite failed to create blob in local file system due to missing permissions.`);
                    res.status(404).send();
                } else if (e.name === 'md5') {
                    console.error(e.message);
                    res.status(400).send(e.message);
                } else {
                    res.status(500).send();
                    throw e;
                }
            })
    }

    _buildHttpProps(httpHeader) {
        return new BlobHttpProperties(
            null, // ETag will be overwritten by most recent value in DB if this is an update of an existing blob
            null,
            // x-ms-* attributes have precedence over according HTTP-Headers
            httpHeader['x-ms-blob-content-type'] || httpHeader['Content-Type'] || 'application/octet-stream',
            httpHeader['x-ms-blob-content-encoding'] || httpHeader['Content-Encoding'] || 'utf8',
            httpHeader['x-ms-blob-content-language'] || httpHeader['Content-Language'],
            httpHeader['x-ms-blob-content-md5'] || httpHeader['Content-MD5'],
            httpHeader['x-ms-blob-cache-control'] || httpHeader['Cache-Control'],
            true)
    }

    _buildMetaProps(httpHeader) {
        let metaProps = {};
        Object.keys(httpHeader).forEach((key) => {
            const value = httpHeader[key];
            if (key.indexOf('x-ms-meta-') !== -1) {
                metaProps[key] = value;
            }
        });
        return metaProps;
    }

    _addResponseHeaders(res, props) {
        res.set({
            'ETag': props.ETag,
            'Last-Modified': props.lastModified,
            'x-ms-version': '2011-08-18',
            'x-ms-request-server-encrypted': false,
            'Content-MD5': props.md5
        });
    }
}

module.exports = new CreateBlockBlob();<|endoftext|>


<commit_before>function isString(x) {
  return typeof x === 'string';
}

function assertTheUnexpected(expect) {
  function AssertionError(err) {
    Error.call(this, err.message);

    this.stack = err.stack;
  }

  AssertionError.prototype = Object.create(Error.prototype);

  function wrappedExpect() {
    var args = Array.prototype.slice.apply(arguments);
    // convert UnexpectedError to AssertionError
    try {
      expect.apply(expect, args);
    } catch (err) {
      throw new AssertionError(err);
    }
  }

  function checkTruthy(value) {
    wrappedExpect(value, 'to be truthy');
  }

  return Object.assign(function (value) {
    checkTruthy(value);
  }, {
    AssertionError: AssertionError,
    deepEqual: function deepEqual(actual, expected) {
      wrappedExpect(actual, 'to equal', expected);
    },
    deepStrictEqual: function deepStrictEqual(actual, expected) {
      wrappedExpect(actual, 'to equal', expected);
    },
    equal: function equal(actual, expected) {
      var a = !actual;
      var b = !expected;

      // undo the null and undefined evaluate equal
      if (!(a && b)) {
        a = actual;
        b = expected;
      }

      if ((Number(a) || Number(b)) && (isString(a) || isString(b))) {
        a = String(a);
        b = String(b);
      }

      wrappedExpect(a, 'to equal', b);
    },
    ifError: function ifError(value) {
      wrappedExpect(value, 'to be falsy').then(function () {
        throw value;
      });
    },
    notEqual: function notEqual(actual, expected) {
      wrappedExpect(actual, 'not to equal', expected);
    },
    notDeepEqual: function notEqual(actual, expected) {
      wrappedExpect(actual, 'not to equal', expected);
    },
    notStrictEqual: function strictEqual(actual, expected) {
      wrappedExpect(actual, 'not to equal', expected);
    },
    ok: function (value) {
      checkTruthy(value);
    },
    strictEqual: function strictEqual(actual, expected) {
      wrappedExpect(actual, 'to equal', expected);
    },
  });
}

module.exports = assertTheUnexpected(require('unexpected'));
<commit_msg>WIP 2/x check for regex lastIndex equality<commit_after>function isString(x) {
  return typeof x === 'string';
}

function assertTheUnexpected(expect) {
  function AssertionError(err) {
    Error.call(this, err.message);

    this.stack = err.stack;
  }

  AssertionError.prototype = Object.create(Error.prototype);

  function wrappedExpect() {
    var args = Array.prototype.slice.apply(arguments);
    // convert UnexpectedError to AssertionError
    try {
      expect.apply(expect, args);
    } catch (err) {
      throw new AssertionError(err);
    }
  }

  function checkTruthy(value) {
    wrappedExpect(value, 'to be truthy');
  }

  return Object.assign(function (value) {
    checkTruthy(value);
  }, {
    AssertionError: AssertionError,
    deepEqual: function deepEqual(actual, expected) {
      wrappedExpect(actual, 'to equal', expected);

      // handle the lastIndex property
      if (actual instanceof RegExp && actual.hasOwnProperty('lastIndex')) {
        wrappedExpect(actual.lastIndex, 'to equal', expected.lastIndex);
      }
    },
    deepStrictEqual: function deepStrictEqual(actual, expected) {
      wrappedExpect(actual, 'to equal', expected);
    },
    equal: function equal(actual, expected) {
      var a = !actual;
      var b = !expected;

      // undo the null and undefined evaluate equal
      if (!(a && b)) {
        a = actual;
        b = expected;
      }

      if ((Number(a) || Number(b)) && (isString(a) || isString(b))) {
        a = String(a);
        b = String(b);
      }

      wrappedExpect(a, 'to equal', b);
    },
    ifError: function ifError(value) {
      wrappedExpect(value, 'to be falsy').then(function () {
        throw value;
      });
    },
    notEqual: function notEqual(actual, expected) {
      wrappedExpect(actual, 'not to equal', expected);
    },
    notDeepEqual: function notEqual(actual, expected) {
      wrappedExpect(actual, 'not to equal', expected);
    },
    notStrictEqual: function strictEqual(actual, expected) {
      wrappedExpect(actual, 'not to equal', expected);
    },
    ok: function (value) {
      checkTruthy(value);
    },
    strictEqual: function strictEqual(actual, expected) {
      wrappedExpect(actual, 'to equal', expected);
    },
  });
}

module.exports = assertTheUnexpected(require('unexpected'));
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 * Code distributed by Google as part of the polymer project is also
 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 */
// jshint node: true
'use strict';

// useful tool to visualize AST: http://esprima.org/demo/parse.html

/**
 * converts literal: {"type": "Literal", "value": 5,  "raw": "5" }
 * to string
 */
function literalToValue(literal) {
  return literal.value;
}

/**
 * converts unary to string
 * unary: { type: 'UnaryExpression', operator: '-', argument: { ... } }
 */
function unaryToValue(unary) {
  var argValue = expressionToValue(unary.argument);
  if (argValue === undefined)
    return;
  return unary.operator + argValue;
}

/**
 * converts identifier to its value
 * identifier { "type": "Identifier", "name": "Number }
 */
function identifierToValue(identifier) {
  return identifier.name;
}

/**
 * Function is a block statement.
 */
function functionDeclarationToValue(fn) {
  if (fn.body.type == "BlockStatement")
    return blockStatementToValue(fn.body);
}

function functionExpressionToValue(fn) {
  if (fn.body.type == "BlockStatement")
    return blockStatementToValue(fn.body);
}
/**
 * Block statement: find last return statement, and return its value
 */
function blockStatementToValue(block) {
  for (var i=block.body.length - 1; i>= 0; i--) {
    if (block.body[i].type === "ReturnStatement")
      return returnStatementToValue(block.body[i]);
  }
}

/**
 * Evaluates return's argument
 */
function returnStatementToValue(ret) {
  return expressionToValue(ret.argument);
}

/**
 * Enclose containing values in []
 */
function arrayExpressionToValue(arry) {
  var value = '[';
  for (var i=0; i<arry.elements.length; i++) {
    var v = expressionToValue(arry.elements[i]);
    if (v === undefined)
      continue;
    if (i !== 0)
      value += ', ';
    value += v;
  }
  value += ']';
  return value;
}

/**
 * Make it look like an object
 */
function objectExpressionToValue(obj) {
  var value = '{';
  for (var i=0; i<obj.properties.length; i++) {
    var k = expressionToValue(obj.properties[i].key);
    var v = expressionToValue(obj.properties[i].value);
    if (v === undefined)
      continue;
    if (i !== 0)
      value += ', ';
    value += '"' + k + '": ' + v;
  }
  value += '}';
  return value;
}

/**
 * BinaryExpressions are of the form "literal" + "literal"
 */
function binaryExpressionToValue(member) {
  if (member.operator == "+") {
    return expressionToValue(member.left) + expressionToValue(member.right);
  }
  return
}

/**
 * MemberExpression references a variable with name
 */
function memberExpressionToValue(member) {
  return expressionToValue(member.object) + "." + expressionToValue(member.property);
}

/**
 * Tries to get a value from expression. Handles Literal, UnaryExpression
 * returns undefined on failure
 * valueExpression example:
 * { type: "Literal",
 */
function expressionToValue(valueExpression) {
  switch(valueExpression.type) {
    case 'Literal':
      return literalToValue(valueExpression);
    case 'UnaryExpression':
      return unaryToValue(valueExpression);
    case 'Identifier':
      return identifierToValue(valueExpression);
    case 'FunctionDeclaration':
      return functionDeclarationToValue(valueExpression);
    case 'FunctionExpression':
      return functionExpressionToValue(valueExpression);
    case 'ArrayExpression':
      return arrayExpressionToValue(valueExpression);
    case 'ObjectExpression':
      return objectExpressionToValue(valueExpression);
    case 'Identifier':
      return identifierToValue(valueExpression);
    case 'MemberExpression':
      return memberExpressionToValue(valueExpression);
    case 'BinaryExpression':
      return binaryExpressionToValue(valueExpression);
    default:
      console.log(valueExpression)
      return;
  }
}

var CANT_CONVERT = 'UNKNOWN';
module.exports = {
  CANT_CONVERT: CANT_CONVERT,
  expressionToValue: expressionToValue
};
<commit_msg>Update ast-value.js<commit_after>/**
 * @license
 * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 * Code distributed by Google as part of the polymer project is also
 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 */
// jshint node: true
'use strict';

// useful tool to visualize AST: http://esprima.org/demo/parse.html

/**
 * converts literal: {"type": "Literal", "value": 5,  "raw": "5" }
 * to string
 */
function literalToValue(literal) {
  return literal.value;
}

/**
 * converts unary to string
 * unary: { type: 'UnaryExpression', operator: '-', argument: { ... } }
 */
function unaryToValue(unary) {
  var argValue = expressionToValue(unary.argument);
  if (argValue === undefined)
    return;
  return unary.operator + argValue;
}

/**
 * converts identifier to its value
 * identifier { "type": "Identifier", "name": "Number }
 */
function identifierToValue(identifier) {
  return identifier.name;
}

/**
 * Function is a block statement.
 */
function functionDeclarationToValue(fn) {
  if (fn.body.type == "BlockStatement")
    return blockStatementToValue(fn.body);
}

function functionExpressionToValue(fn) {
  if (fn.body.type == "BlockStatement")
    return blockStatementToValue(fn.body);
}
/**
 * Block statement: find last return statement, and return its value
 */
function blockStatementToValue(block) {
  for (var i=block.body.length - 1; i>= 0; i--) {
    if (block.body[i].type === "ReturnStatement")
      return returnStatementToValue(block.body[i]);
  }
}

/**
 * Evaluates return's argument
 */
function returnStatementToValue(ret) {
  return expressionToValue(ret.argument);
}

/**
 * Enclose containing values in []
 */
function arrayExpressionToValue(arry) {
  var value = '[';
  for (var i=0; i<arry.elements.length; i++) {
    var v = expressionToValue(arry.elements[i]);
    if (v === undefined)
      continue;
    if (i !== 0)
      value += ', ';
    value += v;
  }
  value += ']';
  return value;
}

/**
 * Make it look like an object
 */
function objectExpressionToValue(obj) {
  var value = '{';
  for (var i=0; i<obj.properties.length; i++) {
    var k = expressionToValue(obj.properties[i].key);
    var v = expressionToValue(obj.properties[i].value);
    if (v === undefined)
      continue;
    if (i !== 0)
      value += ', ';
    value += '"' + k + '": ' + v;
  }
  value += '}';
  return value;
}

/**
 * BinaryExpressions are of the form "literal" + "literal"
 */
function binaryExpressionToValue(member) {
  if (member.operator == "+") {
    return expressionToValue(member.left) + expressionToValue(member.right);
  }
  return
}

/**
 * MemberExpression references a variable with name
 */
function memberExpressionToValue(member) {
  return expressionToValue(member.object) + "." + expressionToValue(member.property);
}

/**
 * Tries to get a value from expression. Handles Literal, UnaryExpression
 * returns undefined on failure
 * valueExpression example:
 * { type: "Literal",
 */
function expressionToValue(valueExpression) {
  switch(valueExpression.type) {
    case 'Literal':
      return literalToValue(valueExpression);
    case 'UnaryExpression':
      return unaryToValue(valueExpression);
    case 'Identifier':
      return identifierToValue(valueExpression);
    case 'FunctionDeclaration':
      return functionDeclarationToValue(valueExpression);
    case 'FunctionExpression':
      return functionExpressionToValue(valueExpression);
    case 'ArrayExpression':
      return arrayExpressionToValue(valueExpression);
    case 'ObjectExpression':
      return objectExpressionToValue(valueExpression);
    case 'Identifier':
      return identifierToValue(valueExpression);
    case 'MemberExpression':
      return memberExpressionToValue(valueExpression);
    case 'BinaryExpression':
      return binaryExpressionToValue(valueExpression);
    default:
      return;
  }
}

var CANT_CONVERT = 'UNKNOWN';
module.exports = {
  CANT_CONVERT: CANT_CONVERT,
  expressionToValue: expressionToValue
};
<|endoftext|>


<commit_before>function h$mkdir(dir_d, dir_o, mode) {
#ifndef GHCJS_BROWSER
  if(h$isNode) {
    return h$handleErrno(-1, function() {
      h$fs.mkdirSync(h$decodeUtf8z(dir_d, dir_o), mode);
      return 0;
     });
  } else
#endif
    return h$unsupported(-1);
}
<commit_msg>add some new stubs for the unix package<commit_after>function h$mkdir(dir_d, dir_o, mode) {
#ifndef GHCJS_BROWSER
  if(h$isNode) {
    return h$handleErrno(-1, function() {
      h$fs.mkdirSync(h$decodeUtf8z(dir_d, dir_o), mode);
      return 0;
     });
  } else
#endif
    return h$unsupported(-1);
}

// TODO: stub, add real implementation
function h$geteuid() {
  return 1;
}

// TODO: stub, add real implementation
function h$sysconf() {
  return 0;
}

// TODO: stub, add real implementation
function h$getpwuid_r(uid, pwd_d, pwd_o, buf_d, buf_o, buflen, result_d, result_o) {
  var i, name = h$encodeUtf8("user"), max = Math.min(72, pwd_d.len);
  if(!result_d.arr) result_d.arr = [];
  result_d.arr[0] = [pwd_d, pwd_o];
  if(!pwd_d.arr) pwd_d.arr = [];
  // we don't really know where the pointers to strings are supposed to go,
  // so we just point to our dummy string everywhere
  for(i = 0; i < max; i+=4) pwd_d.arr[i+pwd_o] = [name, 0];
  for(i = 0; i < (max>>2); i++) pwd_d.i3[i+(pwd_o>>2)] = 1;
  return 0;
}
<|endoftext|>


<commit_before>'use strict';

const _         = require('lodash');
const async     = require('async');
const path      = require('path');
const mutexify  = require('mutexify');

function Asset(bundler, options) {
  this.__bundler__  = bundler;
  this.__buffer__   = null;
  this.__source__   = null;

  this.resolved     = false;
  this.digest       = null;

  this.virtual      = (options || {}).virtual || false;
  this.logicalPath  = (options || {}).logicalPath || '';
  this.plugins      = (options || {}).plugins || [];
  this.wrapBefore   = (options || {}).wrapBefore || '';
  this.wrapAfter    = (options || {}).wrapAfter || '';

  this.__dependencies__   = {};

  this.lock         = mutexify();
}

Object.defineProperty(Asset.prototype, 'destPath', {
  get: function () {
    return this.logicalPath;
  }
});

Object.defineProperty(Asset.prototype, 'digestPath', {
  get: function () {
    this.__throw_if_not_resolved__();

    const path_obj = path.parse(this.destPath);

    return path.join(path_obj.dir, path_obj.name + '-' + this.digest + path_obj.ext);
  }
});

Object.defineProperty(Asset.prototype, 'buffer', {
  get: function () {
    this.__throw_if_not_resolved__();

    if (this.__buffer__ !== null) {
      return this.__buffer__;
    }

    if (this.__source__ !== null) {
      this.__buffer__ = new Buffer(this.source);
      return this.__buffer__;
    }

    return null;
  },
  set: function (buf) {
    this.__source__ = null;
    this.__buffer__ = buf;
  }
});

Object.defineProperty(Asset.prototype, 'source', {
  get: function () {
    // this.__throw_if_not_resolved__();

    if (this.__source__ !== null) {
      return this.__source__;
    }

    if (this.__buffer__ !== null) {
      this.__source__ = String(this.__buffer__);
      return this.__source__;
    }

    return null;
  },
  set: function (src) {
    this.__buffer__ = null;
    this.__source__ = src;
  }
});

Object.defineProperty(Asset.prototype, 'length', {
  get: function () {
    this.__throw_if_not_resolved__();
    return this.buffer.length;
  }
});

Asset.prototype.__run_plugins__ = function (callback) {
  let context = {
    bundler: this.__bundler__,
    asset: this
  };

  async.eachSeries(this.plugins, (plugin, next) => {
    if (_.isString(plugin)) {
      this.__bundler__.__plugins__[plugin](context, next);
      return;
    }

    plugin(context, next);

  }, (err) => {
    if (err) {
      callback(err);
      return;
    }

    callback();
  });
};

Asset.prototype.__throw_if_not_resolved__ = function () {
  if (!this.resolved) {
    throw new Error('Asset: asset ' + this.logicalPath + ' is not resolved, you should call ".resolve()" first');
  }
};

Asset.prototype.resolve = function (/* callback */) {
  throw new Error('Asset: ".resolve()" not implemented in base class');
};

Asset.prototype.__resolveDependencies__ = function (callback) {
  let assetDeps = _.values(this.__dependencies__).filter(d => d.depType === 'asset');

  async.each(assetDeps, (p, next) => {
    let asset = this.__bundler__.findAsset(p.logicalPath);

    if (!asset) {
      next(new Error(`Broken dependency ${p.logicalPath} in asset ${this.logicalPath}`));
      return;
    }

    asset.resolve(next);
  }, callback);
};

Object.defineProperty(Asset.prototype, 'isFresh', {
  get: function () {
    throw new Error('Asset: ".isFresh()" not implemented in base class');
  }
});

Asset.prototype.dependOnFile = function (filename) {
  const stat = this.__bundler__.stat(filename);

  if (!stat) {
    throw new Error(`Asset: dependency file "${filename}" not found`);
  }

  this.__dependencies__[filename] = {
    depType: 'file',
    path: filename,
    digest: this.__bundler__.getFileDigest(filename)
  };
};

Asset.prototype.__save_cache__ = function (callback) {
  let data = {
    dependencies: this.__dependencies__,
    dependenciesDigest: this.dependenciesDigest,
    isBuffer: !!this.__buffer__
  };

  this.__bundler__.cache.put(this.logicalPath, JSON.stringify(data), (err) => {
    if (err) {
      callback(err);
      return;
    }

    this.__bundler__.cache.put(
      this.logicalPath + ':data',
      data.isBuffer ? this.__buffer__ : this.__source__,
      { valueEncoding: data.isBuffer ? 'binary' : 'utf8' },
      callback
    );
  });
};

Asset.prototype.__restore_cache__ = function (callback) {
  this.__bundler__.cache.get(this.logicalPath, (err, cache_string) => {
    if (err) {
      if (err.type === 'NotFoundError') {
        callback(null, false);
        return;
      }

      callback(err);
      return;
    }

    let cache;

    try {
      cache = JSON.parse(cache_string);
    } catch (__) {
      callback(null, false);
      return;
    }

    let deps_names = _.keys(this.__dependencies__);

    // Check if cache contains all defined dependencies
    if (_.intersection(deps_names, _.keys(cache.dependencies)).length !== deps_names.length) {
      callback(null, false);
      return;
    }

    this.__dependencies__ = cache.dependencies;

    this.__resolveDependencies__((err) => {
      if (err) {
        callback(err);
        return;
      }

      if (this.dependenciesDigest !== cache.dependenciesDigest) {
        callback(null, false);
        return;
      }

      this.__bundler__.cache.get(this.logicalPath + ':data', (err, src_data) => {
        if (err) {
          if (err.type === 'NotFoundError') {
            callback(null, false);
            return;
          }

          callback(err);
          return;
        }

        if (cache.isBuffer) {
          this.__buffer__ = new Buffer(src_data, 'binary');
        } else {
          this.__source__ = src_data;
        }

        this.digest = cache.dependenciesDigest;

        callback(null, true);
      });
    });
  });
};

Asset.prototype.dependOnAsset = function (asset) {
  this.__dependencies__[asset.logicalPath] = {
    depType: 'asset',
    logicalPath: asset.logicalPath
  };
};

Asset.prototype.dependOnFunction = function (helperName) {
  const bundler = this.__bundler__,
        result = bundler.__helpers__[helperName](),
        hash   = bundler.hasher.update(JSON.stringify(result)).digest('hex');

  this.__dependencies__[':function:' + helperName] = {
    depType: 'function',
    functionName: helperName,
    digest: hash
  };
};

Asset.prototype.dependencyDigest = function (depObj) {
  const bundler = this.__bundler__;

  switch (depObj.depType) {
    case 'file':
      return bundler.getFileDigest(depObj.path);

    case 'asset':
      return bundler.findAsset(depObj.logicalPath).digest;

    case 'function':
      let result = bundler.__helpers__[depObj.functionName]();
      return bundler.hasher.update(JSON.stringify(result)).digest('hex');

    default:
      throw new Error(`Asset: unknown dependency type ${depObj.depType}`);
  }
};

Asset.prototype.isDependencyFresh = function (depObj) {
  const bundler = this.__bundler__;

  switch (depObj.depType) {
    case 'file':
      let stat = bundler.stat(depObj.path);

      if (!stat) { return false; }

      return depObj.digest === bundler.getFileDigest(depObj.path);

    case 'asset':
      let asset = bundler.findAsset(depObj.logicalPath);

      if (!asset) { return false; }

      return asset.isFresh;

    case 'function':
      let result = bundler.__helpers__[depObj.functionName]();
      let hash = bundler.hasher.update(JSON.stringify(result)).digest('hex');

      return depObj.hash === hash;

    default:
      throw new Error(`Asset: unknown dependency type ${depObj.depType}`);
  }
};

Object.defineProperty(Asset.prototype, 'dependenciesDigest', {
  get: function () {
    const hasher = this.__bundler__.hasher;

    Object.keys(this.__dependencies__).sort().forEach(depName => {
      hasher.update(this.dependencyDigest(this.__dependencies__[depName]));
    });

    return hasher.digest('hex');
  }
});

Object.defineProperty(Asset.prototype, 'dependencies', {
  get: function () {
    this.__throw_if_not_resolved__();
    return this.__dependencies__;
  }
});

Asset.prototype.sourceMap = function () {
  this.__throw_if_not_resolved__();
  return null;
};

Asset.prototype.mappingUrlComment = function () {
  this.__throw_if_not_resolved__();
  return null;
};

module.exports = Asset;
<commit_msg>bundler: improved leveldb usage<commit_after>'use strict';

const _         = require('lodash');
const async     = require('async');
const path      = require('path');
const mutexify  = require('mutexify');

function Asset(bundler, options) {
  this.__bundler__  = bundler;
  this.__buffer__   = null;
  this.__source__   = null;

  this.resolved     = false;
  this.digest       = null;

  this.virtual      = (options || {}).virtual || false;
  this.logicalPath  = (options || {}).logicalPath || '';
  this.plugins      = (options || {}).plugins || [];
  this.wrapBefore   = (options || {}).wrapBefore || '';
  this.wrapAfter    = (options || {}).wrapAfter || '';

  this.__dependencies__   = {};

  this.lock         = mutexify();
}

Object.defineProperty(Asset.prototype, 'destPath', {
  get: function () {
    return this.logicalPath;
  }
});

Object.defineProperty(Asset.prototype, 'digestPath', {
  get: function () {
    this.__throw_if_not_resolved__();

    const path_obj = path.parse(this.destPath);

    return path.join(path_obj.dir, path_obj.name + '-' + this.digest + path_obj.ext);
  }
});

Object.defineProperty(Asset.prototype, 'buffer', {
  get: function () {
    this.__throw_if_not_resolved__();

    if (this.__buffer__ !== null) {
      return this.__buffer__;
    }

    if (this.__source__ !== null) {
      this.__buffer__ = new Buffer(this.source);
      return this.__buffer__;
    }

    return null;
  },
  set: function (buf) {
    this.__source__ = null;
    this.__buffer__ = buf;
  }
});

Object.defineProperty(Asset.prototype, 'source', {
  get: function () {
    // this.__throw_if_not_resolved__();

    if (this.__source__ !== null) {
      return this.__source__;
    }

    if (this.__buffer__ !== null) {
      this.__source__ = String(this.__buffer__);
      return this.__source__;
    }

    return null;
  },
  set: function (src) {
    this.__buffer__ = null;
    this.__source__ = src;
  }
});

Object.defineProperty(Asset.prototype, 'length', {
  get: function () {
    this.__throw_if_not_resolved__();
    return this.buffer.length;
  }
});

Asset.prototype.__run_plugins__ = function (callback) {
  let context = {
    bundler: this.__bundler__,
    asset: this
  };

  async.eachSeries(this.plugins, (plugin, next) => {
    if (_.isString(plugin)) {
      this.__bundler__.__plugins__[plugin](context, next);
      return;
    }

    plugin(context, next);

  }, (err) => {
    if (err) {
      callback(err);
      return;
    }

    callback();
  });
};

Asset.prototype.__throw_if_not_resolved__ = function () {
  if (!this.resolved) {
    throw new Error('Asset: asset ' + this.logicalPath + ' is not resolved, you should call ".resolve()" first');
  }
};

Asset.prototype.resolve = function (/* callback */) {
  throw new Error('Asset: ".resolve()" not implemented in base class');
};

Asset.prototype.__resolveDependencies__ = function (callback) {
  let assetDeps = _.values(this.__dependencies__).filter(d => d.depType === 'asset');

  async.each(assetDeps, (p, next) => {
    let asset = this.__bundler__.findAsset(p.logicalPath);

    if (!asset) {
      next(new Error(`Broken dependency ${p.logicalPath} in asset ${this.logicalPath}`));
      return;
    }

    asset.resolve(next);
  }, callback);
};

Object.defineProperty(Asset.prototype, 'isFresh', {
  get: function () {
    throw new Error('Asset: ".isFresh()" not implemented in base class');
  }
});

Asset.prototype.dependOnFile = function (filename) {
  const stat = this.__bundler__.stat(filename);

  if (!stat) {
    throw new Error(`Asset: dependency file "${filename}" not found`);
  }

  this.__dependencies__[filename] = {
    depType: 'file',
    path: filename,
    digest: this.__bundler__.getFileDigest(filename)
  };
};

Asset.prototype.__save_cache__ = function (callback) {
  let data = {
    dependencies: this.__dependencies__,
    dependenciesDigest: this.dependenciesDigest,
    buffer: this.__buffer__,
    source: this.__source__
  };

  this.__bundler__.cache.put(this.logicalPath, data, { valueEncoding: 'json' }, callback);
};

Asset.prototype.__restore_cache__ = function (callback) {
  this.__bundler__.cache.get(this.logicalPath, { valueEncoding: 'json' }, (err, cache) => {
    if (err) {
      if (err.type === 'NotFoundError') {
        callback(null, false);
        return;
      }

      callback(err);
      return;
    }

    let deps_names = _.keys(this.__dependencies__);

    // Check if cache contains all defined dependencies
    if (_.intersection(deps_names, _.keys(cache.dependencies)).length !== deps_names.length) {
      callback(null, false);
      return;
    }

    this.__dependencies__ = cache.dependencies;

    this.__resolveDependencies__((err) => {
      if (err) {
        callback(err);
        return;
      }

      if (this.dependenciesDigest !== cache.dependenciesDigest) {
        callback(null, false);
        return;
      }

      if (cache.buffer) {
        this.__buffer__ = new Buffer(cache.buffer);
      } else {
        this.__source__ = cache.source;
      }

      this.digest = cache.dependenciesDigest;

      callback(null, true);
    });
  });
};

Asset.prototype.dependOnAsset = function (asset) {
  this.__dependencies__[asset.logicalPath] = {
    depType: 'asset',
    logicalPath: asset.logicalPath
  };
};

Asset.prototype.dependOnFunction = function (helperName) {
  const bundler = this.__bundler__,
        result = bundler.__helpers__[helperName](),
        hash   = bundler.hasher.update(JSON.stringify(result)).digest('hex');

  this.__dependencies__[':function:' + helperName] = {
    depType: 'function',
    functionName: helperName,
    digest: hash
  };
};

Asset.prototype.dependencyDigest = function (depObj) {
  const bundler = this.__bundler__;

  switch (depObj.depType) {
    case 'file':
      return bundler.getFileDigest(depObj.path);

    case 'asset':
      return bundler.findAsset(depObj.logicalPath).digest;

    case 'function':
      let result = bundler.__helpers__[depObj.functionName]();
      return bundler.hasher.update(JSON.stringify(result)).digest('hex');

    default:
      throw new Error(`Asset: unknown dependency type ${depObj.depType}`);
  }
};

Asset.prototype.isDependencyFresh = function (depObj) {
  const bundler = this.__bundler__;

  switch (depObj.depType) {
    case 'file':
      let stat = bundler.stat(depObj.path);

      if (!stat) { return false; }

      return depObj.digest === bundler.getFileDigest(depObj.path);

    case 'asset':
      let asset = bundler.findAsset(depObj.logicalPath);

      if (!asset) { return false; }

      return asset.isFresh;

    case 'function':
      let result = bundler.__helpers__[depObj.functionName]();
      let hash = bundler.hasher.update(JSON.stringify(result)).digest('hex');

      return depObj.hash === hash;

    default:
      throw new Error(`Asset: unknown dependency type ${depObj.depType}`);
  }
};

Object.defineProperty(Asset.prototype, 'dependenciesDigest', {
  get: function () {
    const hasher = this.__bundler__.hasher;

    Object.keys(this.__dependencies__).sort().forEach(depName => {
      hasher.update(this.dependencyDigest(this.__dependencies__[depName]));
    });

    return hasher.digest('hex');
  }
});

Object.defineProperty(Asset.prototype, 'dependencies', {
  get: function () {
    this.__throw_if_not_resolved__();
    return this.__dependencies__;
  }
});

Asset.prototype.sourceMap = function () {
  this.__throw_if_not_resolved__();
  return null;
};

Asset.prototype.mappingUrlComment = function () {
  this.__throw_if_not_resolved__();
  return null;
};

module.exports = Asset;
<|endoftext|>


<commit_before>/* jshint browser: true, jquery: true */
/* global Panel:false, console:false, server:false, addWidget:false */

var PanelManager = function(options) {
  this.panels = [];
  this.columns = 1;
  this.panelsIndex = [];
  this.server = null;
  this.addMode = false;
  this.dragAndDrop = null;
};

PanelManager.prototype.getByName = function(name) {
  var panel = null;

  for(var i = 0; i < this.panels.length; i++) {
    if(this.panels[i].name === name) {
      panel = this.panels[i];
      break;
    }
  }

  return panel;
};

PanelManager.prototype.getById = function(id) {
  var panel = null;

  var idx = this.panelsIndex.indexOf(id);

  if(idx > -1) {
    panel = this.panels[idx];
  }

  return panel;
};

PanelManager.prototype.add = function(panel) {
  this._sendAdd(panel);
};

PanelManager.prototype.update = function(panel) {
  this._sendUpdate(panel);
};

PanelManager.prototype.processMessages = function(server, id, content) {
  var processed = false;

  switch (id) {
    case Panel.MESSAGE_PANELS:
      this._receivedContent(server, content);
      processed = true;
      break;

    case Panel.MESSAGE_ADD_PANEL:
      this._receivedAdd(server, new Panel(content));
      processed = true;
      break;

    case Panel.MESSAGE_DELETE_PANEL:
      this._receivedDelete(server, content);
      processed = true;
      break;

    case Panel.MESSAGE_UPDATE_PANEL:
      this._receivedUpdate(server, new Panel(content));
      processed = true;
      break;

    case Panel.MESSAGE_MOVE_PANEL:
      this._receivedMove(server, content);
      processed = true;
      break;

    case Panel.MESSAGE_MOVE_PANEL_UP:
      this._receivedMoveUp(server, content);
      processed = true;
      break;

    case Panel.MESSAGE_MOVE_PANEL_DOWN:
      this._receivedMoveDown(server, content);
      processed = true;
      break;

    case Panel.MESSAGE_MOVE_PANEL_LEFT:
      this._receivedMoveLeft(server, content);
      processed = true;
      break;

    case Panel.MESSAGE_MOVE_PANEL_RIGHT:
      this._receivedMoveRight(server, content);
      processed = true;
      break;
  }

  return processed;
};

PanelManager.prototype._addDefaultWidgets = function(panel, dataSourceType) {
  var i;
  var dataSourceId = '';
  var widgets = [];

  for(i = 0; i < dataSourceManager.dataSources.length; i++) {
    if(dataSourceManager.dataSources[i].type === dataSourceType) {
      dataSourceId = dataSourceManager.dataSources[i].id;
      break;
    }
  }

  widgets = DataSource.getDefaultPanels(dataSourceType, panel.id, dataSourceId, panel.defaultDataElement);

  for(i = 0; i < widgets.length; i++) {
    widgetManager.addWidget(widgets[i]);
  }
};

PanelManager.prototype._receivedAdd = function(server, panel) {
  this._addToDom(panel, this.addMode);

  switch(panel.style) {
    case Panel.STYLE_AGILE:
      this._addDefaultWidgets(panel, DataSource.TYPE_VERSION_ONE);
      break;

    case Panel.STYLE_CI:
      this._addDefaultWidgets(panel, DataSource.TYPE_JENKINS);
      break;
  }

  this.dragAndDrop.apply();

  if(this.addMode) {
    this.dragAndDrop.enable();
  }
  displayStatusMessage("The panel has been added", "Panels");
};

PanelManager.prototype._receivedDelete = function(server, id) {
  this._deleteFromDom(id);
  displayStatusMessage("The panel has been removed", "Panels");
};

PanelManager.prototype._receivedMove = function(server, content) {
  this._moveOnDom(content);
  displayStatusMessage("The panel move has been recorded", "Panels");
};

PanelManager.prototype._receivedMoveUp = function(server, id) {
  this._moveUpOnDom(id);
};

PanelManager.prototype._receivedMoveDown = function(server, id) {
  this._moveDownOnDom(id);
};

PanelManager.prototype._receivedMoveLeft = function(server, panel) {
  this._changeColumnOnDom(panel);
};

PanelManager.prototype._receivedMoveRight = function(server, panel) {
  this._changeColumnOnDom(panel);
};

PanelManager.prototype._receivedUpdate = function(server, panel) {
  // get current data
  var currentPanelElement = $('#panel' + panel.id);

  var currentPanel = new Panel(currentPanelElement.data());

  // apply changes to DOM
  if(currentPanel.name !== panel.name) {
    $('#panelName' + panel.id).text(panel.name);
    currentPanelElement.data('name', panel.name);
  }

// ignore this for now, presume that only via move left/right that this can happen
//  if(currentPanel.column !== panel.column) {
//
//  }

  if(currentPanel.iconName !== panel.iconName) {
    $('#panelIcon' + panel.id).removeClass(currentPanel.iconName).addClass(panel.iconName);
    currentPanelElement.data('icon-name', panel.iconName);
  }
};

PanelManager.prototype.preferencesChanged = function(systemPreferences) {
  var column;

  if(this.columns === systemPreferences.columns) {
    return;
  }

  if(this.columns > systemPreferences.columns) {
    this._removeColumnsOnDom(this.columns, systemPreferences.columns);
  } else {
    this._updateColumnsOnDom(this.columns, systemPreferences.columns);

    this.dragAndDrop.apply();
  }

  this.columns = systemPreferences.columns;
};

PanelManager.prototype._receivedContent = function(server, d) {
  var panelsArray = [];
  var item;
  var column;

  // remove content from home pane
  $("#panelsPane").empty();

  // add columns as defined in preferences
  this.columns = preferenceManager.getSystemPreference().columns;

  for (column = 1; column <= this.columns; column++) {
    this._addColumnToDom(column, this.columns);
  }

  for (item in d) {
   panelsArray.push(new Panel(d[item]));
  }

  panelsArray.sort(function (a, b) {
      if (a.row  b.row) {
          return 1;
      }
      return 0;
  });

  panelsArray.forEach(function (p) {
    this._addToDom(p, this.addMode);
  }.bind(this));

  this.dragAndDrop.apply();
};

PanelManager.prototype._addColumnToDom = function(column, columns) {
  var columnClass = this._getColumnClass(columns);

  $("#panelsPane").append('

');
};

PanelManager.prototype._updateColumnsOnDom = function(oldColumnCount, newColumnCount) {
  var column = 0;
  var oldColumnClass = this._getColumnClass(oldColumnCount);
  var newColumnClass = this._getColumnClass(newColumnCount);

  var selection = $("#panelsPane ." + oldColumnClass);
  selection.removeClass(oldColumnClass);
  selection.addClass(newColumnClass);

  for(column = oldColumnCount + 1; column <= newColumnCount; column++) {
    $("#panelsPane").append('

');
  }
};

PanelManager.prototype._removeColumnsOnDom = function(oldColumnCount, newColumnCount) {
  for(column = oldColumnCount; column > newColumnCount; column--) {
    $("#column" + column).remove();
  }

  var oldColumnClass = this._getColumnClass(oldColumnCount);
  var newColumnClass = this._getColumnClass(newColumnCount);

  var selection = $("#panelsPane ." + oldColumnClass);
  selection.removeClass(oldColumnClass);
  selection.addClass(newColumnClass);
};

PanelManager.prototype._getColumnClass = function(columns) {
  var columnClass;

  switch(columns) {
    case 1:
      columnClass = "col-md-12";
      break;

    case 2:
      columnClass = "col-md-6";
      break;

    case 3:
      columnClass = "col-md-4";
      break;

    case 4:
      columnClass = "col-md-3";
      break;

    default:
      columnClass = "col-md-12";
  }

  return columnClass;
};

PanelManager.prototype._sendAdd = function(panel) {
  this.server.sendMessage(Panel.MESSAGE_ADD_PANEL, panel);
};

PanelManager.prototype._sendDelete = function(id) {
  this.server.sendMessage(Panel.MESSAGE_DELETE_PANEL, id);
};

PanelManager.prototype._sendUpdate = function(panel) {
  this.server.sendMessage(Panel.MESSAGE_UPDATE_PANEL, panel);
};

PanelManager.prototype.sendMove = function(panelId, sourceColumn, targetColumn, row) {
  this.server.sendMessage(Panel.MESSAGE_MOVE_PANEL, {
    id: panelId,
    sourceColumn: sourceColumn,
    targetColumn: targetColumn,
    row: row
  });
};

PanelManager.prototype._addToDom = function(panel, buttonsVisible) {
  var displayButtonClass = buttonsVisible ? "displayButton" : "";
  var displayStyle = buttonsVisible ? "block" : "none";

  console.log("adding panel: " + panel.column + " : " + this.columns);
  var panelClass = "panel";

  if(this.columns === 1) {
    panelClass += " panel-left panel-left";
  } else if(panel.column === 1) {
    panelClass += " panel-left";
  } else if(panel.column === this.columns) {
    panelClass += " panel-right";
  }

  //$("#columnContainer" + panel.column).append(
  $("#column" + panel.column).append(
    '
' +
    '
' +
    '
' +
    '        <button id="panelBtnAddWidget' + panel.id + '" type="button" class="config-buttons btn btn-default btn-sml ' + displayButtonClass + '" style="display: ' + displayStyle + ';">' +
    '          ' +
    '        </button>' +
    '        <button id="panelBtnDelete' + panel.id + '" type="button" class="config-buttons btn btn-default btn-sml ' + displayButtonClass + '" style="display: ' + displayStyle + ';">' +
    '          ' +
    '        </button>' +
    '        <button id="panelBtnModify' + panel.id + '" type="button" class="config-buttons btn btn-default btn-sml ' + displayButtonClass + '" style="display: ' + displayStyle + ';">' +
    '          ' +
    '        </button>' +
    '
' +
    '     ' + panel.name + '' +
    '
' +
    '
' +
    '
' +
    '
'
  );

  $('#panel' + panel.id).hide().fadeIn('slow');

  $('#panelBtnAddWidget' + panel.id).on('click', function() {
    viewWidgetWizard('add', {}, panel.id);
  }.bind(this));

  $('#panelBtnDelete' + panel.id).on('click', function() {
    this._sendDelete(panel.id);
  }.bind(this));

  $('#panelBtnModify' + panel.id).on('click', function() {
    displayPanelDialog('update', panel);
  }.bind(this));
};

PanelManager.prototype._deleteFromDom = function(id) {
  $('#panel' + id)
    .animate({height: 0, padding: 0, margin: 0}, {easing: "linear", duration: "slow", queue: false})
    .fadeOut('slow', function() {
    this.remove();
  });
};

PanelManager.prototype._moveOnDom = function(content) {
  // TODO: only update if a timer expires before update panel response is received
  // this is due to flickering if we cancel the drag event and wait for backend to confirm

//  content.panelId
//  content.sourceColumn
//  content.targetColumn
//  var row = content.row;
//
//  if(row > 0) {
//    // determine appropriate entry
//    var rows = $("#" + "column" + content.targetColumn + ">div" + ".panel");
//
//    if(content.sourceColumn !== content.targetColumn) {
//      // we want the panel before the drop point, for different row this requires adjustment
//      row--;
//    }
//
//    // add after the correct position
//    $('#panel' + content.id).insertAfter("#" + rows[row].id);
//  } else {
//    $('#panel' + content.id).prependTo("#" + "column" + content.targetColumn);
//  }
};

PanelManager.prototype._moveDownOnDom = function(id) {
  var panelList = this._getList(id);

  if(panelList['panel' + id].position < (Object.keys(panelList).length - 1)) {
    // move down
    this._swapVertically(panelList['panel' + id].id, panelList['panel' + id].nextId);
  }
};

PanelManager.prototype._moveUpOnDom = function(id) {
  var panelList = this._getList(id);

  if(panelList['panel' + id].position > 0) {
    // move up
    this._swapVertically(panelList['panel' + id].id, panelList['panel' + id].prevId);
  }
};

PanelManager.prototype._changeColumnOnDom = function(panelData) {
  var panel = $('#panel' + panelData.id);

  $('#panel' + panelData.id)
    .animate({height: 0, padding: 0, margin: 0}, {easing: "linear", duration: "fast", queue: false})
    .fadeOut('fast', function() {
      panel
        .appendTo("#columnContainer" + panelData.column)
        .hide()
        .css('height', '')
        .css('padding', '')
        .css('margin', '')
        .fadeIn('fast');

  });
};

PanelManager.prototype._getList = function(id) {
  var prevPanel = null;
  var nextPanel = null;
  var counter = 0;
  var panelList = {};

  $('#panel' + id).parent().children().each(function() {
    panelList[$(this).attr('id')] = {
      id: $(this).attr('id'),
      position: counter++,
      value: this,
      prevId: null,
      nextId: null
    };

    if(prevPanel !== null) {
      panelList[$(this).attr('id')].prevId = prevPanel.id;
      prevPanel.nextId = $(this).attr('id');
    }

    prevPanel = panelList[$(this).attr('id')];
  });

  return panelList;
};

PanelManager.prototype._swapVertically = function(a, b){
    a = $('#' + a)[0];
    b = $('#' + b)[0];

    var t = a.parentNode.insertBefore(document.createTextNode(''), a);

    b.parentNode.insertBefore(a, b);
    t.parentNode.insertBefore(b, t);
    t.parentNode.removeChild(t);
};

<commit_msg>Removed debug<commit_after>/* jshint browser: true, jquery: true */
/* global Panel:false, console:false, server:false, addWidget:false */

var PanelManager = function(options) {
  this.panels = [];
  this.columns = 1;
  this.panelsIndex = [];
  this.server = null;
  this.addMode = false;
  this.dragAndDrop = null;
};

PanelManager.prototype.getByName = function(name) {
  var panel = null;

  for(var i = 0; i < this.panels.length; i++) {
    if(this.panels[i].name === name) {
      panel = this.panels[i];
      break;
    }
  }

  return panel;
};

PanelManager.prototype.getById = function(id) {
  var panel = null;

  var idx = this.panelsIndex.indexOf(id);

  if(idx > -1) {
    panel = this.panels[idx];
  }

  return panel;
};

PanelManager.prototype.add = function(panel) {
  this._sendAdd(panel);
};

PanelManager.prototype.update = function(panel) {
  this._sendUpdate(panel);
};

PanelManager.prototype.processMessages = function(server, id, content) {
  var processed = false;

  switch (id) {
    case Panel.MESSAGE_PANELS:
      this._receivedContent(server, content);
      processed = true;
      break;

    case Panel.MESSAGE_ADD_PANEL:
      this._receivedAdd(server, new Panel(content));
      processed = true;
      break;

    case Panel.MESSAGE_DELETE_PANEL:
      this._receivedDelete(server, content);
      processed = true;
      break;

    case Panel.MESSAGE_UPDATE_PANEL:
      this._receivedUpdate(server, new Panel(content));
      processed = true;
      break;

    case Panel.MESSAGE_MOVE_PANEL:
      this._receivedMove(server, content);
      processed = true;
      break;

    case Panel.MESSAGE_MOVE_PANEL_UP:
      this._receivedMoveUp(server, content);
      processed = true;
      break;

    case Panel.MESSAGE_MOVE_PANEL_DOWN:
      this._receivedMoveDown(server, content);
      processed = true;
      break;

    case Panel.MESSAGE_MOVE_PANEL_LEFT:
      this._receivedMoveLeft(server, content);
      processed = true;
      break;

    case Panel.MESSAGE_MOVE_PANEL_RIGHT:
      this._receivedMoveRight(server, content);
      processed = true;
      break;
  }

  return processed;
};

PanelManager.prototype._addDefaultWidgets = function(panel, dataSourceType) {
  var i;
  var dataSourceId = '';
  var widgets = [];

  for(i = 0; i < dataSourceManager.dataSources.length; i++) {
    if(dataSourceManager.dataSources[i].type === dataSourceType) {
      dataSourceId = dataSourceManager.dataSources[i].id;
      break;
    }
  }

  widgets = DataSource.getDefaultPanels(dataSourceType, panel.id, dataSourceId, panel.defaultDataElement);

  for(i = 0; i < widgets.length; i++) {
    widgetManager.addWidget(widgets[i]);
  }
};

PanelManager.prototype._receivedAdd = function(server, panel) {
  this._addToDom(panel, this.addMode);

  switch(panel.style) {
    case Panel.STYLE_AGILE:
      this._addDefaultWidgets(panel, DataSource.TYPE_VERSION_ONE);
      break;

    case Panel.STYLE_CI:
      this._addDefaultWidgets(panel, DataSource.TYPE_JENKINS);
      break;
  }

  this.dragAndDrop.apply();

  if(this.addMode) {
    this.dragAndDrop.enable();
  }
  displayStatusMessage("The panel has been added", "Panels");
};

PanelManager.prototype._receivedDelete = function(server, id) {
  this._deleteFromDom(id);
  displayStatusMessage("The panel has been removed", "Panels");
};

PanelManager.prototype._receivedMove = function(server, content) {
  this._moveOnDom(content);
  displayStatusMessage("The panel move has been recorded", "Panels");
};

PanelManager.prototype._receivedMoveUp = function(server, id) {
  this._moveUpOnDom(id);
};

PanelManager.prototype._receivedMoveDown = function(server, id) {
  this._moveDownOnDom(id);
};

PanelManager.prototype._receivedMoveLeft = function(server, panel) {
  this._changeColumnOnDom(panel);
};

PanelManager.prototype._receivedMoveRight = function(server, panel) {
  this._changeColumnOnDom(panel);
};

PanelManager.prototype._receivedUpdate = function(server, panel) {
  // get current data
  var currentPanelElement = $('#panel' + panel.id);

  var currentPanel = new Panel(currentPanelElement.data());

  // apply changes to DOM
  if(currentPanel.name !== panel.name) {
    $('#panelName' + panel.id).text(panel.name);
    currentPanelElement.data('name', panel.name);
  }

// ignore this for now, presume that only via move left/right that this can happen
//  if(currentPanel.column !== panel.column) {
//
//  }

  if(currentPanel.iconName !== panel.iconName) {
    $('#panelIcon' + panel.id).removeClass(currentPanel.iconName).addClass(panel.iconName);
    currentPanelElement.data('icon-name', panel.iconName);
  }
};

PanelManager.prototype.preferencesChanged = function(systemPreferences) {
  var column;

  if(this.columns === systemPreferences.columns) {
    return;
  }

  if(this.columns > systemPreferences.columns) {
    this._removeColumnsOnDom(this.columns, systemPreferences.columns);
  } else {
    this._updateColumnsOnDom(this.columns, systemPreferences.columns);

    this.dragAndDrop.apply();
  }

  this.columns = systemPreferences.columns;
};

PanelManager.prototype._receivedContent = function(server, d) {
  var panelsArray = [];
  var item;
  var column;

  // remove content from home pane
  $("#panelsPane").empty();

  // add columns as defined in preferences
  this.columns = preferenceManager.getSystemPreference().columns;

  for (column = 1; column <= this.columns; column++) {
    this._addColumnToDom(column, this.columns);
  }

  for (item in d) {
   panelsArray.push(new Panel(d[item]));
  }

  panelsArray.sort(function (a, b) {
      if (a.row  b.row) {
          return 1;
      }
      return 0;
  });

  panelsArray.forEach(function (p) {
    this._addToDom(p, this.addMode);
  }.bind(this));

  this.dragAndDrop.apply();
};

PanelManager.prototype._addColumnToDom = function(column, columns) {
  var columnClass = this._getColumnClass(columns);

  $("#panelsPane").append('

');
};

PanelManager.prototype._updateColumnsOnDom = function(oldColumnCount, newColumnCount) {
  var column = 0;
  var oldColumnClass = this._getColumnClass(oldColumnCount);
  var newColumnClass = this._getColumnClass(newColumnCount);

  var selection = $("#panelsPane ." + oldColumnClass);
  selection.removeClass(oldColumnClass);
  selection.addClass(newColumnClass);

  for(column = oldColumnCount + 1; column <= newColumnCount; column++) {
    $("#panelsPane").append('

');
  }
};

PanelManager.prototype._removeColumnsOnDom = function(oldColumnCount, newColumnCount) {
  for(column = oldColumnCount; column > newColumnCount; column--) {
    $("#column" + column).remove();
  }

  var oldColumnClass = this._getColumnClass(oldColumnCount);
  var newColumnClass = this._getColumnClass(newColumnCount);

  var selection = $("#panelsPane ." + oldColumnClass);
  selection.removeClass(oldColumnClass);
  selection.addClass(newColumnClass);
};

PanelManager.prototype._getColumnClass = function(columns) {
  var columnClass;

  switch(columns) {
    case 1:
      columnClass = "col-md-12";
      break;

    case 2:
      columnClass = "col-md-6";
      break;

    case 3:
      columnClass = "col-md-4";
      break;

    case 4:
      columnClass = "col-md-3";
      break;

    default:
      columnClass = "col-md-12";
  }

  return columnClass;
};

PanelManager.prototype._sendAdd = function(panel) {
  this.server.sendMessage(Panel.MESSAGE_ADD_PANEL, panel);
};

PanelManager.prototype._sendDelete = function(id) {
  this.server.sendMessage(Panel.MESSAGE_DELETE_PANEL, id);
};

PanelManager.prototype._sendUpdate = function(panel) {
  this.server.sendMessage(Panel.MESSAGE_UPDATE_PANEL, panel);
};

PanelManager.prototype.sendMove = function(panelId, sourceColumn, targetColumn, row) {
  this.server.sendMessage(Panel.MESSAGE_MOVE_PANEL, {
    id: panelId,
    sourceColumn: sourceColumn,
    targetColumn: targetColumn,
    row: row
  });
};

PanelManager.prototype._addToDom = function(panel, buttonsVisible) {
  var displayButtonClass = buttonsVisible ? "displayButton" : "";
  var displayStyle = buttonsVisible ? "block" : "none";
  var panelClass = "panel";

  if(this.columns === 1) {
    panelClass += " panel-left panel-left";
  } else if(panel.column === 1) {
    panelClass += " panel-left";
  } else if(panel.column === this.columns) {
    panelClass += " panel-right";
  }

  //$("#columnContainer" + panel.column).append(
  $("#column" + panel.column).append(
    '
' +
    '
' +
    '
' +
    '        <button id="panelBtnAddWidget' + panel.id + '" type="button" class="config-buttons btn btn-default btn-sml ' + displayButtonClass + '" style="display: ' + displayStyle + ';">' +
    '          ' +
    '        </button>' +
    '        <button id="panelBtnDelete' + panel.id + '" type="button" class="config-buttons btn btn-default btn-sml ' + displayButtonClass + '" style="display: ' + displayStyle + ';">' +
    '          ' +
    '        </button>' +
    '        <button id="panelBtnModify' + panel.id + '" type="button" class="config-buttons btn btn-default btn-sml ' + displayButtonClass + '" style="display: ' + displayStyle + ';">' +
    '          ' +
    '        </button>' +
    '
' +
    '     ' + panel.name + '' +
    '
' +
    '
' +
    '
' +
    '
'
  );

  $('#panel' + panel.id).hide().fadeIn('slow');

  $('#panelBtnAddWidget' + panel.id).on('click', function() {
    viewWidgetWizard('add', {}, panel.id);
  }.bind(this));

  $('#panelBtnDelete' + panel.id).on('click', function() {
    this._sendDelete(panel.id);
  }.bind(this));

  $('#panelBtnModify' + panel.id).on('click', function() {
    displayPanelDialog('update', panel);
  }.bind(this));
};

PanelManager.prototype._deleteFromDom = function(id) {
  $('#panel' + id)
    .animate({height: 0, padding: 0, margin: 0}, {easing: "linear", duration: "slow", queue: false})
    .fadeOut('slow', function() {
    this.remove();
  });
};

PanelManager.prototype._moveOnDom = function(content) {
  // TODO: only update if a timer expires before update panel response is received
  // this is due to flickering if we cancel the drag event and wait for backend to confirm

//  content.panelId
//  content.sourceColumn
//  content.targetColumn
//  var row = content.row;
//
//  if(row > 0) {
//    // determine appropriate entry
//    var rows = $("#" + "column" + content.targetColumn + ">div" + ".panel");
//
//    if(content.sourceColumn !== content.targetColumn) {
//      // we want the panel before the drop point, for different row this requires adjustment
//      row--;
//    }
//
//    // add after the correct position
//    $('#panel' + content.id).insertAfter("#" + rows[row].id);
//  } else {
//    $('#panel' + content.id).prependTo("#" + "column" + content.targetColumn);
//  }
};

PanelManager.prototype._moveDownOnDom = function(id) {
  var panelList = this._getList(id);

  if(panelList['panel' + id].position < (Object.keys(panelList).length - 1)) {
    // move down
    this._swapVertically(panelList['panel' + id].id, panelList['panel' + id].nextId);
  }
};

PanelManager.prototype._moveUpOnDom = function(id) {
  var panelList = this._getList(id);

  if(panelList['panel' + id].position > 0) {
    // move up
    this._swapVertically(panelList['panel' + id].id, panelList['panel' + id].prevId);
  }
};

PanelManager.prototype._changeColumnOnDom = function(panelData) {
  var panel = $('#panel' + panelData.id);

  $('#panel' + panelData.id)
    .animate({height: 0, padding: 0, margin: 0}, {easing: "linear", duration: "fast", queue: false})
    .fadeOut('fast', function() {
      panel
        .appendTo("#columnContainer" + panelData.column)
        .hide()
        .css('height', '')
        .css('padding', '')
        .css('margin', '')
        .fadeIn('fast');

  });
};

PanelManager.prototype._getList = function(id) {
  var prevPanel = null;
  var nextPanel = null;
  var counter = 0;
  var panelList = {};

  $('#panel' + id).parent().children().each(function() {
    panelList[$(this).attr('id')] = {
      id: $(this).attr('id'),
      position: counter++,
      value: this,
      prevId: null,
      nextId: null
    };

    if(prevPanel !== null) {
      panelList[$(this).attr('id')].prevId = prevPanel.id;
      prevPanel.nextId = $(this).attr('id');
    }

    prevPanel = panelList[$(this).attr('id')];
  });

  return panelList;
};

PanelManager.prototype._swapVertically = function(a, b){
    a = $('#' + a)[0];
    b = $('#' + b)[0];

    var t = a.parentNode.insertBefore(document.createTextNode(''), a);

    b.parentNode.insertBefore(a, b);
    t.parentNode.insertBefore(b, t);
    t.parentNode.removeChild(t);
};

<|endoftext|>


<commit_before>const assert = require('assert')

const Device = require('../model/device')

class Devstore {
    constructor(keystore, shepherd){
        this._shepherd = shepherd
        this._keystore = keystore
        this._list = []
        this._db = {}
        this._nwkMap = {}
    }

    async refresh(){
        const devices = await Device.all(this._keystore, this._shepherd)
        for(const d of devices){
            this._db[d.addr] = d
            for(const n of d.altNwk){
                const e = this._nwkMap[n]
                if(e && e.nwkAddr === n) continue
                this._nwkMap[n] = d
            }
            this._nwkMap[d.nwkAddr] = d
        }
        this._list = Object.values(devices)
    }

    find(addr){
        // addr: ieeeAddr(String) or nwkAddr(Number)
        assert(typeof addr === 'string' || typeof addr === 'number', 'addr should be a number or a string.')

        if(typeof addr === 'string'){
            return this._db[addr]
        }

        return this._nwkMap[addr]
    }
    all(){
        return this._list
    }
}
module.exports = Devstore<commit_msg>devstore fixes<commit_after>const assert = require('assert')

const Device = require('../model/device')

class Devstore {
    constructor(keystore, shepherd){
        this._shepherd = shepherd
        this._keystore = keystore
        this._list = []
        this._db = {}
        this._nwkMap = {}
    }

    async refresh(){
        const devices = await Device.all(this._keystore, this._shepherd)
        for(const d of devices){
            if(d.ieeeAddr) this._db[d.ieeeAddr] = d
            for(const n of d.altNwk){
                const e = this._nwkMap[n]
                if(e && e.nwkAddr === n) continue
                this._nwkMap[n] = d
            }
            if(!d.nwkAddr !== undefined) this._nwkMap[d.nwkAddr] = d
        }
        this._list = Object.values(devices)
    }

    find(addr){
        // addr: ieeeAddr(String) or nwkAddr(Number)
        assert(typeof addr === 'string' || typeof addr === 'number', 'addr should be a number or a string.')

        if(typeof addr === 'string'){
            return this._db[addr]
        }

        return this._nwkMap[addr]
    }
    all(){
        return this._list
    }
}
module.exports = Devstore<|endoftext|>


<commit_before>// Dependencies
var Fs = require("fs")
  , Ul = require("ul")
  , Repo = require("gry")
  , Calendar = require("./calendar")
  , Path = require("path")
  , Archiver = require('archiver');
  ;

/**
 *  Contributions.getRepo (options, callback)
 *  Generates a repository that will be compressend and its download link wil
 *  be send via callback
 *
 *  Arguments
 *    @options: object containing:
 *      - coordinates: an array of points. E.g.:
 *         [
 *             {x: 1, y: 2}
 *           , {x: 4, y: 1}
 *           ...
 *         ]
 *
 */
var GenerateRepository = module.exports = function (options, done, progress) {

    // Defaults
    done = done || function () {};
    progress = progress || function () {};

    // Coordinates
    if (!options.coordinates) {
        return done(new Error("Missing the coordinates."));
    }

    // Validate coordinates
    if (options.coordinates.constructor !== Array) {
        return done(new Error("Invalid coordinates field value. It must be an array."));
    }

    // Merge defaults
    options = Ul.merge({
        "time": {
            "hour": 10
        }
    }, options);

    // Append date things to the options
    Calendar(options);

    // generate the repository path
    var repoId = Math.random().toString(36).substring(3)
      , publicDir = Path.resolve(__dirname + "/../public/repos")
      , repoPath = publicDir + "/" + repoId
      , numberOfCommits = options.coordinates.length * options.commitsPerDay
      , readmeFilePath = repoPath + "/README.md"
      , completedCommits = 0
      , repo = new Repo(repoPath)
      ;

    /**
     * dummyCommit
     * Creates a dummy commit.
     *
     * @name dummyCommit
     * @function
     * @param {String} message The commit message.
     * @param {Function} callback The callback function.
     * @return {undefined}
     */
    function dummyCommit(message, date, callback) {
        var options = date ? "--date " + date : "";
        Fs.writeFile(readmeFilePath, Math.random().toString(), function (err) {
            if (err) { return callback(err); }
            repo.add(function (err) {
                if (err) { return callback(err); }
                repo.commit(message, options, callback);
            });
        });
    }

    /**
     * initialCommit
     * Creates the repository and the initial commit.
     *
     * @name initialCommit
     * @function
     * @param {Function} callback The callback function.
     * @return {undefined}
     */
    function initialCommit(callback) {
        repo.create(function (err) {
            if (err) { return callback(err); }
            dummyCommit("Initial commit", "", callback);
        });
    }

    /*!
     * lastCommit
     * Creates the last commit.
     *
     * @name lastCommit
     * @function
     * @return {undefined}
     */
    function lastCommit() {
        Fs.writeFile(readmeFilePath,
            "My GitHub Contributions Calendar"
          + "================================"
          + "This repository was generated with [GitHub Contributions](https://github.com/IonicaBizau/github-contributions) generator. Thanks, [@IonicaBizau](https://github.com/IonicaBizau)."
        , function (err) {
            if (err) { return done(err); }
            repo.add(function (err) {
                if (err) { return done(err); }
                repo.commit("Added the title and description (/cc. @IonicaBizau)", function (err) {
                    if (err) { return done(err); }
                    var output = Fs.createWriteStream(repoPath + ".zip")
                      , archive = Archiver("zip")
                      , zipErr = null
                      ;

                    output.on("close", function () {
                        done(zipErr, repoId);
                    });

                    archive.on("error", function(err){
                        zipErr = err;
                    });

                    archive.pipe(output);
                    archive.directory(repoPath);

                    //archive.bulk([
                    //    { expand: true, src: ["*", ".git/**/*"], cwd: , dest: repoId }
                    //]);

                    archive.finalize();
                });
            });
        });
    }

    initialCommit(function (err) {
        if (err) { return done(err); }
        var cDate = null
          ;

        function nextDay(id) {
            cDate = options.dates[id];
            if (!cDate) {
                return lastCommit();
            }

            function commitSeq(i) {

                if (i >= options.commitsPerDay) {
                    return nextDay(id + 1);
                }

                dummyCommit("Dummy", cDate + i * 60, function (err) {
                    if (err) { return done(err); }
                    progress(++completedCommits * 100 / numberOfCommits);
                    commitSeq(i + 1);
                });
            }

            commitSeq(0);
        }

        nextDay(0);
    });
};
<commit_msg>New lines, create the source directory in the zip file.<commit_after>// Dependencies
var Fs = require("fs")
  , Ul = require("ul")
  , Repo = require("gry")
  , Calendar = require("./calendar")
  , Path = require("path")
  , Archiver = require('archiver');
  ;

/**
 *  Contributions.getRepo (options, callback)
 *  Generates a repository that will be compressend and its download link wil
 *  be send via callback
 *
 *  Arguments
 *    @options: object containing:
 *      - coordinates: an array of points. E.g.:
 *         [
 *             {x: 1, y: 2}
 *           , {x: 4, y: 1}
 *           ...
 *         ]
 *
 */
var GenerateRepository = module.exports = function (options, done, progress) {

    // Defaults
    done = done || function () {};
    progress = progress || function () {};

    // Coordinates
    if (!options.coordinates) {
        return done(new Error("Missing the coordinates."));
    }

    // Validate coordinates
    if (options.coordinates.constructor !== Array) {
        return done(new Error("Invalid coordinates field value. It must be an array."));
    }

    // Merge defaults
    options = Ul.merge({
        "time": {
            "hour": 10
        }
    }, options);

    // Append date things to the options
    Calendar(options);

    // generate the repository path
    var repoId = Math.random().toString(36).substring(3)
      , publicDir = Path.resolve(__dirname + "/../public/repos")
      , repoPath = publicDir + "/" + repoId
      , numberOfCommits = options.coordinates.length * options.commitsPerDay
      , readmeFilePath = repoPath + "/README.md"
      , completedCommits = 0
      , repo = new Repo(repoPath)
      ;

    /**
     * dummyCommit
     * Creates a dummy commit.
     *
     * @name dummyCommit
     * @function
     * @param {String} message The commit message.
     * @param {Function} callback The callback function.
     * @return {undefined}
     */
    function dummyCommit(message, date, callback) {
        var options = date ? "--date " + date : "";
        Fs.writeFile(readmeFilePath, Math.random().toString(), function (err) {
            if (err) { return callback(err); }
            repo.add(function (err) {
                if (err) { return callback(err); }
                repo.commit(message, options, callback);
            });
        });
    }

    /**
     * initialCommit
     * Creates the repository and the initial commit.
     *
     * @name initialCommit
     * @function
     * @param {Function} callback The callback function.
     * @return {undefined}
     */
    function initialCommit(callback) {
        repo.create(function (err) {
            if (err) { return callback(err); }
            dummyCommit("Initial commit", "", callback);
        });
    }

    /*!
     * lastCommit
     * Creates the last commit.
     *
     * @name lastCommit
     * @function
     * @return {undefined}
     */
    function lastCommit() {
        Fs.writeFile(readmeFilePath,
            "My GitHub Contributions Calendar"
          + "\n================================"
          + "\nThis repository was generated with [GitHub Contributions](https://github.com/IonicaBizau/github-contributions) generator. Thanks, [@IonicaBizau](https://github.com/IonicaBizau)."
        , function (err) {
            if (err) { return done(err); }
            repo.add(function (err) {
                if (err) { return done(err); }
                repo.commit("Added the title and description (/cc. @IonicaBizau)", function (err) {
                    if (err) { return done(err); }
                    var output = Fs.createWriteStream(repoPath + ".zip")
                      , archive = Archiver("zip")
                      , zipErr = null
                      ;

                    output.on("close", function () {
                        done(zipErr, repoId);
                    });

                    archive.on("error", function(err){
                        zipErr = err;
                    });

                    archive.pipe(output);
                    archive.directory(repoPath, "source");
                    archive.finalize();
                });
            });
        });
    }

    initialCommit(function (err) {
        if (err) { return done(err); }
        var cDate = null
          ;

        function nextDay(id) {
            cDate = options.dates[id];
            if (!cDate) {
                return lastCommit();
            }

            function commitSeq(i) {

                if (i >= options.commitsPerDay) {
                    return nextDay(id + 1);
                }

                dummyCommit("Dummy", cDate + i * 60, function (err) {
                    if (err) { return done(err); }
                    progress(++completedCommits * 100 / numberOfCommits);
                    commitSeq(i + 1);
                });
            }

            commitSeq(0);
        }

        nextDay(0);
    });
};
<|endoftext|>