| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 | 
							- 'use strict';
 
- const Assert = require('./assert');
 
- const Clone = require('./clone');
 
- const Merge = require('./merge');
 
- const Utils = require('./utils');
 
- const internals = {};
 
- module.exports = function (defaults, source, options = {}) {
 
-     Assert(defaults && typeof defaults === 'object', 'Invalid defaults value: must be an object');
 
-     Assert(!source || source === true || typeof source === 'object', 'Invalid source value: must be true, falsy or an object');
 
-     Assert(typeof options === 'object', 'Invalid options: must be an object');
 
-     if (!source) {                                                  // If no source, return null
 
-         return null;
 
-     }
 
-     if (options.shallow) {
 
-         return internals.applyToDefaultsWithShallow(defaults, source, options);
 
-     }
 
-     const copy = Clone(defaults);
 
-     if (source === true) {                                          // If source is set to true, use defaults
 
-         return copy;
 
-     }
 
-     const nullOverride = options.nullOverride !== undefined ? options.nullOverride : false;
 
-     return Merge(copy, source, { nullOverride, mergeArrays: false });
 
- };
 
- internals.applyToDefaultsWithShallow = function (defaults, source, options) {
 
-     const keys = options.shallow;
 
-     Assert(Array.isArray(keys), 'Invalid keys');
 
-     options = Object.assign({}, options);
 
-     options.shallow = false;
 
-     const copy = Clone(defaults, { shallow: keys });
 
-     if (source === true) {                                                      // If source is set to true, use defaults
 
-         return copy;
 
-     }
 
-     const storage = Utils.store(source, keys);                              // Move shallow copy items to storage
 
-     Merge(copy, source, { mergeArrays: false, nullOverride: false });   // Deep copy the rest
 
-     Utils.restore(copy, source, storage);                                   // Shallow copy the stored items and restore
 
-     return copy;
 
- };
 
 
  |