[
  {
    "path": ".eslintrc",
    "content": "{\n\t\"root\": true,\n\n\t\"extends\": \"@ljharb\",\n\n\t\"rules\": {\n\t\t\"eqeqeq\": [2, \"allow-null\"],\n\t\t\"func-name-matching\": [2, \"always\"],\n\t\t\"max-depth\": [1, 4],\n\t\t\"no-magic-numbers\": [2, {\n\t\t\t\"ignore\": [0, 1, 2],\n\t\t}],\n\t\t\"no-restricted-syntax\": [2, \"BreakStatement\", \"ContinueStatement\", \"DebuggerStatement\", \"LabeledStatement\", \"WithStatement\"],\n\t\t\"sort-keys\": [0],\n\t},\n\n\t\"overrides\": [\n\t\t{\n\t\t\t\"files\": \"test/**\",\n\t\t\t\"rules\": {\n\t\t\t\t\"max-lines-per-function\": 0,\n\t\t\t\t\"no-magic-numbers\": 0,\n\t\t\t},\n\t\t},\n\t],\n}\n"
  },
  {
    "path": ".github/SECURITY.md",
    "content": "# Security\n\nPlease email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report.\n"
  },
  {
    "path": ".github/workflows/node-aught.yml",
    "content": "name: 'Tests: node.js < 10'\n\non: [pull_request, push]\n\njobs:\n  tests:\n    uses: ljharb/actions/.github/workflows/node.yml@main\n    with:\n      range: '< 10'\n      type: minors\n      command: npm run tests-only\n\n  node:\n    name: 'node < 10'\n    needs: [tests]\n    runs-on: ubuntu-latest\n    steps:\n      - run: 'echo tests completed'\n"
  },
  {
    "path": ".github/workflows/node-pretest.yml",
    "content": "name: 'Tests: pretest/posttest'\n\non: [pull_request, push]\n\njobs:\n  tests:\n    uses: ljharb/actions/.github/workflows/pretest.yml@main\n"
  },
  {
    "path": ".github/workflows/node-tens.yml",
    "content": "name: 'Tests: node.js >= 10'\n\non: [pull_request, push]\n\njobs:\n  tests:\n    uses: ljharb/actions/.github/workflows/node.yml@main\n    with:\n      range: '>= 10'\n      type: minors\n      command: npm run tests-only\n\n  node:\n    name: 'node >= 10'\n    needs: [tests]\n    runs-on: ubuntu-latest\n    steps:\n      - run: 'echo tests completed'\n"
  },
  {
    "path": ".github/workflows/rebase.yml",
    "content": "name: Automatic Rebase\n\non: [pull_request_target]\n\njobs:\n  _:\n    name: \"Automatic Rebase\"\n\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v2\n      - uses: ljharb/rebase@master\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/require-allow-edits.yml",
    "content": "name: Require “Allow Edits”\n\non: [pull_request_target]\n\njobs:\n  _:\n    name: \"Require “Allow Edits”\"\n\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: ljharb/require-allow-edits@main\n"
  },
  {
    "path": ".gitignore",
    "content": "# gitignore\nnode_modules\n\n# Only apps should have lockfiles\nnpm-shrinkwrap.json\npackage-lock.json\nyarn.lock\n\n.nyc_output/\ncoverage/\n"
  },
  {
    "path": ".npmignore",
    "content": "# gitignore\nnode_modules\n\n# Only apps should have lockfiles\nnpm-shrinkwrap.json\npackage-lock.json\nyarn.lock\n\n.nyc_output/\ncoverage/\n\n.github/workflows\n"
  },
  {
    "path": ".npmrc",
    "content": "package-lock=false\n"
  },
  {
    "path": ".nycrc",
    "content": "{\n\t\"all\": true,\n\t\"check-coverage\": false,\n\t\"reporter\": [\"text-summary\", \"text\", \"html\", \"json\"],\n\t\"lines\": 86,\n\t\"statements\": 85.93,\n\t\"functions\": 82.43,\n\t\"branches\": 76.06,\n\t\"exclude\": [\n\t\t\"coverage\",\n\t\t\"dist\"\n\t]\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "3.0.2 / 2018-07-19\n==================\n  * [Fix] Prevent merging `__proto__` property (#48)\n  * [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape`\n  * [Tests] up to `node` `v10.7`, `v9.11`, `v8.11`, `v7.10`, `v6.14`, `v4.9`; use `nvm install-latest-npm`\n\n3.0.1 / 2017-04-27\n==================\n  * [Fix] deep extending should work with a non-object (#46)\n  * [Dev Deps] update `tape`, `eslint`, `@ljharb/eslint-config`\n  * [Tests] up to `node` `v7.9`, `v6.10`, `v4.8`; improve matrix\n  * [Docs] Switch from vb.teelaun.ch to versionbadg.es for the npm version badge SVG.\n  * [Docs] Add example to readme (#34)\n\n3.0.0 / 2015-07-01\n==================\n  * [Possible breaking change] Use global \"strict\" directive (#32)\n  * [Tests] `int` is an ES3 reserved word\n  * [Tests] Test up to `io.js` `v2.3`\n  * [Tests] Add `npm run eslint`\n  * [Dev Deps] Update `covert`, `jscs`\n\n2.0.2 / 2018-07-19\n==================\n  * [Fix] Prevent merging `__proto__` property (#48)\n  * [Fix] deep extending should work with a non-object (#46)\n  * [Docs] Switch from vb.teelaun.ch to versionbadg.es for the npm version badge SVG.\n  * [Docs] Add example to readme (#34)\n  * [Dev Deps] update `tape`, `eslint`, `@ljharb/eslint-config`, `covert`, `jscs`\n  * [Tests] up to `node` `v10.7`, `v9.11`, `v8.11`, `v7.10`, `v6.14`, `v4.9`; `io.js` `v2.3`; use `nvm install-latest-npm`\n  * [Tests] Add `npm run eslint`\n  * [Tests] `int` is an ES3 reserved word\n\n2.0.1 / 2015-04-25\n==================\n  * Use an inline `isArray` check, for ES3 browsers. (#27)\n  * Some old browsers fail when an identifier is `toString`\n  * Test latest `node` and `io.js` versions on `travis-ci`; speed up builds\n  * Add license info to package.json (#25)\n  * Update `tape`, `jscs`\n  * Adding a CHANGELOG\n\n2.0.0 / 2014-10-01\n==================\n  * Increase code coverage to 100%; run code coverage as part of tests\n  * Add `npm run lint`; Run linter as part of tests\n  * Remove nodeType and setInterval checks in isPlainObject\n  * Updating `tape`, `jscs`, `covert`\n  * General style and README cleanup\n\n1.3.0 / 2014-06-20\n==================\n  * Add component.json for browser support (#18)\n  * Use SVG for badges in README (#16)\n  * Updating `tape`, `covert`\n  * Updating travis-ci to work with multiple node versions\n  * Fix `deep === false` bug (returning target as {}) (#14)\n  * Fixing constructor checks in isPlainObject\n  * Adding additional test coverage\n  * Adding `npm run coverage`\n  * Add LICENSE (#13)\n  * Adding a warning about `false`, per #11\n  * General style and whitespace cleanup\n\n1.2.1 / 2013-09-14\n==================\n  * Fixing hasOwnProperty bugs that would only have shown up in specific browsers. Fixes #8\n  * Updating `tape`\n\n1.2.0 / 2013-09-02\n==================\n  * Updating the README: add badges\n  * Adding a missing variable reference.\n  * Using `tape` instead of `buster` for tests; add more tests (#7)\n  * Adding node 0.10 to Travis CI (#6)\n  * Enabling \"npm test\" and cleaning up package.json (#5)\n  * Add Travis CI.\n\n1.1.3 / 2012-12-06\n==================\n  * Added unit tests.\n  * Ensure extend function is named. (Looks nicer in a stack trace.)\n  * README cleanup.\n\n1.1.1 / 2012-11-07\n==================\n  * README cleanup.\n  * Added installation instructions.\n  * Added a missing semicolon\n\n1.0.0 / 2012-04-08\n==================\n  * Initial commit\n\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Stefan Thomas\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n"
  },
  {
    "path": "README.md",
    "content": "# extend() for Node.js <sup>[![Version Badge][npm-version-svg]][npm-url]</sup>\n\n[![github actions][actions-image]][actions-url]\n[![coverage][codecov-image]][codecov-url]\n[![License][license-image]][license-url]\n[![Downloads][downloads-image]][downloads-url]\n\n[![npm badge][npm-badge-png]][npm-url]\n\n`node-extend` is a port of the classic extend() method from jQuery. It behaves as you expect. It is simple, tried and true.\n\nNotes:\n\n* Since Node.js >= 4,\n  [`Object.assign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)\n  now offers the same functionality natively (but without the \"deep copy\" option).\n  See [ECMAScript 2015 (ES6) in Node.js](https://nodejs.org/en/docs/es6).\n* Some native implementations of `Object.assign` in both Node.js and many\n  browsers (since NPM modules are for the browser too) may not be fully\n  spec-compliant.\n  Check [`object.assign`](https://www.npmjs.com/package/object.assign) module for\n  a compliant candidate.\n\n## Installation\n\nThis package is available on [npm][npm-url] as: `extend`\n\n``` sh\nnpm install extend\n```\n\n## Usage\n\n**Syntax:** extend **(** [`deep`], `target`, `object1`, [`objectN`] **)**\n\n*Extend one object with one or more others, returning the modified object.*\n\n**Example:**\n\n``` js\nvar extend = require('extend');\nextend(targetObject, object1, object2);\n```\n\nKeep in mind that the target object will be modified, and will be returned from extend().\n\nIf a boolean true is specified as the first argument, extend performs a deep copy, recursively copying any objects it finds. Otherwise, the copy will share structure with the original object(s).\nUndefined properties are not copied. However, properties inherited from the object's prototype will be copied over.\nWarning: passing `false` as the first argument is not supported.\n\n### Arguments\n\n* `deep` *Boolean* (optional)\nIf set, the merge becomes recursive (i.e. deep copy).\n* `target`\t*Object*\nThe object to extend.\n* `object1`\t*Object*\nThe object that will be merged into the first.\n* `objectN` *Object* (Optional)\nMore objects to merge into the first.\n\n## License\n\n`node-extend` is licensed under the [MIT License][mit-license-url].\n\n## Acknowledgements\n\nAll credit to the jQuery authors for perfecting this amazing utility.\n\nPorted to Node.js by [Stefan Thomas][github-justmoon] with contributions by [Jonathan Buchanan][github-insin] and [Jordan Harband][github-ljharb].\n\n[npm-url]: https://npmjs.org/package/extend\n[npm-version-svg]: https://versionbadg.es/justmoon/node-extend.svg\n[npm-badge-png]: https://nodei.co/npm/extend.png?downloads=true&stars=true\n[license-image]: https://img.shields.io/npm/l/extend.svg\n[license-url]: LICENSE\n[downloads-image]: https://img.shields.io/npm/dm/extend.svg\n[downloads-url]: https://npm-stat.com/charts.html?package=extend\n[codecov-image]: https://codecov.io/gh/justmoon/node-extend/branch/main/graphs/badge.svg\n[codecov-url]: https://app.codecov.io/gh/justmoon/node-extend/\n[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/justmoon/node-extend\n[actions-url]: https://github.com/justmoon/node-extend/actions\n[github-justmoon]: https://github.com/justmoon\n[github-insin]: https://github.com/insin\n[github-ljharb]: https://github.com/ljharb\n[mit-license-url]: http://opensource.org/licenses/MIT\n"
  },
  {
    "path": "component.json",
    "content": "{\n\t\"name\": \"extend\",\n\t\"author\": \"Stefan Thomas <justmoon@members.fsf.org> (http://www.justmoon.net)\",\n\t\"version\": \"3.0.2\",\n\t\"description\": \"Port of jQuery.extend for node.js and the browser.\",\n\t\"scripts\": [\n\t\t\"index.js\"\n\t],\n\t\"contributors\": [\n\t\t{\n\t\t\t\"name\": \"Jordan Harband\",\n\t\t\t\"url\": \"https://github.com/ljharb\"\n\t\t}\n\t],\n\t\"keywords\": [\n\t\t\"extend\",\n\t\t\"clone\",\n\t\t\"merge\"\n\t],\n\t\"repository\" : {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"https://github.com/justmoon/node-extend.git\"\n\t},\n\t\"dependencies\": {\n\t},\n\t\"devDependencies\": {\n\t\t\"@ljharb/eslint-config\": \"^20.1.0\",\n\t\t\"aud\": \"^1.1.5\",\n\t\t\"eslint\": \"^8.6.0\",\n\t\t\"nyc\": \"^10.3.2\",\n\t\t\"safe-publish-latest\": \"^2.0.0\",\n\t\t\"tape\": \"^4.14.0\"\n\t}\n}\n\n"
  },
  {
    "path": "index.js",
    "content": "'use strict';\n\nvar hasOwn = Object.prototype.hasOwnProperty;\nvar toStr = Object.prototype.toString;\nvar defineProperty = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nvar isArray = function isArray(arr) {\n\tif (typeof Array.isArray === 'function') {\n\t\treturn Array.isArray(arr);\n\t}\n\n\treturn toStr.call(arr) === '[object Array]';\n};\n\nvar isPlainObject = function isPlainObject(obj) {\n\tif (!obj || toStr.call(obj) !== '[object Object]') {\n\t\treturn false;\n\t}\n\n\tvar hasOwnConstructor = hasOwn.call(obj, 'constructor');\n\tvar hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');\n\t// Not own constructor property must be Object\n\tif (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {\n\t\treturn false;\n\t}\n\n\t// Own properties are enumerated firstly, so to speed up, if last one is own, then all properties are own.\n\tvar key;\n\tfor (key in obj) { /**/ }\n\n\treturn typeof key === 'undefined' || hasOwn.call(obj, key);\n};\n\n// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target\nvar setProperty = function setProperty(target, options) {\n\tif (defineProperty && options.name === '__proto__') {\n\t\tdefineProperty(target, options.name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\t\t\tvalue: options.newValue,\n\t\t\twritable: true\n\t\t});\n\t} else {\n\t\t// eslint-disable-next-line no-param-reassign\n\t\ttarget[options.name] = options.newValue;\n\t}\n};\n\n// Return undefined instead of __proto__ if '__proto__' is not an own property\nvar getProperty = function getProperty(obj, name) {\n\tif (name === '__proto__') {\n\t\tif (!hasOwn.call(obj, name)) {\n\t\t\treturn void 0;\n\t\t} else if (gOPD) {\n\t\t\t// In early versions of node, obj['__proto__'] is buggy when obj has __proto__ as an own property. Object.getOwnPropertyDescriptor() works.\n\t\t\treturn gOPD(obj, name).value;\n\t\t}\n\t}\n\n\treturn obj[name];\n};\n\nmodule.exports = function extend() {\n\tvar options, name, src, copy, copyIsArray, clone;\n\tvar target = arguments[0];\n\tvar i = 1;\n\tvar length = arguments.length;\n\tvar deep = false;\n\n\t// Handle a deep copy situation\n\tif (typeof target === 'boolean') {\n\t\tdeep = target;\n\t\ttarget = arguments[1] || {};\n\t\t// skip the boolean and the target\n\t\ti = 2;\n\t}\n\tif (target == null || (typeof target !== 'object' && typeof target !== 'function')) {\n\t\ttarget = {};\n\t}\n\n\tfor (; i < length; ++i) {\n\t\toptions = arguments[i];\n\t\t// Only deal with non-null/undefined values\n\t\tif (options != null) {\n\t\t\t// Extend the base object\n\t\t\tfor (name in options) {\n\t\t\t\tsrc = getProperty(target, name);\n\t\t\t\tcopy = getProperty(options, name);\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif (target !== copy) {\n\t\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\t\tif (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {\n\t\t\t\t\t\tif (copyIsArray) {\n\t\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\t\tclone = src && isArray(src) ? src : [];\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tclone = src && isPlainObject(src) ? src : {};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\t\tsetProperty(target, { name: name, newValue: extend(deep, clone, copy) });\n\n\t\t\t\t\t// Don't bring in undefined values\n\t\t\t\t\t} else if (typeof copy !== 'undefined') {\n\t\t\t\t\t\tsetProperty(target, { name: name, newValue: copy });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n\t\"name\": \"extend\",\n\t\"author\": \"Stefan Thomas <justmoon@members.fsf.org> (http://www.justmoon.net)\",\n\t\"version\": \"3.0.2\",\n\t\"description\": \"Port of jQuery.extend for node.js and the browser\",\n\t\"main\": \"index\",\n\t\"scripts\": {\n\t\t\"prepublishOnly\": \"safe-publish-latest\",\n\t\t\"prepublish\": \"not-in-publish || npm run prepublishOnly\",\n\t\t\"pretest\": \"npm run lint\",\n\t\t\"test\": \"npm run tests-only\",\n\t\t\"posttest\": \"npx npm@\\\">= 10.2\\\" audit --production\",\n\t\t\"tests-only\": \"nyc tape 'test/**/*.js'\",\n\t\t\"lint\": \"eslint --ext=js,mjs .\"\n\t},\n\t\"contributors\": [\n\t\t{\n\t\t\t\"name\": \"Jordan Harband\",\n\t\t\t\"url\": \"https://github.com/ljharb\"\n\t\t}\n\t],\n\t\"keywords\": [\n\t\t\"extend\",\n\t\t\"clone\",\n\t\t\"merge\"\n\t],\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"https://github.com/justmoon/node-extend.git\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@ljharb/eslint-config\": \"^21.1.1\",\n\t\t\"eslint\": \"=8.8.0\",\n\t\t\"nyc\": \"^10.3.2\",\n\t\t\"safe-publish-latest\": \"^2.0.0\",\n\t\t\"tape\": \"^4.17.0\"\n\t},\n\t\"license\": \"MIT\",\n\t\"engines\": {\n\t\t\"node\": \">= 0.4\"\n\t}\n}\n"
  },
  {
    "path": "test/index.js",
    "content": "'use strict';\n\nvar extend = require('../');\nvar test = require('tape');\n\nvar str = 'me a test';\nvar integer = 10;\nvar arr = [1, 'what', new Date(81, 8, 4)];\nvar date = new Date(81, 4, 13);\n\nvar Foo = function () {};\n\nvar obj = {\n\tstr: str,\n\tinteger: integer,\n\tarr: arr,\n\tdate: date,\n\tconstructor: 'fake',\n\tisPrototypeOf: 'not a function',\n\tfoo: new Foo()\n};\n\nvar deep = {\n\tori: obj,\n\tlayer: {\n\t\tinteger: 10,\n\t\tstr: 'str',\n\t\tdate: new Date(84, 5, 12),\n\t\tarr: [101, 'dude', new Date(82, 10, 4)],\n\t\tdeep: {\n\t\t\tstr: obj.str,\n\t\t\tinteger: integer,\n\t\t\tarr: obj.arr,\n\t\t\tdate: new Date(81, 7, 4)\n\t\t}\n\t}\n};\n\ntest('missing arguments', function (t) {\n\tt.deepEqual(extend(undefined, { a: 1 }), { a: 1 }, 'missing first argument is second argument');\n\tt.deepEqual(extend({ a: 1 }), { a: 1 }, 'missing second argument is first argument');\n\tt.deepEqual(extend(true, undefined, { a: 1 }), { a: 1 }, 'deep: missing first argument is second argument');\n\tt.deepEqual(extend(true, { a: 1 }), { a: 1 }, 'deep: missing second argument is first argument');\n\tt.deepEqual(extend(), {}, 'no arguments is object');\n\tt.end();\n});\n\ntest('merge string with string', function (t) {\n\tvar ori = 'what u gonna say';\n\tvar target = extend(ori, str);\n\tvar expectedTarget = {\n\t\t0: 'm',\n\t\t1: 'e',\n\t\t2: ' ',\n\t\t3: 'a',\n\t\t4: ' ',\n\t\t5: 't',\n\t\t6: 'e',\n\t\t7: 's',\n\t\t8: 't'\n\t};\n\n\tt.equal(ori, 'what u gonna say', 'original string 1 is unchanged');\n\tt.equal(str, 'me a test', 'original string 2 is unchanged');\n\tt.deepEqual(target, expectedTarget, 'string + string is merged object form of string');\n\tt.end();\n});\n\ntest('merge string with number', function (t) {\n\tvar ori = 'what u gonna say';\n\tvar target = extend(ori, 10);\n\n\tt.equal(ori, 'what u gonna say', 'original string is unchanged');\n\tt.deepEqual(target, {}, 'string + number is empty object');\n\n\tt.end();\n});\n\ntest('merge string with array', function (t) {\n\tvar ori = 'what u gonna say';\n\tvar target = extend(ori, arr);\n\n\tt.equal(ori, 'what u gonna say', 'original string is unchanged');\n\tt.deepEqual(arr, [1, 'what', new Date(81, 8, 4)], 'array is unchanged');\n\tt.deepEqual(target, {\n\t\t0: 1,\n\t\t1: 'what',\n\t\t2: new Date(81, 8, 4)\n\t}, 'string + array is array');\n\tt.end();\n});\n\ntest('merge string with date', function (t) {\n\tvar ori = 'what u gonna say';\n\tvar target = extend(ori, date);\n\n\tvar testDate = new Date(81, 4, 13);\n\tt.equal(ori, 'what u gonna say', 'original string is unchanged');\n\tt.deepEqual(date, testDate, 'date is unchanged');\n\tt.deepEqual(target, testDate, 'string + date is date');\n\tt.end();\n});\n\ntest('merge string with obj', function (t) {\n\tvar ori = 'what u gonna say';\n\tvar target = extend(ori, obj);\n\n\tt.equal(ori, 'what u gonna say', 'original string is unchanged');\n\tvar testObj = {\n\t\tstr: 'me a test',\n\t\tinteger: 10,\n\t\tarr: [1, 'what', new Date(81, 8, 4)],\n\t\tdate: new Date(81, 4, 13),\n\t\tconstructor: 'fake',\n\t\tisPrototypeOf: 'not a function',\n\t\tfoo: new Foo()\n\t};\n\tt.deepEqual(obj, testObj, 'original obj is unchanged');\n\tt.deepEqual(target, testObj, 'string + obj is obj');\n\tt.end();\n});\n\ntest('merge number with string', function (t) {\n\tvar ori = 20;\n\tvar target = extend(ori, str);\n\n\tt.equal(ori, 20, 'number is unchanged');\n\tt.equal(str, 'me a test', 'string is unchanged');\n\tt.deepEqual(target, {\n\t\t0: 'm',\n\t\t1: 'e',\n\t\t2: ' ',\n\t\t3: 'a',\n\t\t4: ' ',\n\t\t5: 't',\n\t\t6: 'e',\n\t\t7: 's',\n\t\t8: 't'\n\t}, 'number + string is object form of string');\n\tt.end();\n});\n\ntest('merge number with number', function (t) {\n\tt.deepEqual(extend(20, 10), {}, 'number + number is empty object');\n\tt.end();\n});\n\ntest('merge number with array', function (t) {\n\tvar target = extend(20, arr);\n\n\tt.deepEqual(arr, [1, 'what', new Date(81, 8, 4)], 'array is unchanged');\n\tt.deepEqual(target, {\n\t\t0: 1,\n\t\t1: 'what',\n\t\t2: new Date(81, 8, 4)\n\t}, 'number + arr is object with array contents');\n\tt.end();\n});\n\ntest('merge number with date', function (t) {\n\tvar target = extend(20, date);\n\tvar testDate = new Date(81, 4, 13);\n\n\tt.deepEqual(date, testDate, 'original date is unchanged');\n\tt.deepEqual(target, testDate, 'number + date is date');\n\tt.end();\n});\n\ntest('merge number with object', function (t) {\n\tvar target = extend(20, obj);\n\tvar testObj = {\n\t\tstr: 'me a test',\n\t\tinteger: 10,\n\t\tarr: [1, 'what', new Date(81, 8, 4)],\n\t\tdate: new Date(81, 4, 13),\n\t\tconstructor: 'fake',\n\t\tisPrototypeOf: 'not a function',\n\t\tfoo: new Foo()\n\t};\n\n\tt.deepEqual(obj, testObj, 'obj is unchanged');\n\tt.deepEqual(target, testObj, 'number + obj is obj');\n\tt.end();\n});\n\ntest('merge array with string', function (t) {\n\tvar ori = [1, 2, 3, 4, 5, 6];\n\tvar target = extend(ori, str);\n\n\tt.deepEqual(ori, str.split(''), 'array is changed to be an array of string chars');\n\tt.equal(str, 'me a test', 'string is unchanged');\n\tt.deepEqual(target, {\n\t\t0: 'm',\n\t\t1: 'e',\n\t\t2: ' ',\n\t\t3: 'a',\n\t\t4: ' ',\n\t\t5: 't',\n\t\t6: 'e',\n\t\t7: 's',\n\t\t8: 't'\n\t}, 'array + string is object form of string');\n\tt.end();\n});\n\ntest('merge array with number', function (t) {\n\tvar ori = [1, 2, 3, 4, 5, 6];\n\tvar target = extend(ori, 10);\n\n\tt.deepEqual(ori, [1, 2, 3, 4, 5, 6], 'array is unchanged');\n\tt.deepEqual(target, ori, 'array + number is array');\n\tt.end();\n});\n\ntest('merge array with array', function (t) {\n\tvar ori = [1, 2, 3, 4, 5, 6];\n\tvar target = extend(ori, arr);\n\tvar testDate = new Date(81, 8, 4);\n\tvar expectedTarget = [1, 'what', testDate, 4, 5, 6];\n\n\tt.deepEqual(ori, expectedTarget, 'array + array merges arrays; changes first array');\n\tt.deepEqual(arr, [1, 'what', testDate], 'second array is unchanged');\n\tt.deepEqual(target, expectedTarget, 'array + array is merged array');\n\tt.end();\n});\n\ntest('merge array with date', function (t) {\n\tvar ori = [1, 2, 3, 4, 5, 6];\n\tvar target = extend(ori, date);\n\tvar testDate = new Date(81, 4, 13);\n\tvar testArray = [1, 2, 3, 4, 5, 6];\n\n\tt.deepEqual(ori, testArray, 'array is unchanged');\n\tt.deepEqual(date, testDate, 'date is unchanged');\n\tt.deepEqual(target, testArray, 'array + date is array');\n\tt.end();\n});\n\ntest('merge array with object', function (t) {\n\tvar ori = [1, 2, 3, 4, 5, 6];\n\tvar target = extend(ori, obj);\n\tvar testObject = {\n\t\tstr: 'me a test',\n\t\tinteger: 10,\n\t\tarr: [1, 'what', new Date(81, 8, 4)],\n\t\tdate: new Date(81, 4, 13),\n\t\tconstructor: 'fake',\n\t\tisPrototypeOf: 'not a function',\n\t\tfoo: new Foo()\n\t};\n\n\tt.deepEqual(obj, testObject, 'obj is unchanged');\n\tt.equal(ori.length, 6, 'array has proper length');\n\tt.equal(ori.str, obj.str, 'array has obj.str property');\n\tt.equal(ori.integer, obj.integer, 'array has obj.integer property');\n\tt.deepEqual(ori.arr, obj.arr, 'array has obj.arr property');\n\tt.equal(ori.date, obj.date, 'array has obj.date property');\n\n\tt.equal(target.length, 6, 'target has proper length');\n\tt.equal(target.str, obj.str, 'target has obj.str property');\n\tt.equal(target.integer, obj.integer, 'target has obj.integer property');\n\tt.deepEqual(target.arr, obj.arr, 'target has obj.arr property');\n\tt.equal(target.date, obj.date, 'target has obj.date property');\n\tt.end();\n});\n\ntest('merge date with string', function (t) {\n\tvar ori = new Date(81, 9, 20);\n\tvar target = extend(ori, str);\n\tvar testObject = {\n\t\t0: 'm',\n\t\t1: 'e',\n\t\t2: ' ',\n\t\t3: 'a',\n\t\t4: ' ',\n\t\t5: 't',\n\t\t6: 'e',\n\t\t7: 's',\n\t\t8: 't'\n\t};\n\n\tt.deepEqual(ori, testObject, 'date is changed to object form of string');\n\tt.equal(str, 'me a test', 'string is unchanged');\n\tt.deepEqual(target, testObject, 'date + string is object form of string');\n\tt.end();\n});\n\ntest('merge date with number', function (t) {\n\tvar ori = new Date(81, 9, 20);\n\tvar target = extend(ori, 10);\n\n\tt.deepEqual(ori, {}, 'date is changed to empty object');\n\tt.deepEqual(target, {}, 'date + number is empty object');\n\tt.end();\n});\n\ntest('merge date with array', function (t) {\n\tvar ori = new Date(81, 9, 20);\n\tvar target = extend(ori, arr);\n\tvar testDate = new Date(81, 9, 20);\n\tvar testArray = [1, 'what', new Date(81, 8, 4)];\n\n\tt.deepEqual(ori, testDate, 'date is unchanged');\n\tt.deepEqual(arr, testArray, 'array is unchanged');\n\tt.deepEqual(target, testDate, 'date + array is date');\n\tt.end();\n});\n\ntest('merge date with date', function (t) {\n\tvar ori = new Date(81, 9, 20);\n\tvar target = extend(ori, date);\n\n\tt.deepEqual(ori, {}, 'date is empty object');\n\tt.deepEqual(target, {}, 'date + date is empty object');\n\tt.end();\n});\n\ntest('merge date with object', function (t) {\n\tvar ori = new Date(81, 9, 20);\n\tvar target = extend(ori, obj);\n\tvar testDate = new Date(81, 8, 4);\n\tvar testObject = {\n\t\tstr: 'me a test',\n\t\tinteger: 10,\n\t\tarr: [1, 'what', testDate],\n\t\tdate: new Date(81, 4, 13),\n\t\tconstructor: 'fake',\n\t\tisPrototypeOf: 'not a function',\n\t\tfoo: new Foo()\n\t};\n\n\tt.deepEqual(obj, testObject, 'original object is unchanged');\n\tt.deepEqual(ori, testObject, 'date becomes original object');\n\tt.deepEqual(target, testObject, 'date + object is object');\n\tt.end();\n});\n\ntest('merge object with string', function (t) {\n\tvar testDate = new Date(81, 7, 26);\n\tvar ori = {\n\t\tstr: 'no shit',\n\t\tinteger: 76,\n\t\tarr: [1, 2, 3, 4],\n\t\tdate: testDate\n\t};\n\tvar target = extend(ori, str);\n\tvar testObj = {\n\t\t0: 'm',\n\t\t1: 'e',\n\t\t2: ' ',\n\t\t3: 'a',\n\t\t4: ' ',\n\t\t5: 't',\n\t\t6: 'e',\n\t\t7: 's',\n\t\t8: 't',\n\t\tstr: 'no shit',\n\t\tinteger: 76,\n\t\tarr: [1, 2, 3, 4],\n\t\tdate: testDate\n\t};\n\n\tt.deepEqual(ori, testObj, 'original object updated');\n\tt.equal(str, 'me a test', 'string is unchanged');\n\tt.deepEqual(target, testObj, 'object + string is object + object form of string');\n\tt.end();\n});\n\ntest('merge object with number', function (t) {\n\tvar ori = {\n\t\tstr: 'no shit',\n\t\tinteger: 76,\n\t\tarr: [1, 2, 3, 4],\n\t\tdate: new Date(81, 7, 26)\n\t};\n\tvar testObject = {\n\t\tstr: 'no shit',\n\t\tinteger: 76,\n\t\tarr: [1, 2, 3, 4],\n\t\tdate: new Date(81, 7, 26)\n\t};\n\tvar target = extend(ori, 10);\n\tt.deepEqual(ori, testObject, 'object is unchanged');\n\tt.deepEqual(target, testObject, 'object + number is object');\n\tt.end();\n});\n\ntest('merge object with array', function (t) {\n\tvar ori = {\n\t\tstr: 'no shit',\n\t\tinteger: 76,\n\t\tarr: [1, 2, 3, 4],\n\t\tdate: new Date(81, 7, 26)\n\t};\n\tvar target = extend(ori, arr);\n\tvar testObject = {\n\t\t0: 1,\n\t\t1: 'what',\n\t\t2: new Date(81, 8, 4),\n\t\tstr: 'no shit',\n\t\tinteger: 76,\n\t\tarr: [1, 2, 3, 4],\n\t\tdate: new Date(81, 7, 26)\n\t};\n\n\tt.deepEqual(ori, testObject, 'original object is merged');\n\tt.deepEqual(arr, [1, 'what', testObject[2]], 'array is unchanged');\n\tt.deepEqual(target, testObject, 'object + array is merged object');\n\tt.end();\n});\n\ntest('merge object with date', function (t) {\n\tvar ori = {\n\t\tstr: 'no shit',\n\t\tinteger: 76,\n\t\tarr: [1, 2, 3, 4],\n\t\tdate: new Date(81, 7, 26)\n\t};\n\tvar target = extend(ori, date);\n\tvar testObject = {\n\t\tstr: 'no shit',\n\t\tinteger: 76,\n\t\tarr: [1, 2, 3, 4],\n\t\tdate: new Date(81, 7, 26)\n\t};\n\n\tt.deepEqual(ori, testObject, 'original object is unchanged');\n\tt.deepEqual(date, new Date(81, 4, 13), 'date is unchanged');\n\tt.deepEqual(target, testObject, 'object + date is object');\n\tt.end();\n});\n\ntest('merge object with object', function (t) {\n\tvar ori = {\n\t\tstr: 'no shit',\n\t\tinteger: 76,\n\t\tarr: [1, 2, 3, 4],\n\t\tdate: new Date(81, 7, 26),\n\t\tfoo: 'bar'\n\t};\n\tvar target = extend(ori, obj);\n\tvar expectedObj = {\n\t\tstr: 'me a test',\n\t\tinteger: 10,\n\t\tarr: [1, 'what', new Date(81, 8, 4)],\n\t\tdate: new Date(81, 4, 13),\n\t\tconstructor: 'fake',\n\t\tisPrototypeOf: 'not a function',\n\t\tfoo: new Foo()\n\t};\n\tvar expectedTarget = {\n\t\tstr: 'me a test',\n\t\tinteger: 10,\n\t\tarr: [1, 'what', new Date(81, 8, 4)],\n\t\tdate: new Date(81, 4, 13),\n\t\tconstructor: 'fake',\n\t\tisPrototypeOf: 'not a function',\n\t\tfoo: new Foo()\n\t};\n\n\tt.deepEqual(obj, expectedObj, 'obj is unchanged');\n\tt.deepEqual(ori, expectedTarget, 'original has been merged');\n\tt.deepEqual(target, expectedTarget, 'object + object is merged object');\n\tt.end();\n});\n\ntest('deep clone', function (t) {\n\tvar ori = {\n\t\tstr: 'no shit',\n\t\tinteger: 76,\n\t\tarr: [1, 2, 3, 4],\n\t\tdate: new Date(81, 7, 26),\n\t\tlayer: { deep: { integer: 42 } }\n\t};\n\tvar target = extend(true, ori, deep);\n\n\tt.deepEqual(ori, {\n\t\tstr: 'no shit',\n\t\tinteger: 76,\n\t\tarr: [1, 2, 3, 4],\n\t\tdate: new Date(81, 7, 26),\n\t\tori: {\n\t\t\tstr: 'me a test',\n\t\t\tinteger: 10,\n\t\t\tarr: [1, 'what', new Date(81, 8, 4)],\n\t\t\tdate: new Date(81, 4, 13),\n\t\t\tconstructor: 'fake',\n\t\t\tisPrototypeOf: 'not a function',\n\t\t\tfoo: new Foo()\n\t\t},\n\t\tlayer: {\n\t\t\tinteger: 10,\n\t\t\tstr: 'str',\n\t\t\tdate: new Date(84, 5, 12),\n\t\t\tarr: [101, 'dude', new Date(82, 10, 4)],\n\t\t\tdeep: {\n\t\t\t\tstr: 'me a test',\n\t\t\t\tinteger: 10,\n\t\t\t\tarr: [1, 'what', new Date(81, 8, 4)],\n\t\t\t\tdate: new Date(81, 7, 4)\n\t\t\t}\n\t\t}\n\t}, 'original object is merged');\n\tt.deepEqual(deep, {\n\t\tori: {\n\t\t\tstr: 'me a test',\n\t\t\tinteger: 10,\n\t\t\tarr: [1, 'what', new Date(81, 8, 4)],\n\t\t\tdate: new Date(81, 4, 13),\n\t\t\tconstructor: 'fake',\n\t\t\tisPrototypeOf: 'not a function',\n\t\t\tfoo: new Foo()\n\t\t},\n\t\tlayer: {\n\t\t\tinteger: 10,\n\t\t\tstr: 'str',\n\t\t\tdate: new Date(84, 5, 12),\n\t\t\tarr: [101, 'dude', new Date(82, 10, 4)],\n\t\t\tdeep: {\n\t\t\t\tstr: 'me a test',\n\t\t\t\tinteger: 10,\n\t\t\t\tarr: [1, 'what', new Date(81, 8, 4)],\n\t\t\t\tdate: new Date(81, 7, 4)\n\t\t\t}\n\t\t}\n\t}, 'deep is unchanged');\n\tt.deepEqual(target, {\n\t\tstr: 'no shit',\n\t\tinteger: 76,\n\t\tarr: [1, 2, 3, 4],\n\t\tdate: new Date(81, 7, 26),\n\t\tori: {\n\t\t\tstr: 'me a test',\n\t\t\tinteger: 10,\n\t\t\tarr: [1, 'what', new Date(81, 8, 4)],\n\t\t\tdate: new Date(81, 4, 13),\n\t\t\tconstructor: 'fake',\n\t\t\tisPrototypeOf: 'not a function',\n\t\t\tfoo: new Foo()\n\t\t},\n\t\tlayer: {\n\t\t\tinteger: 10,\n\t\t\tstr: 'str',\n\t\t\tdate: new Date(84, 5, 12),\n\t\t\tarr: [101, 'dude', new Date(82, 10, 4)],\n\t\t\tdeep: {\n\t\t\t\tstr: 'me a test',\n\t\t\t\tinteger: 10,\n\t\t\t\tarr: [1, 'what', new Date(81, 8, 4)],\n\t\t\t\tdate: new Date(81, 7, 4)\n\t\t\t}\n\t\t}\n\t}, 'deep + object + object is deeply merged object');\n\n\ttarget.layer.deep = 339;\n\tt.deepEqual(deep, {\n\t\tori: {\n\t\t\tstr: 'me a test',\n\t\t\tinteger: 10,\n\t\t\tarr: [1, 'what', new Date(81, 8, 4)],\n\t\t\tdate: new Date(81, 4, 13),\n\t\t\tconstructor: 'fake',\n\t\t\tisPrototypeOf: 'not a function',\n\t\t\tfoo: new Foo()\n\t\t},\n\t\tlayer: {\n\t\t\tinteger: 10,\n\t\t\tstr: 'str',\n\t\t\tdate: new Date(84, 5, 12),\n\t\t\tarr: [101, 'dude', new Date(82, 10, 4)],\n\t\t\tdeep: {\n\t\t\t\tstr: 'me a test',\n\t\t\t\tinteger: 10,\n\t\t\t\tarr: [1, 'what', new Date(81, 8, 4)],\n\t\t\t\tdate: new Date(81, 7, 4)\n\t\t\t}\n\t\t}\n\t}, 'deep is unchanged after setting target property');\n\t// ----- NEVER USE EXTEND WITH THE ABOVE SITUATION ------------------------------\n\tt.end();\n});\n\ntest('deep clone; arrays are merged', function (t) {\n\tvar defaults = { arr: [1, 2, 3] };\n\tvar override = { arr: ['x'] };\n\tvar expectedTarget = { arr: ['x', 2, 3] };\n\n\tvar target = extend(true, defaults, override);\n\n\tt.deepEqual(target, expectedTarget, 'arrays are merged');\n\tt.end();\n});\n\ntest('deep clone === false; objects merged normally', function (t) {\n\tvar defaults = { a: 1 };\n\tvar override = { a: 2 };\n\tvar target = extend(false, defaults, override);\n\tt.deepEqual(target, override, 'deep === false handled normally');\n\tt.end();\n});\n\ntest('pass in null; should create a valid object', function (t) {\n\tvar override = { a: 1 };\n\tvar target = extend(null, override);\n\tt.deepEqual(target, override, 'null object handled normally');\n\tt.end();\n});\n\ntest('works without Array.isArray', function (t) {\n\tvar savedIsArray = Array.isArray;\n\tArray.isArray = false; // don't delete, to preserve enumerability\n\tvar target = [];\n\tvar source = [1, [2], { 3: true }];\n\tt.deepEqual(\n\t\textend(true, target, source),\n\t\t[1, [2], { 3: true }],\n\t\t'It works without Array.isArray'\n\t);\n\tArray.isArray = savedIsArray;\n\tt.end();\n});\n\ntest('non-object target', function (t) {\n\tt.deepEqual(extend(3.14, { a: 'b' }), { a: 'b' });\n\tt.deepEqual(extend(true, 3.14, { a: 'b' }), { a: 'b' });\n\n\tt.end();\n});\n\ntest('__proto__ is merged as an own property', function (t) {\n\tvar malicious = { fred: 1 };\n\tObject.defineProperty(malicious, '__proto__', { value: { george: 1 }, enumerable: true });\n\tvar target = {};\n\textend(true, target, malicious);\n\tt.notOk(target.george);\n\tt.ok(Object.prototype.hasOwnProperty.call(target, '__proto__'));\n\tt.deepEqual(Object.getOwnPropertyDescriptor(target, '__proto__').value, { george: 1 });\n\n\tt.end();\n});\n"
  }
]