# @rickosborne/foundation

Basic data structures and algorithms.
Built on [@rickosborne/typical](https://www.npmjs.com/package/@rickosborne/typical) for types, and [@rickosborne/guard](https://www.npmjs.com/package/@rickosborne/guard) for guards.
## Usage

Install via your favorite package manager.

Each package supports CommonJS `require`, ESM `import`, and TypeScript usage.

You also have a choice: barrel imports or direct imports.

Barrel imports mean you're going to require/import everything from the same package-level namespace:

```typescript
// CommonJS
const { isPlainObject, isListOf } = require("@rickosborne/guard");
// ESM / TypeScript
import { isPlainObject, isListOf } from "@rickosborne/guard";
```

Implications:

- Nice and simple.
- Your build system needs to do tree-shaking well ... or you'll end up adding the entire package even if you only import two functions.

The other option is to use direct imports:

```typescript
// CommonJS
const { isPlainObject } = require("@rickosborne/guard/is-object");
const { isListOf } = require("@rickosborne/guard/is-list-of");
// ESM / TypeScript
import { isPlainObject } from "@rickosborne/guard/is-object.js";
import { isListOf } from "@rickosborne/guard/is-list-of.js";
```

Implications:

- You (probably) don't have to worry about tree-shaking as your build (likely) ends up with only the functions you need.

If you're using a modern build system, there aren't any strong reasons to prefer one way over the other.
It's really just down to your personal preference.

### A quick note about file extensions

Do you need to use file extensions?
And if so, which extensions?

Honestly ... this is a dumpster fire question.
It really comes down to your own setup and configuration.

Within each package itself:

- The CommonJS files all have `.cjs` extensions.
- The ESM files all have `.mjs` extensions.
- Node subpath exports have been set up to send `.js` imports to the `.cjs` (via `require`) or `.mjs` (via `import`) files, depending on your setup.

So, in theory, the only extension which _won't_ work would be `.ts` because the source isn't included.

If you run into a problem with a particular configuration, file a GitHub issue with:

- Your `tsconfig.json`'s `module`, `moduleResolution`, and `target` settings.
- Your `package.json`'s `type` and `imports` settings.
- An example of another package which imports correctly for you.

## License

This package is licensed as [CC-BY-NC-SA-4.0] unless otherwise noted.
That is, Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International.

[CC-BY-NC-SA-4.0]: https://creativecommons.org/licenses/by-nc-sa/4.0/


***

## API

### Classes

#### ArrayBinaryMinHeap

<a id="api-arraybinaryminheap"></a>

```typescript
 class ArrayBinaryMinHeap<T> implements Queue<T> 
```

Simple implementation of a binary min-heap, meaning low values are sorted before high values, using the supplied comparator. Invert your comparator if you want a max-heap.


#### AsyncIteratorTransformer

<a id="api-asynciteratortransformer"></a>

```typescript
 abstract class AsyncIteratorTransformer<InputT, OutputT> extends IteratorTransformerBase<InputT, OutputT> implements AsyncIterableIterator<OutputT, undefined, undefined> 
```

#### AsyncStringTokenizer

<a id="api-asyncstringtokenizer"></a>

```typescript
 class AsyncStringTokenizer extends AStringTokenizer 
```

#### BetterMap

<a id="api-bettermap"></a>

```typescript
 class BetterMap<K, V> implements BetterMapLike<K, V> 
```

#### IteratorTransformer

<a id="api-iteratortransformer"></a>

```typescript
 abstract class IteratorTransformer<InputT, OutputT> extends IteratorTransformerBase<InputT, OutputT> implements IterableIterator<OutputT, undefined, undefined> 
```

#### IteratorTransformerBase

<a id="api-iteratortransformerbase"></a>

```typescript
 abstract class IteratorTransformerBase<InputT, OutputT> 
```

Basic queues and statistic tracking for a dual-queued Iterator transformer.


#### JsonParseObserver

<a id="api-jsonparseobserver"></a>

```typescript
 class JsonParseObserver 
```

#### JsonPushTokenizer

<a id="api-jsonpushtokenizer"></a>

```typescript
 class JsonPushTokenizer 
```

#### MultiAsyncIterator

<a id="api-multiasynciterator"></a>

```typescript
 class MultiAsyncIterator<T> implements AsyncIterable<T> 
```

Wrapper for an [AsyncIterator](#api-asynciterator) which allows multiple consumers to read from the same iterable via a basic queue which tracks which consumers have read which values.


#### PriorityArray

<a id="api-priorityarray"></a>

```typescript
 class PriorityArray<T> implements Queue<T> 
```

An implementation of a priority queue backed by a JS array, using the given comparator. Sorts low-to-high, so you will need to invert comparator if you want high-to-low.


#### PriorityLinkedList

<a id="api-prioritylinkedlist"></a>

```typescript
 class PriorityLinkedList<T> implements Queue<T> 
```

Implementation of a priority queue backed by a linked list, using the given comparator. Sorts low-to-high, so you will need to invert comparator if you want high-to-low.


#### SkipList

<a id="api-skiplist"></a>

```typescript
 class SkipList<T> implements Queue<T> 
```

Basic skip list implementation, using the given comparator to keep values in order, low-to-high. If you want high-to-low you will need to invert your comparator.


#### StringTokenizer

<a id="api-stringtokenizer"></a>

```typescript
 class StringTokenizer extends AStringTokenizer 
```

Primitive string tokenizer upon which parsers could be built.


#### TimeoutError

<a id="api-timeouterror"></a>

```typescript
 class TimeoutError extends Error 
```

Error which will be thrown if a timeout happens and no other error is provided.


#### TokenGenerator

<a id="api-tokengenerator"></a>

```typescript
 abstract class TokenGenerator<TokenT> extends AsyncStringTokenizer implements AsyncIterable<TokenT> 
```

#### TupleMap

<a id="api-tuplemap"></a>

```typescript
 class TupleMap<K extends unknown[], V> implements BetterMapLike<K, V> 
```

A Map structure which has a tuple key.


#### UnknownError

<a id="api-unknownerror"></a>

```typescript
 class UnknownError extends Error 
```

An error thrown when the root problem is unknown.


### Functions

#### addProperties

<a id="api-addproperties"></a>

```typescript
addProperties: <T, K extends string, R extends Record<K, TypedPropertyDescriptor<unknown>>>(target: T, descriptors: R) => Resolve<T & PropertiesFromDescriptors<R>>
```

A more type-friendly version of <kbd>Object.defineProperties</kbd>. See [Object.defineProperties on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties).


#### addProperty

<a id="api-addproperty"></a>

```typescript
addProperty: <T, K extends string, V, D extends TypedPropertyDescriptor<V>>(target: T, key: K, descriptor: D) => Resolve<T & PropertyFromDescriptor<K, D>>
```

A more type-friendly version of <kbd>Object.defineProperty</kbd>. See [Object.defineProperty on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty).


#### arrayBinaryMaxHeap

<a id="api-arraybinarymaxheap"></a>

```typescript
arrayBinaryMaxHeap: <T>(comparator: Comparator<T>) => ArrayBinaryMinHeap<T>
```

Build a max-heap using the given comparator. Will invert the comparator and build a min-heap, which produces the same outcomes.


#### arrayBinaryMinHeap

<a id="api-arraybinaryminheap"></a>

```typescript
arrayBinaryMinHeap: <T>(comparator: Comparator<T>) => ArrayBinaryMinHeap<T>
```

Build a min-heap using the given comparator.


#### arrayEq

<a id="api-arrayeq"></a>

```typescript
arrayEq: <T>(a: T[], b: T[], predicate?: ((_a: T, _b: T, index: number) => boolean)) => boolean
```

Simple comparison to see if two arrays are equivalent.


#### arrayFromAsync

<a id="api-arrayfromasync"></a>

```typescript
arrayFromAsync: <T>(iterableOrArrayLike: AsyncIterable<T> | Iterable<T | PromiseLike<T>> | ArrayLike<T | PromiseLike<T>>) => Promise<T[]>
```

Polyfill for `Array.fromAsync` for node before v22.


#### arrayUnique

<a id="api-arrayunique"></a>

```typescript
arrayUnique: <T>(array: T[]) => T[]
```

Generate a new array which has no duplicate values. Preserves the order of the first occurrence of each value. Returns the original array if no duplicates were found.


#### asFraction

<a id="api-asfraction"></a>

```typescript
asFraction: (num: number, percentError?: number) => FracTuple
```

Try to find a human-readable fraction for the given decimal value, within a given percentage error. See [the original algorithm by Sjaak](https://stackoverflow.com/a/45314258).


#### asIndexKey

<a id="api-asindexkey"></a>

```typescript
asIndexKey: (key: string) => number | undefined
```

Try to convert the string-format key into an array index key.


#### asyncIteratorFrom

<a id="api-asynciteratorfrom"></a>

```typescript
asyncIteratorFrom: <TYield, TReturn, TNext>(iterator: Iterator<TYield, TReturn, TNext>) => AsyncIterator<TYield, TReturn, TNext>
```

Convert a synchronous iterator into an asynchronous one.


#### asyncIteratorOf

<a id="api-asynciteratorof"></a>

```typescript
asyncIteratorOf: <T>(it: AsyncIterable<T, undefined, undefined> | Iterable<T, undefined, undefined> | AsyncIterator<T, undefined, undefined>) => AsyncIterator<T, undefined, undefined>
```

If the value is already an Iterator, return it. If the value is AsyncIterable, return an Iterator for it. It the value is Iterable, upgrade an Iterator for it to an AsyncIterator and return that. Otherwise, throw an error.



#### asyncIteratorTransformer

<a id="api-asynciteratortransformer"></a>

```typescript
asyncIteratorTransformer: <InputT, OutputT>(map: (inputs: InputT[], inputIsDone: boolean) => IteratorTransformerMapResult<OutputT> | Promise<IteratorTransformerMapResult<OutputT>>, options?: AsyncIteratorTransformerOptions) => (it: AsyncIterator<InputT, undefined, undefined> | AsyncIterable<InputT, undefined, undefined> | Iterable<InputT, undefined, undefined>) => AsyncIteratorTransformer<InputT, OutputT>
```

#### binaryIndexOf

<a id="api-binaryindexof"></a>

```typescript
binaryIndexOf: <T>(value: T, items: T[], comparator: Comparator<T>, config?: BinaryIndexOfConfig) => SearchResult
```

Perform a binary search through the given list for the given value using the given comparator.


#### catchAnd

<a id="api-catchand"></a>

```typescript
catchAnd: <T, O extends CatchAndOptions<T>>(options?: O) => (err: unknown) => CatchAndReturn<T, O>
```

Catch block builder to reduce the noise of thorough error handling.


#### chainableComparator

<a id="api-chainablecomparator"></a>

```typescript
chainableComparator: <T>(comparator: Comparator<T>) => ChainableComparator<T>
```

Wrap the given comparator so you can chain [ChainableComparator](#api-chainablecomparator) functions from it.


#### closeTo

<a id="api-closeto"></a>

```typescript
closeTo: (a: number, b: number, epsilon?: number) => boolean
```

Test for whether two numbers are close enough to each other, within an acceptable margin.


#### closeToZero

<a id="api-closetozero"></a>

```typescript
closeToZero: (n: number, epsilon?: number) => n is 0
```

Test for whether a number is close enough to zero, within an acceptable margin.


#### comparatorBuilder

<a id="api-comparatorbuilder"></a>

```typescript
comparatorBuilder: <T>() => ComparatorBuilder<T>
```

Start building a comparator.


#### computeIfAbsent

<a id="api-computeifabsent"></a>

```typescript
computeIfAbsent: <T, K>(key: K, map: Map<K, T>, compute: (k: K) => T) => T
```

Find the item in the Map, or compute and store it.


#### concatRegExp

<a id="api-concatregexp"></a>

```typescript
concatRegExp: (...patterns: RegExp[]) => RegExp
```

Concatenate the patterns (and flags) of regular expressions so they will match all at once. This does not attempt to fix any problems, such as duplicate named capture groups or incorrectly-numbered backreferences.


#### deepCopy

<a id="api-deepcopy"></a>

```typescript
deepCopy: <T>(source: T, options?: DeepCopyOptions) => T
```

Create a deep copy of an object. This is not a particularly robust check, and won't copy things like class instances.


#### deepEquals

<a id="api-deepequals"></a>

```typescript
 function deepEquals<T>(actual: unknown, expected: T): actual is T;
```

Recursively compare two objects for equivalence. Warning: does not attempt to resolve cycles.


#### deepMerge

<a id="api-deepmerge"></a>

```typescript
deepMerge: <Loser, Winner>(loser: Loser, winner: Winner) => DeepMerge<Loser, Winner>
```

Recursively merge two values, if possible. See [DeepMerge](#api-deepmerge) for details on the logic.


#### deepSort

<a id="api-deepsort"></a>

```typescript
deepSort: <T>(obj: T, options?: DeepSortOptions) => T
```

Sort an object, and any objects nested through plain objects or arrays, by key, so when JSON stringified you will get a deterministic output.


#### divMod

<a id="api-divmod"></a>

```typescript
divMod: (num: number, divisor: number) => [quotient: number, remainder: number]
```

Euclidian division which returns a tuple of the quotient and remainder.



#### doubleLinkedList

<a id="api-doublelinkedlist"></a>

```typescript
doubleLinkedList: <T>() => DoubleLinkedList<T>
```

Build a doubly-linked list.


#### entriesOf

<a id="api-entriesof"></a>

```typescript
entriesOf: <T extends object>(obj: T) => [keyof T, T[keyof T]][]
```

A wrapper for `Object.entries` which has typed keys and values.


#### findConsole

<a id="api-findconsole"></a>

```typescript
findConsole: () => ConsoleLike
```

#### formatBytes

<a id="api-formatbytes"></a>

```typescript
formatBytes: (bytes: number | bigint, base?: 1024 | 1000, precision?: number) => string
```

Pretty-print a byte value with low enough detail to be quickly human-readable.


#### formatDuration

<a id="api-formatduration"></a>

```typescript
formatDuration: (duration: Duration) => string
```

#### formatMarkdownTable

<a id="api-formatmarkdowntable"></a>

```typescript
formatMarkdownTable: <T extends object>(values: T[], options: FormatMarkdownTableOptions<T>) => string
```

Generate a Markdown-formatted table for the given items.


#### holder

<a id="api-holder"></a>

```typescript
 function holder<T>(value: T): ValuedHolder<T>;
```

#### holder

<a id="api-holder"></a>

```typescript
 function holder<T>(): EmptyHolder<T>;
```

#### imprecise

<a id="api-imprecise"></a>

```typescript
imprecise: (num: number, resolution?: number) => string
```

String-format a number rounded to the given resolution, where human readability is more important than precision.


#### isConsoleLike

<a id="api-isconsolelike"></a>

```typescript
isConsoleLike: (obj: unknown) => obj is ConsoleLike
```

#### isSvgAbsolutePathCommand

<a id="api-issvgabsolutepathcommand"></a>

```typescript
isSvgAbsolutePathCommand: (value: unknown) => value is SvgAbsolutePathCommand
```

#### isSvgPathCommand

<a id="api-issvgpathcommand"></a>

```typescript
isSvgPathCommand: (value: unknown) => value is SvgPathCommand
```

#### isSvgRelativePathCommand

<a id="api-issvgrelativepathcommand"></a>

```typescript
isSvgRelativePathCommand: (value: unknown) => value is SvgRelativePathCommand
```

#### iteratorOf

<a id="api-iteratorof"></a>

```typescript
iteratorOf: <T>(it: Iterable<T, undefined, undefined> | Iterator<T, undefined, undefined>) => Iterator<T, undefined, undefined>
```

If the value is already an Iterator, return it. If the value is Iterable, return an Iterator for it. Otherwise, throw an error.


#### iteratorTransformer

<a id="api-iteratortransformer"></a>

```typescript
iteratorTransformer: <InputT, OutputT>(map: (inputs: InputT[], inputIsDone: boolean) => IteratorTransformerMapResult<OutputT>) => (it: Iterator<InputT, undefined, undefined> | Iterable<InputT, undefined, undefined>) => IteratorTransformer<InputT, OutputT>
```

#### jsonParseEventsOf

<a id="api-jsonparseeventsof"></a>

```typescript
 function jsonParseEventsOf(...its: StringIterable[]): Generator<JsonParseEvent, void, undefined>;
```

#### jsonParseEventsOfAsync

<a id="api-jsonparseeventsofasync"></a>

```typescript
 function jsonParseEventsOfAsync(...its: AsyncStringIterable[]): AsyncGenerator<JsonParseEvent, void, undefined>;
```

#### jsonPathAppend

<a id="api-jsonpathappend"></a>

```typescript
jsonPathAppend: (path: string, key: string | number | symbol, options?: JsonPathAppendOptions) => string
```

Append the given property key to the given JSON Path expression. This does not attempt to validate anything about the path or the key, only formats it according to very basic rules. Technically, the spec doesn't handle symbol values, so if you give it a path with a symbol you get an expression which other JSON Path parsers can't handle. However, it does use the correct function syntax, so it should still at least parse correctly.



#### jsonTokensOf

<a id="api-jsontokensof"></a>

```typescript
 function jsonTokensOf(...its: StringIterable[]): Generator<JsonToken, void, undefined>;
```

#### jsonTokensOfAsync

<a id="api-jsontokensofasync"></a>

```typescript
 function jsonTokensOfAsync(...its: AsyncStringIterable[]): AsyncGenerator<JsonToken, void, undefined>;
```

#### lowerFirst

<a id="api-lowerfirst"></a>

```typescript
 function lowerFirst(text: string): string;
```

#### lowerFirst

<a id="api-lowerfirst"></a>

```typescript
 function lowerFirst(text: string | null | undefined): string | undefined;
```

#### memoize

<a id="api-memoize"></a>

```typescript
memoize: <T>(supplier: Supplier<T>) => Supplier<T>
```

Shorthand for [memoizeSupplier](#api-memoizesupplier).


#### memoizeBinary

<a id="api-memoizebinary"></a>

```typescript
memoizeBinary: <T, U, V>(binary: (t: T, u: U) => V) => ((t: T, u: U) => V)
```

#### memoizeMore

<a id="api-memoizemore"></a>

```typescript
memoizeMore: <P extends unknown[] & {
    length: N;
}, R, N extends number>(argCount: N, fn: (...args: P) => R) => ((...args: P) => R)
```

#### memoizeSupplier

<a id="api-memoizesupplier"></a>

```typescript
memoizeSupplier: <T>(supplier: Supplier<T>) => Supplier<T>
```

Memoize the given supplier so that it is called at most once.


#### memoizeUnary

<a id="api-memoizeunary"></a>

```typescript
memoizeUnary: <T, U>(unary: (input: T) => U) => ((input: T) => U)
```

#### minMax

<a id="api-minmax"></a>

```typescript
 function minMax(values: number[]): [number, number];
```

#### minMax

<a id="api-minmax"></a>

```typescript
 function minMax(...values: number[]): [number, number];
```

#### optionalRegExp

<a id="api-optionalregexp"></a>

```typescript
optionalRegExp: (pattern: RegExp) => RegExp
```

Modify a regular expression's pattern to make the entire expression optional, keeping any start/end anchors in place


#### parseDuration

<a id="api-parseduration"></a>

```typescript
parseDuration: (text: string) => DurationWithText
```

Parse an ISO-8601 duration from the given text. If the text contains extra non-duration characters after, will only throw an error if they would produce an ambiguous result, or could indicate an incomplete duration.



#### parseLocalDate

<a id="api-parselocaldate"></a>

```typescript
parseLocalDate: (text: string, config?: ParseLocalDateConfig) => Date
```

Parse an ISO-8860-like date, but do so assuming that the time is intended to be local, not UTC. But if allowed, the date could override this with specific time zone info.



#### positiveDiv

<a id="api-positivediv"></a>

```typescript
positiveDiv: (num: number, divisor: number) => number
```

Modulo where the result is always positive.



#### positiveMod

<a id="api-positivemod"></a>

```typescript
positiveMod: (num: number, divisor: number) => number
```

Modulo where the result is always positive.



#### priorityArray

<a id="api-priorityarray"></a>

```typescript
priorityArray: <T>(comparator: Comparator<T>) => Queue<T>
```

Build a priority queue which uses an array as a backing store.


#### priorityLinkedList

<a id="api-prioritylinkedlist"></a>

```typescript
priorityLinkedList: <T>(comparator: Comparator<T>) => Queue<T>
```

Build a priority queue which uses a linked list as a backing store.


#### randomNumberGenerator

<a id="api-randomnumbergenerator"></a>

```typescript
randomNumberGenerator: (seedOrOptions?: number | RNGOptions, presetName?: LCEPresetName | undefined) => RNG
```

https://en.wikipedia.org/wiki/Linear_congruential_generator


#### reduceToUnique

<a id="api-reducetounique"></a>

```typescript
reduceToUnique: <T>() => [(prev: T[], cur: T) => T[], T[]]
```

Generate the args for an array reducer which keeps only distinct values.



#### reQuote

<a id="api-requote"></a>

```typescript
reQuote: (text: string, options?: ReQuoteOptions) => string
```

Given a text, either wrap it in quotes which make the most sense for the text, or change the quotes to a different set.


#### resolvablePromise

<a id="api-resolvablepromise"></a>

```typescript
 function resolvablePromise<T>(): ResolvablePromise<T>;
```

Build a promise which can be resolved from the outside.


#### roundTo

<a id="api-roundto"></a>

```typescript
roundTo: (value: number, resolution?: number) => number
```

Round a given number to the nearest unit of resolution. For resolution of 1, this is equal to `Math.round`.


#### secondsFromDuration

<a id="api-secondsfromduration"></a>

```typescript
secondsFromDuration: (duration: Partial<DurationWithText>) => number
```

Convert a given duration to an equivalent number of seconds.



#### shuffle

<a id="api-shuffle"></a>

```typescript
shuffle: <T>(list: T[], input?: ShuffleConfig<T>) => T[]
```

Fisher-Yates shuffle. Defaults to in-place sorting, but can sort into a new one via <kbd>into</kbd>.



#### simpleStarMatch

<a id="api-simplestarmatch"></a>

```typescript
simpleStarMatch: (glob: string, text: string) => boolean
```

Match the given simple-* glob against the given text. This _does not_ use "filesystem glob" logic. That is, a `*` here will match anything, including `/`. Similarly, there is no `?` operator.


#### singleCharactersOf

<a id="api-singlecharactersof"></a>

```typescript
 function singleCharactersOf(...its: StringIterable[]): Generator<string, void, unknown>;
```

#### singleCharactersOfAsync

<a id="api-singlecharactersofasync"></a>

```typescript
 function singleCharactersOfAsync(...its: AsyncStringIterable[]): AsyncGenerator<string, void, unknown>;
```

#### singleLinkedList

<a id="api-singlelinkedlist"></a>

```typescript
singleLinkedList: <T>() => List<T>
```

Builder for a single-linked list.


#### skipList

<a id="api-skiplist"></a>

```typescript
skipList: <T>(comparator: Comparator<T>) => SkipList<T>
```

Build a priority queue using a skip list implementation.


#### sleep

<a id="api-sleep"></a>

```typescript
 function sleep<T>(ms: number, value: T): Promise<T>;
```

Sleep at least some number of ms, returning the supplied value when complete.


#### sleep

<a id="api-sleep"></a>

```typescript
 function sleep(ms: number): Promise<undefined>;
```

Sleep at least some number of ms.


#### splitFixed

<a id="api-splitfixed"></a>

```typescript
splitFixed: (text: string, width: number) => string[]
```

Split a string into fixed-width substrings. The last one may be short.


#### starMatchParts

<a id="api-starmatchparts"></a>

```typescript
starMatchParts: (glob: string) => StarGlobPart[]
```

Parse a simple-* glob into its constituent tokens.


#### svgPathCommandsOf

<a id="api-svgpathcommandsof"></a>

```typescript
 function svgPathCommandsOf(...d: StringIterable[]): Generator<SvgPathToken, void, undefined>;
```

Parse an SVG `path` definition into drawing commands.


#### svgPathValuesOf

<a id="api-svgpathvaluesof"></a>

```typescript
 function svgPathValuesOf(...d: StringIterable[]): Generator<SvgPathValue, void, undefined>;
```

Tokenize an SVG `path` definition into `command`, `number`, and `space` tokens.


#### toBatches

<a id="api-tobatches"></a>

```typescript
toBatches: <T>(maxPerBatch: number, list: T[], mode?: ToBatchesMode) => T[][]
```

Group the given list into batches of the given maximum count, optionally using a given strategy.


#### toBatchesReducer

<a id="api-tobatchesreducer"></a>

```typescript
toBatchesReducer: <T>(maxPerBatch: number, mode?: ToBatchesMode) => [reduce: (prev: T[][], cur: T, index: number, list: T[]) => T[][], initial: T[][]]
```

Generate an array reducer which will group the given list into batches of the given maximum count, optionally using a given strategy.



#### toShuffled

<a id="api-toshuffled"></a>

```typescript
toShuffled: <T>(list: T[], config?: Omit<ShuffleConfig<T>, "into"> | undefined) => T[]
```

Wrapper for the [shuffle](#api-shuffle) function which shuffles into a new array, leaving the original intact.


#### uniqueReducer

<a id="api-uniquereducer"></a>

```typescript
uniqueReducer: () => <T>(prev: T[], cur: T) => T[]
```

Generate a function for use in an array reducer which will track and only keep the first occurrence of each value.


#### window2

<a id="api-window2"></a>

```typescript
 function window2<T>(items: Readonly<T[]>): Generator<Readonly<[T, T, number, number]>, void, undefined>;
```

Generator for a sliding window of pairs of values from the given list. It yields each value in the list in a tuple with its successor. The last item wraps around to use the first item as its successor. The indices of the two values are also yielded after the values. For example:

```typescript
for (const [ x, y, xIndex, yIndex ] of window2([ "a", "b", "c" ])) {
    console.log(x, y, xIndex, yIndex);
}
```


This would output: <pre> a, b, 0, 1 b, c, 1, 2 c, a, 2, 0 </pre>


#### window3

<a id="api-window3"></a>

```typescript
 function window3<T>(items: Readonly<T[]>): Generator<Readonly<[T, T, T, number, number, number]>, void, undefined>;
```

Generator for a sliding window of triplets of values from the given list. It yields each value in the list in a tuple with its predecessor and successor. The first and last items wrap around to use the last and first items as their predecessor/successor. The indices of the values are also provided after the values. The middle value (<kbd>y</kbd> in the example below) is the "current" value, with the first value (<kbd>x</kbd>) being its predecessor and the third (<kbd>z</kbd>) its successor. That current value is the one which will be at index 0 for the first iteration of the loop. For example:

```typescript
for (const [ x, y, z, xIndex, yIndex, zIndex ] of window3([ "a", "b", "c" ])) {
    console.log(x, y, z, xIndex, yIndex, zIndex);
}
```


This would output: <pre> c, a, b, 2, 0, 1 a, b, c, 0, 1, 2 b, c, a, 1, 2, 0 </pre>


#### withLazyProperty

<a id="api-withlazyproperty"></a>

```typescript
withLazyProperty: <Target, Property, Name extends string>(target: Target, name: Name, calculator: (t: Target) => Property) => WithProperty<Target, Name, Property>
```

Add a property to the given object which is calculated lazily, and only once.


#### withNullsFirst

<a id="api-withnullsfirst"></a>

```typescript
withNullsFirst: <T>(comparator: Comparator<T>) => Comparator<T | null | undefined>
```

Wrap the given comparator to return null and undefined values before the others.


#### withNullsLast

<a id="api-withnullslast"></a>

```typescript
withNullsLast: <T>(comparator: Comparator<T>) => Comparator<T | null | undefined>
```

Wrap the given comparator to return null and undefined values after the others.


#### withTimeout

<a id="api-withtimeout"></a>

```typescript
 function withTimeout<T>(options: WithTimeoutOptions<T>): Promise<T>;
```

Wrap a given block or promise in another promise which will resolve or reject if the first has not resolved within the specified time limit.


#### zeroPad

<a id="api-zeropad"></a>

```typescript
zeroPad: (num: number, length: number, radix?: number) => string
```

Convert a number to a string and left-pad it out to the given length with zeroes.


### Interfaces

#### ArcSvgPathToken

<a id="api-arcsvgpathtoken"></a>

```typescript
export interface ArcSvgPathToken extends SvgPathTokenBase<"arc"> 
```

#### AsyncIteratorTransformerOptions

<a id="api-asynciteratortransformeroptions"></a>

```typescript
export interface AsyncIteratorTransformerOptions 
```

Additional configuration for an asynchronous Iterator transformer.


#### BetterMapLike

<a id="api-bettermaplike"></a>

```typescript
export interface BetterMapLike<K, V> 
```

A Map-like structure with several handy utility methods.


#### CatchAndOptions

<a id="api-catchandoptions"></a>

```typescript
export interface CatchAndOptions<T> 
```

#### CloseSvgPathToken

<a id="api-closesvgpathtoken"></a>

```typescript
export interface CloseSvgPathToken extends SvgPathTokenBase<"close"> 
```

#### CommandSvgPathValue

<a id="api-commandsvgpathvalue"></a>

```typescript
export interface CommandSvgPathValue extends SvgPathValueBase<"command"> 
```

#### ConsoleLike

<a id="api-consolelike"></a>

```typescript
export interface ConsoleLike 
```

#### CubicCurveSvgPathToken

<a id="api-cubiccurvesvgpathtoken"></a>

```typescript
export interface CubicCurveSvgPathToken extends SvgPathTokenBase<"cubic"> 
```

#### DeepCopyOptions

<a id="api-deepcopyoptions"></a>

```typescript
export interface DeepCopyOptions 
```

#### DeepSortOptions

<a id="api-deepsortoptions"></a>

```typescript
export interface DeepSortOptions 
```

#### Duration

<a id="api-duration"></a>

```typescript
export interface Duration 
```

ISO8601-like measure of a duration. Does not include any concept of being relative to any specific date.


#### DurationWithText

<a id="api-durationwithtext"></a>

```typescript
export interface DurationWithText extends Duration 
```

A duration parsed from text, which includes the extracted (serialized) duration text.


#### EmptyHolder

<a id="api-emptyholder"></a>

```typescript
export interface EmptyHolder<T> extends Holder<T> 
```

A [Holder](#api-holder) without a value, yet.


#### FormatMarkdownTableOptions

<a id="api-formatmarkdowntableoptions"></a>

```typescript
export interface FormatMarkdownTableOptions<T extends object> 
```

Options for [formatMarkdownTable](#api-formatmarkdowntable).


#### Holder

<a id="api-holder"></a>

```typescript
export interface Holder<T> 
```

A structure which can hold any value type, even undefined, and can itself be const, while still allowing the value to be added later.


#### IteratorTransformerMapResult

<a id="api-iteratortransformermapresult"></a>

```typescript
export interface IteratorTransformerMapResult<OutputT> 
```

#### JsonBooleanToken

<a id="api-jsonbooleantoken"></a>

```typescript
export interface JsonBooleanToken extends JsonTokenBase 
```

#### JsonNullToken

<a id="api-jsonnulltoken"></a>

```typescript
export interface JsonNullToken extends JsonTokenBase 
```

#### JsonNumberToken

<a id="api-jsonnumbertoken"></a>

```typescript
export interface JsonNumberToken extends JsonTokenBase 
```

#### JsonParseArrayState

<a id="api-jsonparsearraystate"></a>

```typescript
export interface JsonParseArrayState extends JsonParseStateBase 
```

#### JsonParseItemState

<a id="api-jsonparseitemstate"></a>

```typescript
export interface JsonParseItemState extends JsonParseStateBase 
```

#### JsonParseObjectState

<a id="api-jsonparseobjectstate"></a>

```typescript
export interface JsonParseObjectState extends JsonParseStateBase 
```

#### JsonParsePropertyState

<a id="api-jsonparsepropertystate"></a>

```typescript
export interface JsonParsePropertyState extends JsonParseStateBase 
```

#### JsonParseRootState

<a id="api-jsonparserootstate"></a>

```typescript
export interface JsonParseRootState extends JsonParseStateBase 
```

#### JsonParseStateBase

<a id="api-jsonparsestatebase"></a>

```typescript
export interface JsonParseStateBase 
```

#### JsonPathAppendOptions

<a id="api-jsonpathappendoptions"></a>

```typescript
export interface JsonPathAppendOptions 
```

#### JsonPunctuationToken

<a id="api-jsonpunctuationtoken"></a>

```typescript
export interface JsonPunctuationToken extends JsonTokenBase 
```

#### JsonSpaceToken

<a id="api-jsonspacetoken"></a>

```typescript
export interface JsonSpaceToken extends JsonTokenBase 
```

#### JsonStringToken

<a id="api-jsonstringtoken"></a>

```typescript
export interface JsonStringToken extends JsonTokenBase 
```

#### JsonTokenBase

<a id="api-jsontokenbase"></a>

```typescript
export interface JsonTokenBase 
```

#### LineSvgPathToken

<a id="api-linesvgpathtoken"></a>

```typescript
export interface LineSvgPathToken extends SvgPathTokenBase<"line"> 
```

#### LogLike

<a id="api-loglike"></a>

```typescript
export interface LogLike 
```

#### MoveSvgPathToken

<a id="api-movesvgpathtoken"></a>

```typescript
export interface MoveSvgPathToken extends SvgPathTokenBase<"move"> 
```

#### NumberSvgPathValue

<a id="api-numbersvgpathvalue"></a>

```typescript
export interface NumberSvgPathValue extends SvgPathValueBase<"number"> 
```

#### QuadraticCurveSvgPathToken

<a id="api-quadraticcurvesvgpathtoken"></a>

```typescript
export interface QuadraticCurveSvgPathToken extends SvgPathTokenBase<"quad"> 
```

#### ResolvablePromise

<a id="api-resolvablepromise"></a>

```typescript
export interface ResolvablePromise<T> extends Promise<T> 
```

A promise which can be resolved from the outside.


#### RNG

<a id="api-rng"></a>

```typescript
export interface RNG 
```

#### RNGOptions

<a id="api-rngoptions"></a>

```typescript
export interface RNGOptions 
```

#### SpaceSvgPathValue

<a id="api-spacesvgpathvalue"></a>

```typescript
export interface SpaceSvgPathValue extends SvgPathValueBase<"space"> 
```

#### SvgPathTokenBase

<a id="api-svgpathtokenbase"></a>

```typescript
export interface SvgPathTokenBase<T extends keyof SvgPathTokenByType> 
```

#### SvgPathTokenByType

<a id="api-svgpathtokenbytype"></a>

```typescript
export interface SvgPathTokenByType 
```

#### SvgPathValueBase

<a id="api-svgpathvaluebase"></a>

```typescript
export interface SvgPathValueBase<T extends SvgPathValueType> 
```

#### SvgPathValueByType

<a id="api-svgpathvaluebytype"></a>

```typescript
export interface SvgPathValueByType 
```

#### UnknownErrorOptions

<a id="api-unknownerroroptions"></a>

```typescript
export interface UnknownErrorOptions extends ErrorOptions 
```

Options for [UnknownError](#api-unknownerror).


#### ValuedHolder

<a id="api-valuedholder"></a>

```typescript
export interface ValuedHolder<T> extends Holder<T> 
```

A [Holder](#api-holder) whose value has been set.


#### WithTimeoutOptions

<a id="api-withtimeoutoptions"></a>

```typescript
export interface WithTimeoutOptions<T> 
```

Options for [withTimeout](#api-withtimeout).


### TypeAliases

#### AsyncIteratorTransformerConstructor

<a id="api-asynciteratortransformerconstructor"></a>

```typescript
type AsyncIteratorTransformerConstructor<InputT, OutputT> = AbstractConstructorLike<[iterator: AsyncIterator<InputT, undefined, undefined>], AsyncIteratorTransformer<InputT, OutputT>>;
```

#### AsyncStringIterable

<a id="api-asyncstringiterable"></a>

```typescript
type AsyncStringIterable = StringIterable | AsyncIterable<string, undefined, undefined> | AsyncIterator<string, undefined, undefined>;
```

#### BinaryIndexOfConfig

<a id="api-binaryindexofconfig"></a>

```typescript
type BinaryIndexOfConfig = {
    firstNonUnique?: boolean;
    initialLeft?: number;
    initialRight?: number;
    rangeCheck?: boolean;
};
```

Configuration options for [binaryIndexOf](#api-binaryindexof).


#### ChainableComparator

<a id="api-chainablecomparator"></a>

```typescript
type ChainableComparator<T> = Comparator<T> & {
    get desc(): ChainableComparator<T>;
    get nullsFirst(): ChainableComparator<T | undefined | null>;
    get nullsLast(): ChainableComparator<T | undefined | null>;
};
```

Mixin for a comparator with chaining functions to constrain the behavior of the comparator.


#### ComparatorBuilder

<a id="api-comparatorbuilder"></a>

```typescript
type ComparatorBuilder<T> = {
    build(): Comparator<T>;
    get desc(): ComparatorBuilder<T>;
    get nullsFirst(): ComparatorBuilder<T>;
    get nullsLast(): ComparatorBuilder<T>;
    num(accessor: (t: T) => (undefined | number)): ComparatorBuilder<T>;
    str(accessor: (t: T) => (undefined | string)): ComparatorBuilder<T>;
};
```

Build a comparator for the given type, which goes through the specified checks in the order they are defined.


#### DeepMerge

<a id="api-deepmerge"></a>

```typescript
type DeepMerge<Loser, Winner> = Winner extends object ? Loser extends object ? ({
    [K in keyof Loser as K extends keyof Winner ? never : K]: Loser[K];
} & {
    [K in keyof Winner as K]: K extends keyof Loser ? DeepMerge<Loser[K], Winner[K]> : Winner[K];
}) : Winner : Winner;
```

Given two types, recursively compare and merge them with the following logic: 1. If the two types are different, Winner wins. 2. If either type is not a Record, Winner wins. 3. If both types are Records, each property, in the set of all keys from both, is compared using the same logic. A superset Record is created.


#### DoubleLinkedList

<a id="api-doublelinkedlist"></a>

```typescript
type DoubleLinkedList<T> = List<T> & {
    get tail(): T | undefined;
    reverseValues(): Generator<T, void, undefined>;
    reverseValuesAndIndexes(): Generator<[T, number], void, undefined>;
    reverseWalk(block: (value: T, index: number) => ListWalkDecision<T>): void;
};
```

Mixin for additional methods available when the linked list is double-linked.


#### DurationDesignator

<a id="api-durationdesignator"></a>

```typescript
type DurationDesignator = "Y" | "M" | "W" | "D" | "T" | "H" | "S";
```

ISO-8601 designator for a duration value.


#### FracTuple

<a id="api-fractuple"></a>

```typescript
type FracTuple = [numerator: number, denominator: number];
```

A fraction represented as a tuple of numerator and denominator. The numerator is negative if the value is negative. The denominator is always positive, and at least 1. Both values are integers, though the numerator may be Infinity or NaN as the value requires.


#### GetPropertyDescriptor

<a id="api-getpropertydescriptor"></a>

```typescript
type GetPropertyDescriptor<T> = PropertyDescriptorFlags & {
    get(): T;
    set?: never;
    value?: never;
};
```

Partial property descriptor which includes only an accessor (getter) and not a mutator, and is thus read-only.


#### GetSetPropertyDescriptor

<a id="api-getsetpropertydescriptor"></a>

```typescript
type GetSetPropertyDescriptor<T> = PropertyDescriptorFlags & {
    get(): T;
    set(t: T): void;
};
```

Partial property descriptor which includes both an accessor (getter) and mutator (setter), and is thus read-write.


#### IfReadOnlyDescriptor

<a id="api-ifreadonlydescriptor"></a>

```typescript
type IfReadOnlyDescriptor<T, D extends TypedPropertyDescriptor<unknown>> = D extends ReadOnlyPropertyDescriptor | GetPropertyDescriptor<unknown> ? T : never;
```

Filter type <kbd>T</kbd> based on whether the property descriptor <kbd>D</kbd> would produce a read-only property.


#### IfReadWriteDescriptor

<a id="api-ifreadwritedescriptor"></a>

```typescript
type IfReadWriteDescriptor<T, D extends TypedPropertyDescriptor<unknown>> = D extends ReadOnlyPropertyDescriptor | GetPropertyDescriptor<unknown> | SetPropertyDescriptor<unknown> ? never : T;
```

Filter type <kbd>T</kbd> based on whether the property descriptor <kbd>D</kbd> would produce a read-write (or write-only) property.


#### IfWriteOnlyDescriptor

<a id="api-ifwriteonlydescriptor"></a>

```typescript
type IfWriteOnlyDescriptor<T, D extends TypedPropertyDescriptor<unknown>> = D extends SetPropertyDescriptor<unknown> ? T : never;
```

Filter type <kbd>T</kbd> based on whether the property descriptor <kbd>D</kbd> would produce a write-only property. Note: JS has a concept of a write-only property, and the unit tests cover this. However, TS doesn't have a way of expressing it, at least as of v5.8. So for now, it goes into the read-write bucket, even though you can't actually read from it. The alternative would be to set it to `undefined`, to show you can't read from it ... but then you lose the type info for the setter. Yuck. For now ... The types below will, ahem, mangle the types they produce. Just a little. If you produce a setter-only property, it will end up looking like:

```typescript
const withSetterOnly: WithSetterOnly = addProperty({}, "whatever", { set: (value: string) => void(whatever(value)) });
type WithSetterOnly = {
   whatever: string;
   whateverIsWriteOnly?: undefined;
}
```


So you get a reminder without breaking anything too hard.


#### IntGenerator

<a id="api-intgenerator"></a>

```typescript
type IntGenerator = Generator<number, void, undefined> & {
    toArray(): number[];
};
```

Mixin for a generator which also has the ability to bundle its output into an array.


#### IntGeneratorTo

<a id="api-intgeneratorto"></a>

```typescript
type IntGeneratorTo = {
    toExclusive(stopExclusive: number): IntGenerator;
    toInclusive(stopInclusive: number): IntGenerator;
};
```

Partial for the last step of an [IntRange](#api-intrange) builder.


#### IntRange

<a id="api-intrange"></a>

```typescript
type IntRange = {
    from(startInclusive: number): {
        by(skip: number): IntGeneratorTo;
        get down(): IntGeneratorTo;
        get up(): IntGeneratorTo;
    };
};
```

Integer range generators which (hopefully) make it super clear what your boundary, direction, and increment are.


#### IteratorTransformerConstructor

<a id="api-iteratortransformerconstructor"></a>

```typescript
type IteratorTransformerConstructor<InputT, OutputT> = SyncIteratorTransformerConstructor<InputT, OutputT> | AsyncIteratorTransformerConstructor<InputT, OutputT>;
```

#### IteratorTransformerMore

<a id="api-iteratortransformermore"></a>

```typescript
type IteratorTransformerMore<T> = () => Optional<T>;
```

#### JsonParseEvent

<a id="api-jsonparseevent"></a>

```typescript
type JsonParseEvent = JsonParseBeginEvent<JsonParseState> | JsonParseEndEvent<JsonParseState>;
```

#### JsonParseState

<a id="api-jsonparsestate"></a>

```typescript
type JsonParseState = JsonParseObjectState | JsonParseArrayState | JsonParseItemState | JsonParsePropertyState | JsonParseRootState;
```

#### JsonParseTypeT

<a id="api-jsonparsetypet"></a>

```typescript
type JsonParseTypeT = (typeof JsonParseType)[keyof typeof JsonParseType];
```

#### JsonPunctuation

<a id="api-jsonpunctuation"></a>

```typescript
type JsonPunctuation = "{" | "}" | "[" | "]" | ":" | ",";
```

#### JsonToken

<a id="api-jsontoken"></a>

```typescript
type JsonToken = JsonNullToken | JsonBooleanToken | JsonNumberToken | JsonStringToken | JsonPunctuationToken | JsonSpaceToken;
```

#### JsonTokenTypeT

<a id="api-jsontokentypet"></a>

```typescript
type JsonTokenTypeT = (typeof JsonTokenType)[keyof typeof JsonTokenType];
```

#### LCEPresetName

<a id="api-lcepresetname"></a>

```typescript
type LCEPresetName = keyof typeof LCE_PRESETS;
```

#### List

<a id="api-list"></a>

```typescript
type List<T> = {
    at(index: number): T | undefined;
    get head(): T | undefined;
    insertAt(index: number, value: T): void;
    get isEmpty(): boolean;
    get length(): number;
    pop(): T | undefined;
    push(value: T): void;
    shift(): T | undefined;
    toArray(): T[];
    unshift(value: T): void;
    values(): Generator<T, void, undefined>;
    valuesAndIndexes(): Generator<[T, number], void, undefined>;
    walk(block: (value: T, index: number) => ListWalkDecision<T>): void;
    readonly [Symbol.toStringTag]: string;
};
```

Basic list-like structure.


#### ListWalkDecision

<a id="api-listwalkdecision"></a>

```typescript
type ListWalkDecision<T> = {
    deleteItem?: boolean;
    insertAfter?: T;
    insertBefore?: T;
    keepWalking: boolean;
};
```

Controls how a [List](#api-list)'s <kbd>walk</kbd> operation behaves after each iteration.


#### Optional

<a id="api-optional"></a>

```typescript
type Optional<T> = {
    value: T;
} | undefined;
```

#### ParseLocalDateConfig

<a id="api-parselocaldateconfig"></a>

```typescript
type ParseLocalDateConfig = {
    offsetMinutes?: number;
    time?: boolean;
    timeDelimiters?: string[];
    zone?: boolean;
};
```

Configuration for a [parseLocalDate](#api-parselocaldate) call.


#### PropertiesFromDescriptors

<a id="api-propertiesfromdescriptors"></a>

```typescript
type PropertiesFromDescriptors<R extends Record<string, TypedPropertyDescriptor<unknown>>> = {
    readonly [K in ReadOnlyDescriptorsKeys<R>]: R[K] extends TypedPropertyDescriptor<infer V> ? V : never;
} & {
    [K in ReadWriteDescriptorsKeys<R>]: R[K] extends TypedPropertyDescriptor<infer V> ? V : never;
} & {
    [K in WriteOnlyDescriptorsKeys<R>]: R[K] extends TypedPropertyDescriptor<infer V> ? V : never;
} & {
    [K in RenamedWriteOnlyDescriptorsKeys<R>]?: undefined;
};
```

Produce an object with the properties described by the descriptors. See [RenameIfWriteOnlyDescriptor](#api-renameifwriteonlydescriptor) for details on the mangling of write-only properties.


#### PropertyDescriptorFlags

<a id="api-propertydescriptorflags"></a>

```typescript
type PropertyDescriptorFlags = {
    configurable?: boolean;
    enumerable?: boolean;
    writable?: boolean;
};
```

Basic flags for any property descriptor.


#### PropertyFromDescriptor

<a id="api-propertyfromdescriptor"></a>

```typescript
type PropertyFromDescriptor<K extends string, D extends TypedPropertyDescriptor<unknown>> = D extends TypedPropertyDescriptor<infer V> ? ({
    readonly [key in IfReadOnlyDescriptor<K, D>]: V;
} & {
    [key in IfReadWriteDescriptor<K, D>]: V;
} & {
    [key in IfWriteOnlyDescriptor<K, D>]: V;
} & {
    [key in RenameIfWriteOnlyDescriptor<K, D>]?: undefined;
}) : never;
```

Produce a single-property object type for the given property descriptor. Note: will produce an additional mangled pseudo-property for write-only properties. See [RenameIfWriteOnlyDescriptor](#api-renameifwriteonlydescriptor) for details on the mangling.


#### Queue

<a id="api-queue"></a>

```typescript
type Queue<T> = {
    add(value: T): void;
    peek(): T | undefined;
    remove(value: T): void;
    get length(): number;
    take(): T | undefined;
    toArray(): T[];
    values(): Generator<T, void, undefined>;
};
```

Basic interface for a queue.


#### ReadOnlyDescriptorsKeys

<a id="api-readonlydescriptorskeys"></a>

```typescript
type ReadOnlyDescriptorsKeys<R> = R extends Record<infer K, TypedPropertyDescriptor<unknown>> ? {
    [key in K]: IfReadOnlyDescriptor<key, R[key]>;
}[K] : never;
```

Produce the keys for the given property descriptors record which would produce read-only properties.


#### ReadOnlyPropertyDescriptor

<a id="api-readonlypropertydescriptor"></a>

```typescript
type ReadOnlyPropertyDescriptor = {
    writable: false;
};
```

Partial property descriptor which has been marked as non-writable.


#### ReadWriteDescriptorsKeys

<a id="api-readwritedescriptorskeys"></a>

```typescript
type ReadWriteDescriptorsKeys<R> = R extends Record<infer K, TypedPropertyDescriptor<unknown>> ? {
    [key in K]: IfReadWriteDescriptor<key, R[key]>;
}[K] : never;
```

Produce the keys for the given property descriptors record which would produce read-write (or write-only) properties.


#### RenamedWriteOnlyDescriptorsKeys

<a id="api-renamedwriteonlydescriptorskeys"></a>

```typescript
type RenamedWriteOnlyDescriptorsKeys<R> = R extends Record<infer K, TypedPropertyDescriptor<unknown>> ? {
    [key in string & K]: RenameIfWriteOnlyDescriptor<key, R[key]>;
}[string & K] : never;
```

Produce the <strong>mangled</strong> keys for the given property descriptors record which would produce write-only properties. See [RenameIfWriteOnlyDescriptor](#api-renameifwriteonlydescriptor) for details on the mangling.


#### RenameIfWriteOnlyDescriptor

<a id="api-renameifwriteonlydescriptor"></a>

```typescript
type RenameIfWriteOnlyDescriptor<Key extends string, D extends TypedPropertyDescriptor<unknown>> = D extends SetPropertyDescriptor<unknown> ? `${Key}IsWriteOnly` : never;
```

Mangle the given <kbd>Key</kbd> to <kbd>$\{Key\}IsWriteOnly</kbd> if property descriptor <kbd>D</kbd> would produce a write-only property.


#### ReQuoteOptions

<a id="api-requoteoptions"></a>

```typescript
type ReQuoteOptions = {
    auto?: true;
    quotes?: never;
} | {
    auto?: never;
    quotes?: string;
};
```

#### SearchResult

<a id="api-searchresult"></a>

```typescript
type SearchResult = {
    before?: undefined;
    comparisons: number;
    exists: true;
    index: number;
} | {
    before: number;
    comparisons: number;
    exists: false;
    index?: undefined;
};
```

A result of a search through a list. If the value was found, its index is returned. Otherwise, the <kbd>before</kbd> value is the index before which the value could be inserted. For troubleshooting and instrumentation, also returns the number of comparisons it took to find the value.


#### SetPropertyDescriptor

<a id="api-setpropertydescriptor"></a>

```typescript
type SetPropertyDescriptor<T> = PropertyDescriptorFlags & {
    get?: never;
    set(t: T): void;
};
```

Partial property descriptor which includes only a mutator (setter) and not an accessor (getter), and is thus write-only. Note: TypeScript support for these kinds of properties is very poor as of v5.7.


#### ShuffleConfig

<a id="api-shuffleconfig"></a>

```typescript
type ShuffleConfig<T> = {
    into?: T[] | undefined;
    random01?: () => number;
};
```

Configuration options for the [shuffle](#api-shuffle) function.


#### StarGlobPart

<a id="api-starglobpart"></a>

```typescript
type StarGlobPart = StarGlobText | StarGlobStar;
```

#### StringIterable

<a id="api-stringiterable"></a>

```typescript
type StringIterable = string | Iterable<string, undefined, undefined> | Iterator<string, undefined, undefined>;
```

#### SvgAbsolutePathCommand

<a id="api-svgabsolutepathcommand"></a>

```typescript
type SvgAbsolutePathCommand = "M" | "L" | "H" | "V" | "Z" | "C" | "S" | "Q" | "T" | "A";
```

#### SvgPathCommand

<a id="api-svgpathcommand"></a>

```typescript
type SvgPathCommand = SvgAbsolutePathCommand | SvgRelativePathCommand;
```

#### SvgPathToken

<a id="api-svgpathtoken"></a>

```typescript
type SvgPathToken = SvgPathTokenByType[keyof SvgPathTokenByType];
```

#### SvgPathValue

<a id="api-svgpathvalue"></a>

```typescript
type SvgPathValue = SvgPathValueByType[SvgPathValueType];
```

#### SvgPathValueType

<a id="api-svgpathvaluetype"></a>

```typescript
type SvgPathValueType = keyof SvgPathValueByType;
```

#### SvgRelativePathCommand

<a id="api-svgrelativepathcommand"></a>

```typescript
type SvgRelativePathCommand = Lowercase<SvgAbsolutePathCommand>;
```

#### SyncIteratorTransformerConstructor

<a id="api-synciteratortransformerconstructor"></a>

```typescript
type SyncIteratorTransformerConstructor<InputT, OutputT> = AbstractConstructorLike<[iterator: Iterator<InputT, undefined, undefined>], IteratorTransformer<InputT, OutputT>>;
```

#### ToBatchesMode

<a id="api-tobatchesmode"></a>

```typescript
type ToBatchesMode = typeof SPREAD_BATCHES | typeof FILL_BATCHES;
```

Strategy for grouping array items into batches.


#### TypedPropertyDescriptor_2

<a id="api-typedpropertydescriptor-2"></a>

```typescript
type TypedPropertyDescriptor<T> = ValuePropertyDescriptor<T> | GetPropertyDescriptor<T> | SetPropertyDescriptor<T> | GetSetPropertyDescriptor<T>;
```

Union for reasonable configurations of property descriptors which could affect the type for the property.


#### ValuePropertyDescriptor

<a id="api-valuepropertydescriptor"></a>

```typescript
type ValuePropertyDescriptor<T> = PropertyDescriptorFlags & {
    get?: never;
    set?: never;
    value: T;
};
```

Partial property descriptor which contains a static value, instead of an accessor and/or mutator.


#### WriteOnlyDescriptorsKeys

<a id="api-writeonlydescriptorskeys"></a>

```typescript
type WriteOnlyDescriptorsKeys<R> = R extends Record<infer K, TypedPropertyDescriptor<unknown>> ? {
    [key in string & K]: IfWriteOnlyDescriptor<key, R[key]>;
}[string & K] : never;
```

Produce the non-mangled keys for the given property descriptors record which would produce write-only properties.


### Variables

#### con

<a id="api-con"></a>

```typescript
con: ConsoleLike
```

#### DQ

<a id="api-dq"></a>

```typescript
DQ: "\""
```

#### DURATION_DATE_DESIGNATORS

<a id="api-duration-date-designators"></a>

```typescript
DURATION_DATE_DESIGNATORS: readonly DurationDesignator[]
```

#### DURATION_DESIGNATORS

<a id="api-duration-designators"></a>

```typescript
DURATION_DESIGNATORS: readonly DurationDesignator[]
```

#### DURATION_KEY_BY_DESIGNATOR

<a id="api-duration-key-by-designator"></a>

```typescript
DURATION_KEY_BY_DESIGNATOR: Readonly<{
    readonly Y: "year";
    readonly D: "day";
    readonly H: "hour";
    readonly S: "second";
    readonly W: "week";
}>
```

Map between [DurationDesignator](#api-durationdesignator) and [Duration](#api-duration) property name. Does not include `M`, which is ambiguous, nor `T` which does not correspond to a property.


#### DURATION_KEY_SECONDS

<a id="api-duration-key-seconds"></a>

```typescript
DURATION_KEY_SECONDS: Readonly<Required<Omit<Duration, "month" | "text" | "year">>>
```

Lookup table for the conversion of a [Duration](#api-duration) property value to seconds. Does not include `month` or `year`, which have variable numbers of days.


#### DURATION_TIME_DESIGNATORS

<a id="api-duration-time-designators"></a>

```typescript
DURATION_TIME_DESIGNATORS: readonly DurationDesignator[]
```

#### ecmaKeySort

<a id="api-ecmakeysort"></a>

```typescript
ecmaKeySort: Comparator<string>
```

Comparator for Object keys in ECMA "correct" order. Don't read the history on this. It will only depress you.



#### FILL_BATCHES

<a id="api-fill-batches"></a>

```typescript
FILL_BATCHES = "fill"
```

Fill each batch to the maximum, except possibly the last. That is, if the list has 11 items with a `maxPerBatch` of 5, you would get `[5, 5, 1]`.


#### INDEX_KEY_PATTERN

<a id="api-index-key-pattern"></a>

```typescript
INDEX_KEY_PATTERN: RegExp
```

Pattern for an array index key, basically any integer.


#### INFINITY_SIGIL

<a id="api-infinity-sigil"></a>

```typescript
INFINITY_SIGIL = "∞"
```

Text used for displaying human-readable infinity.


#### INT_SET_SIGIL

<a id="api-int-set-sigil"></a>

```typescript
INT_SET_SIGIL = "ℤ"
```

#### intRange

<a id="api-intrange"></a>

```typescript
intRange: IntRange
```

Start generating a range of integers.


#### JSON_PATH_ROOT

<a id="api-json-path-root"></a>

```typescript
JSON_PATH_ROOT: "$"
```

#### JSON_PUNCTUATION

<a id="api-json-punctuation"></a>

```typescript
JSON_PUNCTUATION: readonly JsonPunctuation[]
```

#### JsonParseTransition

<a id="api-jsonparsetransition"></a>

```typescript
JsonParseTransition: Readonly<{
    readonly Begin: "begin";
    readonly End: "end";
}>
```

#### JsonParseType

<a id="api-jsonparsetype"></a>

```typescript
JsonParseType: Readonly<{
    readonly Arr: "array";
    readonly Item: "item";
    readonly Obj: "object";
    readonly Prop: "property";
    readonly Root: "root";
}>
```

#### JsonTokenType

<a id="api-jsontokentype"></a>

```typescript
JsonTokenType: Readonly<{
    Boo: "boolean";
    Nul: "null";
    Num: "number";
    Pun: "pun";
    Spc: "space";
    Str: "string";
}>
```

Discriminators for each of the `type` values for [JsonToken](#api-jsontoken).


#### LCE_PRESET_NAMES

<a id="api-lce-preset-names"></a>

```typescript
LCE_PRESET_NAMES: LCEPresetName[]
```

#### LCE_PRESETS

<a id="api-lce-presets"></a>

```typescript
LCE_PRESETS: {
    ansiC: (seed: number | bigint | undefined) => {
        a: number;
        c: number;
        m: number;
        seed: number | bigint | undefined;
        width: number;
    };
    borlandC: (seed: number | bigint | undefined) => {
        a: number;
        c: number;
        m: number;
        seed: number | bigint | undefined;
        width: number;
    };
    c88: (seed: number | bigint | undefined) => {
        a: number;
        c: number;
        m: number;
        seed: number | bigint | undefined;
    };
    c93: (seed: number | bigint | undefined) => {
        a: number;
        c: number;
        m: number;
        seed: number | bigint | undefined;
    };
    delphi: (seed: number | bigint | undefined) => {
        a: number;
        c: number;
        m: number;
        seed: number | bigint | undefined;
        width: number;
    };
    glibc: (seed: number | bigint | undefined) => {
        a: number;
        c: number;
        m: number;
        seed: number | bigint | undefined;
        width: number;
    };
    java: (seed?: number | bigint | undefined) => RNGOptions;
    knuth: (seed: number | bigint | undefined) => {
        a: bigint;
        c: number;
        m: bigint;
        seed: number | bigint | undefined;
        width: number;
    };
    visualC: (seed: number | bigint | undefined) => {
        a: number;
        c: number;
        m: number;
        floor: number;
        seed: number | bigint | undefined;
        width: number;
    };
}
```

#### METRIC_PREFIXES

<a id="api-metric-prefixes"></a>

```typescript
METRIC_PREFIXES: readonly string[]
```

List of metric prefixes, where the index is its base-1000 or base-1024 offset.


#### NEG_INFINITY_SIGIL

<a id="api-neg-infinity-sigil"></a>

```typescript
NEG_INFINITY_SIGIL = "-∞"
```

Text used for displaying human-readable negative infinity.


#### numberAsc

<a id="api-numberasc"></a>

```typescript
numberAsc: Comparator<number>
```

Numeric comparator which sorts lower values before higher ones.


#### numberDesc

<a id="api-numberdesc"></a>

```typescript
numberDesc: Comparator<number>
```

Numeric (reverse) comparator which sorts higher values before lower ones.


#### PI_SIGIL

<a id="api-pi-sigil"></a>

```typescript
PI_SIGIL = "π"
```

Text used for displaying human-readable pi.


#### REAL_SET_SIGIL

<a id="api-real-set-sigil"></a>

```typescript
REAL_SET_SIGIL = "ℝ"
```

#### SPREAD_BATCHES

<a id="api-spread-batches"></a>

```typescript
SPREAD_BATCHES = "spread"
```

Try to spread out the batches evenly. That is, if the list has 11 items with a `maxPerBatch` of 5, instead of getting `[5, 5, 1]` you would get `[4, 4, 3]`.


#### SQ

<a id="api-sq"></a>

```typescript
SQ: "'"
```

#### stringAsc

<a id="api-stringasc"></a>

```typescript
stringAsc: Comparator<string>
```

String comparator which sorts in lexicographic (dictionary) order.


#### stringDesc

<a id="api-stringdesc"></a>

```typescript
stringDesc: Comparator<string>
```

String comparator which sorts in reverse lexicographic (dictionary) order.


#### SVG_ABSOLUTE_PATH_COMMANDS

<a id="api-svg-absolute-path-commands"></a>

```typescript
SVG_ABSOLUTE_PATH_COMMANDS: readonly SvgAbsolutePathCommand[]
```

#### SVG_PATH_COMMANDS

<a id="api-svg-path-commands"></a>

```typescript
SVG_PATH_COMMANDS: readonly SvgPathCommand[]
```

#### SVG_RELATIVE_PATH_COMMANDS

<a id="api-svg-relative-path-commands"></a>

```typescript
SVG_RELATIVE_PATH_COMMANDS: readonly SvgRelativePathCommand[]
```

#### TIME_DELIMITERS

<a id="api-time-delimiters"></a>

```typescript
TIME_DELIMITERS: string[]
```

Possible delimiters between a date and a time value.


