'use strict' module.exports = rfdc function rfdc (opts) { opts = opts || {} if (opts.circles) return rfdcCircles(opts) return opts.proto ? cloneProto : clone function cloneArray (a, fn) { var keys = Object.keys(a) var a2 = new Array(keys.length) for (var i = 0; i < keys.length; i++) { var k = keys[i] var cur = a[k] if (typeof cur !== 'object' || cur === null) { a2[k] = cur } else if (cur instanceof Date) { a2[k] = new Date(cur) } else { a2[k] = fn(cur) } } return a2 } function clone (o) { if (typeof o !== 'object' || o === null) return o if (o instanceof Date) return new Date(o) if (Array.isArray(o)) return cloneArray(o, clone) var o2 = {} for (var k in o) { if (Object.hasOwnProperty.call(o, k) === false) continue var cur = o[k] if (typeof cur !== 'object' || cur === null) { o2[k] = cur } else if (cur instanceof Date) { o2[k] = new Date(cur) } else { o2[k] = clone(cur) } } return o2 } function cloneProto (o) { if (typeof o !== 'object' || o === null) return o if (o instanceof Date) return new Date(o) if (Array.isArray(o)) return cloneArray(o, cloneProto) var o2 = {} for (var k in o) { var cur = o[k] if (typeof cur !== 'object' || cur === null) { o2[k] = cur } else if (cur instanceof Date) { o2[k] = new Date(cur) } else { o2[k] = cloneProto(cur) } } return o2 } } function rfdcCircles (opts) { var refs = [] var refsNew = [] return opts.proto ? cloneProto : clone function cloneArray (a, fn) { var keys = Object.keys(a) var a2 = new Array(keys.length) for (var i = 0; i < keys.length; i++) { var k = keys[i] var cur = a[k] if (typeof cur !== 'object' || cur === null) { a2[k] = cur } else if (cur instanceof Date) { a2[k] = new Date(cur) } else { var index = refs.indexOf(cur) if (index !== -1) { a2[k] = refsNew[index] } else { a2[k] = fn(cur) } } } return a2 } function clone (o) { if (typeof o !== 'object' || o === null) return o if (o instanceof Date) return new Date(o) if (Array.isArray(o)) return cloneArray(o, clone) var o2 = {} refs.push(o) refsNew.push(o2) for (var k in o) { if (Object.hasOwnProperty.call(o, k) === false) continue var cur = o[k] if (typeof cur !== 'object' || cur === null) { o2[k] = cur } else if (cur instanceof Date) { o2[k] = new Date(cur) } else { var i = refs.indexOf(cur) if (i !== -1) { o2[k] = refsNew[i] } else { o2[k] = clone(cur) } } } refs.pop() refsNew.pop() return o2 } function cloneProto (o) { if (typeof o !== 'object' || o === null) return o if (o instanceof Date) return new Date(o) if (Array.isArray(o)) return cloneArray(o, cloneProto) var o2 = {} refs.push(o) refsNew.push(o2) for (var k in o) { var cur = o[k] if (typeof cur !== 'object' || cur === null) { o2[k] = cur } else if (cur instanceof Date) { o2[k] = new Date(cur) } else { var i = refs.indexOf(cur) if (i !== -1) { o2[k] = refsNew[i] } else { o2[k] = cloneProto(cur) } } } refs.pop() refsNew.pop() return o2 } }