summaryrefslogtreecommitdiff
path: root/includes/external/school/node_modules/string-left-right/dist/string-left-right.dev.umd.js
diff options
context:
space:
mode:
Diffstat (limited to 'includes/external/school/node_modules/string-left-right/dist/string-left-right.dev.umd.js')
-rw-r--r--includes/external/school/node_modules/string-left-right/dist/string-left-right.dev.umd.js2600
1 files changed, 2600 insertions, 0 deletions
diff --git a/includes/external/school/node_modules/string-left-right/dist/string-left-right.dev.umd.js b/includes/external/school/node_modules/string-left-right/dist/string-left-right.dev.umd.js
new file mode 100644
index 0000000..4737b0c
--- /dev/null
+++ b/includes/external/school/node_modules/string-left-right/dist/string-left-right.dev.umd.js
@@ -0,0 +1,2600 @@
+/**
+ * @name string-left-right
+ * @fileoverview Looks up the first non-whitespace character to the left/right of a given index
+ * @version 4.1.0
+ * @author Roy Revelt, Codsen Ltd
+ * @license MIT
+ * {@link https://codsen.com/os/string-left-right/}
+ */
+
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+typeof define === 'function' && define.amd ? define(['exports'], factory) :
+(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.stringLeftRight = {}));
+}(this, (function (exports) { 'use strict';
+
+var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
+
+/**
+ * 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
+ */
+
+/** `Object#toString` result references. */
+var objectTag = '[object Object]';
+
+/**
+ * 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) {
+ // Many host objects are `Object` objects that can coerce to strings
+ // despite having improperly defined `toString` methods.
+ var result = false;
+ if (value != null && typeof value.toString != 'function') {
+ try {
+ result = !!(value + '');
+ } catch (e) {}
+ }
+ 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));
+ };
+}
+
+/** Used for built-in method references. */
+var funcProto = Function.prototype,
+ objectProto = Object.prototype;
+
+/** 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 infer the `Object` constructor. */
+var objectCtorString = funcToString.call(Object);
+
+/**
+ * Used to resolve the
+ * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objectToString = objectProto.toString;
+
+/** Built-in value references. */
+var getPrototype = overArg(Object.getPrototypeOf, Object);
+
+/**
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
+ * and has a `typeof` result of "object".
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ * @example
+ *
+ * _.isObjectLike({});
+ * // => true
+ *
+ * _.isObjectLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isObjectLike(_.noop);
+ * // => false
+ *
+ * _.isObjectLike(null);
+ * // => false
+ */
+function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+}
+
+/**
+ * Checks if `value` is a plain object, that is, an object created by the
+ * `Object` constructor or one with a `[[Prototype]]` of `null`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.8.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * }
+ *
+ * _.isPlainObject(new Foo);
+ * // => false
+ *
+ * _.isPlainObject([1, 2, 3]);
+ * // => false
+ *
+ * _.isPlainObject({ 'x': 0, 'y': 0 });
+ * // => true
+ *
+ * _.isPlainObject(Object.create(null));
+ * // => true
+ */
+function isPlainObject(value) {
+ if (!isObjectLike(value) ||
+ objectToString.call(value) != objectTag || isHostObject(value)) {
+ return false;
+ }
+ var proto = getPrototype(value);
+ if (proto === null) {
+ return true;
+ }
+ var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
+ return (typeof Ctor == 'function' &&
+ Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
+}
+
+var lodash_isplainobject = isPlainObject;
+
+var lodash_clonedeep = {exports: {}};
+
+/**
+ * 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
+ */
+
+(function (module, exports) {
+/** 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 commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
+
+/** 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 = exports && !exports.nodeType && exports;
+
+/** Detect free variable `module`. */
+var freeModule = freeExports && 'object' == '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) {
+ // Don't return `map.set` because it's not chainable in IE 11.
+ 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) {
+ // Don't return `set.add` because it's not chainable in IE 11.
+ 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 ? undefined : 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) {
+ // Many host objects are `Object` objects that can coerce to strings
+ // despite having improperly defined `toString` methods.
+ 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 : undefined,
+ Symbol = root.Symbol,
+ Uint8Array = root.Uint8Array,
+ getPrototype = overArg(Object.getPrototypeOf, Object),
+ objectCreate = Object.create,
+ propertyIsEnumerable = objectProto.propertyIsEnumerable,
+ splice = arrayProto.splice;
+
+/* Built-in method references for those with the same name as other `lodash` methods. */
+var nativeGetSymbols = Object.getOwnPropertySymbols,
+ nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
+ nativeKeys = overArg(Object.keys, Object);
+
+/* Built-in method references that are verified to be native. */
+var DataView = getNative(root, 'DataView'),
+ Map = getNative(root, 'Map'),
+ Promise = getNative(root, 'Promise'),
+ Set = getNative(root, 'Set'),
+ WeakMap = getNative(root, 'WeakMap'),
+ nativeCreate = getNative(Object, 'create');
+
+/** Used to detect maps, sets, and weakmaps. */
+var dataViewCtorString = toSource(DataView),
+ mapCtorString = toSource(Map),
+ promiseCtorString = toSource(Promise),
+ setCtorString = toSource(Set),
+ weakMapCtorString = toSource(WeakMap);
+
+/** Used to convert symbols to primitives and strings. */
+var symbolProto = Symbol ? Symbol.prototype : undefined,
+ symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
+
+/**
+ * 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 ? undefined : result;
+ }
+ return hasOwnProperty.call(data, key) ? data[key] : undefined;
+}
+
+/**
+ * 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] !== undefined : 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 === undefined) ? HASH_UNDEFINED : value;
+ return this;
+}
+
+// Add methods to `Hash`.
+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;
+ }
+ var lastIndex = data.length - 1;
+ if (index == lastIndex) {
+ 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 ? undefined : 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;
+}
+
+// Add methods to `ListCache`.
+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 || 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;
+}
+
+// Add methods to `MapCache`.
+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 || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
+ pairs.push([key, value]);
+ return this;
+ }
+ cache = this.__data__ = new MapCache(pairs);
+ }
+ cache.set(key, value);
+ return this;
+}
+
+// Add methods to `Stack`.
+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) {
+ // Safari 8.1 makes `arguments.callee` enumerable in strict mode.
+ // Safari 9 makes `arguments.length` enumerable in strict mode.
+ 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 === undefined && !(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 !== undefined) {
+ 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);
+ }
+ }
+ // Check for circular references and return its corresponding clone.
+ 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) {
+ if (props) {
+ key = subValue;
+ subValue = value[key];
+ }
+ // Recursively populate clone (susceptible to call stack limits).
+ assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, 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;
+ }
+ var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
+ return pattern.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) {
+ var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map);
+ return arrayReduce(array, 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) {
+ var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set);
+ return arrayReduce(array, 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)
+ : undefined;
+
+ assignValue(object, key, newValue === undefined ? 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 : undefined;
+}
+
+/**
+ * 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;
+
+// Fallback for data views, maps, sets, and weak maps in IE 11,
+// for data views in Edge < 14, and promises in Node.js.
+if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
+ (Map && getTag(new Map) != mapTag) ||
+ (Promise && getTag(Promise.resolve()) != promiseTag) ||
+ (Set && getTag(new Set) != setTag) ||
+ (WeakMap && getTag(new WeakMap) != weakMapTag)) {
+ getTag = function(value) {
+ var result = objectToString.call(value),
+ Ctor = result == objectTag ? value.constructor : undefined,
+ ctorString = Ctor ? toSource(Ctor) : undefined;
+
+ 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);
+
+ // Add properties assigned by `RegExp#exec`.
+ 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,
+ proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
+
+ return value === proto;
+}
+
+/**
+ * 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(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) {
+ // Safari 8.1 makes `arguments.callee` enumerable in strict mode.
+ 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 to check.
+ * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
+ * @example
+ *
+ * _.isBuffer(new Buffer(2));
+ * // => true
+ *
+ * _.isBuffer(new Uint8Array(2));
+ * // => false
+ */
+var isBuffer = nativeIsBuffer || stubFalse;
+
+/**
+ * Checks if `value` is classified as a `Function` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a function, else `false`.
+ * @example
+ *
+ * _.isFunction(_);
+ * // => true
+ *
+ * _.isFunction(/abc/);
+ * // => false
+ */
+function isFunction(value) {
+ // The use of `Object#toString` avoids issues with the `typeof` operator
+ // in Safari 8-9 which returns 'object' for typed array and other constructors.
+ var tag = isObject(value) ? objectToString.call(value) : '';
+ return tag == funcTag || tag == genTag;
+}
+
+/**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This method is loosely based on
+ * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ * @example
+ *
+ * _.isLength(3);
+ * // => true
+ *
+ * _.isLength(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isLength(Infinity);
+ * // => false
+ *
+ * _.isLength('3');
+ * // => false
+ */
+function isLength(value) {
+ return typeof value == 'number' &&
+ value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+}
+
+/**
+ * Checks if `value` is the
+ * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(_.noop);
+ * // => true
+ *
+ * _.isObject(null);
+ * // => false
+ */
+function isObject(value) {
+ var type = typeof value;
+ return !!value && (type == 'object' || type == 'function');
+}
+
+/**
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
+ * and has a `typeof` result of "object".
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ * @example
+ *
+ * _.isObjectLike({});
+ * // => true
+ *
+ * _.isObjectLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isObjectLike(_.noop);
+ * // => false
+ *
+ * _.isObjectLike(null);
+ * // => false
+ */
+function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+}
+
+/**
+ * Creates an array of the own enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects. See the
+ * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
+ * for more details.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keys(new Foo);
+ * // => ['a', 'b'] (iteration order is not guaranteed)
+ *
+ * _.keys('hi');
+ * // => ['0', '1']
+ */
+function keys(object) {
+ return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
+}
+
+/**
+ * This method returns a new empty array.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.13.0
+ * @category Util
+ * @returns {Array} Returns the new empty array.
+ * @example
+ *
+ * var arrays = _.times(2, _.stubArray);
+ *
+ * console.log(arrays);
+ * // => [[], []]
+ *
+ * console.log(arrays[0] === arrays[1]);
+ * // => false
+ */
+function stubArray() {
+ return [];
+}
+
+/**
+ * This method returns `false`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.13.0
+ * @category Util
+ * @returns {boolean} Returns `false`.
+ * @example
+ *
+ * _.times(2, _.stubFalse);
+ * // => [false, false]
+ */
+function stubFalse() {
+ return false;
+}
+
+module.exports = cloneDeep;
+}(lodash_clonedeep, lodash_clonedeep.exports));
+
+var clone = lodash_clonedeep.exports;
+
+var version$1 = "4.1.0";
+
+const version = version$1;
+const RAWNBSP = "\u00A0";
+// separates the value from flags
+function x(something) {
+ // console.log(
+ // `007 ${`\u001b[${35}m${`x() incoming "${something}"`}\u001b[${39}m`}`
+ // );
+ const res = {
+ value: something,
+ hungry: false,
+ optional: false,
+ };
+ if ((res.value.endsWith("?*") || res.value.endsWith("*?")) &&
+ res.value.length > 2) {
+ res.value = res.value.slice(0, res.value.length - 2);
+ res.optional = true;
+ res.hungry = true;
+ }
+ else if (res.value.endsWith("?") && res.value.length > 1) {
+ res.value = res.value.slice(0, ~-res.value.length);
+ res.optional = true;
+ }
+ else if (res.value.endsWith("*") && res.value.length > 1) {
+ res.value = res.value.slice(0, ~-res.value.length);
+ res.hungry = true;
+ }
+ // console.log(
+ // `036 ${`\u001b[${35}m${`x() returning ${JSON.stringify(
+ // res,
+ // null,
+ // 0
+ // )}`}\u001b[${39}m`}`
+ // );
+ return res;
+}
+function isNum(something) {
+ return typeof something === "number";
+}
+function isStr(something) {
+ return typeof something === "string";
+}
+function rightMain({ str, idx = 0, stopAtNewlines = false, stopAtRawNbsp = false, }) {
+ if (typeof str !== "string" || !str.length) {
+ return null;
+ }
+ if (!idx || typeof idx !== "number") {
+ idx = 0;
+ }
+ if (!str[idx + 1]) {
+ return null;
+ }
+ if (
+ // next character exists
+ str[idx + 1] &&
+ // and...
+ // it's solid
+ (str[idx + 1].trim() ||
+ // or it's a whitespace character, but...
+ // stop at newlines is on
+ (stopAtNewlines &&
+ // and it's a newline
+ "\n\r".includes(str[idx + 1])) ||
+ // stop at raw nbsp is on
+ (stopAtRawNbsp &&
+ // and it's a raw nbsp
+ str[idx + 1] === RAWNBSP))) {
+ // best case scenario - next character is non-whitespace:
+ return idx + 1;
+ }
+ if (
+ // second next character exists
+ str[idx + 2] &&
+ // and...
+ // it's solid
+ (str[idx + 2].trim() ||
+ // it's a whitespace character and...
+ // stop at newlines is on
+ (stopAtNewlines &&
+ // and it's a newline
+ "\n\r".includes(str[idx + 2])) ||
+ // stop at raw nbsp is on
+ (stopAtRawNbsp &&
+ // and it's a raw nbsp
+ str[idx + 2] === RAWNBSP))) {
+ // second best case scenario - second next character is non-whitespace:
+ return idx + 2;
+ }
+ // worst case scenario - traverse forwards
+ for (let i = idx + 1, len = str.length; i < len; i++) {
+ if (
+ // it's solid
+ str[i].trim() ||
+ // it's a whitespace character and...
+ // stop at newlines is on
+ (stopAtNewlines &&
+ // and it's a newline
+ "\n\r".includes(str[i])) ||
+ // stop at raw nbsp is on
+ (stopAtRawNbsp &&
+ // and it's a raw nbsp
+ str[i] === RAWNBSP)) {
+ return i;
+ }
+ }
+ return null;
+}
+function right(str, idx = 0) {
+ return rightMain({ str, idx, stopAtNewlines: false, stopAtRawNbsp: false });
+}
+function rightStopAtNewLines(str, idx) {
+ return rightMain({ str, idx, stopAtNewlines: true, stopAtRawNbsp: false });
+}
+function rightStopAtRawNbsp(str, idx) {
+ return rightMain({ str, idx, stopAtNewlines: false, stopAtRawNbsp: true });
+}
+//
+//
+// lllllll ffffffffffffffff tttt (((((( ))))))
+// l:::::l f::::::::::::::::f ttt:::t ((::::::( )::::::))
+// l:::::l f::::::::::::::::::f t:::::t ((:::::::( ):::::::))
+// l:::::l f::::::fffffff:::::f t:::::t (:::::::(( )):::::::)
+// l::::l eeeeeeeeeeee f:::::f ffffffttttttt:::::ttttttt (::::::( )::::::)
+// l::::l ee::::::::::::ee f:::::f t:::::::::::::::::t (:::::( ):::::)
+// l::::l e::::::eeeee:::::eef:::::::ffffff t:::::::::::::::::t (:::::( ):::::)
+// l::::l e::::::e e:::::ef::::::::::::f tttttt:::::::tttttt (:::::( ):::::)
+// l::::l e:::::::eeeee::::::ef::::::::::::f t:::::t (:::::( ):::::)
+// l::::l e:::::::::::::::::e f:::::::ffffff t:::::t (:::::( ):::::)
+// l::::l e::::::eeeeeeeeeee f:::::f t:::::t (:::::( ):::::)
+// l::::l e:::::::e f:::::f t:::::t tttttt (::::::( )::::::)
+// l::::::le::::::::e f:::::::f t::::::tttt:::::t (:::::::(( )):::::::)
+// l::::::l e::::::::eeeeeeee f:::::::f tt::::::::::::::t ((:::::::( ):::::::))
+// l::::::l ee:::::::::::::e f:::::::f tt:::::::::::tt ((::::::( )::::::)
+// llllllll eeeeeeeeeeeeee fffffffff ttttttttttt (((((( ))))))
+//
+//
+// Finds the index of the first non-whitespace character on the left
+function leftMain({ str, idx, stopAtNewlines, stopAtRawNbsp }) {
+ if (typeof str !== "string" || !str.length) {
+ return null;
+ }
+ if (!idx || typeof idx !== "number") {
+ idx = 0;
+ }
+ if (idx < 1) {
+ return null;
+ }
+ if (
+ // ~- means minus one, in bitwise
+ str[~-idx] &&
+ // either it's not a whitespace
+ (str[~-idx].trim() ||
+ // or it is whitespace, but...
+ // stop at newlines is on
+ (stopAtNewlines &&
+ // and it's a newline
+ "\n\r".includes(str[~-idx])) ||
+ // stop at raw nbsp is on
+ (stopAtRawNbsp &&
+ // and it's a raw nbsp
+ str[~-idx] === RAWNBSP))) {
+ // best case scenario - next character is non-whitespace:
+ return ~-idx;
+ }
+ // if we reached this point, this means character on the left is whitespace -
+ // fine - check the next character on the left, str[idx - 2]
+ if (
+ // second character exists
+ str[idx - 2] &&
+ // either it's not whitespace so Bob's your uncle here's non-whitespace character
+ (str[idx - 2].trim() ||
+ // it is whitespace, but...
+ // stop at newlines is on
+ (stopAtNewlines &&
+ // it's some sort of a newline
+ "\n\r".includes(str[idx - 2])) ||
+ // stop at raw nbsp is on
+ (stopAtRawNbsp &&
+ // and it's a raw nbsp
+ str[idx - 2] === RAWNBSP))) {
+ // second best case scenario - second next character is non-whitespace:
+ return idx - 2;
+ }
+ // worst case scenario - traverse backwards
+ for (let i = idx; i--;) {
+ if (str[i] &&
+ // it's non-whitespace character
+ (str[i].trim() ||
+ // or it is whitespace character, but...
+ // stop at newlines is on
+ (stopAtNewlines &&
+ // it's some sort of a newline
+ "\n\r".includes(str[i])) ||
+ // stop at raw nbsp is on
+ (stopAtRawNbsp &&
+ // and it's a raw nbsp
+ str[i] === RAWNBSP))) {
+ return i;
+ }
+ }
+ return null;
+}
+function left(str, idx = 0) {
+ return leftMain({ str, idx, stopAtNewlines: false, stopAtRawNbsp: false });
+}
+function leftStopAtNewLines(str, idx) {
+ return leftMain({ str, idx, stopAtNewlines: true, stopAtRawNbsp: false });
+}
+function leftStopAtRawNbsp(str, idx) {
+ return leftMain({ str, idx, stopAtNewlines: false, stopAtRawNbsp: true });
+}
+function seq(direction, str, idx, opts, args) {
+ if (typeof str !== "string" || !str.length) {
+ return null;
+ }
+ if (typeof idx !== "number") {
+ idx = 0;
+ }
+ if ((direction === "right" && !str[idx + 1]) ||
+ (direction === "left" && !str[~-idx])) {
+ // if next character on the particular side doesn't even exist, that's a quick end
+ return null;
+ }
+ // we start to look on the particular side from index "idx".
+ // From there on, each finding sets its index to "lastFinding" so that we
+ // know where to start looking on from next. Any failed finding
+ // in a sequence is instant return "null".
+ let lastFinding = idx;
+ const gaps = [];
+ let leftmostChar;
+ let rightmostChar;
+ let satiated; // used to prevent mismatching action kicking in when that
+ // mismatching is after multiple hungry findings.
+ // go through all arguments
+ let i = 0;
+ // we use while loop because for loop would not do in hungry matching cases,
+ // where we need to repeat same step (hungrily matched character) few times.
+ while (i < args.length) {
+ if (!isStr(args[i]) || !args[i].length) {
+ i += 1;
+ continue;
+ }
+ const { value, optional, hungry } = x(args[i]);
+ const whattsOnTheSide = direction === "right" ? right(str, lastFinding) : left(str, lastFinding);
+ if ((opts.i &&
+ str[whattsOnTheSide].toLowerCase() === value.toLowerCase()) ||
+ (!opts.i && str[whattsOnTheSide] === value)) {
+ // OK, one was matched, we're in the right clauses (otherwise we'd skip
+ // if it was optional or break the matching)
+ // Now, it depends, is it a hungry match, because if so, we need to look
+ // for more of these.
+ const temp = direction === "right"
+ ? right(str, whattsOnTheSide)
+ : left(str, whattsOnTheSide);
+ if (hungry &&
+ ((opts.i &&
+ str[temp].toLowerCase() === value.toLowerCase()) ||
+ (!opts.i && str[temp] === value))) {
+ // satiated means next iteration is allowed not to match anything
+ satiated = true;
+ }
+ else {
+ // move on
+ i += 1;
+ }
+ // 1. first, tackle gaps
+ // if there was a gap, push it to gaps array:
+ if (typeof whattsOnTheSide === "number" &&
+ direction === "right" &&
+ whattsOnTheSide > lastFinding + 1) {
+ gaps.push([lastFinding + 1, whattsOnTheSide]);
+ }
+ else if (direction === "left" &&
+ typeof whattsOnTheSide === "number" &&
+ whattsOnTheSide < ~-lastFinding) {
+ gaps.unshift([whattsOnTheSide + 1, lastFinding]);
+ }
+ // 2. second, tackle the matching
+ lastFinding = whattsOnTheSide;
+ if (direction === "right") {
+ if (leftmostChar === undefined) {
+ leftmostChar = whattsOnTheSide;
+ }
+ rightmostChar = whattsOnTheSide;
+ }
+ else {
+ if (rightmostChar === undefined) {
+ rightmostChar = whattsOnTheSide;
+ }
+ leftmostChar = whattsOnTheSide;
+ }
+ }
+ else if (optional) {
+ i += 1;
+ continue;
+ }
+ else if (satiated) {
+ i += 1;
+ satiated = undefined;
+ continue;
+ }
+ else {
+ return null;
+ }
+ }
+ // if all arguments in sequence were empty strings, we return falsey null:
+ if (leftmostChar === undefined || rightmostChar === undefined) {
+ return null;
+ }
+ return { gaps, leftmostChar, rightmostChar };
+}
+//
+//
+// lllllll
+// l:::::l
+// l:::::l
+// l:::::l
+// l::::l rrrrr rrrrrrrrr ssssssssss eeeeeeeeeeee qqqqqqqqq qqqqq
+// l::::l r::::rrr:::::::::r ss::::::::::s ee::::::::::::ee q:::::::::qqq::::q
+// l::::l r:::::::::::::::::r ss:::::::::::::s e::::::eeeee:::::ee q:::::::::::::::::q
+// l::::l --------------- rr::::::rrrrr::::::r s::::::ssss:::::se::::::e e:::::eq::::::qqqqq::::::qq
+// l::::l -:::::::::::::- r:::::r r:::::r s:::::s ssssss e:::::::eeeee::::::eq:::::q q:::::q
+// l::::l --------------- r:::::r rrrrrrr s::::::s e:::::::::::::::::e q:::::q q:::::q
+// l::::l r:::::r s::::::s e::::::eeeeeeeeeee q:::::q q:::::q
+// l::::l r:::::r ssssss s:::::s e:::::::e q::::::q q:::::q
+// l::::::l r:::::r s:::::ssss::::::se::::::::e q:::::::qqqqq:::::q
+// l::::::l r:::::r s::::::::::::::s e::::::::eeeeeeee q::::::::::::::::q
+// l::::::l r:::::r s:::::::::::ss ee:::::::::::::e qq::::::::::::::q
+// llllllll rrrrrrr sssssssssss eeeeeeeeeeeeee qqqqqqqq::::::q
+// q:::::q
+// q:::::q
+// q:::::::q
+// q:::::::q
+// q:::::::q
+// qqqqqqqqq
+const seqDefaults = {
+ i: false,
+};
+function leftSeq(str, idx, ...args) {
+ // if there are no arguments, it becomes left()
+ if (!args || !args.length) {
+ // console.log(`493 leftSeq() calling left()`);
+ // return left(str, idx);
+ throw new Error(`string-left-right/leftSeq(): only two input arguments were passed! Did you intend to use left() method instead?`);
+ }
+ let opts;
+ if (lodash_isplainobject(args[0])) {
+ opts = { ...seqDefaults, ...args.shift() };
+ }
+ else {
+ opts = seqDefaults;
+ }
+ return seq("left", str, idx, opts, Array.from(args).reverse());
+}
+function rightSeq(str, idx, ...args) {
+ // if there are no arguments, it becomes right()
+ if (!args || !args.length) {
+ // console.log(`520 rightSeq() calling right()`);
+ // return right(str, idx);
+ throw new Error(`string-left-right/rightSeq(): only two input arguments were passed! Did you intend to use right() method instead?`);
+ }
+ let opts;
+ if (lodash_isplainobject(args[0])) {
+ opts = { ...seqDefaults, ...args.shift() };
+ }
+ else {
+ opts = seqDefaults;
+ }
+ return seq("right", str, idx, opts, args);
+}
+// chomp() lets you match sequences of characters with zero or more whitespace characters in between each,
+// on left or right of a given string index, with optional granular control over surrounding
+// whitespace-munching. Yes, that's a technical term.
+function chomp(direction, str, idx, opts, args = []) {
+ //
+ // INSURANCE.
+ //
+ if (typeof str !== "string" || !str.length) {
+ return null;
+ }
+ if (!idx || typeof idx !== "number") {
+ idx = 0;
+ }
+ if ((direction === "right" && !str[idx + 1]) ||
+ (direction === "left" && +idx === 0)) {
+ return null;
+ }
+ //
+ // ACTION.
+ //
+ let lastRes = null;
+ let lastIdx = null;
+ do {
+ lastRes =
+ direction === "right"
+ ? rightSeq(str, typeof lastIdx === "number" ? lastIdx : idx, ...args)
+ : leftSeq(str, typeof lastIdx === "number" ? lastIdx : idx, ...args);
+ if (lastRes !== null) {
+ lastIdx =
+ direction === "right" ? lastRes.rightmostChar : lastRes.leftmostChar;
+ }
+ } while (lastRes);
+ if (lastIdx != null && direction === "right") {
+ lastIdx += 1;
+ }
+ if (lastIdx === null) {
+ // if nothing was matched
+ return null;
+ }
+ // the last thing what's left to do is tackle the whitespace on the right.
+ // Depending on opts.mode, there can be different ways.
+ if (direction === "right") {
+ //
+ //
+ //
+ // R I G H T
+ //
+ //
+ //
+ // quick ending - no whitespace on the right at all:
+ if (str[lastIdx] && str[lastIdx].trim()) {
+ // if the character follows tightly right after,
+ return lastIdx;
+ }
+ // Default, 0 is leave single space if possible or chomp up to nearest line
+ // break character or chomp up to EOL
+ const whatsOnTheRight = right(str, lastIdx);
+ if (!opts || opts.mode === 0) {
+ if (whatsOnTheRight === lastIdx + 1) {
+ // if there's one whitespace character, Bob's your uncle here's
+ // the final result
+ return lastIdx;
+ }
+ if (str.slice(lastIdx, whatsOnTheRight || str.length).trim() ||
+ str.slice(lastIdx, whatsOnTheRight || str.length).includes("\n") ||
+ str.slice(lastIdx, whatsOnTheRight || str.length).includes("\r")) {
+ // if there are line break characters between current "lastIdx" we're on
+ // and the first non-whitespace character on the right
+ for (let y = lastIdx, len = str.length; y < len; y++) {
+ if (`\n\r`.includes(str[y])) {
+ return y;
+ }
+ }
+ }
+ else {
+ return whatsOnTheRight ? ~-whatsOnTheRight : str.length;
+ }
+ }
+ else if (opts.mode === 1) {
+ // mode 1 doesn't touch the whitespace, so it's quick:
+ return lastIdx;
+ }
+ else if (opts.mode === 2) {
+ // mode 2 hungrily chomps all whitespace except newlines
+ const remainderString = str.slice(lastIdx);
+ if (remainderString.trim() ||
+ remainderString.includes("\n") ||
+ remainderString.includes("\r")) {
+ // if there are line breaks, we need to loop to chomp up to them but not further
+ for (let y = lastIdx, len = str.length; y < len; y++) {
+ if (str[y].trim() || `\n\r`.includes(str[y])) {
+ return y;
+ }
+ }
+ }
+ // ELSE, last but not least, chomp to the end:
+ return str.length;
+ }
+ // ELSE - mode 3
+ // mode 3 is an aggro chomp - will chump all whitespace
+ return whatsOnTheRight || str.length;
+ //
+ //
+ //
+ // R I G H T E N D S
+ //
+ //
+ //
+ }
+ //
+ //
+ //
+ // L E F T
+ //
+ //
+ //
+ // quick ending - no whitespace on the left at all:
+ if (str[lastIdx] && str[~-lastIdx] && str[~-lastIdx].trim()) {
+ // if the non-whitespace character is on the left
+ return lastIdx;
+ }
+ // Default, 0 is leave single space if possible or chomp up to nearest line
+ // break character or chomp up to index zero, start of the string
+ const whatsOnTheLeft = left(str, lastIdx);
+ if (!opts || opts.mode === 0) {
+ if (whatsOnTheLeft === lastIdx - 2) {
+ // if there's one whitespace character between here and next real character, Bob's your uncle here's
+ // the final result
+ return lastIdx;
+ }
+ if (str.slice(0, lastIdx).trim() ||
+ str.slice(0, lastIdx).includes("\n") ||
+ str.slice(0, lastIdx).includes("\r")) {
+ // if there are line break characters between current "lastIdx" we're on
+ // and the first non-whitespace character on the right
+ for (let y = lastIdx; y--;) {
+ if (`\n\r`.includes(str[y]) || str[y].trim()) {
+ return y + 1 + (str[y].trim() ? 1 : 0);
+ }
+ }
+ }
+ // ELSE
+ return 0;
+ }
+ if (opts.mode === 1) {
+ // mode 1 doesn't touch the whitespace, so it's quick:
+ return lastIdx;
+ }
+ if (opts.mode === 2) {
+ // mode 2 hungrily chomps all whitespace except newlines
+ const remainderString = str.slice(0, lastIdx);
+ if (remainderString.trim() ||
+ remainderString.includes("\n") ||
+ remainderString.includes("\r")) {
+ // if there are line breaks, we need to loop to chomp up to them but not further
+ for (let y = lastIdx; y--;) {
+ if (str[y].trim() || `\n\r`.includes(str[y])) {
+ return y + 1;
+ }
+ }
+ }
+ // ELSE, last but not least, chomp to the end:
+ return 0;
+ }
+ // ELSE - mode 3
+ // mode 3 is an aggro chomp - will chump all whitespace
+ return whatsOnTheLeft !== null ? whatsOnTheLeft + 1 : 0;
+ //
+ //
+ //
+ // L E F T E N D S
+ //
+ //
+ //
+}
+//
+//
+// hhhhhhh LLLLLLLLLLL
+// h:::::h L:::::::::L
+// h:::::h L:::::::::L
+// h:::::h LL:::::::LL
+// cccccccccccccccch::::h hhhhh mmmmmmm mmmmmmm ppppp ppppppppp L:::::L
+// cc:::::::::::::::ch::::hh:::::hhh mm:::::::m m:::::::mm p::::ppp:::::::::p L:::::L
+// c:::::::::::::::::ch::::::::::::::hh m::::::::::mm::::::::::mp:::::::::::::::::p L:::::L
+// c:::::::cccccc:::::ch:::::::hhh::::::h m::::::::::::::::::::::mpp::::::ppppp::::::p L:::::L
+// c::::::c ccccccch::::::h h::::::hm:::::mmm::::::mmm:::::m p:::::p p:::::p L:::::L
+// c:::::c h:::::h h:::::hm::::m m::::m m::::m p:::::p p:::::p L:::::L
+// c:::::c h:::::h h:::::hm::::m m::::m m::::m p:::::p p:::::p L:::::L
+// c::::::c ccccccch:::::h h:::::hm::::m m::::m m::::m p:::::p p::::::p L:::::L LLLLLL
+// c:::::::cccccc:::::ch:::::h h:::::hm::::m m::::m m::::m p:::::ppppp:::::::pLL:::::::LLLLLLLLL:::::L
+// c:::::::::::::::::ch:::::h h:::::hm::::m m::::m m::::m p::::::::::::::::p L::::::::::::::::::::::L
+// cc:::::::::::::::ch:::::h h:::::hm::::m m::::m m::::m p::::::::::::::pp L::::::::::::::::::::::L
+// cccccccccccccccchhhhhhh hhhhhhhmmmmmm mmmmmm mmmmmm p::::::pppppppp LLLLLLLLLLLLLLLLLLLLLLLL
+// p:::::p
+// p:::::p
+// p:::::::p
+// p:::::::p
+// p:::::::p
+// ppppppppp
+//
+function chompLeft(str, idx, ...args) {
+ // if there are no arguments, null
+ if (!args.length || (args.length === 1 && lodash_isplainobject(args[0]))) {
+ return null;
+ }
+ //
+ // OPTS.
+ //
+ // modes:
+ // 0 - leave single space if possible
+ // 1 - stop at first space, leave whitespace alone
+ // 2 - aggressively chomp all whitespace except newlines
+ // 3 - aggressively chomp all whitespace including newlines
+ const defaults = {
+ mode: 0,
+ };
+ // now, the first element within args can be opts.
+ // It's a plain object so it's easy to distinguish
+ if (lodash_isplainobject(args[0])) {
+ const opts = { ...defaults, ...clone(args[0]) };
+ if (!opts.mode) {
+ opts.mode = 0;
+ }
+ else if (isStr(opts.mode) && `0123`.includes(opts.mode)) {
+ opts.mode = Number.parseInt(opts.mode, 10);
+ }
+ else if (!isNum(opts.mode)) {
+ throw new Error(`string-left-right/chompLeft(): [THROW_ID_01] the opts.mode is wrong! It should be 0, 1, 2 or 3. It was given as ${opts.mode} (type ${typeof opts.mode})`);
+ }
+ return chomp("left", str, idx, opts, clone(args).slice(1));
+ }
+ if (!isStr(args[0])) {
+ return chomp("left", str, idx, defaults, clone(args).slice(1));
+ }
+ // ELSE
+ // all arguments are values to match, first element is not options object
+ return chomp("left", str, idx, defaults, clone(args));
+}
+//
+//
+// hhhhhhh RRRRRRRRRRRRRRRRR
+// h:::::h R::::::::::::::::R
+// h:::::h R::::::RRRRRR:::::R
+// h:::::h RR:::::R R:::::R
+// cccccccccccccccch::::h hhhhh mmmmmmm mmmmmmm ppppp ppppppppp R::::R R:::::R
+// cc:::::::::::::::ch::::hh:::::hhh mm:::::::m m:::::::mm p::::ppp:::::::::p R::::R R:::::R
+// c:::::::::::::::::ch::::::::::::::hh m::::::::::mm::::::::::mp:::::::::::::::::p R::::RRRRRR:::::R
+// c:::::::cccccc:::::ch:::::::hhh::::::h m::::::::::::::::::::::mpp::::::ppppp::::::p R:::::::::::::RR
+// c::::::c ccccccch::::::h h::::::hm:::::mmm::::::mmm:::::m p:::::p p:::::p R::::RRRRRR:::::R
+// c:::::c h:::::h h:::::hm::::m m::::m m::::m p:::::p p:::::p R::::R R:::::R
+// c:::::c h:::::h h:::::hm::::m m::::m m::::m p:::::p p:::::p R::::R R:::::R
+// c::::::c ccccccch:::::h h:::::hm::::m m::::m m::::m p:::::p p::::::p R::::R R:::::R
+// c:::::::cccccc:::::ch:::::h h:::::hm::::m m::::m m::::m p:::::ppppp:::::::pRR:::::R R:::::R
+// c:::::::::::::::::ch:::::h h:::::hm::::m m::::m m::::m p::::::::::::::::p R::::::R R:::::R
+// cc:::::::::::::::ch:::::h h:::::hm::::m m::::m m::::m p::::::::::::::pp R::::::R R:::::R
+// cccccccccccccccchhhhhhh hhhhhhhmmmmmm mmmmmm mmmmmm p::::::pppppppp RRRRRRRR RRRRRRR
+// p:::::p
+// p:::::p
+// p:::::::p
+// p:::::::p
+// p:::::::p
+// ppppppppp
+//
+function chompRight(str, idx, ...args) {
+ // if there are no arguments, null
+ if (!args.length || (args.length === 1 && lodash_isplainobject(args[0]))) {
+ return null;
+ }
+ //
+ // OPTS.
+ //
+ // modes:
+ // 0 - leave single space if possible
+ // 1 - stop at first space, leave whitespace alone
+ // 2 - aggressively chomp all whitespace except newlines
+ // 3 - aggressively chomp all whitespace including newlines
+ const defaults = {
+ mode: 0,
+ };
+ // now, the first element within args can be opts.
+ // It's a plain object so it's easy to distinguish
+ if (lodash_isplainobject(args[0])) {
+ const opts = { ...defaults, ...clone(args[0]) };
+ if (!opts.mode) {
+ opts.mode = 0;
+ }
+ else if (isStr(opts.mode) && `0123`.includes(opts.mode)) {
+ opts.mode = Number.parseInt(opts.mode, 10);
+ }
+ else if (!isNum(opts.mode)) {
+ throw new Error(`string-left-right/chompRight(): [THROW_ID_02] the opts.mode is wrong! It should be 0, 1, 2 or 3. It was given as ${opts.mode} (type ${typeof opts.mode})`);
+ }
+ return chomp("right", str, idx, opts, clone(args).slice(1));
+ }
+ if (!isStr(args[0])) {
+ return chomp("right", str, idx, defaults, clone(args).slice(1));
+ }
+ // ELSE
+ // all arguments are values to match, first element is not options object
+ return chomp("right", str, idx, defaults, clone(args));
+}
+
+exports.chompLeft = chompLeft;
+exports.chompRight = chompRight;
+exports.left = left;
+exports.leftSeq = leftSeq;
+exports.leftStopAtNewLines = leftStopAtNewLines;
+exports.leftStopAtRawNbsp = leftStopAtRawNbsp;
+exports.right = right;
+exports.rightSeq = rightSeq;
+exports.rightStopAtNewLines = rightStopAtNewLines;
+exports.rightStopAtRawNbsp = rightStopAtRawNbsp;
+exports.version = version;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+})));