code: function merge(object, options, ...sources) {
  
  	/* iterate through all provided sources */
  	for(const source of sources) {
  
  		/* retrieve the property names defined on object */
  		const propNames = Object.getOwnPropertyNames(source);
  
  		/* recursively merge properties */
  		for(const name of propNames) {
  			const value = source[name];
  
  			/* skip undefined values */
  			if(options && options.skipUndefined && value === undefined) {
  				continue;
  			}
  
  			/* skip if both values equals */
  			if(value === object[name]) {
  				continue;
  			}
  
  			/* merge based on options */
  			if(value && typeof value === "object") {
  				if(options && options.arrayConcat && Array.isArray(object[name]) && Array.isArray(value)) {
  					object[name] = object[name].concat(value);
  					if(options && options.arrayUnique) {
  						object[name] = Array.from(new Set(object[name]));
  					}
  				} else if(Array.isArray(value)) {
  					object[name] = options && options.overwrite || object[name] === undefined ? value : object[name];
  				} else {
  					object[name] = merge(object[name] || {}, options, value);
  				}
  			} else {
  				object[name] = options && options.overwrite || object[name] === undefined ? value : object[name];
  			}
  
  		}
  
  	}
  
  	/* return merged object */
  	return object;
  }
docs: /*  object deep merge function