| 'use strict'; | 
|   | 
| const Reach = require('./reach'); | 
|   | 
|   | 
| const internals = {}; | 
|   | 
|   | 
| exports.keys = function (obj, options = {}) { | 
|   | 
|     return options.symbols !== false ? Reflect.ownKeys(obj) : Object.getOwnPropertyNames(obj);  // Defaults to true | 
| }; | 
|   | 
|   | 
| exports.store = function (source, keys) { | 
|   | 
|     const storage = new Map(); | 
|     for (let i = 0; i < keys.length; ++i) { | 
|         const key = keys[i]; | 
|         const value = Reach(source, key); | 
|         if (typeof value === 'object' || | 
|             typeof value === 'function') { | 
|   | 
|             storage.set(key, value); | 
|             internals.reachSet(source, key, undefined); | 
|         } | 
|     } | 
|   | 
|     return storage; | 
| }; | 
|   | 
|   | 
| exports.restore = function (copy, source, storage) { | 
|   | 
|     for (const [key, value] of storage) { | 
|         internals.reachSet(copy, key, value); | 
|         internals.reachSet(source, key, value); | 
|     } | 
| }; | 
|   | 
|   | 
| internals.reachSet = function (obj, key, value) { | 
|   | 
|     const path = Array.isArray(key) ? key : key.split('.'); | 
|     let ref = obj; | 
|     for (let i = 0; i < path.length; ++i) { | 
|         const segment = path[i]; | 
|         if (i + 1 === path.length) { | 
|             ref[segment] = value; | 
|         } | 
|   | 
|         ref = ref[segment]; | 
|     } | 
| }; |