pncat
Version:
A unified cli tool that enhances package managers catalogs feature.
1,625 lines (1,616 loc) • 73.8 kB
JavaScript
import { a as __toESM, t as __commonJSMin } from "./chunk-6qLfnLNH.mjs";
import { t as require_semver } from "./semver-Df1PSY8l.mjs";
import { readFile, writeFile } from "node:fs/promises";
import { dirname, join, resolve } from "pathe";
import process from "node:process";
import { findUp } from "find-up-simple";
import * as p from "@clack/prompts";
import c from "ansis";
import { parsePnpmWorkspaceYaml } from "pnpm-workspace-yaml";
//#region package.json
var name = "pncat";
var version = "0.7.7";
//#endregion
//#region src/constants.ts
const NAME = name;
const VERSION = version;
const MODE_CHOICES = [
"init",
"detect",
"migrate",
"add",
"remove",
"clean",
"revert"
];
const MODE_ALIASES = {
init: [
"create",
"setup",
"config",
"conf"
],
detect: [
"scan",
"check",
"find",
"d"
],
migrate: [
"move",
"mv",
"mig",
"m"
],
add: [
"install",
"in",
"i"
],
remove: [
"uninstall",
"rm",
"r",
"un",
"u"
],
clean: [
"prune",
"cl",
"c"
],
revert: [
"restore",
"undo",
"rev"
]
};
const AGENTS = [
"pnpm",
"yarn",
"bun",
"vlt"
];
const AGENT_CONFIG = {
pnpm: {
type: "pnpm-workspace.yaml",
depType: "pnpm-workspace",
filename: "pnpm-workspace.yaml",
locks: "pnpm-lock.yaml",
defaultContent: "packages: []"
},
yarn: {
type: ".yarnrc.yml",
depType: "yarn-workspace",
filename: ".yarnrc.yml",
locks: "yarn.lock",
defaultContent: "defaultProtocol: \"npm:\""
},
bun: {
type: "bun-workspace",
depType: "bun-workspace",
filename: "package.json",
locks: ["bun.lockb", "bun.lock"],
defaultContent: ""
},
vlt: {
type: "vlt.json",
depType: "vlt-workspace",
filename: "vlt.json",
locks: "vlt-lock.json",
defaultContent: "{}"
}
};
const CMD_BOOL_FLAGS = new Set([
"save-dev",
"save-peer",
"save-optional",
"save-exact",
"recursive"
]);
const CMD_BOOL_SHORT_FLAGS = new Set([
"D",
"P",
"O",
"E",
"r"
]);
const DEFAULT_CATALOG_OPTIONS = {
mode: "detect",
recursive: true,
force: false,
ignoreOtherWorkspaces: true,
depFields: {
"dependencies": true,
"devDependencies": true,
"peerDependencies": true,
"optionalDependencies": true,
"resolutions": true,
"overrides": true,
"pnpm.overrides": true
},
allowedProtocols: [
"workspace",
"link",
"file"
],
specifierOptions: {
skipComplexRanges: true,
allowPreReleases: true,
allowWildcards: false
},
yes: false,
saveExact: false,
install: true
};
const DEFAULT_IGNORE_PATHS = [
"**/node_modules/**",
"**/dist/**",
"**/public/**",
"**/fixture/**",
"**/fixtures/**"
];
const COMMON_DEPS_FIELDS = [
"dependencies",
"devDependencies",
"peerDependencies",
"optionalDependencies"
];
const DEPS_FIELDS = [
...COMMON_DEPS_FIELDS,
"pnpm.overrides",
"resolutions",
"overrides",
"pnpm-workspace",
"yarn-workspace",
"bun-workspace",
"vlt-workspace"
];
const DEPS_TYPE_SHORT_MAP = {
"dependencies": "",
"devDependencies": "dev",
"peerDependencies": "peer",
"optionalDependencies": "optional",
"resolutions": "resolutions",
"overrides": "overrides",
"pnpm.overrides": "pnpm-overrides",
"pnpm-workspace": "pnpm-workspace",
"yarn-workspace": "yarn-workspace",
"bun-workspace": "bun-workspace",
"vlt-workspace": "vlt-workspace"
};
const DEPS_TYPE_CATALOG_MAP = {
dependencies: "prod",
devDependencies: "dev",
peerDependencies: "peer",
optionalDependencies: "optional"
};
//#endregion
//#region src/utils/specifier.ts
var import_semver$1 = require_semver();
function parseSpec(spec) {
let name$1;
let specifier;
const parts = spec.split(/@/g);
if (parts[0] === "") {
name$1 = parts.slice(0, 2).join("@");
specifier = parts[2];
} else {
name$1 = parts[0];
specifier = parts[1];
}
return {
name: name$1,
specifier
};
}
function cleanSpec(spec, options) {
if (options?.allowedProtocols?.some((p$1) => spec.startsWith(p$1))) return null;
const version$1 = (0, import_semver$1.valid)((0, import_semver$1.clean)(spec));
if (version$1) return version$1;
const coerced = (0, import_semver$1.coerce)(spec);
if (coerced) return coerced.version;
return null;
}
function sortSpecs(specs, options) {
return specs.sort((a, b) => {
const ver1 = cleanSpec(a, options);
const ver2 = cleanSpec(b, options);
if (ver1 && ver2) return (0, import_semver$1.gt)(ver1, ver2) ? -1 : 1;
return 0;
});
}
function mostSpecificRule(matchingRules) {
if (!matchingRules.length) return matchingRules[0];
return matchingRules.reduce((mostSpecific, current) => {
if ((0, import_semver$1.subset)(current.specifier, mostSpecific.specifier)) return current;
if ((0, import_semver$1.subset)(mostSpecific.specifier, current.specifier)) return mostSpecific;
const minVer1 = (0, import_semver$1.minVersion)(mostSpecific.specifier);
const minVer2 = (0, import_semver$1.minVersion)(current.specifier);
if (minVer1 && minVer2) {
if ((0, import_semver$1.gt)(minVer1, minVer2)) return mostSpecific;
return current;
}
return mostSpecific;
});
}
//#endregion
//#region src/utils/catalog.ts
var import_semver = require_semver();
function isCatalogWorkspace(type) {
return type === "pnpm-workspace" || type === "yarn-workspace" || type === "bun-workspace" || type === "vlt-workspace";
}
function isCatalogPackageName(name$1) {
if (!name$1) return false;
return name$1.startsWith("pnpm-catalog:") || name$1.startsWith("yarn-catalog:") || name$1.startsWith("bun-catalog:") || name$1.startsWith("vlt-catalog:");
}
function extractCatalogName(name$1) {
return name$1.replace("pnpm-catalog:", "").replace("yarn-catalog:", "").replace("bun-catalog:", "").replace("vlt-catalog:", "");
}
function isCatalogSpecifier(specifier) {
return specifier.startsWith("catalog:");
}
function normalizeCatalogName(catalogName) {
return catalogName === "default" ? "catalog:" : `catalog:${catalogName}`;
}
function isDepMatched(depName, match) {
if (Array.isArray(match)) return match.some((m) => typeof m === "string" ? depName === m : m.test(depName));
else if (typeof match === "string") return depName === match;
else if (match instanceof RegExp) return match.test(depName);
return false;
}
function inferCatalogName(dep, options) {
for (const rule of options.catalogRules ?? []) {
const { name: name$1, match, specifierRules } = rule;
if (!isDepMatched(dep.name, match)) continue;
if (!specifierRules?.length) return name$1;
const version$1 = cleanSpec(dep.specifier, options);
if (!version$1) return name$1;
const matchingRules = specifierRules.filter((specifierRule) => {
if (specifierRule.match && !isDepMatched(dep.name, specifierRule.match)) return false;
return (0, import_semver.satisfies)(version$1, specifierRule.specifier);
});
if (matchingRules.length === 0) return name$1;
if (matchingRules.length === 1) {
const rule$1 = matchingRules[0];
return rule$1.name || `${name$1}-${rule$1.suffix}`;
}
const bestMatching = mostSpecificRule(matchingRules);
return bestMatching.name || `${name$1}-${bestMatching.suffix}`;
}
return DEPS_TYPE_CATALOG_MAP[dep.source] || "default";
}
function createDepCatalogIndex(workspaceJson) {
const catalogIndex = /* @__PURE__ */ new Map();
if (!workspaceJson) return catalogIndex;
if (workspaceJson.catalog) for (const [depName, specifier] of Object.entries(workspaceJson.catalog)) {
if (!catalogIndex.has(depName)) catalogIndex.set(depName, []);
catalogIndex.get(depName)?.push({
catalogName: "default",
specifier
});
}
if (workspaceJson.catalogs) {
for (const [catalogName, catalog] of Object.entries(workspaceJson.catalogs)) if (catalog) for (const [depName, specifier] of Object.entries(catalog)) {
if (!catalogIndex.has(depName)) catalogIndex.set(depName, []);
catalogIndex.get(depName)?.push({
catalogName,
specifier
});
}
}
return catalogIndex;
}
//#endregion
//#region src/utils/helper.ts
function getDepSource(isDev = false, isOptional = false, isPeer = false) {
return isDev ? "devDependencies" : isOptional ? "optionalDependencies" : isPeer ? "peerDependencies" : "dependencies";
}
function isPnpmOverridesPackageName(pkgName) {
return pkgName === "pnpm-workspace:overrides";
}
async function updatePackageToCatalog(dep, data, workspace) {
if (dep.source === "pnpm.overrides") {
data.raw.pnpm.overrides[dep.name] = normalizeCatalogName(dep.catalogName);
return;
}
if (dep.source === "pnpm-workspace") {
await workspace.catalog.setPackage(normalizeCatalogName(dep.catalogName), dep.name, dep.specifier);
return;
}
data.raw[dep.source][dep.name] = normalizeCatalogName(dep.catalogName);
}
async function updatePackageToSpecifier(dep, data) {
if (dep.source === "pnpm.overrides") {
data.raw.pnpm.overrides[dep.name] = dep.specifier;
return;
}
data.raw[dep.source][dep.name] = dep.specifier;
}
function containsESLint(packages) {
for (const pkg of packages) if (pkg.type === "package.json") {
if (pkg.deps.find((i) => i.name === "eslint")) return true;
}
return false;
}
function containsVSCodeExtension(packages) {
for (const pkg of packages) if (pkg.type === "package.json") {
const { vscode } = pkg.raw.engines ?? {};
if (vscode) return true;
}
return false;
}
//#endregion
//#region src/io/dependencies.ts
function flatten(obj, parents = []) {
if (!obj) return obj;
let flattenData = {};
for (const [key, value] of Object.entries(obj)) if (typeof value === "object") flattenData = {
...flattenData,
...flatten(value, [...parents, key])
};
else if (typeof value === "string") flattenData[key] = {
specifier: value,
parents
};
return flattenData;
}
function getByPath(obj, path) {
return flatten(path.split(".").reduce((o, i) => o?.[i], obj));
}
function parseDependency(name$1, specifier, type, shouldCatalog, options, parents, packageName) {
const dep = {
name: name$1,
specifier,
parents,
source: type,
catalog: isCatalogWorkspace(type) || isCatalogSpecifier(specifier),
catalogable: shouldCatalog(name$1, specifier)
};
return {
...dep,
catalogName: isCatalogWorkspace(type) && !isPnpmOverridesPackageName(packageName) ? extractCatalogName(packageName) : inferCatalogName(dep, options)
};
}
function parseDependencies(pkg, type, shouldCatalog, options) {
return Object.entries(getByPath(pkg, type) || {}).map(([name$1, { specifier, parents }]) => parseDependency(name$1, specifier, type, shouldCatalog, options, parents));
}
//#endregion
//#region node_modules/.pnpm/@antfu+utils@9.3.0/node_modules/@antfu/utils/dist/index.mjs
function toArray(array) {
array = array ?? [];
return Array.isArray(array) ? array : [array];
}
//#endregion
//#region src/io/workspace.ts
async function detectWorkspaceRoot(agent = "pnpm") {
const root$1 = await findUp(".git", { cwd: process.cwd() });
if (root$1) return dirname(root$1);
for (const lock of toArray(AGENT_CONFIG[agent].locks)) {
const filepath = await findUp(lock, { cwd: process.cwd() });
if (filepath) return dirname(filepath);
}
return process.cwd();
}
//#endregion
//#region node_modules/.pnpm/lodash.clonedeep@4.5.0/node_modules/lodash.clonedeep/index.js
var require_lodash = /* @__PURE__ */ __commonJSMin(((exports, module) => {
/**
* lodash (Custom Build) <https://lodash.com/>
* Build: `lodash modularize exports="npm" -o ./`
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/** Used as the size to enable large array optimizations. */
var LARGE_ARRAY_SIZE = 200;
/** Used to stand-in for `undefined` hash values. */
var HASH_UNDEFINED = "__lodash_hash_undefined__";
/** Used as references for various `Number` constants. */
var MAX_SAFE_INTEGER = 9007199254740991;
/** `Object#toString` result references. */
var argsTag = "[object Arguments]", arrayTag = "[object Array]", boolTag = "[object Boolean]", dateTag = "[object Date]", errorTag = "[object Error]", funcTag = "[object Function]", genTag = "[object GeneratorFunction]", mapTag = "[object Map]", numberTag = "[object Number]", objectTag = "[object Object]", promiseTag = "[object Promise]", regexpTag = "[object RegExp]", setTag = "[object Set]", stringTag = "[object String]", symbolTag = "[object Symbol]", weakMapTag = "[object WeakMap]";
var arrayBufferTag = "[object ArrayBuffer]", dataViewTag = "[object DataView]", float32Tag = "[object Float32Array]", float64Tag = "[object Float64Array]", int8Tag = "[object Int8Array]", int16Tag = "[object Int16Array]", int32Tag = "[object Int32Array]", uint8Tag = "[object Uint8Array]", uint8ClampedTag = "[object Uint8ClampedArray]", uint16Tag = "[object Uint16Array]", uint32Tag = "[object Uint32Array]";
/**
* Used to match `RegExp`
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
*/
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
/** Used to match `RegExp` flags from their coerced string values. */
var reFlags = /\w*$/;
/** Used to detect host constructors (Safari). */
var reIsHostCtor = /^\[object .+?Constructor\]$/;
/** Used to detect unsigned integer values. */
var reIsUint = /^(?:0|[1-9]\d*)$/;
/** Used to identify `toStringTag` values supported by `_.clone`. */
var cloneableTags = {};
cloneableTags[argsTag] = cloneableTags[arrayTag] = cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = cloneableTags[boolTag] = cloneableTags[dateTag] = cloneableTags[float32Tag] = cloneableTags[float64Tag] = cloneableTags[int8Tag] = cloneableTags[int16Tag] = cloneableTags[int32Tag] = cloneableTags[mapTag] = cloneableTags[numberTag] = cloneableTags[objectTag] = cloneableTags[regexpTag] = cloneableTags[setTag] = cloneableTags[stringTag] = cloneableTags[symbolTag] = cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
cloneableTags[errorTag] = cloneableTags[funcTag] = cloneableTags[weakMapTag] = false;
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
/** Detect free variable `self`. */
var freeSelf = typeof self == "object" && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function("return this")();
/** Detect free variable `exports`. */
var freeExports = typeof exports == "object" && exports && !exports.nodeType && exports;
/** Detect free variable `module`. */
var freeModule = freeExports && typeof module == "object" && module && !module.nodeType && module;
/** Detect the popular CommonJS extension `module.exports`. */
var moduleExports = freeModule && freeModule.exports === freeExports;
/**
* Adds the key-value `pair` to `map`.
*
* @private
* @param {Object} map The map to modify.
* @param {Array} pair The key-value pair to add.
* @returns {Object} Returns `map`.
*/
function addMapEntry(map, pair) {
map.set(pair[0], pair[1]);
return map;
}
/**
* Adds `value` to `set`.
*
* @private
* @param {Object} set The set to modify.
* @param {*} value The value to add.
* @returns {Object} Returns `set`.
*/
function addSetEntry(set, value) {
set.add(value);
return set;
}
/**
* A specialized version of `_.forEach` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns `array`.
*/
function arrayEach(array, iteratee) {
var index = -1, length = array ? array.length : 0;
while (++index < length) if (iteratee(array[index], index, array) === false) break;
return array;
}
/**
* Appends the elements of `values` to `array`.
*
* @private
* @param {Array} array The array to modify.
* @param {Array} values The values to append.
* @returns {Array} Returns `array`.
*/
function arrayPush(array, values) {
var index = -1, length = values.length, offset = array.length;
while (++index < length) array[offset + index] = values[index];
return array;
}
/**
* A specialized version of `_.reduce` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
* @param {boolean} [initAccum] Specify using the first element of `array` as
* the initial value.
* @returns {*} Returns the accumulated value.
*/
function arrayReduce(array, iteratee, accumulator, initAccum) {
var index = -1, length = array ? array.length : 0;
if (initAccum && length) accumulator = array[++index];
while (++index < length) accumulator = iteratee(accumulator, array[index], index, array);
return accumulator;
}
/**
* The base implementation of `_.times` without support for iteratee shorthands
* or max array length checks.
*
* @private
* @param {number} n The number of times to invoke `iteratee`.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns the array of results.
*/
function baseTimes(n, iteratee) {
var index = -1, result = Array(n);
while (++index < n) result[index] = iteratee(index);
return result;
}
/**
* Gets the value at `key` of `object`.
*
* @private
* @param {Object} [object] The object to query.
* @param {string} key The key of the property to get.
* @returns {*} Returns the property value.
*/
function getValue(object, key) {
return object == null ? void 0 : object[key];
}
/**
* Checks if `value` is a host object in IE < 9.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a host object, else `false`.
*/
function isHostObject(value) {
var result = false;
if (value != null && typeof value.toString != "function") try {
result = !!(value + "");
} catch (e) {}
return result;
}
/**
* Converts `map` to its key-value pairs.
*
* @private
* @param {Object} map The map to convert.
* @returns {Array} Returns the key-value pairs.
*/
function mapToArray(map) {
var index = -1, result = Array(map.size);
map.forEach(function(value, key) {
result[++index] = [key, value];
});
return result;
}
/**
* Creates a unary function that invokes `func` with its argument transformed.
*
* @private
* @param {Function} func The function to wrap.
* @param {Function} transform The argument transform.
* @returns {Function} Returns the new function.
*/
function overArg(func, transform) {
return function(arg) {
return func(transform(arg));
};
}
/**
* Converts `set` to an array of its values.
*
* @private
* @param {Object} set The set to convert.
* @returns {Array} Returns the values.
*/
function setToArray(set) {
var index = -1, result = Array(set.size);
set.forEach(function(value) {
result[++index] = value;
});
return result;
}
/** Used for built-in method references. */
var arrayProto = Array.prototype, funcProto = Function.prototype, objectProto = Object.prototype;
/** Used to detect overreaching core-js shims. */
var coreJsData = root["__core-js_shared__"];
/** Used to detect methods masquerading as native. */
var maskSrcKey = function() {
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || "");
return uid ? "Symbol(src)_1." + uid : "";
}();
/** Used to resolve the decompiled source of functions. */
var funcToString = funcProto.toString;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var objectToString = objectProto.toString;
/** Used to detect if a method is native. */
var reIsNative = RegExp("^" + funcToString.call(hasOwnProperty).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$");
/** Built-in value references. */
var Buffer = moduleExports ? root.Buffer : void 0, Symbol$1 = root.Symbol, Uint8Array = root.Uint8Array, getPrototype = overArg(Object.getPrototypeOf, Object), objectCreate = Object.create, propertyIsEnumerable = objectProto.propertyIsEnumerable, splice = arrayProto.splice;
var nativeGetSymbols = Object.getOwnPropertySymbols, nativeIsBuffer = Buffer ? Buffer.isBuffer : void 0, nativeKeys = overArg(Object.keys, Object);
var DataView = getNative(root, "DataView"), Map$1 = getNative(root, "Map"), Promise$1 = getNative(root, "Promise"), Set$1 = getNative(root, "Set"), WeakMap$1 = getNative(root, "WeakMap"), nativeCreate = getNative(Object, "create");
/** Used to detect maps, sets, and weakmaps. */
var dataViewCtorString = toSource(DataView), mapCtorString = toSource(Map$1), promiseCtorString = toSource(Promise$1), setCtorString = toSource(Set$1), weakMapCtorString = toSource(WeakMap$1);
/** Used to convert symbols to primitives and strings. */
var symbolProto = Symbol$1 ? Symbol$1.prototype : void 0, symbolValueOf = symbolProto ? symbolProto.valueOf : void 0;
/**
* Creates a hash object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function Hash(entries) {
var index = -1, length = entries ? entries.length : 0;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
/**
* Removes all key-value entries from the hash.
*
* @private
* @name clear
* @memberOf Hash
*/
function hashClear() {
this.__data__ = nativeCreate ? nativeCreate(null) : {};
}
/**
* Removes `key` and its value from the hash.
*
* @private
* @name delete
* @memberOf Hash
* @param {Object} hash The hash to modify.
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function hashDelete(key) {
return this.has(key) && delete this.__data__[key];
}
/**
* Gets the hash value for `key`.
*
* @private
* @name get
* @memberOf Hash
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function hashGet(key) {
var data = this.__data__;
if (nativeCreate) {
var result = data[key];
return result === HASH_UNDEFINED ? void 0 : result;
}
return hasOwnProperty.call(data, key) ? data[key] : void 0;
}
/**
* Checks if a hash value for `key` exists.
*
* @private
* @name has
* @memberOf Hash
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function hashHas(key) {
var data = this.__data__;
return nativeCreate ? data[key] !== void 0 : hasOwnProperty.call(data, key);
}
/**
* Sets the hash `key` to `value`.
*
* @private
* @name set
* @memberOf Hash
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the hash instance.
*/
function hashSet(key, value) {
var data = this.__data__;
data[key] = nativeCreate && value === void 0 ? HASH_UNDEFINED : value;
return this;
}
Hash.prototype.clear = hashClear;
Hash.prototype["delete"] = hashDelete;
Hash.prototype.get = hashGet;
Hash.prototype.has = hashHas;
Hash.prototype.set = hashSet;
/**
* Creates an list cache object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function ListCache(entries) {
var index = -1, length = entries ? entries.length : 0;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
/**
* Removes all key-value entries from the list cache.
*
* @private
* @name clear
* @memberOf ListCache
*/
function listCacheClear() {
this.__data__ = [];
}
/**
* Removes `key` and its value from the list cache.
*
* @private
* @name delete
* @memberOf ListCache
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function listCacheDelete(key) {
var data = this.__data__, index = assocIndexOf(data, key);
if (index < 0) return false;
if (index == data.length - 1) data.pop();
else splice.call(data, index, 1);
return true;
}
/**
* Gets the list cache value for `key`.
*
* @private
* @name get
* @memberOf ListCache
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function listCacheGet(key) {
var data = this.__data__, index = assocIndexOf(data, key);
return index < 0 ? void 0 : data[index][1];
}
/**
* Checks if a list cache value for `key` exists.
*
* @private
* @name has
* @memberOf ListCache
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function listCacheHas(key) {
return assocIndexOf(this.__data__, key) > -1;
}
/**
* Sets the list cache `key` to `value`.
*
* @private
* @name set
* @memberOf ListCache
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the list cache instance.
*/
function listCacheSet(key, value) {
var data = this.__data__, index = assocIndexOf(data, key);
if (index < 0) data.push([key, value]);
else data[index][1] = value;
return this;
}
ListCache.prototype.clear = listCacheClear;
ListCache.prototype["delete"] = listCacheDelete;
ListCache.prototype.get = listCacheGet;
ListCache.prototype.has = listCacheHas;
ListCache.prototype.set = listCacheSet;
/**
* Creates a map cache object to store key-value pairs.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function MapCache(entries) {
var index = -1, length = entries ? entries.length : 0;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
/**
* Removes all key-value entries from the map.
*
* @private
* @name clear
* @memberOf MapCache
*/
function mapCacheClear() {
this.__data__ = {
"hash": new Hash(),
"map": new (Map$1 || ListCache)(),
"string": new Hash()
};
}
/**
* Removes `key` and its value from the map.
*
* @private
* @name delete
* @memberOf MapCache
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function mapCacheDelete(key) {
return getMapData(this, key)["delete"](key);
}
/**
* Gets the map value for `key`.
*
* @private
* @name get
* @memberOf MapCache
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function mapCacheGet(key) {
return getMapData(this, key).get(key);
}
/**
* Checks if a map value for `key` exists.
*
* @private
* @name has
* @memberOf MapCache
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function mapCacheHas(key) {
return getMapData(this, key).has(key);
}
/**
* Sets the map `key` to `value`.
*
* @private
* @name set
* @memberOf MapCache
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the map cache instance.
*/
function mapCacheSet(key, value) {
getMapData(this, key).set(key, value);
return this;
}
MapCache.prototype.clear = mapCacheClear;
MapCache.prototype["delete"] = mapCacheDelete;
MapCache.prototype.get = mapCacheGet;
MapCache.prototype.has = mapCacheHas;
MapCache.prototype.set = mapCacheSet;
/**
* Creates a stack cache object to store key-value pairs.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function Stack(entries) {
this.__data__ = new ListCache(entries);
}
/**
* Removes all key-value entries from the stack.
*
* @private
* @name clear
* @memberOf Stack
*/
function stackClear() {
this.__data__ = new ListCache();
}
/**
* Removes `key` and its value from the stack.
*
* @private
* @name delete
* @memberOf Stack
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function stackDelete(key) {
return this.__data__["delete"](key);
}
/**
* Gets the stack value for `key`.
*
* @private
* @name get
* @memberOf Stack
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function stackGet(key) {
return this.__data__.get(key);
}
/**
* Checks if a stack value for `key` exists.
*
* @private
* @name has
* @memberOf Stack
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function stackHas(key) {
return this.__data__.has(key);
}
/**
* Sets the stack `key` to `value`.
*
* @private
* @name set
* @memberOf Stack
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the stack cache instance.
*/
function stackSet(key, value) {
var cache = this.__data__;
if (cache instanceof ListCache) {
var pairs = cache.__data__;
if (!Map$1 || pairs.length < LARGE_ARRAY_SIZE - 1) {
pairs.push([key, value]);
return this;
}
cache = this.__data__ = new MapCache(pairs);
}
cache.set(key, value);
return this;
}
Stack.prototype.clear = stackClear;
Stack.prototype["delete"] = stackDelete;
Stack.prototype.get = stackGet;
Stack.prototype.has = stackHas;
Stack.prototype.set = stackSet;
/**
* Creates an array of the enumerable property names of the array-like `value`.
*
* @private
* @param {*} value The value to query.
* @param {boolean} inherited Specify returning inherited property names.
* @returns {Array} Returns the array of property names.
*/
function arrayLikeKeys(value, inherited) {
var result = isArray(value) || isArguments(value) ? baseTimes(value.length, String) : [];
var length = result.length, skipIndexes = !!length;
for (var key in value) if ((inherited || hasOwnProperty.call(value, key)) && !(skipIndexes && (key == "length" || isIndex(key, length)))) result.push(key);
return result;
}
/**
* Assigns `value` to `key` of `object` if the existing value is not equivalent
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons.
*
* @private
* @param {Object} object The object to modify.
* @param {string} key The key of the property to assign.
* @param {*} value The value to assign.
*/
function assignValue(object, key, value) {
var objValue = object[key];
if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || value === void 0 && !(key in object)) object[key] = value;
}
/**
* Gets the index at which the `key` is found in `array` of key-value pairs.
*
* @private
* @param {Array} array The array to inspect.
* @param {*} key The key to search for.
* @returns {number} Returns the index of the matched value, else `-1`.
*/
function assocIndexOf(array, key) {
var length = array.length;
while (length--) if (eq(array[length][0], key)) return length;
return -1;
}
/**
* The base implementation of `_.assign` without support for multiple sources
* or `customizer` functions.
*
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @returns {Object} Returns `object`.
*/
function baseAssign(object, source) {
return object && copyObject(source, keys(source), object);
}
/**
* The base implementation of `_.clone` and `_.cloneDeep` which tracks
* traversed objects.
*
* @private
* @param {*} value The value to clone.
* @param {boolean} [isDeep] Specify a deep clone.
* @param {boolean} [isFull] Specify a clone including symbols.
* @param {Function} [customizer] The function to customize cloning.
* @param {string} [key] The key of `value`.
* @param {Object} [object] The parent object of `value`.
* @param {Object} [stack] Tracks traversed objects and their clone counterparts.
* @returns {*} Returns the cloned value.
*/
function baseClone(value, isDeep, isFull, customizer, key, object, stack) {
var result;
if (customizer) result = object ? customizer(value, key, object, stack) : customizer(value);
if (result !== void 0) return result;
if (!isObject(value)) return value;
var isArr = isArray(value);
if (isArr) {
result = initCloneArray(value);
if (!isDeep) return copyArray(value, result);
} else {
var tag = getTag(value), isFunc = tag == funcTag || tag == genTag;
if (isBuffer(value)) return cloneBuffer(value, isDeep);
if (tag == objectTag || tag == argsTag || isFunc && !object) {
if (isHostObject(value)) return object ? value : {};
result = initCloneObject(isFunc ? {} : value);
if (!isDeep) return copySymbols(value, baseAssign(result, value));
} else {
if (!cloneableTags[tag]) return object ? value : {};
result = initCloneByTag(value, tag, baseClone, isDeep);
}
}
stack || (stack = new Stack());
var stacked = stack.get(value);
if (stacked) return stacked;
stack.set(value, result);
if (!isArr) var props = isFull ? getAllKeys(value) : keys(value);
arrayEach(props || value, function(subValue, key$1) {
if (props) {
key$1 = subValue;
subValue = value[key$1];
}
assignValue(result, key$1, baseClone(subValue, isDeep, isFull, customizer, key$1, value, stack));
});
return result;
}
/**
* The base implementation of `_.create` without support for assigning
* properties to the created object.
*
* @private
* @param {Object} prototype The object to inherit from.
* @returns {Object} Returns the new object.
*/
function baseCreate(proto) {
return isObject(proto) ? objectCreate(proto) : {};
}
/**
* The base implementation of `getAllKeys` and `getAllKeysIn` which uses
* `keysFunc` and `symbolsFunc` to get the enumerable property names and
* symbols of `object`.
*
* @private
* @param {Object} object The object to query.
* @param {Function} keysFunc The function to get the keys of `object`.
* @param {Function} symbolsFunc The function to get the symbols of `object`.
* @returns {Array} Returns the array of property names and symbols.
*/
function baseGetAllKeys(object, keysFunc, symbolsFunc) {
var result = keysFunc(object);
return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
}
/**
* The base implementation of `getTag`.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
function baseGetTag(value) {
return objectToString.call(value);
}
/**
* The base implementation of `_.isNative` without bad shim checks.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a native function,
* else `false`.
*/
function baseIsNative(value) {
if (!isObject(value) || isMasked(value)) return false;
return (isFunction(value) || isHostObject(value) ? reIsNative : reIsHostCtor).test(toSource(value));
}
/**
* The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
*/
function baseKeys(object) {
if (!isPrototype(object)) return nativeKeys(object);
var result = [];
for (var key in Object(object)) if (hasOwnProperty.call(object, key) && key != "constructor") result.push(key);
return result;
}
/**
* Creates a clone of `buffer`.
*
* @private
* @param {Buffer} buffer The buffer to clone.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Buffer} Returns the cloned buffer.
*/
function cloneBuffer(buffer, isDeep) {
if (isDeep) return buffer.slice();
var result = new buffer.constructor(buffer.length);
buffer.copy(result);
return result;
}
/**
* Creates a clone of `arrayBuffer`.
*
* @private
* @param {ArrayBuffer} arrayBuffer The array buffer to clone.
* @returns {ArrayBuffer} Returns the cloned array buffer.
*/
function cloneArrayBuffer(arrayBuffer) {
var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
new Uint8Array(result).set(new Uint8Array(arrayBuffer));
return result;
}
/**
* Creates a clone of `dataView`.
*
* @private
* @param {Object} dataView The data view to clone.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the cloned data view.
*/
function cloneDataView(dataView, isDeep) {
var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
}
/**
* Creates a clone of `map`.
*
* @private
* @param {Object} map The map to clone.
* @param {Function} cloneFunc The function to clone values.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the cloned map.
*/
function cloneMap(map, isDeep, cloneFunc) {
return arrayReduce(isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map), addMapEntry, new map.constructor());
}
/**
* Creates a clone of `regexp`.
*
* @private
* @param {Object} regexp The regexp to clone.
* @returns {Object} Returns the cloned regexp.
*/
function cloneRegExp(regexp) {
var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
result.lastIndex = regexp.lastIndex;
return result;
}
/**
* Creates a clone of `set`.
*
* @private
* @param {Object} set The set to clone.
* @param {Function} cloneFunc The function to clone values.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the cloned set.
*/
function cloneSet(set, isDeep, cloneFunc) {
return arrayReduce(isDeep ? cloneFunc(setToArray(set), true) : setToArray(set), addSetEntry, new set.constructor());
}
/**
* Creates a clone of the `symbol` object.
*
* @private
* @param {Object} symbol The symbol object to clone.
* @returns {Object} Returns the cloned symbol object.
*/
function cloneSymbol(symbol) {
return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
}
/**
* Creates a clone of `typedArray`.
*
* @private
* @param {Object} typedArray The typed array to clone.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the cloned typed array.
*/
function cloneTypedArray(typedArray, isDeep) {
var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
}
/**
* Copies the values of `source` to `array`.
*
* @private
* @param {Array} source The array to copy values from.
* @param {Array} [array=[]] The array to copy values to.
* @returns {Array} Returns `array`.
*/
function copyArray(source, array) {
var index = -1, length = source.length;
array || (array = Array(length));
while (++index < length) array[index] = source[index];
return array;
}
/**
* Copies properties of `source` to `object`.
*
* @private
* @param {Object} source The object to copy properties from.
* @param {Array} props The property identifiers to copy.
* @param {Object} [object={}] The object to copy properties to.
* @param {Function} [customizer] The function to customize copied values.
* @returns {Object} Returns `object`.
*/
function copyObject(source, props, object, customizer) {
object || (object = {});
var index = -1, length = props.length;
while (++index < length) {
var key = props[index];
var newValue = customizer ? customizer(object[key], source[key], key, object, source) : void 0;
assignValue(object, key, newValue === void 0 ? source[key] : newValue);
}
return object;
}
/**
* Copies own symbol properties of `source` to `object`.
*
* @private
* @param {Object} source The object to copy symbols from.
* @param {Object} [object={}] The object to copy symbols to.
* @returns {Object} Returns `object`.
*/
function copySymbols(source, object) {
return copyObject(source, getSymbols(source), object);
}
/**
* Creates an array of own enumerable property names and symbols of `object`.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names and symbols.
*/
function getAllKeys(object) {
return baseGetAllKeys(object, keys, getSymbols);
}
/**
* Gets the data for `map`.
*
* @private
* @param {Object} map The map to query.
* @param {string} key The reference key.
* @returns {*} Returns the map data.
*/
function getMapData(map, key) {
var data = map.__data__;
return isKeyable(key) ? data[typeof key == "string" ? "string" : "hash"] : data.map;
}
/**
* Gets the native function at `key` of `object`.
*
* @private
* @param {Object} object The object to query.
* @param {string} key The key of the method to get.
* @returns {*} Returns the function if it's native, else `undefined`.
*/
function getNative(object, key) {
var value = getValue(object, key);
return baseIsNative(value) ? value : void 0;
}
/**
* Creates an array of the own enumerable symbol properties of `object`.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the array of symbols.
*/
var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray;
/**
* Gets the `toStringTag` of `value`.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
var getTag = baseGetTag;
if (DataView && getTag(new DataView(/* @__PURE__ */ new ArrayBuffer(1))) != dataViewTag || Map$1 && getTag(new Map$1()) != mapTag || Promise$1 && getTag(Promise$1.resolve()) != promiseTag || Set$1 && getTag(new Set$1()) != setTag || WeakMap$1 && getTag(new WeakMap$1()) != weakMapTag) getTag = function(value) {
var result = objectToString.call(value), Ctor = result == objectTag ? value.constructor : void 0, ctorString = Ctor ? toSource(Ctor) : void 0;
if (ctorString) switch (ctorString) {
case dataViewCtorString: return dataViewTag;
case mapCtorString: return mapTag;
case promiseCtorString: return promiseTag;
case setCtorString: return setTag;
case weakMapCtorString: return weakMapTag;
}
return result;
};
/**
* Initializes an array clone.
*
* @private
* @param {Array} array The array to clone.
* @returns {Array} Returns the initialized clone.
*/
function initCloneArray(array) {
var length = array.length, result = array.constructor(length);
if (length && typeof array[0] == "string" && hasOwnProperty.call(array, "index")) {
result.index = array.index;
result.input = array.input;
}
return result;
}
/**
* Initializes an object clone.
*
* @private
* @param {Object} object The object to clone.
* @returns {Object} Returns the initialized clone.
*/
function initCloneObject(object) {
return typeof object.constructor == "function" && !isPrototype(object) ? baseCreate(getPrototype(object)) : {};
}
/**
* Initializes an object clone based on its `toStringTag`.
*
* **Note:** This function only supports cloning values with tags of
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
*
* @private
* @param {Object} object The object to clone.
* @param {string} tag The `toStringTag` of the object to clone.
* @param {Function} cloneFunc The function to clone values.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the initialized clone.
*/
function initCloneByTag(object, tag, cloneFunc, isDeep) {
var Ctor = object.constructor;
switch (tag) {
case arrayBufferTag: return cloneArrayBuffer(object);
case boolTag:
case dateTag: return new Ctor(+object);
case dataViewTag: return cloneDataView(object, isDeep);
case float32Tag:
case float64Tag:
case int8Tag:
case int16Tag:
case int32Tag:
case uint8Tag:
case uint8ClampedTag:
case uint16Tag:
case uint32Tag: return cloneTypedArray(object, isDeep);
case mapTag: return cloneMap(object, isDeep, cloneFunc);
case numberTag:
case stringTag: return new Ctor(object);
case regexpTag: return cloneRegExp(object);
case setTag: return cloneSet(object, isDeep, cloneFunc);
case symbolTag: return cloneSymbol(object);
}
}
/**
* Checks if `value` is a valid array-like index.
*
* @private
* @param {*} value The value to check.
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
*/
function isIndex(value, length) {
length = length == null ? MAX_SAFE_INTEGER : length;
return !!length && (typeof value == "number" || reIsUint.test(value)) && value > -1 && value % 1 == 0 && value < length;
}
/**
* Checks if `value` is suitable for use as unique object key.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is suitable, else `false`.
*/
function isKeyable(value) {
var type = typeof value;
return type == "string" || type == "number" || type == "symbol" || type == "boolean" ? value !== "__proto__" : value === null;
}
/**
* Checks if `func` has its source masked.
*
* @private
* @param {Function} func The function to check.
* @returns {boolean} Returns `true` if `func` is masked, else `false`.
*/
function isMasked(func) {
return !!maskSrcKey && maskSrcKey in func;
}
/**
* Checks if `value` is likely a prototype object.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
*/
function isPrototype(value) {
var Ctor = value && value.constructor;
return value === (typeof Ctor == "function" && Ctor.prototype || objectProto);
}
/**
* Converts `func` to its source code.
*
* @private
* @param {Function} func The function to process.
* @returns {string} Returns the source code.
*/
function toSource(func) {
if (func != null) {
try {
return funcToString.call(func);
} catch (e) {}
try {
return func + "";
} catch (e) {}
}
return "";
}
/**
* This method is like `_.clone` except that it recursively clones `value`.
*
* @static
* @memberOf _
* @since 1.0.0
* @category Lang
* @param {*} value The value to recursively clone.
* @returns {*} Returns the deep cloned value.
* @see _.clone
* @example
*
* var objects = [{ 'a': 1 }, { 'b': 2 }];
*
* var deep = _.cloneDeep(objects);
* console.log(deep[0] === objects[0]);
* // => false
*/
function cloneDeep$1(value) {
return baseClone(value, true, true);
}
/**
* Performs a
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* comparison between two values to determine if they are equivalent.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
* @example
*
* var object = { 'a': 1 };
* var other = { 'a': 1 };
*
* _.eq(object, object);
* // => true
*
* _.eq(object, other);
* // => false
*
* _.eq('a', 'a');
* // => true
*
* _.eq('a', Object('a'));
* // => false
*
* _.eq(NaN, NaN);
* // => true
*/
function eq(value, other) {
return value === other || value !== value && other !== other;
}
/**
* Checks if `value` is likely an `arguments` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
* else `false`.
* @example
*
* _.isArguments(function() { return arguments; }());
* // => true
*
* _.isArguments([1, 2, 3]);
* // => false
*/
function isArguments(value) {
return isArrayLikeObject(value) && hasOwnProperty.call(value, "callee") && (!propertyIsEnumerable.call(value, "callee") || objectToString.call(value) == argsTag);
}
/**
* Checks if `value` is classified as an `Array` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(document.body.children);
* // => false
*
* _.isArray('abc');
* // => false
*
* _.isArray(_.noop);
* // => false
*/
var isArray = Array.isArray;
/**
* Checks if `value` is array-like. A value is considered array-like if it's
* not a function and has a `value.length` that's an integer greater than or
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
* @example
*
* _.isArrayLike([1, 2, 3]);
* // => true
*
* _.isArrayLike(document.body.children);
* // => true
*
* _.isArrayLike('abc');
* // => true
*
* _.isArrayLike(_.noop);
* // => false
*/
function isArrayLike(value) {
return value != null && isLength(value.length) && !isFunction(value);
}
/**
* This method is like `_.isArrayLike` except that it also checks if `value`
* is an object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array-like object,
* else `false`.
* @example
*
* _.isArrayLikeObject([1, 2, 3]);
* // => true
*
* _.isArrayLikeObject(document.body.children);
* // => true
*
* _.isArrayLikeObject('abc');
* // => false
*
* _.isArrayLikeObject(_.noop);
* // => false
*/
function isArrayLikeObject(value) {
return isObjectLike(value) && isArrayLike(value);
}
/**
* Checks if `value` is a buffer.
*
* @static
* @memberOf _
* @since 4.3.0
* @category Lang
* @param {*} value The value