123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929 |
- /*!
- * @license deepcopy.js Copyright(c) 2013 sasa+1
- * https://github.com/sasaplus1/deepcopy.js
- * Released under the MIT license.
- *
- * type-detect
- * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
- typeof define === 'function' && define.amd ? define(factory) :
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.deepcopy = factory());
- }(this, (function () { 'use strict';
- var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
- function createCommonjsModule(fn, module) {
- return module = { exports: {} }, fn(module, module.exports), module.exports;
- }
- var typeDetect = createCommonjsModule(function (module, exports) {
- (function (global, factory) {
- module.exports = factory() ;
- }(commonjsGlobal, (function () {
- /* !
- * type-detect
- * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
- * MIT Licensed
- */
- var promiseExists = typeof Promise === 'function';
- /* eslint-disable no-undef */
- var globalObject = typeof self === 'object' ? self : commonjsGlobal; // eslint-disable-line id-blacklist
- var symbolExists = typeof Symbol !== 'undefined';
- var mapExists = typeof Map !== 'undefined';
- var setExists = typeof Set !== 'undefined';
- var weakMapExists = typeof WeakMap !== 'undefined';
- var weakSetExists = typeof WeakSet !== 'undefined';
- var dataViewExists = typeof DataView !== 'undefined';
- var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined';
- var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined';
- var setEntriesExists = setExists && typeof Set.prototype.entries === 'function';
- var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function';
- var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries());
- var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries());
- var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function';
- var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]());
- var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function';
- var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]());
- var toStringLeftSliceLength = 8;
- var toStringRightSliceLength = -1;
- /**
- * ### typeOf (obj)
- *
- * Uses `Object.prototype.toString` to determine the type of an object,
- * normalising behaviour across engine versions & well optimised.
- *
- * @param {Mixed} object
- * @return {String} object type
- * @api public
- */
- function typeDetect(obj) {
- /* ! Speed optimisation
- * Pre:
- * string literal x 3,039,035 ops/sec ±1.62% (78 runs sampled)
- * boolean literal x 1,424,138 ops/sec ±4.54% (75 runs sampled)
- * number literal x 1,653,153 ops/sec ±1.91% (82 runs sampled)
- * undefined x 9,978,660 ops/sec ±1.92% (75 runs sampled)
- * function x 2,556,769 ops/sec ±1.73% (77 runs sampled)
- * Post:
- * string literal x 38,564,796 ops/sec ±1.15% (79 runs sampled)
- * boolean literal x 31,148,940 ops/sec ±1.10% (79 runs sampled)
- * number literal x 32,679,330 ops/sec ±1.90% (78 runs sampled)
- * undefined x 32,363,368 ops/sec ±1.07% (82 runs sampled)
- * function x 31,296,870 ops/sec ±0.96% (83 runs sampled)
- */
- var typeofObj = typeof obj;
- if (typeofObj !== 'object') {
- return typeofObj;
- }
- /* ! Speed optimisation
- * Pre:
- * null x 28,645,765 ops/sec ±1.17% (82 runs sampled)
- * Post:
- * null x 36,428,962 ops/sec ±1.37% (84 runs sampled)
- */
- if (obj === null) {
- return 'null';
- }
- /* ! Spec Conformance
- * Test: `Object.prototype.toString.call(window)``
- * - Node === "[object global]"
- * - Chrome === "[object global]"
- * - Firefox === "[object Window]"
- * - PhantomJS === "[object Window]"
- * - Safari === "[object Window]"
- * - IE 11 === "[object Window]"
- * - IE Edge === "[object Window]"
- * Test: `Object.prototype.toString.call(this)``
- * - Chrome Worker === "[object global]"
- * - Firefox Worker === "[object DedicatedWorkerGlobalScope]"
- * - Safari Worker === "[object DedicatedWorkerGlobalScope]"
- * - IE 11 Worker === "[object WorkerGlobalScope]"
- * - IE Edge Worker === "[object WorkerGlobalScope]"
- */
- if (obj === globalObject) {
- return 'global';
- }
- /* ! Speed optimisation
- * Pre:
- * array literal x 2,888,352 ops/sec ±0.67% (82 runs sampled)
- * Post:
- * array literal x 22,479,650 ops/sec ±0.96% (81 runs sampled)
- */
- if (
- Array.isArray(obj) &&
- (symbolToStringTagExists === false || !(Symbol.toStringTag in obj))
- ) {
- return 'Array';
- }
- // Not caching existence of `window` and related properties due to potential
- // for `window` to be unset before tests in quasi-browser environments.
- if (typeof window === 'object' && window !== null) {
- /* ! Spec Conformance
- * (https://html.spec.whatwg.org/multipage/browsers.html#location)
- * WhatWG HTML$7.7.3 - The `Location` interface
- * Test: `Object.prototype.toString.call(window.location)``
- * - IE <=11 === "[object Object]"
- * - IE Edge <=13 === "[object Object]"
- */
- if (typeof window.location === 'object' && obj === window.location) {
- return 'Location';
- }
- /* ! Spec Conformance
- * (https://html.spec.whatwg.org/#document)
- * WhatWG HTML$3.1.1 - The `Document` object
- * Note: Most browsers currently adher to the W3C DOM Level 2 spec
- * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268)
- * which suggests that browsers should use HTMLTableCellElement for
- * both TD and TH elements. WhatWG separates these.
- * WhatWG HTML states:
- * > For historical reasons, Window objects must also have a
- * > writable, configurable, non-enumerable property named
- * > HTMLDocument whose value is the Document interface object.
- * Test: `Object.prototype.toString.call(document)``
- * - Chrome === "[object HTMLDocument]"
- * - Firefox === "[object HTMLDocument]"
- * - Safari === "[object HTMLDocument]"
- * - IE <=10 === "[object Document]"
- * - IE 11 === "[object HTMLDocument]"
- * - IE Edge <=13 === "[object HTMLDocument]"
- */
- if (typeof window.document === 'object' && obj === window.document) {
- return 'Document';
- }
- if (typeof window.navigator === 'object') {
- /* ! Spec Conformance
- * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray)
- * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray
- * Test: `Object.prototype.toString.call(navigator.mimeTypes)``
- * - IE <=10 === "[object MSMimeTypesCollection]"
- */
- if (typeof window.navigator.mimeTypes === 'object' &&
- obj === window.navigator.mimeTypes) {
- return 'MimeTypeArray';
- }
- /* ! Spec Conformance
- * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
- * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray
- * Test: `Object.prototype.toString.call(navigator.plugins)``
- * - IE <=10 === "[object MSPluginsCollection]"
- */
- if (typeof window.navigator.plugins === 'object' &&
- obj === window.navigator.plugins) {
- return 'PluginArray';
- }
- }
- if ((typeof window.HTMLElement === 'function' ||
- typeof window.HTMLElement === 'object') &&
- obj instanceof window.HTMLElement) {
- /* ! Spec Conformance
- * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
- * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement`
- * Test: `Object.prototype.toString.call(document.createElement('blockquote'))``
- * - IE <=10 === "[object HTMLBlockElement]"
- */
- if (obj.tagName === 'BLOCKQUOTE') {
- return 'HTMLQuoteElement';
- }
- /* ! Spec Conformance
- * (https://html.spec.whatwg.org/#htmltabledatacellelement)
- * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement`
- * Note: Most browsers currently adher to the W3C DOM Level 2 spec
- * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
- * which suggests that browsers should use HTMLTableCellElement for
- * both TD and TH elements. WhatWG separates these.
- * Test: Object.prototype.toString.call(document.createElement('td'))
- * - Chrome === "[object HTMLTableCellElement]"
- * - Firefox === "[object HTMLTableCellElement]"
- * - Safari === "[object HTMLTableCellElement]"
- */
- if (obj.tagName === 'TD') {
- return 'HTMLTableDataCellElement';
- }
- /* ! Spec Conformance
- * (https://html.spec.whatwg.org/#htmltableheadercellelement)
- * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement`
- * Note: Most browsers currently adher to the W3C DOM Level 2 spec
- * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
- * which suggests that browsers should use HTMLTableCellElement for
- * both TD and TH elements. WhatWG separates these.
- * Test: Object.prototype.toString.call(document.createElement('th'))
- * - Chrome === "[object HTMLTableCellElement]"
- * - Firefox === "[object HTMLTableCellElement]"
- * - Safari === "[object HTMLTableCellElement]"
- */
- if (obj.tagName === 'TH') {
- return 'HTMLTableHeaderCellElement';
- }
- }
- }
- /* ! Speed optimisation
- * Pre:
- * Float64Array x 625,644 ops/sec ±1.58% (80 runs sampled)
- * Float32Array x 1,279,852 ops/sec ±2.91% (77 runs sampled)
- * Uint32Array x 1,178,185 ops/sec ±1.95% (83 runs sampled)
- * Uint16Array x 1,008,380 ops/sec ±2.25% (80 runs sampled)
- * Uint8Array x 1,128,040 ops/sec ±2.11% (81 runs sampled)
- * Int32Array x 1,170,119 ops/sec ±2.88% (80 runs sampled)
- * Int16Array x 1,176,348 ops/sec ±5.79% (86 runs sampled)
- * Int8Array x 1,058,707 ops/sec ±4.94% (77 runs sampled)
- * Uint8ClampedArray x 1,110,633 ops/sec ±4.20% (80 runs sampled)
- * Post:
- * Float64Array x 7,105,671 ops/sec ±13.47% (64 runs sampled)
- * Float32Array x 5,887,912 ops/sec ±1.46% (82 runs sampled)
- * Uint32Array x 6,491,661 ops/sec ±1.76% (79 runs sampled)
- * Uint16Array x 6,559,795 ops/sec ±1.67% (82 runs sampled)
- * Uint8Array x 6,463,966 ops/sec ±1.43% (85 runs sampled)
- * Int32Array x 5,641,841 ops/sec ±3.49% (81 runs sampled)
- * Int16Array x 6,583,511 ops/sec ±1.98% (80 runs sampled)
- * Int8Array x 6,606,078 ops/sec ±1.74% (81 runs sampled)
- * Uint8ClampedArray x 6,602,224 ops/sec ±1.77% (83 runs sampled)
- */
- var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]);
- if (typeof stringTag === 'string') {
- return stringTag;
- }
- var objPrototype = Object.getPrototypeOf(obj);
- /* ! Speed optimisation
- * Pre:
- * regex literal x 1,772,385 ops/sec ±1.85% (77 runs sampled)
- * regex constructor x 2,143,634 ops/sec ±2.46% (78 runs sampled)
- * Post:
- * regex literal x 3,928,009 ops/sec ±0.65% (78 runs sampled)
- * regex constructor x 3,931,108 ops/sec ±0.58% (84 runs sampled)
- */
- if (objPrototype === RegExp.prototype) {
- return 'RegExp';
- }
- /* ! Speed optimisation
- * Pre:
- * date x 2,130,074 ops/sec ±4.42% (68 runs sampled)
- * Post:
- * date x 3,953,779 ops/sec ±1.35% (77 runs sampled)
- */
- if (objPrototype === Date.prototype) {
- return 'Date';
- }
- /* ! Spec Conformance
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag)
- * ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise":
- * Test: `Object.prototype.toString.call(Promise.resolve())``
- * - Chrome <=47 === "[object Object]"
- * - Edge <=20 === "[object Object]"
- * - Firefox 29-Latest === "[object Promise]"
- * - Safari 7.1-Latest === "[object Promise]"
- */
- if (promiseExists && objPrototype === Promise.prototype) {
- return 'Promise';
- }
- /* ! Speed optimisation
- * Pre:
- * set x 2,222,186 ops/sec ±1.31% (82 runs sampled)
- * Post:
- * set x 4,545,879 ops/sec ±1.13% (83 runs sampled)
- */
- if (setExists && objPrototype === Set.prototype) {
- return 'Set';
- }
- /* ! Speed optimisation
- * Pre:
- * map x 2,396,842 ops/sec ±1.59% (81 runs sampled)
- * Post:
- * map x 4,183,945 ops/sec ±6.59% (82 runs sampled)
- */
- if (mapExists && objPrototype === Map.prototype) {
- return 'Map';
- }
- /* ! Speed optimisation
- * Pre:
- * weakset x 1,323,220 ops/sec ±2.17% (76 runs sampled)
- * Post:
- * weakset x 4,237,510 ops/sec ±2.01% (77 runs sampled)
- */
- if (weakSetExists && objPrototype === WeakSet.prototype) {
- return 'WeakSet';
- }
- /* ! Speed optimisation
- * Pre:
- * weakmap x 1,500,260 ops/sec ±2.02% (78 runs sampled)
- * Post:
- * weakmap x 3,881,384 ops/sec ±1.45% (82 runs sampled)
- */
- if (weakMapExists && objPrototype === WeakMap.prototype) {
- return 'WeakMap';
- }
- /* ! Spec Conformance
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag)
- * ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView":
- * Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))``
- * - Edge <=13 === "[object Object]"
- */
- if (dataViewExists && objPrototype === DataView.prototype) {
- return 'DataView';
- }
- /* ! Spec Conformance
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag)
- * ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator":
- * Test: `Object.prototype.toString.call(new Map().entries())``
- * - Edge <=13 === "[object Object]"
- */
- if (mapExists && objPrototype === mapIteratorPrototype) {
- return 'Map Iterator';
- }
- /* ! Spec Conformance
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag)
- * ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator":
- * Test: `Object.prototype.toString.call(new Set().entries())``
- * - Edge <=13 === "[object Object]"
- */
- if (setExists && objPrototype === setIteratorPrototype) {
- return 'Set Iterator';
- }
- /* ! Spec Conformance
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag)
- * ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator":
- * Test: `Object.prototype.toString.call([][Symbol.iterator]())``
- * - Edge <=13 === "[object Object]"
- */
- if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) {
- return 'Array Iterator';
- }
- /* ! Spec Conformance
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag)
- * ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator":
- * Test: `Object.prototype.toString.call(''[Symbol.iterator]())``
- * - Edge <=13 === "[object Object]"
- */
- if (stringIteratorExists && objPrototype === stringIteratorPrototype) {
- return 'String Iterator';
- }
- /* ! Speed optimisation
- * Pre:
- * object from null x 2,424,320 ops/sec ±1.67% (76 runs sampled)
- * Post:
- * object from null x 5,838,000 ops/sec ±0.99% (84 runs sampled)
- */
- if (objPrototype === null) {
- return 'Object';
- }
- return Object
- .prototype
- .toString
- .call(obj)
- .slice(toStringLeftSliceLength, toStringRightSliceLength);
- }
- return typeDetect;
- })));
- });
- const isBufferExists = typeof Buffer !== 'undefined';
- const isBufferFromExists = isBufferExists && typeof Buffer.from !== 'undefined';
- const isBuffer = isBufferExists
- ? /**
- * is value is Buffer?
- *
- * @param {*} value
- * @return {boolean}
- */
- function isBuffer(value) {
- return Buffer.isBuffer(value);
- }
- : /**
- * return false
- *
- * NOTE: for Buffer unsupported
- *
- * @return {boolean}
- */
- function isBuffer() {
- return false;
- };
- const copy = isBufferFromExists
- ? /**
- * copy Buffer
- *
- * @param {Buffer} value
- * @return {Buffer}
- */
- function copy(value) {
- return Buffer.from(value);
- }
- : isBufferExists
- ? /**
- * copy Buffer
- *
- * NOTE: for old node.js
- *
- * @param {Buffer} value
- * @return {Buffer}
- */
- function copy(value) {
- return new Buffer(value);
- }
- : /**
- * shallow copy
- *
- * NOTE: for Buffer unsupported
- *
- * @param {*}
- * @return {*}
- */
- function copy(value) {
- return value;
- };
- /**
- * detect type of value
- *
- * @param {*} value
- * @return {string}
- */
- function detectType(value) {
- // NOTE: isBuffer must execute before type-detect,
- // because type-detect returns 'Uint8Array'.
- if (isBuffer(value)) {
- return 'Buffer';
- }
- return typeDetect(value);
- }
- /**
- * collection types
- */
- const collectionTypeSet = new Set([
- 'Arguments',
- 'Array',
- 'Map',
- 'Object',
- 'Set'
- ]);
- /**
- * get value from collection
- *
- * @param {Array|Object|Map|Set} collection
- * @param {string|number|symbol} key
- * @param {string} [type=null]
- * @return {*}
- */
- function get(collection, key, type = null) {
- const valueType = type || detectType(collection);
- switch (valueType) {
- case 'Arguments':
- case 'Array':
- case 'Object':
- return collection[key];
- case 'Map':
- return collection.get(key);
- case 'Set':
- // NOTE: Set.prototype.keys is alias of Set.prototype.values
- // it means key is equals value
- return key;
- }
- }
- /**
- * check to type string is collection
- *
- * @param {string} type
- */
- function isCollection(type) {
- return collectionTypeSet.has(type);
- }
- /**
- * set value to collection
- *
- * @param {Array|Object|Map|Set} collection
- * @param {string|number|symbol} key
- * @param {*} value
- * @param {string} [type=null]
- * @return {Array|Object|Map|Set}
- */
- function set(collection, key, value, type = null) {
- const valueType = type || detectType(collection);
- switch (valueType) {
- case 'Arguments':
- case 'Array':
- case 'Object':
- collection[key] = value;
- break;
- case 'Map':
- collection.set(key, value);
- break;
- case 'Set':
- collection.add(value);
- break;
- }
- return collection;
- }
- const freeGlobalThis =
- typeof globalThis !== 'undefined' &&
- globalThis !== null &&
- globalThis.Object === Object &&
- globalThis;
- const freeGlobal =
- typeof global !== 'undefined' &&
- global !== null &&
- global.Object === Object &&
- global;
- const freeSelf =
- typeof self !== 'undefined' &&
- self !== null &&
- self.Object === Object &&
- self;
- const globalObject =
- freeGlobalThis || freeGlobal || freeSelf || Function('return this')();
- /**
- * copy ArrayBuffer
- *
- * @param {ArrayBuffer} value
- * @return {ArrayBuffer}
- */
- function copyArrayBuffer(value) {
- return value.slice(0);
- }
- /**
- * copy Boolean
- *
- * @param {Boolean} value
- * @return {Boolean}
- */
- function copyBoolean(value) {
- return new Boolean(value.valueOf());
- }
- /**
- * copy DataView
- *
- * @param {DataView} value
- * @return {DataView}
- */
- function copyDataView(value) {
- // TODO: copy ArrayBuffer?
- return new DataView(value.buffer);
- }
- /**
- * copy Buffer
- *
- * @param {Buffer} value
- * @return {Buffer}
- */
- function copyBuffer(value) {
- return copy(value);
- }
- /**
- * copy Date
- *
- * @param {Date} value
- * @return {Date}
- */
- function copyDate(value) {
- return new Date(value.getTime());
- }
- /**
- * copy Number
- *
- * @param {Number} value
- * @return {Number}
- */
- function copyNumber(value) {
- return new Number(value);
- }
- /**
- * copy RegExp
- *
- * @param {RegExp} value
- * @return {RegExp}
- */
- function copyRegExp(value) {
- return new RegExp(value.source, value.flags);
- }
- /**
- * copy String
- *
- * @param {String} value
- * @return {String}
- */
- function copyString(value) {
- return new String(value);
- }
- /**
- * copy TypedArray
- *
- * @param {*} value
- * @return {*}
- */
- function copyTypedArray(value, type) {
- const typedArray = globalObject[type];
- if (typedArray.from) {
- return globalObject[type].from(value);
- }
- return new globalObject[type](value);
- }
- /**
- * shallow copy
- *
- * @param {*} value
- * @return {*}
- */
- function shallowCopy(value) {
- return value;
- }
- /**
- * get empty Array
- *
- * @return {Array}
- */
- function getEmptyArray() {
- return [];
- }
- /**
- * get empty Map
- *
- * @return {Map}
- */
- function getEmptyMap() {
- return new Map();
- }
- /**
- * get empty Object
- *
- * @return {Object}
- */
- function getEmptyObject() {
- return {};
- }
- /**
- * get empty Set
- *
- * @return {Set}
- */
- function getEmptySet() {
- return new Set();
- }
- var copyMap = new Map([
- // deep copy
- ['ArrayBuffer', copyArrayBuffer],
- ['Boolean', copyBoolean],
- ['Buffer', copyBuffer],
- ['DataView', copyDataView],
- ['Date', copyDate],
- ['Number', copyNumber],
- ['RegExp', copyRegExp],
- ['String', copyString],
- // typed arrays
- // TODO: pass bound function
- ['Float32Array', copyTypedArray],
- ['Float64Array', copyTypedArray],
- ['Int16Array', copyTypedArray],
- ['Int32Array', copyTypedArray],
- ['Int8Array', copyTypedArray],
- ['Uint16Array', copyTypedArray],
- ['Uint32Array', copyTypedArray],
- ['Uint8Array', copyTypedArray],
- ['Uint8ClampedArray', copyTypedArray],
- // shallow copy
- ['Array Iterator', shallowCopy],
- ['Map Iterator', shallowCopy],
- ['Promise', shallowCopy],
- ['Set Iterator', shallowCopy],
- ['String Iterator', shallowCopy],
- ['function', shallowCopy],
- ['global', shallowCopy],
- // NOTE: WeakMap and WeakSet cannot get entries
- ['WeakMap', shallowCopy],
- ['WeakSet', shallowCopy],
- // primitives
- ['boolean', shallowCopy],
- ['null', shallowCopy],
- ['number', shallowCopy],
- ['string', shallowCopy],
- ['symbol', shallowCopy],
- ['undefined', shallowCopy],
- // collections
- // NOTE: return empty value, because recursively copy later.
- ['Arguments', getEmptyArray],
- ['Array', getEmptyArray],
- ['Map', getEmptyMap],
- ['Object', getEmptyObject],
- ['Set', getEmptySet]
- // NOTE: type-detect returns following types
- // 'Location'
- // 'Document'
- // 'MimeTypeArray'
- // 'PluginArray'
- // 'HTMLQuoteElement'
- // 'HTMLTableDataCellElement'
- // 'HTMLTableHeaderCellElement'
- // TODO: is type-detect never return 'object'?
- // 'object'
- ]);
- /**
- * no operation
- */
- function noop() {}
- /**
- * copy value
- *
- * @param {*} value
- * @param {string} [type=null]
- * @param {Function} [customizer=noop]
- * @return {*}
- */
- function copy$1(value, type = null, customizer = noop) {
- if (arguments.length === 2 && typeof type === 'function') {
- customizer = type;
- type = null;
- }
- const valueType = type || detectType(value);
- const copyFunction = copyMap.get(valueType);
- if (valueType === 'Object') {
- const result = customizer(value, valueType);
- if (result !== undefined) {
- return result;
- }
- }
- // NOTE: TypedArray needs pass type to argument
- return copyFunction ? copyFunction(value, valueType) : value;
- }
- /**
- * deepcopy function
- *
- * @param {*} value
- * @param {Object|Function} [options]
- * @return {*}
- */
- function deepcopy(value, options = {}) {
- if (typeof options === 'function') {
- options = {
- customizer: options
- };
- }
- const {
- // TODO: before/after customizer
- customizer
- // TODO: max depth
- // depth = Infinity,
- } = options;
- const valueType = detectType(value);
- if (!isCollection(valueType)) {
- return recursiveCopy(value, null, null, null);
- }
- const copiedValue = copy$1(value, valueType, customizer);
- const references = new WeakMap([[value, copiedValue]]);
- const visited = new WeakSet([value]);
- return recursiveCopy(value, copiedValue, references, visited);
- }
- /**
- * recursively copy
- *
- * @param {*} value target value
- * @param {*} clone clone of value
- * @param {WeakMap} references visited references of clone
- * @param {WeakSet} visited visited references of value
- * @param {Function} customizer user customize function
- * @return {*}
- */
- function recursiveCopy(value, clone, references, visited, customizer) {
- const type = detectType(value);
- const copiedValue = copy$1(value, type);
- // return if not a collection value
- if (!isCollection(type)) {
- return copiedValue;
- }
- let keys;
- switch (type) {
- case 'Arguments':
- case 'Array':
- keys = Object.keys(value);
- break;
- case 'Object':
- keys = Object.keys(value);
- keys.push(...Object.getOwnPropertySymbols(value));
- break;
- case 'Map':
- case 'Set':
- keys = value.keys();
- break;
- }
- // walk within collection with iterator
- for (let collectionKey of keys) {
- const collectionValue = get(value, collectionKey, type);
- if (visited.has(collectionValue)) {
- // for [Circular]
- set(clone, collectionKey, references.get(collectionValue), type);
- } else {
- const collectionValueType = detectType(collectionValue);
- const copiedCollectionValue = copy$1(collectionValue, collectionValueType);
- // save reference if value is collection
- if (isCollection(collectionValueType)) {
- references.set(collectionValue, copiedCollectionValue);
- visited.add(collectionValue);
- }
- set(
- clone,
- collectionKey,
- recursiveCopy(
- collectionValue,
- copiedCollectionValue,
- references,
- visited),
- type
- );
- }
- }
- // TODO: isSealed/isFrozen/isExtensible
- return clone;
- }
- return deepcopy;
- })));
- //# sourceMappingURL=deepcopy.js.map
|