@tidyjs/tidy 2.4.4 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/groupBy.js +2 -1
- package/dist/es/groupBy.js.map +1 -1
- package/dist/es/helpers/isObject.js +7 -0
- package/dist/es/helpers/isObject.js.map +1 -0
- package/dist/es/index.js +1 -0
- package/dist/es/index.js.map +1 -1
- package/dist/es/item/rate.js +7 -7
- package/dist/es/item/rate.js.map +1 -1
- package/dist/es/mutate.js +5 -5
- package/dist/es/mutate.js.map +1 -1
- package/dist/es/summary/deviation.js.map +1 -1
- package/dist/es/summary/first.js.map +1 -1
- package/dist/es/summary/last.js.map +1 -1
- package/dist/es/summary/max.js.map +1 -1
- package/dist/es/summary/mean.js.map +1 -1
- package/dist/es/summary/meanRate.js.map +1 -1
- package/dist/es/summary/median.js.map +1 -1
- package/dist/es/summary/min.js.map +1 -1
- package/dist/es/summary/n.js +5 -1
- package/dist/es/summary/n.js.map +1 -1
- package/dist/es/summary/nDistinct.js +2 -1
- package/dist/es/summary/nDistinct.js.map +1 -1
- package/dist/es/summary/sum.js +7 -2
- package/dist/es/summary/sum.js.map +1 -1
- package/dist/es/summary/variance.js.map +1 -1
- package/dist/es/vector/cumsum.js.map +1 -1
- package/dist/es/vector/lag.js +1 -1
- package/dist/es/vector/lag.js.map +1 -1
- package/dist/es/vector/lead.js +1 -1
- package/dist/es/vector/lead.js.map +1 -1
- package/dist/es/vector/roll.js +4 -3
- package/dist/es/vector/roll.js.map +1 -1
- package/dist/es/vector/rowNumber.js +10 -0
- package/dist/es/vector/rowNumber.js.map +1 -0
- package/dist/lib/groupBy.js +2 -1
- package/dist/lib/groupBy.js.map +1 -1
- package/dist/lib/helpers/isObject.js +11 -0
- package/dist/lib/helpers/isObject.js.map +1 -0
- package/dist/lib/index.js +2 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/item/rate.js +7 -7
- package/dist/lib/item/rate.js.map +1 -1
- package/dist/lib/mutate.js +5 -5
- package/dist/lib/mutate.js.map +1 -1
- package/dist/lib/summary/deviation.js.map +1 -1
- package/dist/lib/summary/first.js.map +1 -1
- package/dist/lib/summary/last.js.map +1 -1
- package/dist/lib/summary/max.js.map +1 -1
- package/dist/lib/summary/mean.js.map +1 -1
- package/dist/lib/summary/meanRate.js.map +1 -1
- package/dist/lib/summary/median.js.map +1 -1
- package/dist/lib/summary/min.js.map +1 -1
- package/dist/lib/summary/n.js +5 -1
- package/dist/lib/summary/n.js.map +1 -1
- package/dist/lib/summary/nDistinct.js +2 -1
- package/dist/lib/summary/nDistinct.js.map +1 -1
- package/dist/lib/summary/sum.js +7 -2
- package/dist/lib/summary/sum.js.map +1 -1
- package/dist/lib/summary/variance.js.map +1 -1
- package/dist/lib/vector/cumsum.js.map +1 -1
- package/dist/lib/vector/lag.js +1 -1
- package/dist/lib/vector/lag.js.map +1 -1
- package/dist/lib/vector/lead.js +1 -1
- package/dist/lib/vector/lead.js.map +1 -1
- package/dist/lib/vector/roll.js +4 -3
- package/dist/lib/vector/roll.js.map +1 -1
- package/dist/lib/vector/rowNumber.js +14 -0
- package/dist/lib/vector/rowNumber.js.map +1 -0
- package/dist/tidy.d.ts +40 -19
- package/dist/umd/tidy.js +47 -22
- package/dist/umd/tidy.js.map +1 -1
- package/dist/umd/tidy.min.js +1 -1
- package/dist/umd/tidy.min.js.map +1 -1
- package/package.json +2 -2
package/dist/umd/tidy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tidy.js","sources":["../../src/tidy.ts","../../src/filter.ts","../../src/when.ts","../../src/map.ts","../../src/helpers/singleOrArray.ts","../../src/distinct.ts","../../src/arrange.ts","../../src/summarize.ts","../../src/mutate.ts","../../src/total.ts","../../src/helpers/assignGroupKeys.ts","../../src/helpers/groupTraversal.ts","../../src/helpers/groupMap.ts","../../src/helpers/identity.ts","../../src/groupBy.ts","../../src/summary/n.ts","../../src/summary/sum.ts","../../src/tally.ts","../../src/count.ts","../../src/rename.ts","../../src/slice.ts","../../src/innerJoin.ts","../../src/leftJoin.ts","../../src/fullJoin.ts","../../src/mutateWithSummary.ts","../../src/helpers/keysFromItems.ts","../../src/selectors/everything.ts","../../src/select.ts","../../src/transmute.ts","../../src/addRows.ts","../../src/pivotWider.ts","../../src/pivotLonger.ts","../../src/expand.ts","../../src/sequences/fullSeq.ts","../../src/replaceNully.ts","../../src/complete.ts","../../src/fill.ts","../../src/debug.ts","../../src/math/math.ts","../../src/item/rate.ts","../../src/helpers/summation.ts","../../src/vector/cumsum.ts","../../src/vector/roll.ts","../../src/vector/lag.ts","../../src/vector/lead.ts","../../src/summary/min.ts","../../src/summary/max.ts","../../src/summary/mean.ts","../../src/summary/meanRate.ts","../../src/summary/median.ts","../../src/summary/deviation.ts","../../src/summary/variance.ts","../../src/summary/nDistinct.ts","../../src/summary/first.ts","../../src/summary/last.ts","../../src/selectors/startsWith.ts","../../src/selectors/endsWith.ts","../../src/selectors/contains.ts","../../src/selectors/matches.ts","../../src/selectors/numRange.ts","../../src/selectors/negate.ts"],"sourcesContent":["// note prettier is ignored here via .prettierignore\nimport { TidyFn, TidyGroupExportFn } from './types';\n\n// pipe types not well supported: https://github.com/microsoft/TypeScript/issues/29904\n// so manually make types overloaded for up to 10 steps\n\n/**\n * Forms a tidy pipeline that can be called with (items)\n * @param items array of items to manipulate\n * @param fns Tidy functions\n */\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, T8 extends object, T9 extends object, T10 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyFn<T6, T7>, f8: TidyFn<T7, T8>, f9: TidyFn<T8, T9>, f10: TidyFn<T9, T10>): T10[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, T8 extends object, T9 extends object, T10 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyFn<T6, T7>, f8: TidyFn<T7, T8>, f9: TidyFn<T8, T9>, f10: TidyGroupExportFn<T9, T10>): T10;\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, T8 extends object, T9 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyFn<T6, T7>, f8: TidyFn<T7, T8>, f9: TidyFn<T8, T9>): T9[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, T8 extends object, T9 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyFn<T6, T7>, f8: TidyFn<T7, T8>, f9: TidyGroupExportFn<T8, T9>): T9;\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, T8 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyFn<T6, T7>, f8: TidyFn<T7, T8>): T8[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, T8 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyFn<T6, T7>, f8: TidyGroupExportFn<T7, T8>): T8;\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyFn<T6, T7>): T7[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyGroupExportFn<T6, T7>): T7;\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>): T6[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyGroupExportFn<T5, T6>): T6;\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5> ): T5[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyGroupExportFn<T4, T5> ): T5;\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>): T4[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyGroupExportFn<T3, T4>): T4;\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>): T3[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyGroupExportFn<T2, T3>): T3;\nexport function tidy<T extends object, T1 extends object, T2 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>): T2[];\nexport function tidy<T extends object, T1 extends object, T2 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyGroupExportFn<T1, T2>): T2;\nexport function tidy<T extends object, T1 extends object>(items: T[], f1: TidyFn<T, T1>): T1[];\nexport function tidy<T extends object, T1 extends object>(items: T[], f1: TidyGroupExportFn<T, T1>): T1;\nexport function tidy<InputT extends object>(\n items: InputT[],\n ...fns: (TidyFn<any, any> | TidyGroupExportFn<any, any>)[]\n): any {\n if (typeof items === 'function') {\n throw new Error('You must supply the data as the first argument to tidy()');\n }\n\n let result: any = items;\n for (const fn of fns) {\n if (fn) {\n // skip falsy values\n result = fn(result);\n }\n }\n\n return result;\n}\n","import { TidyFn } from './types';\n\n/**\n * Filters items\n * @param filterFn Returns true to keep the item, false to filter out\n */\nexport function filter<T extends object, O extends T>(\n filterFn: (item: T, index: number, array: T[]) => item is O\n): TidyFn<T, O>;\nexport function filter<T extends object>(\n filterFn: (item: T, index: number, array: T[]) => boolean\n): TidyFn<T>;\nexport function filter<T extends object>(\n filterFn: (item: T, index: number, array: T[]) => boolean\n): TidyFn<T> {\n const _filter: TidyFn<T> = (items: T[]): T[] => items.filter(filterFn);\n return _filter;\n}\n","import { TidyFn } from './types';\nimport { tidy } from './tidy';\n\n/**\n * Conditionally runs a tidy sub-flow\n */\nexport function when<T extends object>(\n predicate: ((items: T[]) => boolean) | boolean,\n fns: TidyFn<any, any>[]\n): TidyFn<T, any> {\n const _when: TidyFn<T, any> = (items: T[]) => {\n if (typeof predicate === 'function') {\n if (!predicate(items)) return items;\n } else if (!predicate) {\n return items;\n }\n\n const results = (tidy as any)(items, ...fns);\n return results;\n };\n return _when;\n}\n","import { TidyFn } from './types';\n\n/**\n * Maps items\n * @param mapFn Maps items from one form to another\n */\nexport function map<T extends object, OutputT>(\n mapFn: (item: T, index: number, array: T[]) => OutputT\n): TidyFn<T, OutputT> {\n const _map: TidyFn<T, OutputT> = (items: T[]) => items.map(mapFn);\n return _map;\n}\n","export type SingleOrArray<T> = T | T[];\n\n/**\n * Given an arg that may or may not be an array, make it an array if it isn't one.\n */\nexport function singleOrArray<T>(d: SingleOrArray<T> | null | undefined): T[] {\n return d == null ? [] : Array.isArray(d) ? d : [d];\n}\n","import { KeyOrFn, TidyFn } from './types';\nimport { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\n\n/**\n * Removes items with duplicate values for the specified keys.\n * If no keys provided, uses strict equality.\n *\n * @param keys Keys to compute distinct across\n */\nexport function distinct<T extends object>(\n keys?: SingleOrArray<KeyOrFn<T>> | null | undefined\n): TidyFn<T> {\n const _distinct: TidyFn<T> = (items: T[]): T[] => {\n keys = singleOrArray(keys);\n\n if (!keys.length) {\n // https://jsperf.com/unique-array-by-strict-equality\n const set = new Set<T>();\n for (const item of items) {\n set.add(item);\n }\n return Array.from(set);\n }\n\n // compare keys\n // https://jsperf.com/distinct-by-key\n // turns out nested Maps are faster than string keys. AND they support\n // and arbitrary value.\n const rootMap = new Map();\n const distinctItems: T[] = [];\n const lastKey = keys[keys.length - 1];\n for (const item of items) {\n let map = rootMap;\n let hasItem = false;\n\n // go through each key to find out if we have it\n for (const key of keys) {\n const mapItemKey =\n typeof key === 'function' ? key(item) : item[key as keyof T];\n // last key, check if we already added it\n if (key === lastKey) {\n hasItem = map.has(mapItemKey);\n if (!hasItem) {\n distinctItems.push(item);\n map.set(mapItemKey, true);\n }\n break;\n }\n\n // create maps all the way down\n if (!map.has(mapItemKey)) {\n map.set(mapItemKey, new Map());\n }\n\n // move to next inner map\n map = map.get(mapItemKey);\n }\n }\n\n return distinctItems;\n };\n\n return _distinct;\n}\n","import { ascending } from 'd3-array';\nimport { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\nimport { Comparator, Key, KeyOrFn, TidyFn } from './types';\n\n/**\n * Sorts items\n * @param comparators Given a, b return -1 if a comes before b, 0 if equal, 1 if after\n */\nexport function arrange<T extends object>(\n // note: had to switch to returning `any` instead of using Comparator<T> (returns number)\n // for #49 - otherwise typescript failed to do type inference on accessors\n comparators: SingleOrArray<Key | ((a: T, b: T) => any)>\n): TidyFn<T> {\n const _arrange: TidyFn<T> = (items: T[]): T[] => {\n // expand strings `key` to `asc(key)`\n const comparatorFns = singleOrArray(comparators).map((comp) =>\n typeof comp === 'function'\n ? // length === 1 means it is an accessor (1 argument). convert to comparator via asc\n comp.length === 1\n ? asc(comp as (d: T) => unknown)\n : (comp as Comparator<T>)\n : asc<T>(comp)\n );\n\n return items.slice().sort((a, b) => {\n for (const comparator of comparatorFns) {\n const result = comparator(a, b);\n if (result) return result;\n }\n\n return 0;\n });\n };\n\n return _arrange;\n}\n\n/**\n * Creates an ascending comparator based on a key\n * @param key property key of T\n */\nexport function asc<T>(key: Key | ((d: T) => any)): Comparator<T> {\n const keyFn = typeof key === 'function' ? key : (d: any) => d[key];\n\n return function _asc(a: T, b: T) {\n return emptyAwareComparator(keyFn(a), keyFn(b), false);\n };\n}\n\n/**\n * Creates a descending comparator based on a key\n * @param key property key of T\n */\nexport function desc<T>(key: Key | ((d: T) => any)): Comparator<T> {\n const keyFn = typeof key === 'function' ? key : (d: any) => d[key];\n return function _desc(a: T, b: T) {\n return emptyAwareComparator(keyFn(a), keyFn(b), true);\n };\n}\n\n/**\n * Creates a comparator that sorts values based on a key\n * and a supplied array of the desired order for the values.\n * Items not found in the array will be sorted last.\n * @param order array of desired sort order\n */\nexport function fixedOrder<T>(\n key: KeyOrFn<T>,\n order: Array<T[keyof T]>,\n options?: { position?: 'start' | 'end' }\n): (a: T, b: T) => number {\n let { position = 'start' } = options ?? {};\n const positionFactor = position === 'end' ? -1 : 1;\n\n const indexMap = new Map();\n for (let i = 0; i < order.length; ++i) {\n indexMap.set(order[i], i);\n }\n\n const keyFn =\n typeof key === 'function'\n ? key\n : (d: T) => (d[key as keyof T] as unknown) as any;\n\n return function _fixedOrder(a: T, b: T) {\n const aIndex: number = indexMap.get(keyFn(a)) ?? -1;\n const bIndex: number = indexMap.get(keyFn(b)) ?? -1;\n\n if (aIndex >= 0 && bIndex >= 0) {\n return aIndex - bIndex;\n }\n\n if (aIndex >= 0) {\n return positionFactor * -1;\n }\n\n if (bIndex >= 0) {\n return positionFactor * 1;\n }\n\n return 0;\n };\n}\n\nfunction emptyAwareComparator(aInput: any, bInput: any, desc: boolean) {\n // we swap order to get descending behavior\n let a = desc ? bInput : aInput;\n let b = desc ? aInput : bInput;\n\n // NaN, null, undefined is the order for emptys\n if (isEmpty(a) && isEmpty(b)) {\n const rankA = a !== a ? 0 : a === null ? 1 : 2;\n const rankB = b !== b ? 0 : b === null ? 1 : 2;\n const order = rankA - rankB;\n return desc ? -order : order;\n }\n\n // keep empty values at the bottom\n if (isEmpty(a)) {\n return desc ? -1 : 1;\n }\n if (isEmpty(b)) {\n return desc ? 1 : -1;\n }\n\n // descending is handled by swapping the a and b args at the start\n return ascending(a, b);\n}\n\nfunction isEmpty(value: any) {\n return value == null || value !== value /* NaN check */;\n}\n","import { A } from 'ts-toolbelt';\nimport { singleOrArray } from './helpers/singleOrArray';\nimport { Key, TidyFn, Vector } from './types';\n\nexport type SummarizeSpec<T> = Record<Key, (items: T[]) => any>;\n\nexport interface SummarizeOptions<T = any> {\n rest?: (key: keyof T) => (items: T[]) => any;\n}\n\ntype SummarizedT<\n T extends object,\n SumSpec extends SummarizeSpec<T>,\n Options extends SummarizeOptions<T> | undefined\n> = {\n // summarized values map to return type of the spec functions\n [K in keyof SumSpec]: ReturnType<SumSpec[K]>;\n} & // if there is a 'rest' option, add in the other values from T\n (NonNullable<Options>['rest'] extends Function\n ? Exclude<T, keyof SumSpec>\n : void);\n\n/**\n * summarizes items\n */\nexport function summarize<\n T extends object,\n SummarizedSpec extends SummarizeSpec<T> = SummarizeSpec<T>,\n Options extends SummarizeOptions<T> = SummarizeOptions<T>\n>(\n summarizeSpec: SummarizedSpec,\n options?: Options\n): TidyFn<T, A.Compute<SummarizedT<T, SummarizedSpec, Options>>> {\n type Output = SummarizedT<T, SummarizedSpec, Options>;\n\n const _summarize: TidyFn<T, A.Compute<Output>> = (\n items: T[]\n ): A.Compute<Output>[] => {\n options = options ?? ({} as Options);\n\n // reduce but use a loop to be more readable\n const summarized = {} as Output;\n const keys = Object.keys(summarizeSpec) as (keyof SummarizedSpec)[];\n\n for (const key of keys) {\n summarized[key as keyof Output] = summarizeSpec[key](items);\n }\n\n // if we a function to apply to the rest of the keys is supplied, use it\n // TODO: improve types for rest\n if (options.rest && items.length) {\n const objectKeys = Object.keys(items[0]) as (keyof T)[];\n for (const objKey of objectKeys) {\n if (keys.includes(objKey as any)) {\n continue;\n }\n\n (summarized as any)[objKey] = options.rest(objKey)(items);\n }\n }\n\n return [summarized] as A.Compute<Output>[];\n };\n\n return _summarize;\n}\n\n/*-------- summarize helpers ----------------------------------------*/\n\nexport type SummaryKeyFn<T, K = keyof T> = (key: K) => (items: T[]) => any;\n\nfunction _summarizeHelper<\n T extends object,\n SummarizedT extends object = { [K in keyof T]: any }\n>(\n items: T[],\n summaryFn: SummaryKeyFn<T>,\n predicateFn?: (vector: Vector<T>) => boolean,\n keys?: Array<keyof T | ((items: T[]) => (keyof T)[])>\n): SummarizedT[] {\n if (!items.length) return [];\n\n // reduce but use a loop to be more readable\n const summarized = {} as SummarizedT;\n\n // read in keys from first object if not provided\n let keysArr: (keyof T)[];\n if (keys == null) {\n keysArr = Object.keys(items[0]) as (keyof T)[];\n } else {\n // expand them all to a flat list of keys\n keysArr = [];\n for (const keyInput of singleOrArray(keys as any)) {\n if (typeof keyInput === 'function') {\n keysArr.push(...(keyInput(items) as (keyof T)[]));\n } else {\n keysArr.push(keyInput);\n }\n }\n }\n\n for (const key of keysArr) {\n if (predicateFn) {\n // inefficient to compute this vector here, wonder if it should\n // be computed prior to this func being called somehow? (TODO)\n const vector = items.map((d) => d[key]);\n if (!predicateFn(vector)) {\n continue;\n }\n }\n summarized[(key as unknown) as keyof SummarizedT] = summaryFn(key)(\n items\n ) as any;\n }\n\n return [summarized];\n}\n\n/*---- summarizeAll() --------------------------------------------*/\n\ntype SummaryFnOutput<T extends object, F extends SummaryKeyFn<T>> = ReturnType<\n ReturnType<F>\n>;\n\nexport function summarizeAll<T extends object, F extends SummaryKeyFn<T>>(\n summaryFn: F\n): TidyFn<T, A.Compute<Record<keyof T, SummaryFnOutput<T, F>>>> {\n const _summarizeAll: TidyFn<\n T,\n A.Compute<Record<keyof T, SummaryFnOutput<T, F>>>\n > = (items: T[]): A.Compute<Record<keyof T, SummaryFnOutput<T, F>>>[] =>\n _summarizeHelper(items, summaryFn);\n\n return _summarizeAll;\n}\n\n/*---- summarizeIf() --------------------------------------------*/\n// type is not perfect since it returns all keys of T, but better to have more than less I figure\nexport function summarizeIf<T extends object, F extends SummaryKeyFn<T>>(\n predicateFn: (vector: Vector<T>) => boolean,\n summaryFn: F\n): TidyFn<T, A.Compute<Record<keyof T, SummaryFnOutput<T, F>>>> {\n const _summarizeIf: TidyFn<\n T,\n A.Compute<Record<keyof T, SummaryFnOutput<T, F>>>\n > = (items: T[]): A.Compute<Record<keyof T, SummaryFnOutput<T, F>>>[] =>\n _summarizeHelper(items, summaryFn, predicateFn);\n\n return _summarizeIf;\n}\n\n/*---- summarizeAt() --------------------------------------------*/\nexport function summarizeAt<\n T extends object,\n Keys extends (keyof T)[],\n F extends SummaryKeyFn<T, Keys[number]>\n>(\n keys: Keys,\n summaryFn: F\n): TidyFn<T, A.Compute<Record<Keys[number], SummaryFnOutput<T, F>>>> {\n const _summarizeAt: TidyFn<\n T,\n A.Compute<Record<Keys[number], SummaryFnOutput<T, F>>>\n > = (items: T[]): A.Compute<Record<Keys[number], SummaryFnOutput<T, F>>>[] =>\n _summarizeHelper(items, summaryFn, undefined, keys);\n\n return _summarizeAt;\n}\n","import { TidyFn, NonFunctionValue, Key } from './types';\nimport { A } from 'ts-toolbelt';\n\ntype MutateSpecValue<T, O = any> = ((item: T) => O) | NonFunctionValue;\nexport type MutateSpec<T> = Record<Key, MutateSpecValue<T>>;\nexport type ResolvedObj<Obj extends Record<Key, MutateSpecValue<any>>> = {\n [K in keyof Obj]: Obj[K] extends (...args: any) => any\n ? ReturnType<Obj[K]> extends any[]\n ? ReturnType<Obj[K]>[number]\n : ReturnType<Obj[K]>\n : Obj[K];\n};\n\ntype Mutated<T, MSpec extends MutateSpec<T>> = T & ResolvedObj<MSpec>;\n\ntype Compute<T> = A.Compute<T>;\n\n/**\n * Mutates items, one item at a time. For mutating across multiple items,\n * use mutateWithSummary.\n * @param mutateSpec\n */\nexport function mutate<T extends object, MSpec extends MutateSpec<T>>(\n mutateSpec: MSpec\n): TidyFn<T, Compute<Mutated<T, MSpec>>> {\n type MutatedT = Mutated<T, MSpec>;\n // use Compute for better intellisense (reveals all keys in obj)\n const _mutate: TidyFn<T, Compute<MutatedT>> = (\n items: T[]\n ): Compute<MutatedT>[] => {\n // create the base items to merge mutated values into\n const mutatedItems: MutatedT[] = [];\n\n // we can update each item completely one at a time, since mutate doesn't\n // support looking across items. Use mutateWithSummary for that.\n for (const item of items) {\n const mutatedItem = { ...item } as MutatedT;\n\n for (const key in mutateSpec) {\n // get the mutated value for this item (either run the fn or use the constant)\n const mutateSpecValue = mutateSpec[key];\n const mutatedResult =\n typeof mutateSpecValue === 'function'\n ? mutateSpecValue(mutatedItem)\n : mutateSpecValue;\n\n mutatedItem[key as keyof MutatedT] = mutatedResult;\n }\n\n mutatedItems.push(mutatedItem);\n }\n\n return mutatedItems as Compute<MutatedT>[];\n };\n\n return _mutate;\n}\n","import { mutate, MutateSpec } from './mutate';\nimport {\n SummarizeSpec,\n summarize,\n summarizeAll,\n summarizeAt,\n summarizeIf,\n SummaryKeyFn,\n} from './summarize';\nimport { TidyFn, Vector } from './types';\n\n/**\n * Adds a summarized total row\n */\nexport function total<\n T extends object,\n SummarizedSpec extends SummarizeSpec<T> = SummarizeSpec<T>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(summarizeSpec: SummarizedSpec, mutateSpec: MutSpec): TidyFn<T> {\n const _total: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarize<T, SummarizedSpec>(summarizeSpec)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]);\n return [...items, ...mutated];\n };\n\n return _total;\n}\n\n// ----------------------------------------------------------------------------\n\n/**\n * Adds a summarized total row\n */\nexport function totalAll<\n T extends object,\n F extends SummaryKeyFn<T>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(summaryFn: F, mutateSpec: MutSpec): TidyFn<T> {\n const _totalAll: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarizeAll<T, F>(summaryFn)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]);\n return [...items, ...mutated];\n };\n\n return _totalAll;\n}\n\n// ----------------------------------------------------------------------------\n\n/**\n * Adds a summarized total row\n */\nexport function totalIf<\n T extends object,\n F extends SummaryKeyFn<T>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(\n predicateFn: (vector: Vector<T>) => boolean,\n summaryFn: F,\n mutateSpec: MutSpec\n): TidyFn<T> {\n const _totalIf: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarizeIf<T, F>(predicateFn, summaryFn)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]);\n return [...items, ...mutated];\n };\n\n return _totalIf;\n}\n\n// ----------------------------------------------------------------------------\n\n/**\n * Adds a summarized total row\n */\nexport function totalAt<\n T extends object,\n Keys extends (keyof T)[],\n F extends SummaryKeyFn<T, Keys[number]>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(keys: Keys, summaryFn: F, mutateSpec: MutSpec): TidyFn<T> {\n const _totalAt: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarizeAt<T, Keys, F>(keys, summaryFn)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]);\n return [...items, ...mutated];\n };\n\n return _totalAt;\n}\n","import { GroupKey } from '../types';\n\n/**\n * Given an object and a set of group keys [[keyName, keyValue], ...]\n * set the keys as properties within the object: { [keyName]: keyValue, ... }\n * (creates a new object with these properties added)\n */\nexport function assignGroupKeys<T extends object>(d: T, keys: GroupKey[]) {\n // abort if atypical input\n if (d == null || typeof d !== 'object' || Array.isArray(d)) return d;\n\n // transform to { groupKey1: value, ... } excluding function group keys\n const keysObj = Object.fromEntries(\n keys.filter((key) => typeof key[0] !== 'function')\n );\n\n return Object.assign(keysObj, d);\n}\n","import { Grouped, Datum } from '../types';\n\n/**\n * Traverse the leaves of the grouped items and and run the\n * groupFn on them. Basically an in-order traversal. Can you\n * believe this is real and not part of a coding interview??\n */\nexport function groupTraversal<\n T extends object,\n T2 extends Datum = T,\n OutputType = Grouped<T2>\n>(\n grouped: Grouped<T>,\n outputGrouped: OutputType,\n keys: any[],\n addSubgroup: (root: OutputType, keys: any[], level: number) => OutputType,\n addLeaves: (root: OutputType, keys: any[], items: T[], level: number) => void,\n level: number = 0\n) {\n for (const [key, value] of grouped.entries()) {\n const keysHere = [...keys, key];\n\n // internal node\n if (value instanceof Map) {\n const subgroup = addSubgroup(outputGrouped, keysHere, level);\n\n // recurse\n groupTraversal(\n value,\n subgroup,\n keysHere,\n addSubgroup,\n addLeaves,\n level + 1\n );\n } else {\n // leaf\n addLeaves(outputGrouped, keysHere, value, level);\n }\n }\n\n return outputGrouped;\n}\n","import { Grouped } from '../types';\nimport { groupTraversal } from './groupTraversal';\n\nexport function groupMap<T extends object, OutputT extends object = T>(\n grouped: Grouped<T>,\n groupFn: (items: T[], keys: any[]) => OutputT[],\n keyFn: (keys: any[]) => any = (keys) =>\n keys[\n keys.length - 1\n ] /* optional func to transform key based on all keys in map so far */\n): Grouped<OutputT> {\n function addSubgroup(parentGrouped: Grouped<OutputT>, keys: any[]) {\n const subgroup = new Map();\n parentGrouped.set(keyFn(keys), subgroup);\n return subgroup;\n }\n\n function addLeaves(\n parentGrouped: Grouped<OutputT>,\n keys: any[],\n values: T[]\n ) {\n parentGrouped.set(keyFn(keys), groupFn(values, keys));\n }\n\n const outputGrouped: Grouped<OutputT> = new Map();\n\n groupTraversal(grouped, outputGrouped, [], addSubgroup, addLeaves);\n\n return outputGrouped;\n}\n","export const identity = <T>(d: T): T => d;\n","import { group } from 'd3-array';\nimport { A, O } from 'ts-toolbelt';\nimport { assignGroupKeys } from './helpers/assignGroupKeys';\nimport { groupMap } from './helpers/groupMap';\nimport { groupTraversal } from './helpers/groupTraversal';\nimport { identity } from './helpers/identity';\nimport { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\nimport { Grouped, GroupKey, TidyGroupExportFn, Key, TidyFn } from './types';\n\n/** [key, values] where values could be more nested entries */\ntype EntriesOutput = [any, any][];\ntype EntriesObjectOutput = { key: Key; values: any }[];\n\n/** nested objects: { [key]: values } */\ntype ObjectOutput = Record<Key, any>;\n\n/** nested keys: e.g. [key, key, key, [key, key, [key]]] */\ntype KeysOutput = any[];\n\n/** nested values: e.g. [[value1_1, value1_2], [value2_1, value2_2]] */\ntype ValuesOutput = any[];\n\nexport type LevelSpec = {\n id?: string;\n createEmptySubgroup: () => any;\n addSubgroup: (\n parentGrouped: any,\n newSubgroup: any,\n key: any,\n level: number\n ) => void;\n addLeaf: (parentGrouped: any, key: any, values: any[], level: number) => void;\n};\n\n/**\n * Options to affect export type\n */\ninterface GroupByOptions {\n /** whether to merge group keys back into the objects */\n readonly addGroupKeys?: boolean;\n\n // -- export related -- //\n /** export method */\n readonly export?:\n | 'grouped'\n | 'entries'\n | 'entries-object'\n | 'object'\n | 'map'\n | 'keys'\n | 'values'\n | 'levels'\n | 'ungrouped';\n /** if all nested levels should be brought to a single top level */\n readonly flat?: boolean;\n /** when flat is true, how to flatten nested keys */\n readonly compositeKey?: (keys: any[]) => string;\n /** whether the leaf sets consist of just one item (typical after summarize).\n * if true, uses the first element in the leaf set instead of an array\n */\n readonly single?: boolean;\n /** operation called on each leaf during export to map it to a different value\n * (default: identity)\n */\n readonly mapLeaf?: (value: any) => any;\n /** operation called on each leaf set to map the array of values to a different value.\n * Similar to `rollup` from d3-collection nest or d3-array\n * (default: identity)\n */\n readonly mapLeaves?: (values: any[]) => any;\n /** [entries only] operation called on entries to map from [key, values] to\n * whatever the output of this is (e.g. `{ key, values }`)\n * (default: identity)\n */\n readonly mapEntry?: (entry: [any, any], level: number) => any;\n\n /** [required for levels] specifies the export operation for each level of the grouping */\n readonly levels?: (\n | 'entries'\n | 'entries-object'\n | 'object'\n | 'map'\n | 'keys'\n | 'values'\n | LevelSpec\n )[];\n}\n\n// aliases to make overloads shorter\ntype GK<T extends object> = SingleOrArray<keyof T | ((d: T) => any)>;\ntype F<I extends object, O extends object> = TidyFn<I, O>;\n\n// merge back in group keys to output types\ntype MergeGroupKeys<\n T extends object,\n Out extends object,\n Keys extends GK<T>\n> = Keys extends keyof T\n ? O.Merge<Pick<T, Keys>, Out>\n : Keys extends (keyof T)[]\n ? O.Merge<Pick<T, Keys[number]>, Out>\n : Out;\n\n// do not merge in group keys if explicitly said not to\ntype WithGroupKeys<\n T extends object,\n Out extends object,\n Keys extends GK<T>,\n Opts extends GroupByOptions | undefined\n> = NonNullable<Opts>['addGroupKeys'] extends false\n ? Out\n : MergeGroupKeys<T, Out, Keys>;\n\n/**\n * output varies based on export options\n */\ntype GroupByOutput<\n T extends object,\n O extends object,\n Keys extends GK<T>,\n Opts extends GroupByOptions | undefined\n> = A.Compute<\n NonNullable<Opts>['export'] extends 'grouped'\n ? Grouped<WithGroupKeys<T, O, Keys, Opts>>\n : NonNullable<Opts>['export'] extends 'entries'\n ? EntriesOutput\n : NonNullable<Opts>['export'] extends 'entries-object'\n ? EntriesObjectOutput\n : NonNullable<Opts>['export'] extends 'object'\n ? ObjectOutput\n : NonNullable<Opts>['export'] extends 'map'\n ? Map<any, any>\n : NonNullable<Opts>['export'] extends 'keys'\n ? KeysOutput\n : NonNullable<Opts>['export'] extends 'values'\n ? ValuesOutput\n : NonNullable<Opts>['export'] extends 'levels'\n ? any\n : WithGroupKeys<T, O, Keys, Opts>[]\n>;\n\ntype GroupByFn<\n T extends object,\n O extends object,\n Keys extends GK<T>,\n Opts extends GroupByOptions\n> = Opts['export'] extends\n | 'grouped'\n | 'entries'\n | 'entries-object'\n | 'object'\n | 'map'\n | 'keys'\n | 'values'\n | 'levels'\n ? TidyGroupExportFn<T, GroupByOutput<T, O, Keys, Opts>>\n : // default is no export, ungrouped and back in simple form\n TidyFn<T, WithGroupKeys<T, O, Keys, Opts>>;\n\n/**\n * Nests the data by the specified groupings\n */\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: F<T, T1>, options?: Opts): GroupByFn<T, T1, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>, F<T5, T6>, F<T6, T7>], options?: Opts): GroupByFn<T, T7, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>, F<T5, T6>], options?: Opts): GroupByFn<T, T6, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>], options?: Opts): GroupByFn<T, T5, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>], options?: Opts): GroupByFn<T, T4, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>], options?: Opts): GroupByFn<T, T3, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>], options?: Opts): GroupByFn<T, T2, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>], options?: Opts): GroupByFn<T, T1, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [], options?: Opts): GroupByFn<T, T, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, options?: Opts): GroupByFn<T, T, Keys, Opts>;\nexport function groupBy<\n T extends object,\n O extends object,\n Keys extends GK<T>,\n Opts extends GroupByOptions\n>(\n groupKeys: Keys,\n fns: TidyFn<any, any>[] | TidyFn<any, any>,\n options?: Opts\n): GroupByFn<T, O, Keys, Opts> {\n if (typeof fns === 'function') {\n fns = [fns];\n } else if (arguments.length === 2 && fns != null && !Array.isArray(fns)) {\n options = fns as any;\n }\n\n const _groupBy: GroupByFn<T, O, Keys, Opts> = ((items: T[]) => {\n // form into a nested map\n const grouped = makeGrouped(items, groupKeys);\n\n // run group functions\n const results = runFlow(\n grouped,\n fns as TidyFn<any, any>[],\n options?.addGroupKeys\n );\n\n // export\n if (options?.export) {\n switch (options.export) {\n case 'grouped':\n return results;\n case 'levels':\n return exportLevels(results, options);\n case 'entries-obj' as any:\n case 'entriesObject' as any:\n return exportLevels(results, {\n ...options,\n export: 'levels',\n levels: ['entries-object'],\n });\n default:\n return exportLevels(results, {\n ...options,\n export: 'levels',\n levels: [options.export],\n });\n }\n }\n\n // export === 'ungrouped' or nully:\n const ungrouped = ungroup(results, options?.addGroupKeys);\n return ungrouped as any;\n }) as GroupByFn<T, O, Keys, Opts>;\n // (_groupBy as any).tidyType = 'group-export';\n\n return _groupBy;\n}\n// convenient export option configs\ngroupBy.grouped = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'grouped' } as const);\ngroupBy.entries = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'entries' } as const);\ngroupBy.entriesObject = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'entries-object' } as const);\ngroupBy.object = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'object' } as const);\ngroupBy.map = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'map' } as const);\ngroupBy.keys = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'keys' } as const);\ngroupBy.values = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'values' } as const);\ngroupBy.levels = (options?: Omit<GroupByOptions, 'export'>) =>\n ({ ...options, export: 'levels' } as const);\n\nfunction runFlow<T extends object>(\n items: Grouped<T>,\n fns?: TidyFn<any, any>[],\n addGroupKeys?: boolean\n) {\n let result: any = items;\n if (!fns?.length) return result;\n\n for (const fn of fns) {\n if (!fn) continue;\n\n // otherwise break it up and call it on each leaf set\n result = groupMap(result, (items, keys) => {\n // ensure we kept the group keys in the object\n // (necessary for e.g. summarize which may remove them)\n const context = { groupKeys: keys };\n let leafItemsMapped = fn(items, context);\n if (addGroupKeys !== false) {\n leafItemsMapped = leafItemsMapped.map((item: T) =>\n assignGroupKeys(item, keys)\n );\n }\n\n return leafItemsMapped;\n });\n }\n\n return result;\n}\n\nfunction makeGrouped<T extends object>(\n items: T[],\n groupKeys: SingleOrArray<keyof T | ((d: T) => any)>\n): Grouped<T> {\n // convert string based keys to functions and keep the key name with the key value in a tuple\n const groupKeyFns = singleOrArray(groupKeys).map((key, i) => {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n // use a cache so we don't generate new keys for the same tuple\n const keyCache = new Map();\n return (d: T) => {\n const keyValue = keyFn(d);\n\n const keyValueOf =\n typeof keyValue === 'object' ? keyValue.valueOf() : keyValue;\n // used cache tuple if available\n if (keyCache.has(keyValueOf)) {\n return keyCache.get(keyValueOf) as GroupKey;\n }\n\n const keyWithName = [key, keyValue];\n keyCache.set(keyValueOf, keyWithName);\n\n return keyWithName;\n };\n });\n\n const grouped = group(items, ...groupKeyFns);\n return grouped;\n}\n\n/**\n * flattens a grouped collection back to a simple array\n */\nfunction ungroup<T extends object>(\n grouped: Grouped<T>,\n addGroupKeys: boolean | undefined\n): T[] {\n // flatten the groups\n const items: T[] = [];\n\n groupTraversal(grouped, items, [], identity, (root, keys, values) => {\n // ensure we have group keys on items (in case runFlow didn't run)\n let valuesToAdd = values;\n if (addGroupKeys !== false) {\n valuesToAdd = values.map((d) => assignGroupKeys(d, keys));\n }\n root.push(...valuesToAdd);\n });\n\n return items;\n}\n\n// -----------------------------------------------------------------------\n// --- EXPORTS -----------------------------------------------------------\n// -----------------------------------------------------------------------\nconst defaultCompositeKey = (keys: any[]) => keys.join('/');\n\nfunction processFromGroupsOptions<T extends object>(options: GroupByOptions) {\n const {\n flat,\n single,\n mapLeaf = identity,\n mapLeaves = identity,\n addGroupKeys,\n } = options;\n let compositeKey: (keys: any[]) => string;\n if (options.flat) {\n compositeKey = options.compositeKey! ?? defaultCompositeKey;\n }\n\n const groupFn = (values: T[], keys: any[]) => {\n return single\n ? mapLeaf(\n addGroupKeys === false ? values[0] : assignGroupKeys(values[0], keys)\n )\n : mapLeaves(\n values.map((d) =>\n mapLeaf(addGroupKeys === false ? d : assignGroupKeys(d, keys))\n )\n );\n };\n\n const keyFn = flat\n ? (keys: GroupKey[]) => compositeKey(keys.map((d) => d[1]))\n : (keys: GroupKey[]) => keys[keys.length - 1][1];\n\n return { groupFn, keyFn };\n}\n\n// -- Levels -------------------------------------------------------------\nfunction exportLevels<T extends object>(\n grouped: Grouped<T>,\n options: GroupByOptions\n): any {\n type NestedEntries<T> = Array<[any, NestedEntries<T> | T[]]>;\n type NestedObject<T> = { [key: string]: NestedObject<T> | T[] };\n\n const { groupFn, keyFn } = processFromGroupsOptions(options);\n let { mapEntry = identity } = options;\n const { levels = ['entries'] } = options;\n\n const levelSpecs: LevelSpec[] = [];\n for (const levelOption of levels) {\n switch (levelOption) {\n // entries / entries-object -----------------------------------------\n case 'entries':\n case 'entries-object':\n case 'entries-obj' as any:\n case 'entriesObject' as any: {\n const levelMapEntry =\n (levelOption === 'entries-object' ||\n levelOption === ('entries-obj' as any) ||\n levelOption === ('entriesObject' as any)) &&\n options.mapEntry == null\n ? ([key, values]: any) => ({ key, values })\n : mapEntry;\n\n levelSpecs.push({\n id: 'entries',\n createEmptySubgroup: () => [],\n addSubgroup: (\n parentGrouped: NestedEntries<T>,\n newSubgroup: any,\n key: any,\n level: number\n ) => {\n parentGrouped.push(levelMapEntry([key, newSubgroup], level));\n },\n\n addLeaf: (\n parentGrouped: NestedEntries<T>,\n key: any,\n values: T[],\n level: number\n ) => {\n parentGrouped.push(levelMapEntry([key, values], level));\n },\n });\n break;\n }\n // map -------------------------------------------------------------\n case 'map':\n levelSpecs.push({\n id: 'map',\n createEmptySubgroup: () => new Map(),\n addSubgroup: (\n parentGrouped: Map<any, any>,\n newSubgroup: any,\n key: any\n ) => {\n parentGrouped.set(key, newSubgroup);\n },\n\n addLeaf: (parentGrouped: Map<any, any>, key: any, values: T[]) => {\n parentGrouped.set(key, values);\n },\n });\n break;\n\n // object ----------------------------------------------------------\n case 'object':\n levelSpecs.push({\n id: 'object',\n createEmptySubgroup: () => ({}),\n addSubgroup: (\n parentGrouped: NestedObject<T>,\n newSubgroup: any,\n key: any\n ) => {\n parentGrouped[key] = newSubgroup;\n },\n\n addLeaf: (parentGrouped: NestedObject<T>, key: any, values: T[]) => {\n parentGrouped[key] = values;\n },\n });\n break;\n\n // keys ------------------------------------------------------------\n case 'keys':\n levelSpecs.push({\n id: 'keys',\n createEmptySubgroup: () => [],\n addSubgroup: (parentGrouped: any, newSubgroup: any, key: any) => {\n parentGrouped.push([key, newSubgroup]);\n },\n\n addLeaf: (parentGrouped: any, key: any) => {\n parentGrouped.push(key);\n },\n });\n break;\n\n // values ----------------------------------------------------------\n case 'values':\n levelSpecs.push({\n id: 'values',\n createEmptySubgroup: () => [],\n addSubgroup: (parentGrouped: any, newSubgroup: any) => {\n parentGrouped.push(newSubgroup);\n },\n\n addLeaf: (parentGrouped: any, key: any, values: T[]) => {\n parentGrouped.push(values);\n },\n });\n break;\n\n // custom ----------------------------------------------------------\n default: {\n // LevelSpec obj already\n if (typeof levelOption === 'object') {\n levelSpecs.push(levelOption);\n }\n }\n }\n }\n\n // add subgroup\n const addSubgroup = (parentGrouped: any, keys: any[], level: number): any => {\n if (options.flat) {\n return parentGrouped;\n }\n\n const levelSpec = levelSpecs[level] ?? levelSpecs[levelSpecs.length - 1];\n const nextLevelSpec = levelSpecs[level + 1] ?? levelSpec;\n const newSubgroup = nextLevelSpec.createEmptySubgroup();\n levelSpec!.addSubgroup(parentGrouped, newSubgroup, keyFn(keys), level);\n return newSubgroup;\n };\n\n // add leaves\n const addLeaf = (\n parentGrouped: any,\n keys: any[],\n values: T[],\n level: number\n ) => {\n const levelSpec = levelSpecs[level] ?? levelSpecs[levelSpecs.length - 1];\n levelSpec!.addLeaf(\n parentGrouped,\n keyFn(keys),\n groupFn(values, keys),\n level\n );\n };\n\n const initialOutputObject = levelSpecs[0]!.createEmptySubgroup();\n return groupTraversal(grouped, initialOutputObject, [], addSubgroup, addLeaf);\n}\n","/**\n * Returns a function that computes the count over an array of items\n */\nexport function n() {\n return (items: any[]) => items.length;\n}\n","import { fsum } from 'd3-array';\n\n/**\n * Returns a function that computes the sum over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function sum<T extends object>(key: keyof T | ((d: T) => number)) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => fsum(items, keyFn);\n}\n","import { summarize } from './summarize';\nimport { n } from './summary/n';\nimport { sum } from './summary/sum';\nimport { TidyFn } from './types';\n\ntype TallyOptions = {\n readonly name?: string;\n readonly wt?: string;\n};\n\ntype TallyOutput<Options extends TallyOptions> = Options['name'] extends string\n ? { [K in Options['name']]: number }\n : { n: number };\n\nexport function tally<T extends object, Options extends TallyOptions>(\n options?: Options\n): TidyFn<T, TallyOutput<Options>> {\n const _tally: TidyFn<T, TallyOutput<Options>> = (\n items: T[]\n ): TallyOutput<Options>[] => {\n const { name = 'n', wt } = options ?? {};\n\n const summarized = summarize({ [name]: wt == null ? n() : sum(wt as any) })(\n items\n );\n return summarized as TallyOutput<Options>[];\n };\n\n return _tally;\n}\n","import { arrange, desc } from './arrange';\nimport { groupBy } from './groupBy';\nimport { identity } from './helpers/identity';\nimport { SingleOrArray } from './helpers/singleOrArray';\nimport { tally } from './tally';\nimport { tidy } from './tidy';\nimport { KeyOrFn } from './types';\n\ntype CountOptions = {\n name?: string;\n sort?: boolean;\n wt?: string;\n};\n\n/**\n * Tallies the number distinct values for the specified keys and adds\n * the count as a new key (default `n`). Optionally sorts by the count.\n */\nexport function count<T extends object, Keys extends SingleOrArray<KeyOrFn<T>>>(\n groupKeys: Keys,\n options?: CountOptions | null | undefined\n) {\n const _count = (items: T[]) => {\n options = options ?? {};\n const { name = 'n', sort } = options;\n\n const results = tidy(\n items,\n groupBy(groupKeys, [tally(options)]),\n sort ? arrange(desc(name)) : identity\n );\n\n return results;\n };\n\n return _count;\n}\n","import { O } from 'ts-toolbelt';\nimport { TidyFn } from './types';\n\ntype RenameSpec<T> = Partial<\n {\n [K in keyof T]: string;\n }\n>;\n\n// helper types\ntype OutputT<T extends object, Spec extends RenameSpec<T>> = O.Merge<\n Omit<T, keyof Spec>,\n {\n [NewKey in Exclude<Spec[keyof Spec], undefined>]: T[O.SelectKeys<\n Spec,\n NewKey\n >];\n }\n>;\n\n/**\n * Renames properties/columns in collection\n *\n * @param renameSpec Mapping of current name to new name { currKey: newKey }\n */\nexport function rename<T extends object, Spec extends RenameSpec<T>>(\n renameSpec: Spec\n): TidyFn<T, OutputT<T, Spec>> {\n type Output = OutputT<T, Spec>;\n const _rename: TidyFn<T, Output> = (items: T[]): Output[] => {\n return items.map((d) => {\n const mapped = {} as any;\n const keys = Object.keys(d) as (keyof T)[];\n for (const key of keys) {\n const newKey: keyof Output =\n ((renameSpec[key] as unknown) as keyof Output) ?? key;\n mapped[newKey] = d[key];\n }\n\n return mapped as Output;\n });\n };\n\n return _rename;\n}\n","import { shuffle } from 'd3-array';\nimport { arrange, desc } from './arrange';\nimport { SingleOrArray } from './helpers/singleOrArray';\nimport { Comparator, Key, TidyFn } from './types';\n\n/**\n * Truncates the array to the specified range\n */\nexport function slice<T extends object>(\n start: number,\n end?: number\n): TidyFn<T> {\n const _slice: TidyFn<T> = (items: T[]): T[] => items.slice(start, end);\n\n return _slice;\n}\n\n// -------------------------------------------------------------------\n/**\n * Truncates the array to the first N items\n */\nexport const sliceHead = <T extends object>(n: number) => slice<T>(0, n);\n\n// -------------------------------------------------------------------\n/**\n * Truncates the array to the last N items\n */\nexport const sliceTail = <T extends object>(n: number) => slice<T>(-n);\n\n// -------------------------------------------------------------------\n\n/**\n * Truncates the array to the first N items ordered by some key\n */\nexport function sliceMin<T extends object>(\n n: number,\n orderBy: SingleOrArray<Key | Comparator<T>>\n): TidyFn<T> {\n const _sliceMin: TidyFn<T> = (items: T[]): T[] =>\n arrange<T>(orderBy)(items).slice(0, n);\n\n return _sliceMin;\n}\n\n// -------------------------------------------------------------------\n\n/**\n * Truncates the array to the last N items ordered by some key\n */\nexport function sliceMax<T extends object>(\n n: number,\n orderBy: SingleOrArray<Key | Comparator<T>>\n): TidyFn<T> {\n // note: we use desc() so we get proper handling of nullish values\n // unless they provided an explicit comparator.\n const _sliceMax: TidyFn<T> = (items: T[]): T[] =>\n typeof orderBy === 'function'\n ? arrange<T>(orderBy)(items).slice(-n).reverse()\n : arrange<T>(desc(orderBy as any))(items).slice(0, n);\n\n return _sliceMax;\n}\n\n// -------------------------------------------------------------------\n\ntype SampleOptions = {\n replace?: boolean;\n};\n/**\n * Truncates the array to the last N items ordered by some key\n */\nexport function sliceSample<T extends object>(\n n: number,\n options?: SampleOptions | null | undefined\n): TidyFn<T> {\n options = options ?? {};\n const { replace } = options;\n\n const _sliceSample: TidyFn<T> = (items: T[]) => {\n if (!items.length) return items.slice();\n\n // sample items with replacement\n if (replace) {\n const sliced = [];\n for (let i = 0; i < n; ++i) {\n sliced.push(items[Math.floor(Math.random() * items.length)]);\n }\n return sliced;\n }\n\n // sample items without replacement\n return shuffle(items.slice()).slice(0, n);\n };\n\n return _sliceSample;\n}\n","import { O } from 'ts-toolbelt';\nimport { TidyFn, Datum } from './types';\n\ntype ByMap<JoinT extends Datum, T extends Datum> = Partial<\n Record<keyof JoinT, keyof T>\n>;\n\nexport type JoinOptions<JoinT extends Datum, T extends Datum> = {\n by?: keyof T | (keyof T)[] | ByMap<JoinT, T>;\n};\n\n/**\n * Compares first two sets of items to find overlapping keys\n * Naively looks at first element... could cause problems if first\n * elements don't have all keys, but scanning each entire set seems\n * unnecessarily slow for most cases.\n */\nexport function autodetectByMap<A, B>(itemsA: A[], itemsB: B[]) {\n if (itemsA.length === 0 || itemsB.length === 0) return {};\n\n // intersection of shared keys\n const keysA = Object.keys(itemsA[0]);\n const keysB = Object.keys(itemsB[0]);\n\n // naive linear intersection, but we don't expect objects to have tons of keys\n // so it's probably fine.\n const byMap: any = {};\n for (const key of keysA) {\n if (keysB.includes(key)) {\n byMap[key] = key;\n }\n }\n\n return byMap;\n}\n\n// convert by option in to a map from JoinT to T key\nexport function makeByMap<T extends Datum, JoinT extends Datum>(\n by: JoinOptions<JoinT, T>['by']\n): ByMap<JoinT, T> {\n // convert by option in to a map from JoinT to T key\n if (Array.isArray(by)) {\n const byMap: ByMap<JoinT, T> = {};\n for (const key of by) {\n byMap[key as any] = key;\n }\n return byMap;\n } else if (typeof by === 'object') {\n return by;\n }\n return { [by as keyof JoinT]: by as keyof T } as ByMap<JoinT, T>;\n}\n\nexport function isMatch<T extends object, JoinT extends object>(\n d: T,\n j: JoinT,\n byMap: ByMap<JoinT, T>\n) {\n for (const jKey in byMap) {\n const dKey = byMap[jKey];\n if ((d[dKey as keyof T] as any) !== j[jKey as keyof JoinT]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Performs an inner join on two collections\n * @param itemsToJoin The rows/items to be appended to end of collection\n */\nexport function innerJoin<T extends object, JoinT extends object>(\n itemsToJoin: JoinT[],\n options?: JoinOptions<JoinT, T> | null | undefined\n): TidyFn<T, O.Merge<T, JoinT>> {\n const _innerJoin: TidyFn<T, O.Merge<T, JoinT>> = (\n items: T[]\n ): O.Merge<T, JoinT>[] => {\n // convert by option in to a map from JoinT to T key\n const byMap =\n options?.by == null\n ? autodetectByMap(items, itemsToJoin)\n : makeByMap(options.by);\n\n const joined = items.flatMap((d: T) => {\n const matches = itemsToJoin.filter((j: JoinT) => isMatch(d, j, byMap));\n return matches.map((j: JoinT) => ({ ...d, ...j }));\n });\n\n return joined as O.Merge<T, JoinT>[];\n };\n return _innerJoin;\n}\n","import { Datum, TidyFn } from './types';\nimport { isMatch, makeByMap, autodetectByMap, JoinOptions } from './innerJoin';\nimport { O } from 'ts-toolbelt';\n\n/**\n * Performs a left join on two collections\n * @param itemsToJoin The rows/items to be appended to end of collection\n */\nexport function leftJoin<T extends Datum, JoinT extends Datum>(\n itemsToJoin: JoinT[],\n options?: JoinOptions<JoinT, T> | null | undefined\n): TidyFn<T, O.Merge<T, Partial<JoinT>>> {\n const _leftJoin: TidyFn<T, O.Merge<T, Partial<JoinT>>> = (\n items: T[]\n ): O.Merge<T, Partial<JoinT>>[] => {\n if (!itemsToJoin.length) return items as any;\n\n // convert by option in to a map from T key to JoinT key\n const byMap =\n options?.by == null\n ? autodetectByMap(items, itemsToJoin)\n : makeByMap(options.by);\n\n // when we miss a join, we want to explicitly add in undefined\n // so our rows all have the same keys. get those keys here.\n const joinObjectKeys = Object.keys(itemsToJoin[0]);\n\n const joined = items.flatMap((d: T) => {\n const matches = itemsToJoin.filter((j: JoinT) => isMatch(d, j, byMap));\n if (matches.length) {\n return matches.map((j: JoinT) => ({ ...d, ...j }));\n }\n\n // add in missing keys explicitly as undefined without\n // overriding existing values and while maintaining order\n // of keys\n const undefinedFill = Object.fromEntries(\n joinObjectKeys\n .filter((key) => d[key] == null)\n .map((key) => [key, undefined])\n );\n\n return { ...d, ...undefinedFill };\n });\n\n return joined;\n };\n return _leftJoin;\n}\n","import { Datum, TidyFn } from './types';\nimport { isMatch, makeByMap, autodetectByMap, JoinOptions } from './innerJoin';\nimport { O } from 'ts-toolbelt';\n\n/**\n * Performs a full join on two collections\n * @param itemsToJoin The rows/items to be appended to end of collection\n */\nexport function fullJoin<T extends Datum, JoinT extends Datum>(\n itemsToJoin: JoinT[],\n options?: JoinOptions<JoinT, T> | null | undefined\n): TidyFn<T, O.Merge<T, Partial<JoinT>>> {\n const _fullJoin: TidyFn<T, O.Merge<T, Partial<JoinT>>> = (\n items: T[]\n ): O.Merge<T, Partial<JoinT>>[] => {\n if (!itemsToJoin.length) return items as any;\n if (!items.length) return itemsToJoin as any;\n\n // convert by option in to a map from T key to JoinT key\n const byMap =\n options?.by == null\n ? autodetectByMap(items, itemsToJoin)\n : makeByMap(options.by);\n\n // keep track of what has been matched\n const matchMap = new Map();\n\n // when we miss a join, we want to explicitly add in undefined\n // so our rows all have the same keys. get those keys here.\n const joinObjectKeys = Object.keys(itemsToJoin[0]);\n\n const joined = items.flatMap((d: T) => {\n const matches = itemsToJoin.filter((j: JoinT) => {\n const matched = isMatch(d, j, byMap);\n if (matched) {\n matchMap.set(j, true);\n }\n return matched;\n });\n\n if (matches.length) {\n return matches.map((j: JoinT) => ({ ...d, ...j }));\n }\n\n // add in missing keys explicitly as undefined without\n // overriding existing values and while maintaining order\n // of keys\n const undefinedFill = Object.fromEntries(\n joinObjectKeys\n .filter((key) => d[key] == null)\n .map((key) => [key, undefined])\n );\n\n return { ...d, ...undefinedFill };\n });\n\n // add in the ones we missed\n if (matchMap.size < itemsToJoin.length) {\n const leftEmptyObject = Object.fromEntries(\n Object.keys(items[0]).map((key) => [key, undefined])\n );\n for (const item of itemsToJoin) {\n if (!matchMap.has(item)) {\n joined.push({ ...leftEmptyObject, ...item });\n }\n }\n }\n\n return joined;\n };\n return _fullJoin;\n}\n","import { TidyFn, NonFunctionValue, Key } from './types';\nimport { A } from 'ts-toolbelt';\n\ntype MutateSpecValue<T, O = any> = ((items: T[]) => O[] | O) | NonFunctionValue;\nexport type MutateSummarySpec<T> = Record<Key, MutateSpecValue<T>>;\nexport type ResolvedObj<Obj extends Record<Key, MutateSpecValue<any>>> = {\n [K in keyof Obj]: Obj[K] extends (...args: any) => any\n ? ReturnType<Obj[K]> extends any[]\n ? ReturnType<Obj[K]>[number]\n : ReturnType<Obj[K]> extends Float64Array\n ? number\n : ReturnType<Obj[K]>\n : Obj[K];\n};\n\ntype Mutated<T, MSpec extends MutateSummarySpec<T>> = T & ResolvedObj<MSpec>;\n\ntype Compute<T> = A.Compute<T>;\n\n/**\n * Mutates items, looking at multiple items at a time to enable summarization.\n * For simpler, item by item mutations, use mutate.\n * @param mutateSpec\n */\nexport function mutateWithSummary<\n T extends object,\n MSpec extends MutateSummarySpec<T>\n>(mutateSpec: MSpec): TidyFn<T, Compute<Mutated<T, MSpec>>> {\n type MutatedT = Mutated<T, MSpec>;\n // use Compute for better intellisense (reveals all keys in obj)\n const _mutate: TidyFn<T, Compute<MutatedT>> = (\n items: T[]\n ): Compute<MutatedT>[] => {\n // create the base items to merge mutated values into\n const mutatedItems: MutatedT[] = items.map((d) => ({ ...d })) as MutatedT[];\n\n // create vectors for each mutated value\n for (const key in mutateSpec) {\n // convert individual values to a vector of the same value\n // this allows mutate functions to return single numbers and still work\n const mutateSpecValue = mutateSpec[key];\n const mutatedResult =\n typeof mutateSpecValue === 'function'\n ? mutateSpecValue(mutatedItems)\n : mutateSpecValue;\n const mutatedVector =\n mutatedResult?.[Symbol.iterator] && typeof mutatedResult !== 'string'\n ? mutatedResult\n : items.map(() => mutatedResult);\n\n // merge the mutated vector into the mutated items\n let i = -1;\n for (const mutatedItem of mutatedItems) {\n mutatedItem[key as keyof MutatedT] = mutatedVector[++i];\n }\n }\n\n return mutatedItems as Compute<MutatedT>[];\n };\n\n return _mutate;\n}\n","/**\n * Helper to get keys from a collection of items.\n * For now, it naively just looks at the first item, but a more complete\n * solution involves looking at all of them (in case keys are omitted).\n * This isn't very efficient though, so perhaps there's a future where\n * the keys are stored sneakily on the object somewhere and that set\n * is updated after each tidy fn is called (if we can do it efficiently)\n *\n * Or perhaps this function can be memoized in a smart way where we don't\n * call it more than necessary?\n */\nexport function keysFromItems<T extends object>(items: T[]): (keyof T)[] {\n if (items.length < 1) return [];\n const keys = Object.keys(items[0]) as (keyof T)[];\n return keys;\n}\n","import { keysFromItems } from '../helpers/keysFromItems';\n\n/**\n * Returns all keys\n */\nexport function everything<T extends object>() {\n return (items: T[]) => {\n const keys = keysFromItems(items);\n return keys;\n };\n}\n","import { Datum, TidyFn, Key } from './types';\nimport { singleOrArray } from './helpers/singleOrArray';\nimport { everything } from './selectors/everything';\nimport { O, U } from 'ts-toolbelt';\n\ntype DropKey<T extends Datum> = keyof T extends string | number\n ? `-${keyof T}`\n : never;\n// type KeysInput1<T> = readonly (keyof T)[] | keyof T;\nexport type KeysInput<T> =\n | (Key | ((items: T[]) => Key[]))[]\n | readonly DropKey<T>[]\n | readonly (keyof T)[]\n | DropKey<T>\n | keyof T;\n\ntype Output<\n T extends object,\n KS extends KeysInput<T>\n // is it an array of drop keys?\n> = KS extends readonly DropKey<T>[]\n ? O.Pick<\n T,\n {\n [TK in keyof T]: `-${U.Intersect<TK, string>}` extends KS[number]\n ? never\n : TK;\n }[keyof T]\n >\n : // is an array of keys?\n KS extends readonly Key[]\n ? O.Pick<T, KS[number]>\n : // is a single drop key?\n KS extends DropKey<T>\n ? O.Pick<\n T,\n {\n [TK in keyof T]: `-${U.Intersect<TK, string>}` extends KS ? never : TK;\n }[keyof T]\n >\n : // is a single key?\n KS extends Key\n ? O.Pick<T, U.Intersect<KS, keyof T>>\n : // any other case, just be dumb and say T was returned\n T;\n\nexport function processSelectors<T extends object, Keys extends KeysInput<T>>(\n items: T[],\n selectKeys: Keys\n): string[] {\n let processedSelectKeys: string[] = [];\n // expand them all to a flat list of keys\n for (const keyInput of singleOrArray(selectKeys as any)) {\n if (typeof keyInput === 'function') {\n processedSelectKeys.push(...(keyInput(items) as string[]));\n } else {\n processedSelectKeys.push(keyInput);\n }\n }\n\n // if the first key is negative, add in everything at the front\n if (processedSelectKeys.length && processedSelectKeys[0][0] === '-') {\n processedSelectKeys = [...everything()(items), ...processedSelectKeys];\n }\n\n const negationMap: any = {};\n const keysWithoutNegations = [];\n // go through the list backwards and remove negations\n for (let k = processedSelectKeys.length - 1; k >= 0; k--) {\n const key: any = processedSelectKeys[k];\n if (key[0] === '-') {\n negationMap[key.substring(1)] = true;\n continue;\n }\n if (negationMap[key]) {\n negationMap[key] = false;\n continue;\n }\n keysWithoutNegations.unshift(key);\n }\n\n // remove duplicates\n processedSelectKeys = Array.from(new Set(keysWithoutNegations));\n\n return processedSelectKeys;\n}\n\n/**\n * selects subparts of the objects (aka pick)\n * @param selectFn Returns true to keep the item, false to select out\n */\n// export function select<T extends object, Keys extends SingleOrArray<Key | ((items: T[]) => (keyof T)[])>>(\nexport function select<T extends object, Keys extends KeysInput<T>>(\n selectKeys: Keys\n): TidyFn<T, Output<T, Keys>> {\n type OutputT = Output<T, Keys>;\n const _select: TidyFn<T, OutputT> = (items: T[]): OutputT[] => {\n let processedSelectKeys: string[] = processSelectors(items, selectKeys);\n\n if (!processedSelectKeys.length) return items as OutputT[];\n\n // use the processed keys to create reduced objects\n return items.map((d: T) => {\n const mapped: any = {};\n for (const key of processedSelectKeys) {\n mapped[key] = d[key as keyof T];\n }\n\n return mapped;\n });\n };\n\n return _select;\n}\n","import { TidyFn } from './types';\nimport { mutate, MutateSpec, ResolvedObj } from './mutate';\nimport { select } from './select';\nimport { A } from 'ts-toolbelt';\n\n/**\n * Transmutes items\n * @param mutateSpec\n */\nexport function transmute<T extends object, MSpec extends MutateSpec<T>>(\n mutateSpec: MSpec\n): TidyFn<T, A.Compute<ResolvedObj<MSpec>>> {\n const _transmute: TidyFn<T, A.Compute<ResolvedObj<MSpec>>> = (items: T[]) => {\n const mutated = mutate<T, MSpec>(mutateSpec)(items);\n const picked = select(Object.keys(mutateSpec) as string[])(mutated);\n return picked as A.Compute<ResolvedObj<MSpec>>[];\n };\n\n return _transmute;\n}\n","import { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\nimport { TidyFn } from './types';\n\n/**\n * adds items to the end of the collection\n * @param itemsToAdd The rows/items to be appended to end of collection\n */\nexport function addRows<T extends object>(\n itemsToAdd: SingleOrArray<T> | ((items: T[]) => SingleOrArray<T>)\n): TidyFn<T> {\n const _addRows: TidyFn<T> = (items: T[]): T[] => {\n // TODO: allow options for specifying where it is inserted?\n if (typeof itemsToAdd === 'function') {\n return [...items, ...singleOrArray((itemsToAdd as Function)(items))];\n }\n\n return [...items, ...singleOrArray(itemsToAdd)];\n };\n\n return _addRows;\n}\n","import { groupBy } from './groupBy';\nimport { SingleOrArray } from './helpers/singleOrArray';\nimport { tidy } from './tidy';\nimport { Key, TidyFn } from './types';\n\ntype PivotOutput = Record<Key, any>;\n\ntype PivotWiderOptions<T extends object> = {\n namesFrom: SingleOrArray<keyof T>;\n namesSep?: string;\n valuesFrom: SingleOrArray<keyof T>;\n valuesFill?: any;\n valuesFillMap?: Partial<Record<Key, any>>;\n};\n\nexport function pivotWider<T extends object>(\n options: PivotWiderOptions<T>\n): TidyFn<T, PivotOutput> {\n const _pivotWider: TidyFn<T, PivotOutput> = (items: T[]): PivotOutput[] => {\n const {\n namesFrom,\n valuesFrom,\n valuesFill,\n valuesFillMap,\n namesSep = '_',\n } = options;\n\n const namesFromKeys: (keyof T)[] = Array.isArray(namesFrom)\n ? namesFrom\n : [namesFrom];\n const valuesFromKeys: (keyof T)[] = Array.isArray(valuesFrom)\n ? valuesFrom\n : [valuesFrom];\n const wider: PivotOutput[] = [];\n\n if (!items.length) return wider;\n\n // get all the keys that are left (id columns)\n const idColumns = Object.keys(items[0]).filter(\n (key) =>\n !namesFromKeys.includes(key as keyof T) &&\n !valuesFromKeys.includes(key as keyof T)\n ) as (keyof T)[];\n\n // get all possibilities for the name properties so we can fill them\n const nameValuesMap: any = {};\n for (const item of items) {\n for (const nameKey of namesFromKeys) {\n if (nameValuesMap[nameKey] == null) {\n nameValuesMap[nameKey] = {};\n }\n nameValuesMap[nameKey][item[nameKey]] = true;\n }\n }\n\n const nameValuesLists: string[][] = [];\n for (const nameKey in nameValuesMap) {\n nameValuesLists.push(Object.keys(nameValuesMap[nameKey]));\n }\n\n // prefill values if valuesFill is set for each name values combination\n const baseWideObj: any = {};\n const combos = makeCombinations(namesSep, nameValuesLists);\n\n for (const nameKey of combos) {\n if (valuesFromKeys.length === 1) {\n baseWideObj[nameKey] =\n valuesFillMap != null\n ? valuesFillMap[valuesFromKeys[0] as any]\n : valuesFill;\n continue;\n }\n\n for (const valueKey of valuesFromKeys) {\n baseWideObj[`${valueKey}${namesSep}${nameKey}`] =\n valuesFillMap != null ? valuesFillMap[valueKey as any] : valuesFill;\n }\n }\n\n // given a collection of items, widen\n function widenItems(items: T[]) {\n if (!items.length) return [];\n\n const wide: PivotOutput = { ...baseWideObj };\n\n // add the id columns (same for each object, so just look at first)\n for (const idKey of idColumns) {\n wide[idKey as keyof PivotOutput] = items[0][idKey];\n }\n\n // go through each object and widen their values\n for (const item of items) {\n const nameKey = namesFromKeys.map((key) => item[key]).join(namesSep);\n\n if (valuesFromKeys.length === 1) {\n wide[nameKey] = item[valuesFromKeys[0]];\n continue;\n }\n\n for (const valueKey of valuesFromKeys) {\n wide[`${valueKey}${namesSep}${nameKey}`] = item[valueKey];\n }\n }\n return [wide];\n }\n\n // no id columns, don't do any grouping, just widen and return\n if (!idColumns.length) {\n return widenItems(items);\n }\n\n // group by the id columns\n // for each group, widen/flatten to a single value\n const finish = tidy(items, groupBy(idColumns, [widenItems]));\n return finish;\n };\n\n return _pivotWider;\n}\n\n/*\n Recursively compute key combinations\n*/\nfunction makeCombinations(separator = '_', arrays: string[][]): string[] {\n function combine(\n accum: string[],\n prefix: string | null,\n remainingArrays: string[][]\n ) {\n if (!remainingArrays.length && prefix != null) {\n accum.push(prefix);\n return;\n }\n\n const array = remainingArrays[0];\n const newRemainingArrays = remainingArrays.slice(1);\n for (const item of array) {\n combine(\n accum,\n prefix == null ? item : `${prefix}${separator}${item}`,\n newRemainingArrays\n );\n }\n }\n\n const result: string[] = [];\n combine(result, null, arrays);\n return result;\n}\n","import { SingleOrArray } from './helpers/singleOrArray';\nimport { TidyFn, Key } from './types';\nimport { processSelectors } from './select';\n\ntype PivotLongerOptions = {\n cols?: any; // Typescript gives me max call stack failed if I use KeysInput from `select`\n namesTo: SingleOrArray<Key>;\n namesSep?: string;\n valuesTo: SingleOrArray<Key>;\n};\n\ntype PivotOutput = Record<Key, any>;\n\nexport function pivotLonger<T extends object>(\n options: PivotLongerOptions\n): TidyFn<T, PivotOutput> {\n const _pivotLonger: TidyFn<T, PivotOutput> = (items: T[]): PivotOutput[] => {\n const { namesTo, valuesTo, namesSep = '_' } = options;\n const cols = options.cols ?? [];\n const colsKeys = processSelectors(items, cols) as (keyof T)[];\n\n const namesToKeys = Array.isArray(namesTo) ? namesTo : [namesTo];\n const valuesToKeys = Array.isArray(valuesTo) ? valuesTo : [valuesTo];\n const hasMultipleNamesTo = namesToKeys.length > 1;\n const hasMultipleValuesTo = valuesToKeys.length > 1;\n\n const longer: PivotOutput[] = [];\n\n // expand each item into multiple items\n for (const item of items) {\n // keys not included in colsKeys must be kept\n const remainingKeys = Object.keys(item).filter(\n (key) => !colsKeys.includes(key as keyof T)\n ) as (keyof T)[];\n\n // the keys not in `cols` are the same for each row\n const baseObj = {} as PivotOutput;\n for (const key of remainingKeys) {\n baseObj[key as keyof PivotOutput] = item[key];\n }\n\n // remove the `${valueKey}_` prefix when we have multiple values\n const nameValueKeysWithoutValuePrefix = hasMultipleValuesTo\n ? Array.from(\n new Set(\n colsKeys.map((key) =>\n (key as string).substring((key as string).indexOf(namesSep) + 1)\n )\n )\n )\n : colsKeys;\n\n // e.g. `nameValue` or `nameValue1_nameValue2`\n for (const nameValue of nameValueKeysWithoutValuePrefix) {\n const entryObj = { ...baseObj };\n for (const valueKey of valuesToKeys) {\n // e.g. `valueKey_nameValue1_nameValue2`\n const itemKey = hasMultipleValuesTo\n ? `${valueKey}${namesSep}${nameValue}`\n : nameValue;\n const nameValueParts = hasMultipleNamesTo\n ? (nameValue as string).split(namesSep)\n : [nameValue];\n\n let i = 0;\n for (const nameKey of namesToKeys) {\n const nameValuePart = nameValueParts[i++];\n entryObj[nameKey] = nameValuePart;\n entryObj[valueKey] = item[itemKey as keyof T];\n }\n }\n\n longer.push(entryObj);\n }\n }\n\n return longer;\n };\n\n return _pivotLonger;\n}\n","import { A, O } from 'ts-toolbelt';\nimport { SingleOrArray } from './helpers/singleOrArray';\nimport { Key, TidyFn } from './types';\n\n// helper types\nexport type KeyMap<T extends object = any> = Partial<\n {\n [key in keyof T]: keyof T | Array<T[key]> | ((items: T[]) => T[key][]);\n }\n>;\n\n/**\n * Expands a set of items to include all combinations of the specified keys.\n */\n// prettier-ignore\nexport function expand<T extends object = any, K extends keyof T = keyof T>(expandKeys: K): TidyFn<T, A.Compute<Pick<T, K>>>;\n// prettier-ignore\nexport function expand<T extends object = any, K extends (keyof T)[] = (keyof T)[]>(expandKeys: K): TidyFn<T, A.Compute<Pick<T, K[number]>>>;\n// prettier-ignore\nexport function expand<T extends object = any, K extends KeyMap<T> = KeyMap<T>>(expandKeys: K): TidyFn<T, O.Pick<T, keyof K>>\n// prettier-ignore\nexport function expand<T extends object>(expandKeys: SingleOrArray<Key> | KeyMap<T>): TidyFn<T> {\n const _expand: TidyFn<T> = (items: T[]) => {\n const keyMap = makeKeyMap(expandKeys);\n\n // for each key, get all distinct values or use the provided values\n const vectors = [];\n for (const key in keyMap) {\n const keyValue = keyMap[key];\n let values;\n if (typeof keyValue === 'function') {\n values = keyValue(items);\n } else if (Array.isArray(keyValue)) {\n values = keyValue;\n } else {\n // read distinct values from the key in the data\n values = Array.from(new Set(items.map((d) => d[key as keyof T])));\n }\n\n vectors.push(values.map((value: any) => ({ [key]: value })));\n }\n\n // make all combinations of all value sets\n return makeCombinations(vectors);\n };\n\n return _expand;\n}\n\n/*\n Recursively compute key combinations\n*/\nfunction makeCombinations(vectors: any[][]): any[] {\n function combine(accum: any[], baseObj: any, remainingVectors: any[][]) {\n if (!remainingVectors.length && baseObj != null) {\n accum.push(baseObj);\n return;\n }\n\n const vector = remainingVectors[0];\n const newRemainingArrays = remainingVectors.slice(1);\n for (const item of vector) {\n combine(accum, { ...baseObj, ...item }, newRemainingArrays);\n }\n }\n\n const result: any[] = [];\n combine(result, null, vectors);\n return result;\n}\n\n// convert by option in to a map from T key to JoinT key\nexport function makeKeyMap(keys: SingleOrArray<Key> | KeyMap): KeyMap {\n if (Array.isArray(keys)) {\n const keyMap: KeyMap = {};\n for (const key of keys) {\n keyMap[key as any] = key;\n }\n return keyMap;\n } else if (typeof keys === 'object') {\n return keys;\n }\n\n return { [keys]: keys as any } as KeyMap;\n}\n","import { extent } from 'd3-array';\nimport { Granularity } from '../types';\n\n/**\n * Create a full sequence given a vector of values\n */\nexport function vectorSeq(values: number[], period: number = 1): number[] {\n let [min, max] = extent(values) as [number, number];\n\n const sequence: number[] = [];\n let value = min;\n while (value <= max) {\n sequence.push(value);\n value += period;\n }\n\n return sequence;\n}\n\n/**\n * Create a full sequence given a vector of values\n */\nexport function vectorSeqDate(\n values: Date[],\n granularity: Granularity = 'day',\n period: number = 1\n): Date[] {\n let [min, max] = extent(values) as [Date, Date];\n\n const sequence: Date[] = [];\n let value = new Date(min);\n while (value <= max) {\n sequence.push(new Date(value));\n\n // increment date\n if (\n granularity === 'second' ||\n granularity === 's' ||\n granularity === 'seconds'\n ) {\n value.setUTCSeconds(value.getUTCSeconds() + 1 * period);\n } else if (\n granularity === 'minute' ||\n granularity === 'min' ||\n granularity === 'minutes'\n ) {\n value.setUTCMinutes(value.getUTCMinutes() + 1 * period);\n } else if (\n granularity === 'day' ||\n granularity === 'd' ||\n granularity === 'days'\n ) {\n value.setUTCDate(value.getUTCDate() + 1 * period);\n } else if (\n granularity === 'week' ||\n granularity === 'w' ||\n granularity === 'weeks'\n ) {\n value.setUTCDate(value.getUTCDate() + 7 * period);\n } else if (\n granularity === 'month' ||\n granularity === 'm' ||\n granularity === 'months'\n ) {\n value.setUTCMonth(value.getUTCMonth() + 1 * period);\n } else if (\n granularity === 'year' ||\n granularity === 'y' ||\n granularity === 'years'\n ) {\n value.setUTCFullYear(value.getUTCFullYear() + 1 * period);\n } else {\n throw new Error('Invalid granularity for date sequence: ' + granularity);\n }\n }\n\n return sequence;\n}\n\n/**\n * Create a full sequence given a set of data.\n * @param items\n * @param key\n */\nexport function fullSeq<T extends object>(\n key: keyof T | ((d: T) => number),\n period?: number | null | undefined\n): (items: T[]) => number[] {\n return function fullSeqInner(items: T[]): number[] {\n period = period ?? 1;\n\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return vectorSeq(items.map(keyFn), period);\n };\n}\n\nexport function fullSeqDate<T extends object>(\n key: keyof T | ((d: T) => Date),\n granularity?: Granularity | null | undefined,\n period?: number | null | undefined\n): (items: T[]) => Date[] {\n return function fullSeqDateInner(items: T[]): Date[] {\n granularity = granularity ?? 'day';\n period = period ?? 1;\n\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as Date;\n\n return vectorSeqDate(items.map(keyFn), granularity, period);\n };\n}\n\nexport function fullSeqDateISOString<T extends object>(\n key: keyof T | ((d: T) => string),\n granularity?: Granularity | null | undefined,\n period?: number | null | undefined\n): (items: T[]) => string[] {\n return function fullSeqDateISOStringInner(items: T[]): string[] {\n granularity = granularity ?? 'day';\n period = period ?? 1;\n\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as string;\n\n return vectorSeqDate(\n items.map((d) => new Date(keyFn(d))),\n granularity,\n period\n ).map((date) => date.toISOString());\n };\n}\n","import { O } from 'ts-toolbelt';\nimport { TidyFn } from './types';\n\ntype Spec<T extends object> = {\n [K in keyof T]: T[K];\n};\n\ntype Output<T extends object, ReplaceSpec extends Partial<Spec<T>>> = O.Merge<\n Omit<T, keyof ReplaceSpec>,\n {\n [K in keyof ReplaceSpec]: K extends keyof T\n ? Exclude<T[K], null | undefined> | ReplaceSpec[K]\n : ReplaceSpec[K];\n }\n>;\n\n/**\n * Replaces nully values with what is specified in the spec\n */\nexport function replaceNully<\n T extends object,\n ReplaceSpec extends Spec<Partial<T>> = Spec<Partial<T>>\n>(replaceSpec: ReplaceSpec): TidyFn<T, Output<T, ReplaceSpec>> {\n const _replaceNully: TidyFn<T, Output<T, ReplaceSpec>> = (\n items: T[]\n ): Output<T, ReplaceSpec>[] => {\n const replacedItems: Output<T, ReplaceSpec>[] = [];\n\n for (const d of items) {\n const obj = { ...d } as any;\n for (const key in replaceSpec) {\n if (obj[(key as unknown) as keyof T] == null) {\n obj[(key as unknown) as keyof T] = replaceSpec[key] as any;\n }\n }\n replacedItems.push(obj);\n }\n\n return replacedItems;\n };\n\n return _replaceNully;\n}\n","import { expand, KeyMap } from './expand';\nimport { leftJoin } from './leftJoin';\nimport { Key, TidyFn } from './types';\nimport { replaceNully } from './replaceNully';\nimport { SingleOrArray } from './helpers/singleOrArray';\n\n/**\n * Complete a collection with missing combinations of data\n * @param expandKeys The keys to expand to all combinations of\n * @param replaceNullySpec a map from key name to value of how to deal with undefined values\n */\nexport function complete<T extends object>(\n expandKeys: SingleOrArray<Key> | KeyMap<T>,\n replaceNullySpec?: Partial<T> | null | undefined\n): TidyFn<T> {\n const _complete: TidyFn<T> = (items: T[]): T[] => {\n const expanded = expand<T, any>(expandKeys)(items);\n const joined = leftJoin(items)(expanded) as T[]; // actually may have some undefineds...\n return replaceNullySpec\n ? (replaceNully(replaceNullySpec)(joined) as T[])\n : joined;\n };\n\n return _complete;\n}\n","import { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\nimport { Key, TidyFn } from './types';\n\n/**\n * Fills values for the specified keys to match the last seen value in the collection.\n */\nexport function fill<T extends object>(keys: SingleOrArray<Key>): TidyFn<T> {\n const _fill: TidyFn<T> = (items: T[]): T[] => {\n const keysArray = singleOrArray(keys);\n\n const replaceMap: Partial<T> = {};\n\n return items.map((d) => {\n const obj = { ...d };\n for (const key of keysArray) {\n if (obj[key as keyof T] != null) {\n replaceMap[key as keyof T] = obj[key as keyof T];\n } else if (replaceMap[key as keyof T] != null) {\n obj[key as keyof T] = replaceMap[key as keyof T] as any;\n }\n }\n return obj;\n });\n };\n\n return _fill;\n}\n","import { TidyContext, TidyFn } from './types';\n\ntype Options = {\n limit?: number | null;\n output?: 'log' | 'table';\n};\n\n/**\n * Debugs items\n */\nexport function debug<T extends object>(\n label?: string | null | undefined,\n options?: Options | null | undefined\n): TidyFn<T> {\n const _debug: TidyFn<T> = (items: T[], context?: TidyContext): T[] => {\n let prefix = '[tidy.debug';\n if (context?.groupKeys?.length) {\n const groupKeys = context.groupKeys;\n const groupKeyStrings = groupKeys\n .map((keyPair: any) => keyPair.join(': '))\n .join(', ');\n if (groupKeyStrings.length) {\n prefix += '|' + groupKeyStrings;\n }\n }\n options = options ?? {};\n const { limit = 10, output = 'table' } = options;\n\n // check for sneaky group keys as last arg\n const dashString =\n '--------------------------------------------------------------------------------';\n let numDashes = dashString.length;\n const prefixedLabel = prefix + ']' + (label == null ? '' : ' ' + label);\n numDashes = Math.max(0, numDashes - (prefixedLabel.length + 2));\n\n console.log(`${prefixedLabel} ${dashString.substring(0, numDashes)}`);\n console[output](\n limit == null || limit >= items.length ? items : items.slice(0, limit)\n );\n return items;\n };\n\n return _debug;\n}\n","/** Tidy math helpers */\n\n/** Compute a fraction while handling common edge cases */\nexport function rate(\n numerator: number | null | undefined,\n denominator: number | null | undefined,\n allowDivideByZero?: boolean\n): number | undefined {\n return numerator == null || denominator == null\n ? undefined\n : denominator === 0 && numerator === 0\n ? 0\n : !allowDivideByZero && denominator === 0\n ? undefined\n : numerator / denominator;\n}\n\nexport function subtract(\n a: number | null | undefined,\n b: number | null | undefined,\n nullyZero?: boolean\n) {\n return a == null || b == null\n ? nullyZero\n ? (a ?? 0) - (b ?? 0)\n : undefined\n : a - b;\n}\n\nexport function add(\n a: number | null | undefined,\n b: number | null | undefined,\n nullyZero?: boolean\n) {\n return a == null || b == null\n ? nullyZero\n ? (a ?? 0) + (b ?? 0)\n : undefined\n : a + b;\n}\n","import { rate as mathRate } from '../math/math';\n\ntype RateOptions<T> = {\n predicate?: (d: T) => boolean;\n allowDivideByZero?: boolean;\n};\n\n/**\n * Returns a function that computes a rate (numerator / denominator), setting the value to\n * 0 if denominator = 0 and numerator = 0.\n */\nexport function rate<T extends object>(\n numerator: keyof T | ((d: T) => number),\n denominator: keyof T | ((d: T) => number),\n options?: RateOptions<T>\n) {\n const numeratorFn =\n typeof numerator === 'function'\n ? numerator\n : (d: T) => (d[numerator] as unknown) as number;\n const denominatorFn =\n typeof denominator === 'function'\n ? denominator\n : (d: T) => (d[denominator] as unknown) as number;\n\n const { predicate, allowDivideByZero } = options ?? {};\n return predicate == null\n ? (d: T) => {\n const denom = denominatorFn(d);\n const numer = numeratorFn(d);\n return mathRate(numer, denom, allowDivideByZero);\n }\n : (d: T) => {\n if (!predicate(d)) return undefined;\n\n const denom = denominatorFn(d);\n const numer = numeratorFn(d);\n return mathRate(numer, denom, allowDivideByZero);\n };\n}\n","import { fsum, Adder } from 'd3-array';\n\n// See also https://observablehq.com/@fil/fcumsum\nexport function fcumsum<T>(\n items: T[],\n accessor: (element: T, i: number, array: Iterable<T>) => any\n): Float64Array {\n let sum = new Adder(),\n i = 0;\n\n return Float64Array.from(\n items,\n // we do not actually need to coerce the Adder to number,\n // as @Fil demonstrated here: https://github.com/pbeshai/tidy/pull/5\n // so we can just tell typescript to be quiet.\n (value: T): number =>\n (sum.add(+(accessor(value, i++, items) || 0)) as unknown) as number\n );\n}\n\nexport function mean<T>(\n items: T[],\n accessor: (element: T, i: number, array: Iterable<T>) => any\n): number | undefined {\n let n = 0;\n for (let i = 0; i < items.length; ++i) {\n const value = accessor(items[i], i, items);\n // count it if we have a valid number\n if (+value === value) {\n n += 1;\n }\n }\n\n return n ? fsum(items, accessor) / n : undefined;\n}\n","import { fcumsum } from '../helpers/summation';\n\nexport function cumsum<T extends object>(\n key: keyof T | ((d: T) => number | null | undefined)\n) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n // note returns Float64Array not a normal array\n return (items: T[]) => fcumsum(items, keyFn);\n}\n","type RollOptions = {\n partial?: boolean;\n};\n\n/**\n * Returns a function that computes the a rolling value (e.g. moving average) by\n * applying a function over a window of data\n * @param width The size of the window\n * @param rollFn The function to apply to the window (should reduce to a single value)\n * @param options Options to configure roll. e.g. whether to run on partial windows.\n */\nexport function roll<T extends object>(\n width: number,\n rollFn: (itemsInWindow: T[], endIndex: number) => any,\n options?: RollOptions | undefined | null\n) {\n const { partial = false } = options ?? {};\n\n return (items: any[]) => {\n return items.map((_, i) => {\n const endIndex = i;\n\n // partial window and we don't allow partial computation, return undefined\n if (!partial && endIndex - width + 1 < 0) {\n return undefined;\n }\n\n const startIndex = Math.max(0, endIndex - width + 1);\n const itemsInWindow = items.slice(startIndex, endIndex + 1);\n\n // reduce them to a single value\n return rollFn(itemsInWindow, endIndex);\n });\n };\n}\n","type LagOptions = {\n /** Number of positions to lag by (default: 1) */\n n?: number;\n /** The default value for non-existent rows. */\n default?: any;\n};\n\n/**\n * Returns a function that lags a vector by a specified offset (n). Useful for\n * finding previous values to compute deltas with later.\n * @param key The key or accessor to lag\n * @param options Options to configure roll. e.g. whether to run on partial windows.\n */\nexport function lag<T extends object>(\n key: keyof T | ((d: T) => any),\n options?: LagOptions | undefined | null\n) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n const { n = 1, default: defaultValue } = options ?? {};\n\n return (items: any[]) => {\n return items.map((_, i) => {\n const lagItem = items[i - n];\n return lagItem == null ? defaultValue : keyFn(lagItem);\n });\n };\n}\n","type LeadOptions = {\n /** Number of positions to lead by (default: 1) */\n n?: number;\n /** The default value for non-existent rows. */\n default?: any;\n};\n\n/**\n * Returns a functions that leads a vector by a specified offset (n). Useful for\n * finding next values for computing deltas with.\n * @param key The key or accessor to lead\n * @param options Options to configure roll. e.g. whether to run on partial windows.\n */\nexport function lead<T extends object>(\n key: keyof T | ((d: T) => any),\n options?: LeadOptions | undefined | null\n) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n const { n = 1, default: defaultValue } = options ?? {};\n\n return (items: any[]) => {\n return items.map((_, i) => {\n const leadItem = items[i + n];\n return leadItem == null ? defaultValue : keyFn(leadItem);\n });\n };\n}\n","import { min as d3min } from 'd3-array';\n\n/**\n * Returns a function that computes the min over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function min<T extends object>(key: keyof T | ((d: T) => number)) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3min(items, keyFn);\n}\n","import { max as d3max } from 'd3-array';\n\n/**\n * Returns a function that computes the max over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function max<T extends object>(key: keyof T | ((d: T) => number)) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3max(items, keyFn);\n}\n","import { mean as meanInternal } from '../helpers/summation';\n\n/**\n * Returns a function that computes the mean over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function mean<T extends object>(key: keyof T | ((d: T) => number)) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => meanInternal(items, keyFn);\n}\n","import { fsum } from 'd3-array';\nimport { rate } from '../math/math';\n\n/**\n * Returns a function that computes the mean of a rate over an array of items\n * @param numerator A string key of the object or an accessor converting the object to a number\n * @param denominator A string key of the object or an accessor converting the object to a number\n */\nexport function meanRate<T extends object>(\n numerator: keyof T | ((d: T) => number),\n denominator: keyof T | ((d: T) => number)\n) {\n const numeratorFn =\n typeof numerator === 'function'\n ? numerator\n : (d: T) => (d[numerator] as unknown) as number;\n const denominatorFn =\n typeof denominator === 'function'\n ? denominator\n : (d: T) => (d[denominator] as unknown) as number;\n\n return (items: T[]) => {\n const numerator = fsum(items, numeratorFn);\n const denominator = fsum(items, denominatorFn);\n return rate(numerator, denominator);\n };\n}\n","import { median as d3median } from 'd3-array';\n\n/**\n * Returns a function that computes the median over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function median<T extends object>(key: keyof T | ((d: T) => number)) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3median(items, keyFn);\n}\n","import { deviation as d3deviation } from 'd3-array';\n\n/**\n * Returns a function that computes the deviation over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function deviation<T extends object>(key: keyof T | ((d: T) => number)) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3deviation(items, keyFn);\n}\n","import { variance as d3variance } from 'd3-array';\n\n/**\n * Returns a function that computes the variance over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function variance<T extends object>(key: keyof T | ((d: T) => number)) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3variance(items, keyFn);\n}\n","/**\n * Returns a function that computes the distinct count for a key\n * over an array of items. By default it counts nulls but not undefined\n */\nexport function nDistinct<T extends object>(\n key: keyof T | ((d: T) => any),\n options: { includeNull?: boolean; includeUndefined?: boolean } = {}\n) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n return (items: T[]) => {\n const uniques = new Map();\n let count = 0;\n\n for (const item of items) {\n const value = keyFn(item);\n\n if (!uniques.has(value)) {\n // default includes null but not undefined\n if (\n (!options.includeUndefined && value === undefined) ||\n (options.includeNull === false && value === null)\n ) {\n continue;\n }\n\n count += 1;\n uniques.set(value, true);\n }\n }\n\n return count;\n };\n}\n","/**\n * Returns a function that returns the first value for the specified key\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function first<T extends object>(key: keyof T | ((d: T) => number)) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => (items.length ? keyFn(items[0]) : undefined);\n}\n","/**\n * Returns a function that returns the last value for the specified key\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function last<T extends object>(key: keyof T | ((d: T) => number)) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) =>\n items.length ? keyFn(items[items.length - 1]) : undefined;\n}\n","import { keysFromItems } from '../helpers/keysFromItems';\n\n/**\n * Returns all keys that start with the specified prefix\n */\nexport function startsWith<T extends object>(\n prefix: string,\n ignoreCase: boolean = true\n) {\n return (items: T[]) => {\n const regex = new RegExp(`^${prefix}`, ignoreCase ? 'i' : undefined);\n const keys = keysFromItems(items);\n return keys.filter((d) => regex.test(d as string));\n };\n}\n","import { keysFromItems } from '../helpers/keysFromItems';\n\n/**\n * Returns all keys that end with the specified suffix\n */\nexport function endsWith<T extends object>(\n suffix: string,\n ignoreCase: boolean = true\n) {\n return (items: T[]) => {\n const regex = new RegExp(`${suffix}$`, ignoreCase ? 'i' : undefined);\n const keys = keysFromItems(items);\n return keys.filter((d) => regex.test(d as string));\n };\n}\n","import { keysFromItems } from '../helpers/keysFromItems';\n\n/**\n * Returns all keys that contain the specified substring\n */\nexport function contains<T extends object>(\n substring: string,\n ignoreCase: boolean = true\n) {\n return (items: T[]) => {\n const regex = new RegExp(substring, ignoreCase ? 'i' : undefined);\n const keys = keysFromItems(items);\n return keys.filter((d) => regex.test(d as string));\n };\n}\n","import { keysFromItems } from '../helpers/keysFromItems';\n\n/**\n * Returns all keys that match the specified regex\n */\nexport function matches<T extends object>(regex: RegExp) {\n return (items: T[]) => {\n const keys = keysFromItems(items);\n return keys.filter((d) => regex.test(d as string));\n };\n}\n","import { keysFromItems } from '../helpers/keysFromItems';\n\n/**\n * Returns all keys that match the prefix + num range.\n * e.g., wk, [10, 15], width=3 -> wk010, wk011, wk012, wk013, wk014, wk015\n */\nexport function numRange<T extends object>(\n prefix: string,\n range: [number, number],\n width?: number\n) {\n return (items: T[]) => {\n const keys = keysFromItems(items);\n const matchKeys: string[] = [];\n for (let i = range[0]; i <= range[1]; ++i) {\n const num = width == null ? i : new String('00000000' + i).slice(-width);\n matchKeys.push(`${prefix}${num}`);\n }\n\n return keys.filter((d) => (matchKeys as (keyof T)[]).includes(d));\n };\n}\n","import { SingleOrArray, singleOrArray } from '../helpers/singleOrArray';\n\n/**\n * Given a set of selectors, inverts their output to be drop keys. e.g.,\n * `key` becomes `-key`.\n */\nexport function negate<T extends object>(\n selectors: SingleOrArray<keyof T | ((items: T[]) => (keyof T)[])>\n) {\n return (items: T[]) => {\n let keySet = new Set<keyof T>();\n for (const selector of singleOrArray(selectors as any)) {\n if (typeof selector === 'function') {\n const keys = selector(items) as (keyof T)[];\n for (const key of keys) {\n keySet.add(key);\n }\n } else {\n keySet.add(selector);\n }\n }\n const keys = Array.from(keySet).map((key) => `-${key}`);\n return keys as (keyof T)[];\n };\n}\n"],"names":["ascending","group","fsum","shuffle","makeCombinations","extent","mathRate","Adder","d3min","d3max","meanInternal","d3median","d3deviation","d3variance"],"mappings":";;;;;;gBAgCE,UACG;EAEH,MAAI,OAAO,UAAU;EACnB,UAAM,IAAI,MAAM;EAAA;EAGlB,MAAI,SAAc;EAClB,aAAW,MAAM;EACf,QAAI;EAEF,eAAS,GAAG;EAAA;EAAA;EAIhB,SAAO;EAAA;;kBClCP;EAEA,QAAM,UAAqB,CAAC,UAAoB,MAAM,OAAO;EAC7D,SAAO;EAAA;;gBCTP,WACA;EAEA,QAAM,QAAwB,CAAC;EAC7B,QAAI,OAAO,cAAc;EACvB,UAAI,CAAC,UAAU;EAAQ,eAAO;EAAA,eACrB,CAAC;EACV,aAAO;EAAA;EAGT,UAAM,UAAW,KAAa,OAAO,GAAG;EACxC,WAAO;EAAA;EAET,SAAO;EAAA;;eCbP;EAEA,QAAM,OAA2B,CAAC,UAAe,MAAM,IAAI;EAC3D,SAAO;EAAA;;yBCLwB;EAC/B,SAAO,KAAK,OAAO,KAAK,MAAM,QAAQ,KAAK,IAAI,CAAC;EAAA;;oBCIhD;EAEA,QAAM,YAAuB,CAAC;EAC5B,WAAO,cAAc;EAErB,QAAI,CAAC,KAAK;EAER,YAAM,MAAM,IAAI;EAChB,iBAAW,QAAQ;EACjB,YAAI,IAAI;EAAA;EAEV,aAAO,MAAM,KAAK;EAAA;EAOpB,UAAM,UAAU,IAAI;EACpB,UAAM,gBAAqB;EAC3B,UAAM,UAAU,KAAK,KAAK,SAAS;EACnC,eAAW,QAAQ;EACjB,UAAI,MAAM;EACV,UAAI,UAAU;EAGd,iBAAW,OAAO;EAChB,cAAM,aACJ,OAAO,QAAQ,aAAa,IAAI,QAAQ,KAAK;EAE/C,YAAI,QAAQ;EACV,oBAAU,IAAI,IAAI;EAClB,cAAI,CAAC;EACH,0BAAc,KAAK;EACnB,gBAAI,IAAI,YAAY;EAAA;EAEtB;EAAA;EAIF,YAAI,CAAC,IAAI,IAAI;EACX,cAAI,IAAI,YAAY,IAAI;EAAA;EAI1B,cAAM,IAAI,IAAI;EAAA;EAAA;EAIlB,WAAO;EAAA;EAGT,SAAO;EAAA;;mBCnDP;EAEA,QAAM,WAAsB,CAAC;EAE3B,UAAM,gBAAgB,cAAc,aAAa,IAAI,CAAC,SACpD,OAAO,SAAS,aAEZ,KAAK,WAAW,IACd,IAAI,QACH,OACH,IAAO;EAGb,WAAO,MAAM,QAAQ,KAAK,CAAC,GAAG;EAC5B,iBAAW,cAAc;EACvB,cAAM,SAAS,WAAW,GAAG;EAC7B,YAAI;EAAQ,iBAAO;EAAA;EAGrB,aAAO;EAAA;EAAA;EAIX,SAAO;EAAA;eAOc;EACrB,QAAM,QAAQ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAW,EAAE;EAE9D,SAAO,cAAc,GAAM;EACzB,WAAO,qBAAqB,MAAM,IAAI,MAAM,IAAI;EAAA;EAAA;gBAQ5B;EACtB,QAAM,QAAQ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAW,EAAE;EAC9D,SAAO,eAAe,GAAM;EAC1B,WAAO,qBAAqB,MAAM,IAAI,MAAM,IAAI;EAAA;EAAA;sBAWlD,KACA,OACA;EAEA,MAAI,CAAE,WAAW,WAAY,4BAAW;EACxC,QAAM,iBAAiB,aAAa,QAAQ,KAAK;EAEjD,QAAM,WAAW,IAAI;EACrB,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,EAAE;EAClC,aAAS,IAAI,MAAM,IAAI;EAAA;EAGzB,QAAM,QACJ,OAAO,QAAQ,aACX,MACA,CAAC,MAAU,EAAE;EAEnB,SAAO,qBAAqB,GAAM;EApFpC;EAqFI,UAAM,SAAiB,eAAS,IAAI,MAAM,QAAnB,YAA0B;EACjD,UAAM,SAAiB,eAAS,IAAI,MAAM,QAAnB,YAA0B;EAEjD,QAAI,UAAU,KAAK,UAAU;EAC3B,aAAO,SAAS;EAAA;EAGlB,QAAI,UAAU;EACZ,aAAO,iBAAiB;EAAA;EAG1B,QAAI,UAAU;EACZ,aAAO,iBAAiB;EAAA;EAG1B,WAAO;EAAA;EAAA;EAIX,8BAA8B,QAAa,QAAa;EAEtD,MAAI,IAAI,QAAO,SAAS;EACxB,MAAI,IAAI,QAAO,SAAS;EAGxB,MAAI,QAAQ,MAAM,QAAQ;EACxB,UAAM,QAAQ,MAAM,IAAI,IAAI,MAAM,OAAO,IAAI;EAC7C,UAAM,QAAQ,MAAM,IAAI,IAAI,MAAM,OAAO,IAAI;EAC7C,UAAM,QAAQ,QAAQ;EACtB,WAAO,QAAO,CAAC,QAAQ;EAAA;EAIzB,MAAI,QAAQ;EACV,WAAO,QAAO,KAAK;EAAA;EAErB,MAAI,QAAQ;EACV,WAAO,QAAO,IAAI;EAAA;EAIpB,SAAOA,kBAAU,GAAG;EAAA;EAGtB,iBAAiB;EACf,SAAO,SAAS,QAAQ,UAAU;EAAA;;qBCpGlC,eACA;EAIA,QAAM,aAA2C,CAC/C;EAEA,cAAU,4BAAY;EAGtB,UAAM,aAAa;EACnB,UAAM,OAAO,OAAO,KAAK;EAEzB,eAAW,OAAO;EAChB,iBAAW,OAAuB,cAAc,KAAK;EAAA;EAKvD,QAAI,QAAQ,QAAQ,MAAM;EACxB,YAAM,aAAa,OAAO,KAAK,MAAM;EACrC,iBAAW,UAAU;EACnB,YAAI,KAAK,SAAS;EAChB;EAAA;EAGF,QAAC,WAAmB,UAAU,QAAQ,KAAK,QAAQ;EAAA;EAAA;EAIvD,WAAO,CAAC;EAAA;EAGV,SAAO;EAAA;EAOT,0BAIE,OACA,WACA,aACA;EAEA,MAAI,CAAC,MAAM;EAAQ,WAAO;EAG1B,QAAM,aAAa;EAGnB,MAAI;EACJ,MAAI,QAAQ;EACV,cAAU,OAAO,KAAK,MAAM;EAAA;EAG5B,cAAU;EACV,eAAW,YAAY,cAAc;EACnC,UAAI,OAAO,aAAa;EACtB,gBAAQ,KAAK,GAAI,SAAS;EAAA;EAE1B,gBAAQ,KAAK;EAAA;EAAA;EAAA;EAKnB,aAAW,OAAO;EAChB,QAAI;EAGF,YAAM,SAAS,MAAM,IAAI,CAAC,MAAM,EAAE;EAClC,UAAI,CAAC,YAAY;EACf;EAAA;EAAA;EAGJ,eAAY,OAAwC,UAAU,KAC5D;EAAA;EAIJ,SAAO,CAAC;EAAA;wBAUR;EAEA,QAAM,gBAGF,CAAC,UACH,iBAAiB,OAAO;EAE1B,SAAO;EAAA;uBAMP,aACA;EAEA,QAAM,eAGF,CAAC,UACH,iBAAiB,OAAO,WAAW;EAErC,SAAO;EAAA;uBASP,MACA;EAEA,QAAM,eAGF,CAAC,UACH,iBAAiB,OAAO,WAAW,QAAW;EAEhD,SAAO;EAAA;;kBC/IP;EAIA,QAAM,UAAwC,CAC5C;EAGA,UAAM,eAA2B;EAIjC,eAAW,QAAQ;EACjB,YAAM,cAAc,IAAK;EAEzB,iBAAW,OAAO;EAEhB,cAAM,kBAAkB,WAAW;EACnC,cAAM,gBACJ,OAAO,oBAAoB,aACvB,gBAAgB,eAChB;EAEN,oBAAY,OAAyB;EAAA;EAGvC,mBAAa,KAAK;EAAA;EAGpB,WAAO;EAAA;EAGT,SAAO;EAAA;;iBCrCP,eAA+B;EAC/B,QAAM,SAAuB,CAAC;EAC5B,UAAM,aAAa,UAA6B,eAAe;EAC/D,UAAM,UAAU,OAAmB,YAAY;EAC/C,WAAO,CAAC,GAAG,OAAO,GAAG;EAAA;EAGvB,SAAO;EAAA;oBAYP,WAAc;EACd,QAAM,YAA0B,CAAC;EAC/B,UAAM,aAAa,aAAmB,WAAW;EACjD,UAAM,UAAU,OAAmB,YAAY;EAC/C,WAAO,CAAC,GAAG,OAAO,GAAG;EAAA;EAGvB,SAAO;EAAA;mBAaP,aACA,WACA;EAEA,QAAM,WAAyB,CAAC;EAC9B,UAAM,aAAa,YAAkB,aAAa,WAAW;EAC7D,UAAM,UAAU,OAAmB,YAAY;EAC/C,WAAO,CAAC,GAAG,OAAO,GAAG;EAAA;EAGvB,SAAO;EAAA;mBAaP,MAAY,WAAc;EAC1B,QAAM,WAAyB,CAAC;EAC9B,UAAM,aAAa,YAAwB,MAAM,WAAW;EAC5D,UAAM,UAAU,OAAmB,YAAY;EAC/C,WAAO,CAAC,GAAG,OAAO,GAAG;EAAA;EAGvB,SAAO;EAAA;;2BChFyC,GAAM;EAEtD,MAAI,KAAK,QAAQ,OAAO,MAAM,YAAY,MAAM,QAAQ;EAAI,WAAO;EAGnE,QAAM,UAAU,OAAO,YACrB,KAAK,OAAO,CAAC,QAAQ,OAAO,IAAI,OAAO;EAGzC,SAAO,OAAO,OAAO,SAAS;EAAA;;0BCJ9B,SACA,eACA,MACA,aACA,WACA,QAAgB;EAEhB,aAAW,CAAC,KAAK,UAAU,QAAQ;EACjC,UAAM,WAAW,CAAC,GAAG,MAAM;EAG3B,QAAI,iBAAiB;EACnB,YAAM,WAAW,YAAY,eAAe,UAAU;EAGtD,qBACE,OACA,UACA,UACA,aACA,WACA,QAAQ;EAAA;EAIV,gBAAU,eAAe,UAAU,OAAO;EAAA;EAAA;EAI9C,SAAO;EAAA;;oBCrCP,SACA,SACA,QAA8B,CAAC,SAC7B,KACE,KAAK,SAAS;EAGlB,uBAAqB,eAAiC;EACpD,UAAM,WAAW,IAAI;EACrB,kBAAc,IAAI,MAAM,OAAO;EAC/B,WAAO;EAAA;EAGT,qBACE,eACA,MACA;EAEA,kBAAc,IAAI,MAAM,OAAO,QAAQ,QAAQ;EAAA;EAGjD,QAAM,gBAAkC,IAAI;EAE5C,iBAAe,SAAS,eAAe,IAAI,aAAa;EAExD,SAAO;EAAA;;QC7BI,WAAW,CAAI,MAAY;;mBC4LtC,WACA,KACA;EAEA,MAAI,OAAO,QAAQ;EACjB,UAAM,CAAC;EAAA,aACE,UAAU,WAAW,KAAK,OAAO,QAAQ,CAAC,MAAM,QAAQ;EACjE,cAAU;EAAA;EAGZ,QAAM,WAAyC,CAAC;EAE9C,UAAM,UAAU,YAAY,OAAO;EAGnC,UAAM,UAAU,QACd,SACA,KACA,mCAAS;EAIX,QAAI,mCAAS;EACX,cAAQ,QAAQ;EAAA,aACT;EACH,iBAAO;EAAA,aACJ;EACH,iBAAO,aAAa,SAAS;EAAA,aAC1B;EAAA,aACA;EACH,iBAAO,aAAa,SAAS;EAAA,eACxB;EAAA,YACH,QAAQ;EAAA,YACR,QAAQ,CAAC;EAAA;EAAA;EAGX,iBAAO,aAAa,SAAS;EAAA,eACxB;EAAA,YACH,QAAQ;EAAA,YACR,QAAQ,CAAC,QAAQ;EAAA;EAAA;EAAA;EAMzB,UAAM,YAAY,QAAQ,SAAS,mCAAS;EAC5C,WAAO;EAAA;EAIT,SAAO;EAAA;EAGT,QAAQ,UAAU,CAAC,iBACX,SAAS,QAAQ;EACzB,QAAQ,UAAU,CAAC,iBACX,SAAS,QAAQ;EACzB,QAAQ,gBAAgB,CAAC,iBACjB,SAAS,QAAQ;EACzB,QAAQ,SAAS,CAAC,iBACV,SAAS,QAAQ;EACzB,QAAQ,MAAM,CAAC,iBACP,SAAS,QAAQ;EACzB,QAAQ,OAAO,CAAC,iBACR,SAAS,QAAQ;EACzB,QAAQ,SAAS,CAAC,iBACV,SAAS,QAAQ;EACzB,QAAQ,SAAS,CAAC,iBACV,SAAS,QAAQ;EAEzB,iBACE,OACA,KACA;EAEA,MAAI,SAAc;EAClB,MAAI,6BAAM;EAAQ,WAAO;EAEzB,aAAW,MAAM;EACf,QAAI,CAAC;EAAI;EAGT,aAAS,SAAS,QAAQ,CAAC,QAAO;EAGhC,YAAM,UAAU,CAAE,WAAW;EAC7B,UAAI,kBAAkB,GAAG,QAAO;EAChC,UAAI,iBAAiB;EACnB,0BAAkB,gBAAgB,IAAI,CAAC,SACrC,gBAAgB,MAAM;EAAA;EAI1B,aAAO;EAAA;EAAA;EAIX,SAAO;EAAA;EAGT,qBACE,OACA;EAGA,QAAM,cAAc,cAAc,WAAW,IAAI,CAAC,KAAK;EACrD,UAAM,QAAQ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAS,EAAE;EAG5D,UAAM,WAAW,IAAI;EACrB,WAAO,CAAC;EACN,YAAM,WAAW,MAAM;EAEvB,YAAM,aACJ,OAAO,aAAa,WAAW,SAAS,YAAY;EAEtD,UAAI,SAAS,IAAI;EACf,eAAO,SAAS,IAAI;EAAA;EAGtB,YAAM,cAAc,CAAC,KAAK;EAC1B,eAAS,IAAI,YAAY;EAEzB,aAAO;EAAA;EAAA;EAIX,QAAM,UAAUC,cAAM,OAAO,GAAG;EAChC,SAAO;EAAA;EAMT,iBACE,SACA;EAGA,QAAM,QAAa;EAEnB,iBAAe,SAAS,OAAO,IAAI,UAAU,CAAC,MAAM,MAAM;EAExD,QAAI,cAAc;EAClB,QAAI,iBAAiB;EACnB,oBAAc,OAAO,IAAI,CAAC,MAAM,gBAAgB,GAAG;EAAA;EAErD,SAAK,KAAK,GAAG;EAAA;EAGf,SAAO;EAAA;EAMT,MAAM,sBAAsB,CAAC,SAAgB,KAAK,KAAK;EAEvD,kCAAoD;EA1VpD;EA2VE,QAAM;EAAA,IACJ;EAAA,IACA;EAAA,IACA,UAAU;EAAA,IACV,YAAY;EAAA,IACZ;EAAA,MACE;EACJ,MAAI;EACJ,MAAI,QAAQ;EACV,mBAAe,cAAQ,iBAAR,YAAyB;EAAA;EAG1C,QAAM,UAAU,CAAC,QAAa;EAC5B,WAAO,SACH,QACE,iBAAiB,QAAQ,OAAO,KAAK,gBAAgB,OAAO,IAAI,SAElE,UACE,OAAO,IAAI,CAAC,MACV,QAAQ,iBAAiB,QAAQ,IAAI,gBAAgB,GAAG;EAAA;EAKlE,QAAM,QAAQ,OACV,CAAC,SAAqB,aAAa,KAAK,IAAI,CAAC,MAAM,EAAE,OACrD,CAAC,SAAqB,KAAK,KAAK,SAAS,GAAG;EAEhD,SAAO,CAAE,SAAS;EAAA;EAIpB,sBACE,SACA;EAKA,QAAM,CAAE,SAAS,SAAU,yBAAyB;EACpD,MAAI,CAAE,WAAW,YAAa;EAC9B,QAAM,CAAE,SAAS,CAAC,cAAe;EAEjC,QAAM,aAA0B;EAChC,aAAW,eAAe;EACxB,YAAQ;EAAA,WAED;EAAA,WACA;EAAA,WACA;EAAA,WACA;EACH,cAAM,gBACH,iBAAgB,oBACf,gBAAiB,iBACjB,gBAAiB,oBACnB,QAAQ,YAAY,OAChB,CAAC,CAAC,KAAK,cAAoB,KAAK,WAChC;EAEN,mBAAW,KAAK;EAAA,UACd,IAAI;EAAA,UACJ,qBAAqB,MAAM;EAAA,UAC3B,aAAa,CACX,eACA,aACA,KACA;EAEA,0BAAc,KAAK,cAAc,CAAC,KAAK,cAAc;EAAA;EAAA,UAGvD,SAAS,CACP,eACA,KACA,QACA;EAEA,0BAAc,KAAK,cAAc,CAAC,KAAK,SAAS;EAAA;EAAA;EAGpD;EAAA;EAAA,WAGG;EACH,mBAAW,KAAK;EAAA,UACd,IAAI;EAAA,UACJ,qBAAqB,MAAM,IAAI;EAAA,UAC/B,aAAa,CACX,eACA,aACA;EAEA,0BAAc,IAAI,KAAK;EAAA;EAAA,UAGzB,SAAS,CAAC,eAA8B,KAAU;EAChD,0BAAc,IAAI,KAAK;EAAA;EAAA;EAG3B;EAAA,WAGG;EACH,mBAAW,KAAK;EAAA,UACd,IAAI;EAAA,UACJ,qBAAqB;EAAO,UAC5B,aAAa,CACX,eACA,aACA;EAEA,0BAAc,OAAO;EAAA;EAAA,UAGvB,SAAS,CAAC,eAAgC,KAAU;EAClD,0BAAc,OAAO;EAAA;EAAA;EAGzB;EAAA,WAGG;EACH,mBAAW,KAAK;EAAA,UACd,IAAI;EAAA,UACJ,qBAAqB,MAAM;EAAA,UAC3B,aAAa,CAAC,eAAoB,aAAkB;EAClD,0BAAc,KAAK,CAAC,KAAK;EAAA;EAAA,UAG3B,SAAS,CAAC,eAAoB;EAC5B,0BAAc,KAAK;EAAA;EAAA;EAGvB;EAAA,WAGG;EACH,mBAAW,KAAK;EAAA,UACd,IAAI;EAAA,UACJ,qBAAqB,MAAM;EAAA,UAC3B,aAAa,CAAC,eAAoB;EAChC,0BAAc,KAAK;EAAA;EAAA,UAGrB,SAAS,CAAC,eAAoB,KAAU;EACtC,0BAAc,KAAK;EAAA;EAAA;EAGvB;EAAA;EAKA,YAAI,OAAO,gBAAgB;EACzB,qBAAW,KAAK;EAAA;EAAA;EAAA;EAAA;EAOxB,QAAM,cAAc,CAAC,eAAoB,MAAa;EA5fxD;EA6fI,QAAI,QAAQ;EACV,aAAO;EAAA;EAGT,UAAM,YAAY,iBAAW,WAAX,YAAqB,WAAW,WAAW,SAAS;EACtE,UAAM,gBAAgB,iBAAW,QAAQ,OAAnB,YAAyB;EAC/C,UAAM,cAAc,cAAc;EAClC,cAAW,YAAY,eAAe,aAAa,MAAM,OAAO;EAChE,WAAO;EAAA;EAIT,QAAM,UAAU,CACd,eACA,MACA,QACA;EA7gBJ;EA+gBI,UAAM,YAAY,iBAAW,WAAX,YAAqB,WAAW,WAAW,SAAS;EACtE,cAAW,QACT,eACA,MAAM,OACN,QAAQ,QAAQ,OAChB;EAAA;EAIJ,QAAM,sBAAsB,WAAW,GAAI;EAC3C,SAAO,eAAe,SAAS,qBAAqB,IAAI,aAAa;EAAA;;;ECrhBrE,SAAO,CAAC,UAAiB,MAAM;EAAA;;eCEK;EACpC,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;EAEjD,SAAO,CAAC,UAAeC,aAAK,OAAO;EAAA;;iBCKnC;EAEA,QAAM,SAA0C,CAC9C;EAEA,UAAM,CAAE,OAAO,KAAK,MAAO,4BAAW;EAEtC,UAAM,aAAa,UAAU,EAAG,OAAO,MAAM,OAAO,MAAM,IAAI,MAC5D;EAEF,WAAO;EAAA;EAGT,SAAO;EAAA;;iBCTP,WACA;EAEA,QAAM,SAAS,CAAC;EACd,cAAU,4BAAW;EACrB,UAAM,CAAE,OAAO,KAAK,QAAS;EAE7B,UAAM,UAAU,KACd,OACA,QAAQ,WAAW,CAAC,MAAM,YAC1B,OAAO,QAAQ,KAAK,SAAS;EAG/B,WAAO;EAAA;EAGT,SAAO;EAAA;;kBCTP;EAGA,QAAM,UAA6B,CAAC;EAClC,WAAO,MAAM,IAAI,CAAC;EA9BtB;EA+BM,YAAM,SAAS;EACf,YAAM,OAAO,OAAO,KAAK;EACzB,iBAAW,OAAO;EAChB,cAAM,SACF,iBAAW,SAAX,YAAgD;EACpD,eAAO,UAAU,EAAE;EAAA;EAGrB,aAAO;EAAA;EAAA;EAIX,SAAO;EAAA;;iBClCP,OACA;EAEA,QAAM,SAAoB,CAAC,UAAoB,MAAM,MAAM,OAAO;EAElE,SAAO;EAAA;QAOI,YAAY,CAAmB,MAAc,MAAS,GAAG;QAMzD,YAAY,CAAmB,MAAc,MAAS,CAAC;oBAQlE,GACA;EAEA,QAAM,YAAuB,CAAC,UAC5B,QAAW,SAAS,OAAO,MAAM,GAAG;EAEtC,SAAO;EAAA;oBASP,GACA;EAIA,QAAM,YAAuB,CAAC,UAC5B,OAAO,YAAY,aACf,QAAW,SAAS,OAAO,MAAM,CAAC,GAAG,YACrC,QAAW,KAAK,UAAiB,OAAO,MAAM,GAAG;EAEvD,SAAO;EAAA;uBAYP,GACA;EAEA,YAAU,4BAAW;EACrB,QAAM,CAAE,WAAY;EAEpB,QAAM,eAA0B,CAAC;EAC/B,QAAI,CAAC,MAAM;EAAQ,aAAO,MAAM;EAGhC,QAAI;EACF,YAAM,SAAS;EACf,eAAS,IAAI,GAAG,IAAI,GAAG,EAAE;EACvB,eAAO,KAAK,MAAM,KAAK,MAAM,KAAK,WAAW,MAAM;EAAA;EAErD,aAAO;EAAA;EAIT,WAAOC,gBAAQ,MAAM,SAAS,MAAM,GAAG;EAAA;EAGzC,SAAO;EAAA;;2BC7E6B,QAAa;EACjD,MAAI,OAAO,WAAW,KAAK,OAAO,WAAW;EAAG,WAAO;EAGvD,QAAM,QAAQ,OAAO,KAAK,OAAO;EACjC,QAAM,QAAQ,OAAO,KAAK,OAAO;EAIjC,QAAM,QAAa;EACnB,aAAW,OAAO;EAChB,QAAI,MAAM,SAAS;EACjB,YAAM,OAAO;EAAA;EAAA;EAIjB,SAAO;EAAA;qBAKP;EAGA,MAAI,MAAM,QAAQ;EAChB,UAAM,QAAyB;EAC/B,eAAW,OAAO;EAChB,YAAM,OAAc;EAAA;EAEtB,WAAO;EAAA,aACE,OAAO,OAAO;EACvB,WAAO;EAAA;EAET,SAAO,EAAG,KAAoB;EAAA;mBAI9B,GACA,GACA;EAEA,aAAW,QAAQ;EACjB,UAAM,OAAO,MAAM;EACnB,QAAK,EAAE,UAA6B,EAAE;EACpC,aAAO;EAAA;EAAA;EAGX,SAAO;EAAA;qBAQP,aACA;EAEA,QAAM,aAA2C,CAC/C;EAGA,UAAM,QACJ,oCAAS,OAAM,OACX,gBAAgB,OAAO,eACvB,UAAU,QAAQ;EAExB,UAAM,SAAS,MAAM,QAAQ,CAAC;EAC5B,YAAM,UAAU,YAAY,OAAO,CAAC,MAAa,QAAQ,GAAG,GAAG;EAC/D,aAAO,QAAQ,IAAI,CAAC,WAAmB,MAAM;EAAA;EAG/C,WAAO;EAAA;EAET,SAAO;EAAA;;oBClFP,aACA;EAEA,QAAM,YAAmD,CACvD;EAEA,QAAI,CAAC,YAAY;EAAQ,aAAO;EAGhC,UAAM,QACJ,oCAAS,OAAM,OACX,gBAAgB,OAAO,eACvB,UAAU,QAAQ;EAIxB,UAAM,iBAAiB,OAAO,KAAK,YAAY;EAE/C,UAAM,SAAS,MAAM,QAAQ,CAAC;EAC5B,YAAM,UAAU,YAAY,OAAO,CAAC,MAAa,QAAQ,GAAG,GAAG;EAC/D,UAAI,QAAQ;EACV,eAAO,QAAQ,IAAI,CAAC,WAAmB,MAAM;EAAA;EAM/C,YAAM,gBAAgB,OAAO,YAC3B,eACG,OAAO,CAAC,QAAQ,EAAE,QAAQ,MAC1B,IAAI,CAAC,QAAQ,CAAC,KAAK;EAGxB,aAAO,IAAK,MAAM;EAAA;EAGpB,WAAO;EAAA;EAET,SAAO;EAAA;;oBCtCP,aACA;EAEA,QAAM,YAAmD,CACvD;EAEA,QAAI,CAAC,YAAY;EAAQ,aAAO;EAChC,QAAI,CAAC,MAAM;EAAQ,aAAO;EAG1B,UAAM,QACJ,oCAAS,OAAM,OACX,gBAAgB,OAAO,eACvB,UAAU,QAAQ;EAGxB,UAAM,WAAW,IAAI;EAIrB,UAAM,iBAAiB,OAAO,KAAK,YAAY;EAE/C,UAAM,SAAS,MAAM,QAAQ,CAAC;EAC5B,YAAM,UAAU,YAAY,OAAO,CAAC;EAClC,cAAM,UAAU,QAAQ,GAAG,GAAG;EAC9B,YAAI;EACF,mBAAS,IAAI,GAAG;EAAA;EAElB,eAAO;EAAA;EAGT,UAAI,QAAQ;EACV,eAAO,QAAQ,IAAI,CAAC,WAAmB,MAAM;EAAA;EAM/C,YAAM,gBAAgB,OAAO,YAC3B,eACG,OAAO,CAAC,QAAQ,EAAE,QAAQ,MAC1B,IAAI,CAAC,QAAQ,CAAC,KAAK;EAGxB,aAAO,IAAK,MAAM;EAAA;EAIpB,QAAI,SAAS,OAAO,YAAY;EAC9B,YAAM,kBAAkB,OAAO,YAC7B,OAAO,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK;EAE3C,iBAAW,QAAQ;EACjB,YAAI,CAAC,SAAS,IAAI;EAChB,iBAAO,KAAK,IAAK,oBAAoB;EAAA;EAAA;EAAA;EAK3C,WAAO;EAAA;EAET,SAAO;EAAA;;6BC3CP;EAGA,QAAM,UAAwC,CAC5C;EAGA,UAAM,eAA2B,MAAM,IAAI,CAAC,WAAY;EAGxD,eAAW,OAAO;EAGhB,YAAM,kBAAkB,WAAW;EACnC,YAAM,gBACJ,OAAO,oBAAoB,aACvB,gBAAgB,gBAChB;EACN,YAAM,gBACJ,gDAAgB,OAAO,cAAa,OAAO,kBAAkB,WACzD,gBACA,MAAM,IAAI,MAAM;EAGtB,UAAI,IAAI;EACR,iBAAW,eAAe;EACxB,oBAAY,OAAyB,cAAc,EAAE;EAAA;EAAA;EAIzD,WAAO;EAAA;EAGT,SAAO;EAAA;;yBCjDuC;EAC9C,MAAI,MAAM,SAAS;EAAG,WAAO;EAC7B,QAAM,OAAO,OAAO,KAAK,MAAM;EAC/B,SAAO;EAAA;;;ECRP,SAAO,CAAC;EACN,UAAM,OAAO,cAAc;EAC3B,WAAO;EAAA;EAAA;;4BCuCT,OACA;EAEA,MAAI,sBAAgC;EAEpC,aAAW,YAAY,cAAc;EACnC,QAAI,OAAO,aAAa;EACtB,0BAAoB,KAAK,GAAI,SAAS;EAAA;EAEtC,0BAAoB,KAAK;EAAA;EAAA;EAK7B,MAAI,oBAAoB,UAAU,oBAAoB,GAAG,OAAO;EAC9D,0BAAsB,CAAC,GAAG,aAAa,QAAQ,GAAG;EAAA;EAGpD,QAAM,cAAmB;EACzB,QAAM,uBAAuB;EAE7B,WAAS,IAAI,oBAAoB,SAAS,GAAG,KAAK,GAAG;EACnD,UAAM,MAAW,oBAAoB;EACrC,QAAI,IAAI,OAAO;EACb,kBAAY,IAAI,UAAU,MAAM;EAChC;EAAA;EAEF,QAAI,YAAY;EACd,kBAAY,OAAO;EACnB;EAAA;EAEF,yBAAqB,QAAQ;EAAA;EAI/B,wBAAsB,MAAM,KAAK,IAAI,IAAI;EAEzC,SAAO;EAAA;kBASP;EAGA,QAAM,UAA8B,CAAC;EACnC,QAAI,sBAAgC,iBAAiB,OAAO;EAE5D,QAAI,CAAC,oBAAoB;EAAQ,aAAO;EAGxC,WAAO,MAAM,IAAI,CAAC;EAChB,YAAM,SAAc;EACpB,iBAAW,OAAO;EAChB,eAAO,OAAO,EAAE;EAAA;EAGlB,aAAO;EAAA;EAAA;EAIX,SAAO;EAAA;;qBCtGP;EAEA,QAAM,aAAuD,CAAC;EAC5D,UAAM,UAAU,OAAiB,YAAY;EAC7C,UAAM,SAAS,OAAO,OAAO,KAAK,aAAyB;EAC3D,WAAO;EAAA;EAGT,SAAO;EAAA;;mBCVP;EAEA,QAAM,WAAsB,CAAC;EAE3B,QAAI,OAAO,eAAe;EACxB,aAAO,CAAC,GAAG,OAAO,GAAG,cAAe,WAAwB;EAAA;EAG9D,WAAO,CAAC,GAAG,OAAO,GAAG,cAAc;EAAA;EAGrC,SAAO;EAAA;;sBCHP;EAEA,QAAM,cAAsC,CAAC;EAC3C,UAAM;EAAA,MACJ;EAAA,MACA;EAAA,MACA;EAAA,MACA;EAAA,MACA,WAAW;EAAA,QACT;EAEJ,UAAM,gBAA6B,MAAM,QAAQ,aAC7C,YACA,CAAC;EACL,UAAM,iBAA8B,MAAM,QAAQ,cAC9C,aACA,CAAC;EACL,UAAM,QAAuB;EAE7B,QAAI,CAAC,MAAM;EAAQ,aAAO;EAG1B,UAAM,YAAY,OAAO,KAAK,MAAM,IAAI,OACtC,CAAC,QACC,CAAC,cAAc,SAAS,QACxB,CAAC,eAAe,SAAS;EAI7B,UAAM,gBAAqB;EAC3B,eAAW,QAAQ;EACjB,iBAAW,WAAW;EACpB,YAAI,cAAc,YAAY;EAC5B,wBAAc,WAAW;EAAA;EAE3B,sBAAc,SAAS,KAAK,YAAY;EAAA;EAAA;EAI5C,UAAM,kBAA8B;EACpC,eAAW,WAAW;EACpB,sBAAgB,KAAK,OAAO,KAAK,cAAc;EAAA;EAIjD,UAAM,cAAmB;EACzB,UAAM,SAAS,iBAAiB,UAAU;EAE1C,eAAW,WAAW;EACpB,UAAI,eAAe,WAAW;EAC5B,oBAAY,WACV,iBAAiB,OACb,cAAc,eAAe,MAC7B;EACN;EAAA;EAGF,iBAAW,YAAY;EACrB,oBAAY,GAAG,WAAW,WAAW,aACnC,iBAAiB,OAAO,cAAc,YAAmB;EAAA;EAAA;EAK/D,wBAAoB;EAClB,UAAI,CAAC,OAAM;EAAQ,eAAO;EAE1B,YAAM,OAAoB,IAAK;EAG/B,iBAAW,SAAS;EAClB,aAAK,SAA8B,OAAM,GAAG;EAAA;EAI9C,iBAAW,QAAQ;EACjB,cAAM,UAAU,cAAc,IAAI,CAAC,QAAQ,KAAK,MAAM,KAAK;EAE3D,YAAI,eAAe,WAAW;EAC5B,eAAK,WAAW,KAAK,eAAe;EACpC;EAAA;EAGF,mBAAW,YAAY;EACrB,eAAK,GAAG,WAAW,WAAW,aAAa,KAAK;EAAA;EAAA;EAGpD,aAAO,CAAC;EAAA;EAIV,QAAI,CAAC,UAAU;EACb,aAAO,WAAW;EAAA;EAKpB,UAAM,SAAS,KAAK,OAAO,QAAQ,WAAW,CAAC;EAC/C,WAAO;EAAA;EAGT,SAAO;EAAA;EAMT,0BAA0B,YAAY,KAAK;EACzC,mBACE,OACA,QACA;EAEA,QAAI,CAAC,gBAAgB,UAAU,UAAU;EACvC,YAAM,KAAK;EACX;EAAA;EAGF,UAAM,QAAQ,gBAAgB;EAC9B,UAAM,qBAAqB,gBAAgB,MAAM;EACjD,eAAW,QAAQ;EACjB,cACE,OACA,UAAU,OAAO,OAAO,GAAG,SAAS,YAAY,QAChD;EAAA;EAAA;EAKN,QAAM,SAAmB;EACzB,UAAQ,QAAQ,MAAM;EACtB,SAAO;EAAA;;uBCrIP;EAEA,QAAM,eAAuC,CAAC;EAhBhD;EAiBI,UAAM,CAAE,SAAS,UAAU,WAAW,OAAQ;EAC9C,UAAM,OAAO,cAAQ,SAAR,YAAgB;EAC7B,UAAM,WAAW,iBAAiB,OAAO;EAEzC,UAAM,cAAc,MAAM,QAAQ,WAAW,UAAU,CAAC;EACxD,UAAM,eAAe,MAAM,QAAQ,YAAY,WAAW,CAAC;EAC3D,UAAM,qBAAqB,YAAY,SAAS;EAChD,UAAM,sBAAsB,aAAa,SAAS;EAElD,UAAM,SAAwB;EAG9B,eAAW,QAAQ;EAEjB,YAAM,gBAAgB,OAAO,KAAK,MAAM,OACtC,CAAC,QAAQ,CAAC,SAAS,SAAS;EAI9B,YAAM,UAAU;EAChB,iBAAW,OAAO;EAChB,gBAAQ,OAA4B,KAAK;EAAA;EAI3C,YAAM,kCAAkC,sBACpC,MAAM,KACJ,IAAI,IACF,SAAS,IAAI,CAAC,QACX,IAAe,UAAW,IAAe,QAAQ,YAAY,QAIpE;EAGJ,iBAAW,aAAa;EACtB,cAAM,WAAW,IAAK;EACtB,mBAAW,YAAY;EAErB,gBAAM,UAAU,sBACZ,GAAG,WAAW,WAAW,cACzB;EACJ,gBAAM,iBAAiB,qBAClB,UAAqB,MAAM,YAC5B,CAAC;EAEL,cAAI,IAAI;EACR,qBAAW,WAAW;EACpB,kBAAM,gBAAgB,eAAe;EACrC,qBAAS,WAAW;EACpB,qBAAS,YAAY,KAAK;EAAA;EAAA;EAI9B,eAAO,KAAK;EAAA;EAAA;EAIhB,WAAO;EAAA;EAGT,SAAO;EAAA;;kBC1DgC;EACvC,QAAM,UAAqB,CAAC;EAC1B,UAAM,SAAS,WAAW;EAG1B,UAAM,UAAU;EAChB,eAAW,OAAO;EAChB,YAAM,WAAW,OAAO;EACxB,UAAI;EACJ,UAAI,OAAO,aAAa;EACtB,iBAAS,SAAS;EAAA,iBACT,MAAM,QAAQ;EACvB,iBAAS;EAAA;EAGT,iBAAS,MAAM,KAAK,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE;EAAA;EAGjD,cAAQ,KAAK,OAAO,IAAI,CAAC,aAAmB,MAAM;EAAA;EAIpD,WAAOC,mBAAiB;EAAA;EAG1B,SAAO;EAAA;EAMT,4BAA0B;EACxB,mBAAiB,OAAc,SAAc;EAC3C,QAAI,CAAC,iBAAiB,UAAU,WAAW;EACzC,YAAM,KAAK;EACX;EAAA;EAGF,UAAM,SAAS,iBAAiB;EAChC,UAAM,qBAAqB,iBAAiB,MAAM;EAClD,eAAW,QAAQ;EACjB,cAAQ,OAAO,IAAK,YAAY,OAAQ;EAAA;EAAA;EAI5C,QAAM,SAAgB;EACtB,UAAQ,QAAQ,MAAM;EACtB,SAAO;EAAA;sBAIkB;EACzB,MAAI,MAAM,QAAQ;EAChB,UAAM,SAAiB;EACvB,eAAW,OAAO;EAChB,aAAO,OAAc;EAAA;EAEvB,WAAO;EAAA,aACE,OAAO,SAAS;EACzB,WAAO;EAAA;EAGT,SAAO,EAAG,OAAO;EAAA;;qBC7EO,QAAkB,SAAiB;EAC3D,MAAI,CAAC,KAAK,OAAOC,eAAO;EAExB,QAAM,WAAqB;EAC3B,MAAI,QAAQ;EACZ,SAAO,SAAS;EACd,aAAS,KAAK;EACd,aAAS;EAAA;EAGX,SAAO;EAAA;yBAOP,QACA,cAA2B,OAC3B,SAAiB;EAEjB,MAAI,CAAC,KAAK,OAAOA,eAAO;EAExB,QAAM,WAAmB;EACzB,MAAI,QAAQ,IAAI,KAAK;EACrB,SAAO,SAAS;EACd,aAAS,KAAK,IAAI,KAAK;EAGvB,QACE,gBAAgB,YAChB,gBAAgB,OAChB,gBAAgB;EAEhB,YAAM,cAAc,MAAM,kBAAkB,IAAI;EAAA,eAEhD,gBAAgB,YAChB,gBAAgB,SAChB,gBAAgB;EAEhB,YAAM,cAAc,MAAM,kBAAkB,IAAI;EAAA,eAEhD,gBAAgB,SAChB,gBAAgB,OAChB,gBAAgB;EAEhB,YAAM,WAAW,MAAM,eAAe,IAAI;EAAA,eAE1C,gBAAgB,UAChB,gBAAgB,OAChB,gBAAgB;EAEhB,YAAM,WAAW,MAAM,eAAe,IAAI;EAAA,eAE1C,gBAAgB,WAChB,gBAAgB,OAChB,gBAAgB;EAEhB,YAAM,YAAY,MAAM,gBAAgB,IAAI;EAAA,eAE5C,gBAAgB,UAChB,gBAAgB,OAChB,gBAAgB;EAEhB,YAAM,eAAe,MAAM,mBAAmB,IAAI;EAAA;EAElD,YAAM,IAAI,MAAM,4CAA4C;EAAA;EAAA;EAIhE,SAAO;EAAA;mBASP,KACA;EAEA,SAAO,sBAAsB;EAC3B,aAAS,0BAAU;EAEnB,UAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;EAEjD,WAAO,UAAU,MAAM,IAAI,QAAQ;EAAA;EAAA;uBAKrC,KACA,aACA;EAEA,SAAO,0BAA0B;EAC/B,kBAAc,oCAAe;EAC7B,aAAS,0BAAU;EAEnB,UAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;EAEjD,WAAO,cAAc,MAAM,IAAI,QAAQ,aAAa;EAAA;EAAA;gCAKtD,KACA,aACA;EAEA,SAAO,mCAAmC;EACxC,kBAAc,oCAAe;EAC7B,aAAS,0BAAU;EAEnB,UAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;EAEjD,WAAO,cACL,MAAM,IAAI,CAAC,MAAM,IAAI,KAAK,MAAM,MAChC,aACA,QACA,IAAI,CAAC,SAAS,KAAK;EAAA;EAAA;;wBC5GvB;EACA,QAAM,gBAAmD,CACvD;EAEA,UAAM,gBAA0C;EAEhD,eAAW,KAAK;EACd,YAAM,MAAM,IAAK;EACjB,iBAAW,OAAO;EAChB,YAAI,IAAK,QAA+B;EACtC,cAAK,OAA8B,YAAY;EAAA;EAAA;EAGnD,oBAAc,KAAK;EAAA;EAGrB,WAAO;EAAA;EAGT,SAAO;EAAA;;oBC7BP,YACA;EAEA,QAAM,YAAuB,CAAC;EAC5B,UAAM,WAAW,OAAe,YAAY;EAC5C,UAAM,SAAS,SAAS,OAAO;EAC/B,WAAO,mBACF,aAAa,kBAAkB,UAChC;EAAA;EAGN,SAAO;EAAA;;gBCjB8B;EACrC,QAAM,QAAmB,CAAC;EACxB,UAAM,YAAY,cAAc;EAEhC,UAAM,aAAyB;EAE/B,WAAO,MAAM,IAAI,CAAC;EAChB,YAAM,MAAM,IAAK;EACjB,iBAAW,OAAO;EAChB,YAAI,IAAI,QAAmB;EACzB,qBAAW,OAAkB,IAAI;EAAA,mBACxB,WAAW,QAAmB;EACvC,cAAI,OAAkB,WAAW;EAAA;EAAA;EAGrC,aAAO;EAAA;EAAA;EAIX,SAAO;EAAA;;iBCdP,OACA;EAEA,QAAM,SAAoB,CAAC,OAAY;EAdzC;EAeI,QAAI,SAAS;EACb,QAAI,yCAAS,cAAT,mBAAoB;EACtB,YAAM,YAAY,QAAQ;EAC1B,YAAM,kBAAkB,UACrB,IAAI,CAAC,YAAiB,QAAQ,KAAK,OACnC,KAAK;EACR,UAAI,gBAAgB;EAClB,kBAAU,MAAM;EAAA;EAAA;EAGpB,cAAU,4BAAW;EACrB,UAAM,CAAE,QAAQ,IAAI,SAAS,WAAY;EAGzC,UAAM,aACJ;EACF,QAAI,YAAY,WAAW;EAC3B,UAAM,gBAAgB,SAAS,gBAAgB,OAAO,KAAK,MAAM;EACjE,gBAAY,KAAK,IAAI,GAAG,2BAA2B,SAAS;EAE5D,YAAQ,IAAI,GAAG,iBAAiB,WAAW,UAAU,GAAG;EACxD,YAAQ,QACN,SAAS,QAAQ,SAAS,MAAM,SAAS,QAAQ,MAAM,MAAM,GAAG;EAElE,WAAO;EAAA;EAGT,SAAO;EAAA;;gBCtCP,WACA,aACA;EAEA,SAAO,aAAa,QAAQ,eAAe,OACvC,SACA,gBAAgB,KAAK,cAAc,IACnC,IACA,CAAC,qBAAqB,gBAAgB,IACtC,SACA,YAAY;EAAA;oBAIhB,GACA,GACA;EAEA,SAAO,KAAK,QAAQ,KAAK,OACrB,YACG,iBAAK,sBAAW,KACjB,SACF,IAAI;EAAA;eAIR,GACA,GACA;EAEA,SAAO,KAAK,QAAQ,KAAK,OACrB,YACG,iBAAK,sBAAW,KACjB,SACF,IAAI;EAAA;;;;;;;;;kBC1BR,WACA,aACA;EAEA,QAAM,cACJ,OAAO,cAAc,aACjB,YACA,CAAC,MAAU,EAAE;EACnB,QAAM,gBACJ,OAAO,gBAAgB,aACnB,cACA,CAAC,MAAU,EAAE;EAEnB,QAAM,CAAE,WAAW,qBAAsB,4BAAW;EACpD,SAAO,aAAa,OAChB,CAAC;EACC,UAAM,QAAQ,cAAc;EAC5B,UAAM,QAAQ,YAAY;EAC1B,WAAOC,KAAS,OAAO,OAAO;EAAA,MAEhC,CAAC;EACC,QAAI,CAAC,UAAU;EAAI,aAAO;EAE1B,UAAM,QAAQ,cAAc;EAC5B,UAAM,QAAQ,YAAY;EAC1B,WAAOA,KAAS,OAAO,OAAO;EAAA;EAAA;;mBCjCpC,OACA;EAEA,MAAI,MAAM,IAAIC,iBACZ,IAAI;EAEN,SAAO,aAAa,KAClB,OAIA,CAAC,UACE,IAAI,IAAI,WAAW,OAAO,KAAK,UAAU;EAAA;gBAK9C,OACA;EAEA,MAAI,IAAI;EACR,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,EAAE;EAClC,UAAM,QAAQ,SAAS,MAAM,IAAI,GAAG;EAEpC,QAAI,CAAC,UAAU;EACb,WAAK;EAAA;EAAA;EAIT,SAAO,IAAIL,aAAK,OAAO,YAAY,IAAI;EAAA;;kBC9BvC;EAEA,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;EAGjD,SAAO,CAAC,UAAe,QAAQ,OAAO;EAAA;;gBCGtC,OACA,QACA;EAEA,QAAM,CAAE,UAAU,SAAU,4BAAW;EAEvC,SAAO,CAAC;EACN,WAAO,MAAM,IAAI,CAAC,GAAG;EACnB,YAAM,WAAW;EAGjB,UAAI,CAAC,WAAW,WAAW,QAAQ,IAAI;EACrC,eAAO;EAAA;EAGT,YAAM,aAAa,KAAK,IAAI,GAAG,WAAW,QAAQ;EAClD,YAAM,gBAAgB,MAAM,MAAM,YAAY,WAAW;EAGzD,aAAO,OAAO,eAAe;EAAA;EAAA;EAAA;;eCjBjC,KACA;EAEA,QAAM,QAAQ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAS,EAAE;EAE5D,QAAM,CAAE,IAAI,GAAG,SAAS,gBAAiB,4BAAW;EAEpD,SAAO,CAAC;EACN,WAAO,MAAM,IAAI,CAAC,GAAG;EACnB,YAAM,UAAU,MAAM,IAAI;EAC1B,aAAO,WAAW,OAAO,eAAe,MAAM;EAAA;EAAA;EAAA;;gBCVlD,KACA;EAEA,QAAM,QAAQ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAS,EAAE;EAE5D,QAAM,CAAE,IAAI,GAAG,SAAS,gBAAiB,4BAAW;EAEpD,SAAO,CAAC;EACN,WAAO,MAAM,IAAI,CAAC,GAAG;EACnB,YAAM,WAAW,MAAM,IAAI;EAC3B,aAAO,YAAY,OAAO,eAAe,MAAM;EAAA;EAAA;EAAA;;eClBf;EACpC,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;EAEjD,SAAO,CAAC,UAAeM,YAAM,OAAO;EAAA;;eCJA;EACpC,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;EAEjD,SAAO,CAAC,UAAeC,YAAM,OAAO;EAAA;;kBCJC;EACrC,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;EAEjD,SAAO,CAAC,UAAeC,KAAa,OAAO;EAAA;;oBCD3C,WACA;EAEA,QAAM,cACJ,OAAO,cAAc,aACjB,YACA,CAAC,MAAU,EAAE;EACnB,QAAM,gBACJ,OAAO,gBAAgB,aACnB,cACA,CAAC,MAAU,EAAE;EAEnB,SAAO,CAAC;EACN,UAAM,aAAYR,aAAK,OAAO;EAC9B,UAAM,eAAcA,aAAK,OAAO;EAChC,WAAO,KAAK,YAAW;EAAA;EAAA;;kBClBc;EACvC,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;EAEjD,SAAO,CAAC,UAAeS,eAAS,OAAO;EAAA;;qBCJG;EAC1C,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;EAEjD,SAAO,CAAC,UAAeC,kBAAY,OAAO;EAAA;;oBCJD;EACzC,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;EAEjD,SAAO,CAAC,UAAeC,iBAAW,OAAO;EAAA;;qBCLzC,KACA,UAAiE;EAEjE,QAAM,QAAQ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAS,EAAE;EAE5D,SAAO,CAAC;EACN,UAAM,UAAU,IAAI;EACpB,QAAI,QAAQ;EAEZ,eAAW,QAAQ;EACjB,YAAM,QAAQ,MAAM;EAEpB,UAAI,CAAC,QAAQ,IAAI;EAEf,YACG,CAAC,QAAQ,oBAAoB,UAAU,UACvC,QAAQ,gBAAgB,SAAS,UAAU;EAE5C;EAAA;EAGF,iBAAS;EACT,gBAAQ,IAAI,OAAO;EAAA;EAAA;EAIvB,WAAO;EAAA;EAAA;;iBC3B6B;EACtC,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;EAEjD,SAAO,CAAC,UAAgB,MAAM,SAAS,MAAM,MAAM,MAAM;EAAA;;gBCJpB;EACrC,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;EAEjD,SAAO,CAAC,UACN,MAAM,SAAS,MAAM,MAAM,MAAM,SAAS,MAAM;EAAA;;sBCHlD,QACA,aAAsB;EAEtB,SAAO,CAAC;EACN,UAAM,QAAQ,IAAI,OAAO,IAAI,UAAU,aAAa,MAAM;EAC1D,UAAM,OAAO,cAAc;EAC3B,WAAO,KAAK,OAAO,CAAC,MAAM,MAAM,KAAK;EAAA;EAAA;;oBCNvC,QACA,aAAsB;EAEtB,SAAO,CAAC;EACN,UAAM,QAAQ,IAAI,OAAO,GAAG,WAAW,aAAa,MAAM;EAC1D,UAAM,OAAO,cAAc;EAC3B,WAAO,KAAK,OAAO,CAAC,MAAM,MAAM,KAAK;EAAA;EAAA;;oBCNvC,WACA,aAAsB;EAEtB,SAAO,CAAC;EACN,UAAM,QAAQ,IAAI,OAAO,WAAW,aAAa,MAAM;EACvD,UAAM,OAAO,cAAc;EAC3B,WAAO,KAAK,OAAO,CAAC,MAAM,MAAM,KAAK;EAAA;EAAA;;mBCPC;EACxC,SAAO,CAAC;EACN,UAAM,OAAO,cAAc;EAC3B,WAAO,KAAK,OAAO,CAAC,MAAM,MAAM,KAAK;EAAA;EAAA;;oBCDvC,QACA,OACA;EAEA,SAAO,CAAC;EACN,UAAM,OAAO,cAAc;EAC3B,UAAM,YAAsB;EAC5B,aAAS,IAAI,MAAM,IAAI,KAAK,MAAM,IAAI,EAAE;EACtC,YAAM,MAAM,SAAS,OAAO,IAAI,IAAI,OAAO,aAAa,GAAG,MAAM,CAAC;EAClE,gBAAU,KAAK,GAAG,SAAS;EAAA;EAG7B,WAAO,KAAK,OAAO,CAAC,MAAO,UAA0B,SAAS;EAAA;EAAA;;kBCZhE;EAEA,SAAO,CAAC;EACN,QAAI,SAAS,IAAI;EACjB,eAAW,YAAY,cAAc;EACnC,UAAI,OAAO,aAAa;EACtB,cAAM,QAAO,SAAS;EACtB,mBAAW,OAAO;EAChB,iBAAO,IAAI;EAAA;EAAA;EAGb,eAAO,IAAI;EAAA;EAAA;EAGf,UAAM,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,QAAQ,IAAI;EACjD,WAAO;EAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"tidy.js","sources":["../../src/tidy.ts","../../src/filter.ts","../../src/when.ts","../../src/map.ts","../../src/helpers/singleOrArray.ts","../../src/distinct.ts","../../src/arrange.ts","../../src/summarize.ts","../../src/mutate.ts","../../src/total.ts","../../src/helpers/assignGroupKeys.ts","../../src/helpers/groupTraversal.ts","../../src/helpers/groupMap.ts","../../src/helpers/identity.ts","../../src/helpers/isObject.ts","../../src/groupBy.ts","../../src/summary/n.ts","../../src/summary/sum.ts","../../src/tally.ts","../../src/count.ts","../../src/rename.ts","../../src/slice.ts","../../src/innerJoin.ts","../../src/leftJoin.ts","../../src/fullJoin.ts","../../src/mutateWithSummary.ts","../../src/helpers/keysFromItems.ts","../../src/selectors/everything.ts","../../src/select.ts","../../src/transmute.ts","../../src/addRows.ts","../../src/pivotWider.ts","../../src/pivotLonger.ts","../../src/expand.ts","../../src/sequences/fullSeq.ts","../../src/replaceNully.ts","../../src/complete.ts","../../src/fill.ts","../../src/debug.ts","../../src/math/math.ts","../../src/item/rate.ts","../../src/helpers/summation.ts","../../src/vector/cumsum.ts","../../src/vector/roll.ts","../../src/vector/lag.ts","../../src/vector/lead.ts","../../src/vector/rowNumber.ts","../../src/summary/min.ts","../../src/summary/max.ts","../../src/summary/mean.ts","../../src/summary/meanRate.ts","../../src/summary/median.ts","../../src/summary/deviation.ts","../../src/summary/variance.ts","../../src/summary/nDistinct.ts","../../src/summary/first.ts","../../src/summary/last.ts","../../src/selectors/startsWith.ts","../../src/selectors/endsWith.ts","../../src/selectors/contains.ts","../../src/selectors/matches.ts","../../src/selectors/numRange.ts","../../src/selectors/negate.ts"],"sourcesContent":["// note prettier is ignored here via .prettierignore\nimport { TidyFn, TidyGroupExportFn } from './types';\n\n// pipe types not well supported: https://github.com/microsoft/TypeScript/issues/29904\n// so manually make types overloaded for up to 10 steps\n\n/**\n * Forms a tidy pipeline that can be called with (items)\n * @param items array of items to manipulate\n * @param fns Tidy functions\n */\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, T8 extends object, T9 extends object, T10 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyFn<T6, T7>, f8: TidyFn<T7, T8>, f9: TidyFn<T8, T9>, f10: TidyFn<T9, T10>): T10[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, T8 extends object, T9 extends object, T10 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyFn<T6, T7>, f8: TidyFn<T7, T8>, f9: TidyFn<T8, T9>, f10: TidyGroupExportFn<T9, T10>): T10;\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, T8 extends object, T9 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyFn<T6, T7>, f8: TidyFn<T7, T8>, f9: TidyFn<T8, T9>): T9[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, T8 extends object, T9 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyFn<T6, T7>, f8: TidyFn<T7, T8>, f9: TidyGroupExportFn<T8, T9>): T9;\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, T8 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyFn<T6, T7>, f8: TidyFn<T7, T8>): T8[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, T8 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyFn<T6, T7>, f8: TidyGroupExportFn<T7, T8>): T8;\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyFn<T6, T7>): T7[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>, f7: TidyGroupExportFn<T6, T7>): T7;\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyFn<T5, T6>): T6[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5>, f6: TidyGroupExportFn<T5, T6>): T6;\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyFn<T4, T5> ): T5[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>, f5: TidyGroupExportFn<T4, T5> ): T5;\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyFn<T3, T4>): T4[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>, f4: TidyGroupExportFn<T3, T4>): T4;\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyFn<T2, T3>): T3[];\nexport function tidy<T extends object, T1 extends object, T2 extends object, T3 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>, f3: TidyGroupExportFn<T2, T3>): T3;\nexport function tidy<T extends object, T1 extends object, T2 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyFn<T1, T2>): T2[];\nexport function tidy<T extends object, T1 extends object, T2 extends object>(items: T[], f1: TidyFn<T, T1>, f2: TidyGroupExportFn<T1, T2>): T2;\nexport function tidy<T extends object, T1 extends object>(items: T[], f1: TidyFn<T, T1>): T1[];\nexport function tidy<T extends object, T1 extends object>(items: T[], f1: TidyGroupExportFn<T, T1>): T1;\nexport function tidy<InputT extends object>(\n items: InputT[],\n ...fns: (TidyFn<any, any> | TidyGroupExportFn<any, any>)[]\n): any {\n if (typeof items === 'function') {\n throw new Error('You must supply the data as the first argument to tidy()');\n }\n\n let result: any = items;\n for (const fn of fns) {\n if (fn) {\n // skip falsy values\n result = fn(result);\n }\n }\n\n return result;\n}\n","import { TidyFn } from './types';\n\n/**\n * Filters items\n * @param filterFn Returns true to keep the item, false to filter out\n */\nexport function filter<T extends object, O extends T>(\n filterFn: (item: T, index: number, array: T[]) => item is O\n): TidyFn<T, O>;\nexport function filter<T extends object>(\n filterFn: (item: T, index: number, array: T[]) => boolean\n): TidyFn<T>;\nexport function filter<T extends object>(\n filterFn: (item: T, index: number, array: T[]) => boolean\n): TidyFn<T> {\n const _filter: TidyFn<T> = (items: T[]): T[] => items.filter(filterFn);\n return _filter;\n}\n","import { TidyFn } from './types';\nimport { tidy } from './tidy';\n\n/**\n * Conditionally runs a tidy sub-flow\n */\nexport function when<T extends object>(\n predicate: ((items: T[]) => boolean) | boolean,\n fns: TidyFn<any, any>[]\n): TidyFn<T, any> {\n const _when: TidyFn<T, any> = (items: T[]) => {\n if (typeof predicate === 'function') {\n if (!predicate(items)) return items;\n } else if (!predicate) {\n return items;\n }\n\n const results = (tidy as any)(items, ...fns);\n return results;\n };\n return _when;\n}\n","import { TidyFn } from './types';\n\n/**\n * Maps items\n * @param mapFn Maps items from one form to another\n */\nexport function map<T extends object, OutputT>(\n mapFn: (item: T, index: number, array: T[]) => OutputT\n): TidyFn<T, OutputT> {\n const _map: TidyFn<T, OutputT> = (items: T[]) => items.map(mapFn);\n return _map;\n}\n","export type SingleOrArray<T> = T | T[];\n\n/**\n * Given an arg that may or may not be an array, make it an array if it isn't one.\n */\nexport function singleOrArray<T>(d: SingleOrArray<T> | null | undefined): T[] {\n return d == null ? [] : Array.isArray(d) ? d : [d];\n}\n","import { KeyOrFn, TidyFn } from './types';\nimport { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\n\n/**\n * Removes items with duplicate values for the specified keys.\n * If no keys provided, uses strict equality.\n *\n * @param keys Keys to compute distinct across\n */\nexport function distinct<T extends object>(\n keys?: SingleOrArray<KeyOrFn<T>> | null | undefined\n): TidyFn<T> {\n const _distinct: TidyFn<T> = (items: T[]): T[] => {\n keys = singleOrArray(keys);\n\n if (!keys.length) {\n // https://jsperf.com/unique-array-by-strict-equality\n const set = new Set<T>();\n for (const item of items) {\n set.add(item);\n }\n return Array.from(set);\n }\n\n // compare keys\n // https://jsperf.com/distinct-by-key\n // turns out nested Maps are faster than string keys. AND they support\n // and arbitrary value.\n const rootMap = new Map();\n const distinctItems: T[] = [];\n const lastKey = keys[keys.length - 1];\n for (const item of items) {\n let map = rootMap;\n let hasItem = false;\n\n // go through each key to find out if we have it\n for (const key of keys) {\n const mapItemKey =\n typeof key === 'function' ? key(item) : item[key as keyof T];\n // last key, check if we already added it\n if (key === lastKey) {\n hasItem = map.has(mapItemKey);\n if (!hasItem) {\n distinctItems.push(item);\n map.set(mapItemKey, true);\n }\n break;\n }\n\n // create maps all the way down\n if (!map.has(mapItemKey)) {\n map.set(mapItemKey, new Map());\n }\n\n // move to next inner map\n map = map.get(mapItemKey);\n }\n }\n\n return distinctItems;\n };\n\n return _distinct;\n}\n","import { ascending } from 'd3-array';\nimport { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\nimport { Comparator, Key, KeyOrFn, TidyFn } from './types';\n\n/**\n * Sorts items\n * @param comparators Given a, b return -1 if a comes before b, 0 if equal, 1 if after\n */\nexport function arrange<T extends object>(\n // note: had to switch to returning `any` instead of using Comparator<T> (returns number)\n // for #49 - otherwise typescript failed to do type inference on accessors\n comparators: SingleOrArray<Key | ((a: T, b: T) => any)>\n): TidyFn<T> {\n const _arrange: TidyFn<T> = (items: T[]): T[] => {\n // expand strings `key` to `asc(key)`\n const comparatorFns = singleOrArray(comparators).map((comp) =>\n typeof comp === 'function'\n ? // length === 1 means it is an accessor (1 argument). convert to comparator via asc\n comp.length === 1\n ? asc(comp as (d: T) => unknown)\n : (comp as Comparator<T>)\n : asc<T>(comp)\n );\n\n return items.slice().sort((a, b) => {\n for (const comparator of comparatorFns) {\n const result = comparator(a, b);\n if (result) return result;\n }\n\n return 0;\n });\n };\n\n return _arrange;\n}\n\n/**\n * Creates an ascending comparator based on a key\n * @param key property key of T\n */\nexport function asc<T>(key: Key | ((d: T) => any)): Comparator<T> {\n const keyFn = typeof key === 'function' ? key : (d: any) => d[key];\n\n return function _asc(a: T, b: T) {\n return emptyAwareComparator(keyFn(a), keyFn(b), false);\n };\n}\n\n/**\n * Creates a descending comparator based on a key\n * @param key property key of T\n */\nexport function desc<T>(key: Key | ((d: T) => any)): Comparator<T> {\n const keyFn = typeof key === 'function' ? key : (d: any) => d[key];\n return function _desc(a: T, b: T) {\n return emptyAwareComparator(keyFn(a), keyFn(b), true);\n };\n}\n\n/**\n * Creates a comparator that sorts values based on a key\n * and a supplied array of the desired order for the values.\n * Items not found in the array will be sorted last.\n * @param order array of desired sort order\n */\nexport function fixedOrder<T>(\n key: KeyOrFn<T>,\n order: Array<T[keyof T]>,\n options?: { position?: 'start' | 'end' }\n): (a: T, b: T) => number {\n let { position = 'start' } = options ?? {};\n const positionFactor = position === 'end' ? -1 : 1;\n\n const indexMap = new Map();\n for (let i = 0; i < order.length; ++i) {\n indexMap.set(order[i], i);\n }\n\n const keyFn =\n typeof key === 'function'\n ? key\n : (d: T) => (d[key as keyof T] as unknown) as any;\n\n return function _fixedOrder(a: T, b: T) {\n const aIndex: number = indexMap.get(keyFn(a)) ?? -1;\n const bIndex: number = indexMap.get(keyFn(b)) ?? -1;\n\n if (aIndex >= 0 && bIndex >= 0) {\n return aIndex - bIndex;\n }\n\n if (aIndex >= 0) {\n return positionFactor * -1;\n }\n\n if (bIndex >= 0) {\n return positionFactor * 1;\n }\n\n return 0;\n };\n}\n\nfunction emptyAwareComparator(aInput: any, bInput: any, desc: boolean) {\n // we swap order to get descending behavior\n let a = desc ? bInput : aInput;\n let b = desc ? aInput : bInput;\n\n // NaN, null, undefined is the order for emptys\n if (isEmpty(a) && isEmpty(b)) {\n const rankA = a !== a ? 0 : a === null ? 1 : 2;\n const rankB = b !== b ? 0 : b === null ? 1 : 2;\n const order = rankA - rankB;\n return desc ? -order : order;\n }\n\n // keep empty values at the bottom\n if (isEmpty(a)) {\n return desc ? -1 : 1;\n }\n if (isEmpty(b)) {\n return desc ? 1 : -1;\n }\n\n // descending is handled by swapping the a and b args at the start\n return ascending(a, b);\n}\n\nfunction isEmpty(value: any) {\n return value == null || value !== value /* NaN check */;\n}\n","import { A } from 'ts-toolbelt';\nimport { singleOrArray } from './helpers/singleOrArray';\nimport { Key, TidyFn, Vector } from './types';\n\nexport type SummarizeSpec<T> = Record<Key, (items: T[]) => any>;\n\nexport interface SummarizeOptions<T = any> {\n rest?: (key: keyof T) => (items: T[]) => any;\n}\n\ntype SummarizedT<\n T extends object,\n SumSpec extends SummarizeSpec<T>,\n Options extends SummarizeOptions<T> | undefined\n> = {\n // summarized values map to return type of the spec functions\n [K in keyof SumSpec]: ReturnType<SumSpec[K]>;\n} & // if there is a 'rest' option, add in the other values from T\n (NonNullable<Options>['rest'] extends Function\n ? Exclude<T, keyof SumSpec>\n : void);\n\n/**\n * summarizes items\n */\nexport function summarize<\n T extends object,\n SummarizedSpec extends SummarizeSpec<T> = SummarizeSpec<T>,\n Options extends SummarizeOptions<T> = SummarizeOptions<T>\n>(\n summarizeSpec: SummarizedSpec,\n options?: Options\n): TidyFn<T, A.Compute<SummarizedT<T, SummarizedSpec, Options>>> {\n type Output = SummarizedT<T, SummarizedSpec, Options>;\n\n const _summarize: TidyFn<T, A.Compute<Output>> = (\n items: T[]\n ): A.Compute<Output>[] => {\n options = options ?? ({} as Options);\n\n // reduce but use a loop to be more readable\n const summarized = {} as Output;\n const keys = Object.keys(summarizeSpec) as (keyof SummarizedSpec)[];\n\n for (const key of keys) {\n summarized[key as keyof Output] = summarizeSpec[key](items);\n }\n\n // if we a function to apply to the rest of the keys is supplied, use it\n // TODO: improve types for rest\n if (options.rest && items.length) {\n const objectKeys = Object.keys(items[0]) as (keyof T)[];\n for (const objKey of objectKeys) {\n if (keys.includes(objKey as any)) {\n continue;\n }\n\n (summarized as any)[objKey] = options.rest(objKey)(items);\n }\n }\n\n return [summarized] as A.Compute<Output>[];\n };\n\n return _summarize;\n}\n\n/*-------- summarize helpers ----------------------------------------*/\n\nexport type SummaryKeyFn<T, K = keyof T> = (key: K) => (items: T[]) => any;\n\nfunction _summarizeHelper<\n T extends object,\n SummarizedT extends object = { [K in keyof T]: any }\n>(\n items: T[],\n summaryFn: SummaryKeyFn<T>,\n predicateFn?: (vector: Vector<T>) => boolean,\n keys?: Array<keyof T | ((items: T[]) => (keyof T)[])>\n): SummarizedT[] {\n if (!items.length) return [];\n\n // reduce but use a loop to be more readable\n const summarized = {} as SummarizedT;\n\n // read in keys from first object if not provided\n let keysArr: (keyof T)[];\n if (keys == null) {\n keysArr = Object.keys(items[0]) as (keyof T)[];\n } else {\n // expand them all to a flat list of keys\n keysArr = [];\n for (const keyInput of singleOrArray(keys as any)) {\n if (typeof keyInput === 'function') {\n keysArr.push(...(keyInput(items) as (keyof T)[]));\n } else {\n keysArr.push(keyInput);\n }\n }\n }\n\n for (const key of keysArr) {\n if (predicateFn) {\n // inefficient to compute this vector here, wonder if it should\n // be computed prior to this func being called somehow? (TODO)\n const vector = items.map((d) => d[key]);\n if (!predicateFn(vector)) {\n continue;\n }\n }\n summarized[(key as unknown) as keyof SummarizedT] = summaryFn(key)(\n items\n ) as any;\n }\n\n return [summarized];\n}\n\n/*---- summarizeAll() --------------------------------------------*/\n\ntype SummaryFnOutput<T extends object, F extends SummaryKeyFn<T>> = ReturnType<\n ReturnType<F>\n>;\n\nexport function summarizeAll<T extends object, F extends SummaryKeyFn<T>>(\n summaryFn: F\n): TidyFn<T, A.Compute<Record<keyof T, SummaryFnOutput<T, F>>>> {\n const _summarizeAll: TidyFn<\n T,\n A.Compute<Record<keyof T, SummaryFnOutput<T, F>>>\n > = (items: T[]): A.Compute<Record<keyof T, SummaryFnOutput<T, F>>>[] =>\n _summarizeHelper(items, summaryFn);\n\n return _summarizeAll;\n}\n\n/*---- summarizeIf() --------------------------------------------*/\n// type is not perfect since it returns all keys of T, but better to have more than less I figure\nexport function summarizeIf<T extends object, F extends SummaryKeyFn<T>>(\n predicateFn: (vector: Vector<T>) => boolean,\n summaryFn: F\n): TidyFn<T, A.Compute<Record<keyof T, SummaryFnOutput<T, F>>>> {\n const _summarizeIf: TidyFn<\n T,\n A.Compute<Record<keyof T, SummaryFnOutput<T, F>>>\n > = (items: T[]): A.Compute<Record<keyof T, SummaryFnOutput<T, F>>>[] =>\n _summarizeHelper(items, summaryFn, predicateFn);\n\n return _summarizeIf;\n}\n\n/*---- summarizeAt() --------------------------------------------*/\nexport function summarizeAt<\n T extends object,\n Keys extends (keyof T)[],\n F extends SummaryKeyFn<T, Keys[number]>\n>(\n keys: Keys,\n summaryFn: F\n): TidyFn<T, A.Compute<Record<Keys[number], SummaryFnOutput<T, F>>>> {\n const _summarizeAt: TidyFn<\n T,\n A.Compute<Record<Keys[number], SummaryFnOutput<T, F>>>\n > = (items: T[]): A.Compute<Record<Keys[number], SummaryFnOutput<T, F>>>[] =>\n _summarizeHelper(items, summaryFn, undefined, keys);\n\n return _summarizeAt;\n}\n","import { TidyFn, NonFunctionValue, Key } from './types';\nimport { A } from 'ts-toolbelt';\n\ntype MutateSpecValue<T, O = any> =\n | ((item: T, index: number, array: Iterable<T>) => O)\n | NonFunctionValue;\nexport type MutateSpec<T> = Record<Key, MutateSpecValue<T>>;\nexport type ResolvedObj<Obj extends Record<Key, MutateSpecValue<any>>> = {\n [K in keyof Obj]: Obj[K] extends (...args: any) => any\n ? ReturnType<Obj[K]> extends any[]\n ? ReturnType<Obj[K]>[number]\n : ReturnType<Obj[K]>\n : Obj[K];\n};\n\ntype Mutated<T, MSpec extends MutateSpec<T>> = T & ResolvedObj<MSpec>;\n\ntype Compute<T> = A.Compute<T>;\n\n/**\n * Mutates items, one item at a time. For mutating across multiple items,\n * use mutateWithSummary.\n * @param mutateSpec\n */\nexport function mutate<T extends object, MSpec extends MutateSpec<T>>(\n mutateSpec: MSpec\n): TidyFn<T, Compute<Mutated<T, MSpec>>> {\n type MutatedT = Mutated<T, MSpec>;\n // use Compute for better intellisense (reveals all keys in obj)\n const _mutate: TidyFn<T, Compute<MutatedT>> = (\n items: T[]\n ): Compute<MutatedT>[] => {\n // create the base items to merge mutated values into\n // note we start with the original array so when we pass it as the third argument\n // to a mutate function, you get the values that have been changed so far\n const mutatedItems: MutatedT[] = items.map((d) => ({ ...d })) as MutatedT[];\n\n // we can update each item completely one at a time, since mutate doesn't\n // support looking across items. Use mutateWithSummary for that.\n let i = 0;\n for (const mutatedItem of mutatedItems) {\n for (const key in mutateSpec) {\n // get the mutated value for this item (either run the fn or use the constant)\n const mutateSpecValue = mutateSpec[key];\n const mutatedResult =\n typeof mutateSpecValue === 'function'\n ? mutateSpecValue(mutatedItem, i, mutatedItems)\n : mutateSpecValue;\n\n mutatedItem[key as keyof MutatedT] = mutatedResult;\n }\n\n ++i;\n }\n\n return mutatedItems as Compute<MutatedT>[];\n };\n\n return _mutate;\n}\n","import { mutate, MutateSpec } from './mutate';\nimport {\n SummarizeSpec,\n summarize,\n summarizeAll,\n summarizeAt,\n summarizeIf,\n SummaryKeyFn,\n} from './summarize';\nimport { TidyFn, Vector } from './types';\n\n/**\n * Adds a summarized total row\n */\nexport function total<\n T extends object,\n SummarizedSpec extends SummarizeSpec<T> = SummarizeSpec<T>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(summarizeSpec: SummarizedSpec, mutateSpec: MutSpec): TidyFn<T> {\n const _total: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarize<T, SummarizedSpec>(summarizeSpec)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]);\n return [...items, ...mutated];\n };\n\n return _total;\n}\n\n// ----------------------------------------------------------------------------\n\n/**\n * Adds a summarized total row\n */\nexport function totalAll<\n T extends object,\n F extends SummaryKeyFn<T>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(summaryFn: F, mutateSpec: MutSpec): TidyFn<T> {\n const _totalAll: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarizeAll<T, F>(summaryFn)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]);\n return [...items, ...mutated];\n };\n\n return _totalAll;\n}\n\n// ----------------------------------------------------------------------------\n\n/**\n * Adds a summarized total row\n */\nexport function totalIf<\n T extends object,\n F extends SummaryKeyFn<T>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(\n predicateFn: (vector: Vector<T>) => boolean,\n summaryFn: F,\n mutateSpec: MutSpec\n): TidyFn<T> {\n const _totalIf: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarizeIf<T, F>(predicateFn, summaryFn)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]);\n return [...items, ...mutated];\n };\n\n return _totalIf;\n}\n\n// ----------------------------------------------------------------------------\n\n/**\n * Adds a summarized total row\n */\nexport function totalAt<\n T extends object,\n Keys extends (keyof T)[],\n F extends SummaryKeyFn<T, Keys[number]>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(keys: Keys, summaryFn: F, mutateSpec: MutSpec): TidyFn<T> {\n const _totalAt: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarizeAt<T, Keys, F>(keys, summaryFn)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]);\n return [...items, ...mutated];\n };\n\n return _totalAt;\n}\n","import { GroupKey } from '../types';\n\n/**\n * Given an object and a set of group keys [[keyName, keyValue], ...]\n * set the keys as properties within the object: { [keyName]: keyValue, ... }\n * (creates a new object with these properties added)\n */\nexport function assignGroupKeys<T extends object>(d: T, keys: GroupKey[]) {\n // abort if atypical input\n if (d == null || typeof d !== 'object' || Array.isArray(d)) return d;\n\n // transform to { groupKey1: value, ... } excluding function group keys\n const keysObj = Object.fromEntries(\n keys.filter((key) => typeof key[0] !== 'function')\n );\n\n return Object.assign(keysObj, d);\n}\n","import { Grouped, Datum } from '../types';\n\n/**\n * Traverse the leaves of the grouped items and and run the\n * groupFn on them. Basically an in-order traversal. Can you\n * believe this is real and not part of a coding interview??\n */\nexport function groupTraversal<\n T extends object,\n T2 extends Datum = T,\n OutputType = Grouped<T2>\n>(\n grouped: Grouped<T>,\n outputGrouped: OutputType,\n keys: any[],\n addSubgroup: (root: OutputType, keys: any[], level: number) => OutputType,\n addLeaves: (root: OutputType, keys: any[], items: T[], level: number) => void,\n level: number = 0\n) {\n for (const [key, value] of grouped.entries()) {\n const keysHere = [...keys, key];\n\n // internal node\n if (value instanceof Map) {\n const subgroup = addSubgroup(outputGrouped, keysHere, level);\n\n // recurse\n groupTraversal(\n value,\n subgroup,\n keysHere,\n addSubgroup,\n addLeaves,\n level + 1\n );\n } else {\n // leaf\n addLeaves(outputGrouped, keysHere, value, level);\n }\n }\n\n return outputGrouped;\n}\n","import { Grouped } from '../types';\nimport { groupTraversal } from './groupTraversal';\n\nexport function groupMap<T extends object, OutputT extends object = T>(\n grouped: Grouped<T>,\n groupFn: (items: T[], keys: any[]) => OutputT[],\n keyFn: (keys: any[]) => any = (keys) =>\n keys[\n keys.length - 1\n ] /* optional func to transform key based on all keys in map so far */\n): Grouped<OutputT> {\n function addSubgroup(parentGrouped: Grouped<OutputT>, keys: any[]) {\n const subgroup = new Map();\n parentGrouped.set(keyFn(keys), subgroup);\n return subgroup;\n }\n\n function addLeaves(\n parentGrouped: Grouped<OutputT>,\n keys: any[],\n values: T[]\n ) {\n parentGrouped.set(keyFn(keys), groupFn(values, keys));\n }\n\n const outputGrouped: Grouped<OutputT> = new Map();\n\n groupTraversal(grouped, outputGrouped, [], addSubgroup, addLeaves);\n\n return outputGrouped;\n}\n","export const identity = <T>(d: T): T => d;\n","/**\n * Returns true if input is an object\n */\nexport function isObject(obj: any) {\n const type = typeof obj;\n return obj != null && (type === 'object' || type === 'function');\n}\n","import { group } from 'd3-array';\nimport { A, O } from 'ts-toolbelt';\nimport { assignGroupKeys } from './helpers/assignGroupKeys';\nimport { groupMap } from './helpers/groupMap';\nimport { groupTraversal } from './helpers/groupTraversal';\nimport { identity } from './helpers/identity';\nimport { isObject } from './helpers/isObject';\nimport { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\nimport { Grouped, GroupKey, TidyGroupExportFn, Key, TidyFn } from './types';\n\n/** [key, values] where values could be more nested entries */\ntype EntriesOutput = [any, any][];\ntype EntriesObjectOutput = { key: Key; values: any }[];\n\n/** nested objects: { [key]: values } */\ntype ObjectOutput = Record<Key, any>;\n\n/** nested keys: e.g. [key, key, key, [key, key, [key]]] */\ntype KeysOutput = any[];\n\n/** nested values: e.g. [[value1_1, value1_2], [value2_1, value2_2]] */\ntype ValuesOutput = any[];\n\nexport type LevelSpec = {\n id?: string;\n createEmptySubgroup: () => any;\n addSubgroup: (\n parentGrouped: any,\n newSubgroup: any,\n key: any,\n level: number\n ) => void;\n addLeaf: (parentGrouped: any, key: any, values: any[], level: number) => void;\n};\n\n/**\n * Options to affect export type\n */\ninterface GroupByOptions {\n /** whether to merge group keys back into the objects */\n readonly addGroupKeys?: boolean;\n\n // -- export related -- //\n /** export method */\n readonly export?:\n | 'grouped'\n | 'entries'\n | 'entries-object'\n | 'object'\n | 'map'\n | 'keys'\n | 'values'\n | 'levels'\n | 'ungrouped';\n /** if all nested levels should be brought to a single top level */\n readonly flat?: boolean;\n /** when flat is true, how to flatten nested keys */\n readonly compositeKey?: (keys: any[]) => string;\n /** whether the leaf sets consist of just one item (typical after summarize).\n * if true, uses the first element in the leaf set instead of an array\n */\n readonly single?: boolean;\n /** operation called on each leaf during export to map it to a different value\n * (default: identity)\n */\n readonly mapLeaf?: (value: any) => any;\n /** operation called on each leaf set to map the array of values to a different value.\n * Similar to `rollup` from d3-collection nest or d3-array\n * (default: identity)\n */\n readonly mapLeaves?: (values: any[]) => any;\n /** [entries only] operation called on entries to map from [key, values] to\n * whatever the output of this is (e.g. `{ key, values }`)\n * (default: identity)\n */\n readonly mapEntry?: (entry: [any, any], level: number) => any;\n\n /** [required for levels] specifies the export operation for each level of the grouping */\n readonly levels?: (\n | 'entries'\n | 'entries-object'\n | 'object'\n | 'map'\n | 'keys'\n | 'values'\n | LevelSpec\n )[];\n}\n\n// aliases to make overloads shorter\ntype GK<T extends object> = SingleOrArray<keyof T | ((d: T) => any)>;\ntype F<I extends object, O extends object> = TidyFn<I, O>;\n\n// merge back in group keys to output types\ntype MergeGroupKeys<\n T extends object,\n Out extends object,\n Keys extends GK<T>\n> = Keys extends keyof T\n ? O.Merge<Pick<T, Keys>, Out>\n : Keys extends (keyof T)[]\n ? O.Merge<Pick<T, Keys[number]>, Out>\n : Out;\n\n// do not merge in group keys if explicitly said not to\ntype WithGroupKeys<\n T extends object,\n Out extends object,\n Keys extends GK<T>,\n Opts extends GroupByOptions | undefined\n> = NonNullable<Opts>['addGroupKeys'] extends false\n ? Out\n : MergeGroupKeys<T, Out, Keys>;\n\n/**\n * output varies based on export options\n */\ntype GroupByOutput<\n T extends object,\n O extends object,\n Keys extends GK<T>,\n Opts extends GroupByOptions | undefined\n> = A.Compute<\n NonNullable<Opts>['export'] extends 'grouped'\n ? Grouped<WithGroupKeys<T, O, Keys, Opts>>\n : NonNullable<Opts>['export'] extends 'entries'\n ? EntriesOutput\n : NonNullable<Opts>['export'] extends 'entries-object'\n ? EntriesObjectOutput\n : NonNullable<Opts>['export'] extends 'object'\n ? ObjectOutput\n : NonNullable<Opts>['export'] extends 'map'\n ? Map<any, any>\n : NonNullable<Opts>['export'] extends 'keys'\n ? KeysOutput\n : NonNullable<Opts>['export'] extends 'values'\n ? ValuesOutput\n : NonNullable<Opts>['export'] extends 'levels'\n ? any\n : WithGroupKeys<T, O, Keys, Opts>[]\n>;\n\ntype GroupByFn<\n T extends object,\n O extends object,\n Keys extends GK<T>,\n Opts extends GroupByOptions\n> = Opts['export'] extends\n | 'grouped'\n | 'entries'\n | 'entries-object'\n | 'object'\n | 'map'\n | 'keys'\n | 'values'\n | 'levels'\n ? TidyGroupExportFn<T, GroupByOutput<T, O, Keys, Opts>>\n : // default is no export, ungrouped and back in simple form\n TidyFn<T, WithGroupKeys<T, O, Keys, Opts>>;\n\n/**\n * Nests the data by the specified groupings\n */\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: F<T, T1>, options?: Opts): GroupByFn<T, T1, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>, F<T5, T6>, F<T6, T7>], options?: Opts): GroupByFn<T, T7, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>, F<T5, T6>], options?: Opts): GroupByFn<T, T6, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>], options?: Opts): GroupByFn<T, T5, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>], options?: Opts): GroupByFn<T, T4, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>], options?: Opts): GroupByFn<T, T3, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>], options?: Opts): GroupByFn<T, T2, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>], options?: Opts): GroupByFn<T, T1, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [], options?: Opts): GroupByFn<T, T, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, options?: Opts): GroupByFn<T, T, Keys, Opts>;\nexport function groupBy<\n T extends object,\n O extends object,\n Keys extends GK<T>,\n Opts extends GroupByOptions\n>(\n groupKeys: Keys,\n fns: TidyFn<any, any>[] | TidyFn<any, any>,\n options?: Opts\n): GroupByFn<T, O, Keys, Opts> {\n if (typeof fns === 'function') {\n fns = [fns];\n } else if (arguments.length === 2 && fns != null && !Array.isArray(fns)) {\n options = fns as any;\n }\n\n const _groupBy: GroupByFn<T, O, Keys, Opts> = ((items: T[]) => {\n // form into a nested map\n const grouped = makeGrouped(items, groupKeys);\n\n // run group functions\n const results = runFlow(\n grouped,\n fns as TidyFn<any, any>[],\n options?.addGroupKeys\n );\n\n // export\n if (options?.export) {\n switch (options.export) {\n case 'grouped':\n return results;\n case 'levels':\n return exportLevels(results, options);\n case 'entries-obj' as any:\n case 'entriesObject' as any:\n return exportLevels(results, {\n ...options,\n export: 'levels',\n levels: ['entries-object'],\n });\n default:\n return exportLevels(results, {\n ...options,\n export: 'levels',\n levels: [options.export],\n });\n }\n }\n\n // export === 'ungrouped' or nully:\n const ungrouped = ungroup(results, options?.addGroupKeys);\n return ungrouped as any;\n }) as GroupByFn<T, O, Keys, Opts>;\n // (_groupBy as any).tidyType = 'group-export';\n\n return _groupBy;\n}\n// convenient export option configs\ngroupBy.grouped = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'grouped' } as const);\ngroupBy.entries = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'entries' } as const);\ngroupBy.entriesObject = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'entries-object' } as const);\ngroupBy.object = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'object' } as const);\ngroupBy.map = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'map' } as const);\ngroupBy.keys = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'keys' } as const);\ngroupBy.values = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'values' } as const);\ngroupBy.levels = (options?: Omit<GroupByOptions, 'export'>) =>\n ({ ...options, export: 'levels' } as const);\n\nfunction runFlow<T extends object>(\n items: Grouped<T>,\n fns?: TidyFn<any, any>[],\n addGroupKeys?: boolean\n) {\n let result: any = items;\n if (!fns?.length) return result;\n\n for (const fn of fns) {\n if (!fn) continue;\n\n // otherwise break it up and call it on each leaf set\n result = groupMap(result, (items, keys) => {\n // ensure we kept the group keys in the object\n // (necessary for e.g. summarize which may remove them)\n const context = { groupKeys: keys };\n let leafItemsMapped = fn(items, context);\n if (addGroupKeys !== false) {\n leafItemsMapped = leafItemsMapped.map((item: T) =>\n assignGroupKeys(item, keys)\n );\n }\n\n return leafItemsMapped;\n });\n }\n\n return result;\n}\n\nfunction makeGrouped<T extends object>(\n items: T[],\n groupKeys: SingleOrArray<keyof T | ((d: T) => any)>\n): Grouped<T> {\n // convert string based keys to functions and keep the key name with the key value in a tuple\n const groupKeyFns = singleOrArray(groupKeys).map((key, i) => {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n // use a cache so we don't generate new keys for the same tuple\n const keyCache = new Map();\n return (d: T) => {\n const keyValue = keyFn(d);\n\n const keyValueOf = isObject(keyValue) ? keyValue.valueOf() : keyValue;\n // used cache tuple if available\n if (keyCache.has(keyValueOf)) {\n return keyCache.get(keyValueOf) as GroupKey;\n }\n\n const keyWithName = [key, keyValue];\n keyCache.set(keyValueOf, keyWithName);\n\n return keyWithName;\n };\n });\n\n const grouped = group(items, ...groupKeyFns);\n return grouped;\n}\n\n/**\n * flattens a grouped collection back to a simple array\n */\nfunction ungroup<T extends object>(\n grouped: Grouped<T>,\n addGroupKeys: boolean | undefined\n): T[] {\n // flatten the groups\n const items: T[] = [];\n\n groupTraversal(grouped, items, [], identity, (root, keys, values) => {\n // ensure we have group keys on items (in case runFlow didn't run)\n let valuesToAdd = values;\n if (addGroupKeys !== false) {\n valuesToAdd = values.map((d) => assignGroupKeys(d, keys));\n }\n root.push(...valuesToAdd);\n });\n\n return items;\n}\n\n// -----------------------------------------------------------------------\n// --- EXPORTS -----------------------------------------------------------\n// -----------------------------------------------------------------------\nconst defaultCompositeKey = (keys: any[]) => keys.join('/');\n\nfunction processFromGroupsOptions<T extends object>(options: GroupByOptions) {\n const {\n flat,\n single,\n mapLeaf = identity,\n mapLeaves = identity,\n addGroupKeys,\n } = options;\n let compositeKey: (keys: any[]) => string;\n if (options.flat) {\n compositeKey = options.compositeKey! ?? defaultCompositeKey;\n }\n\n const groupFn = (values: T[], keys: any[]) => {\n return single\n ? mapLeaf(\n addGroupKeys === false ? values[0] : assignGroupKeys(values[0], keys)\n )\n : mapLeaves(\n values.map((d) =>\n mapLeaf(addGroupKeys === false ? d : assignGroupKeys(d, keys))\n )\n );\n };\n\n const keyFn = flat\n ? (keys: GroupKey[]) => compositeKey(keys.map((d) => d[1]))\n : (keys: GroupKey[]) => keys[keys.length - 1][1];\n\n return { groupFn, keyFn };\n}\n\n// -- Levels -------------------------------------------------------------\nfunction exportLevels<T extends object>(\n grouped: Grouped<T>,\n options: GroupByOptions\n): any {\n type NestedEntries<T> = Array<[any, NestedEntries<T> | T[]]>;\n type NestedObject<T> = { [key: string]: NestedObject<T> | T[] };\n\n const { groupFn, keyFn } = processFromGroupsOptions(options);\n let { mapEntry = identity } = options;\n const { levels = ['entries'] } = options;\n\n const levelSpecs: LevelSpec[] = [];\n for (const levelOption of levels) {\n switch (levelOption) {\n // entries / entries-object -----------------------------------------\n case 'entries':\n case 'entries-object':\n case 'entries-obj' as any:\n case 'entriesObject' as any: {\n const levelMapEntry =\n (levelOption === 'entries-object' ||\n levelOption === ('entries-obj' as any) ||\n levelOption === ('entriesObject' as any)) &&\n options.mapEntry == null\n ? ([key, values]: any) => ({ key, values })\n : mapEntry;\n\n levelSpecs.push({\n id: 'entries',\n createEmptySubgroup: () => [],\n addSubgroup: (\n parentGrouped: NestedEntries<T>,\n newSubgroup: any,\n key: any,\n level: number\n ) => {\n parentGrouped.push(levelMapEntry([key, newSubgroup], level));\n },\n\n addLeaf: (\n parentGrouped: NestedEntries<T>,\n key: any,\n values: T[],\n level: number\n ) => {\n parentGrouped.push(levelMapEntry([key, values], level));\n },\n });\n break;\n }\n // map -------------------------------------------------------------\n case 'map':\n levelSpecs.push({\n id: 'map',\n createEmptySubgroup: () => new Map(),\n addSubgroup: (\n parentGrouped: Map<any, any>,\n newSubgroup: any,\n key: any\n ) => {\n parentGrouped.set(key, newSubgroup);\n },\n\n addLeaf: (parentGrouped: Map<any, any>, key: any, values: T[]) => {\n parentGrouped.set(key, values);\n },\n });\n break;\n\n // object ----------------------------------------------------------\n case 'object':\n levelSpecs.push({\n id: 'object',\n createEmptySubgroup: () => ({}),\n addSubgroup: (\n parentGrouped: NestedObject<T>,\n newSubgroup: any,\n key: any\n ) => {\n parentGrouped[key] = newSubgroup;\n },\n\n addLeaf: (parentGrouped: NestedObject<T>, key: any, values: T[]) => {\n parentGrouped[key] = values;\n },\n });\n break;\n\n // keys ------------------------------------------------------------\n case 'keys':\n levelSpecs.push({\n id: 'keys',\n createEmptySubgroup: () => [],\n addSubgroup: (parentGrouped: any, newSubgroup: any, key: any) => {\n parentGrouped.push([key, newSubgroup]);\n },\n\n addLeaf: (parentGrouped: any, key: any) => {\n parentGrouped.push(key);\n },\n });\n break;\n\n // values ----------------------------------------------------------\n case 'values':\n levelSpecs.push({\n id: 'values',\n createEmptySubgroup: () => [],\n addSubgroup: (parentGrouped: any, newSubgroup: any) => {\n parentGrouped.push(newSubgroup);\n },\n\n addLeaf: (parentGrouped: any, key: any, values: T[]) => {\n parentGrouped.push(values);\n },\n });\n break;\n\n // custom ----------------------------------------------------------\n default: {\n // LevelSpec obj already\n if (typeof levelOption === 'object') {\n levelSpecs.push(levelOption);\n }\n }\n }\n }\n\n // add subgroup\n const addSubgroup = (parentGrouped: any, keys: any[], level: number): any => {\n if (options.flat) {\n return parentGrouped;\n }\n\n const levelSpec = levelSpecs[level] ?? levelSpecs[levelSpecs.length - 1];\n const nextLevelSpec = levelSpecs[level + 1] ?? levelSpec;\n const newSubgroup = nextLevelSpec.createEmptySubgroup();\n levelSpec!.addSubgroup(parentGrouped, newSubgroup, keyFn(keys), level);\n return newSubgroup;\n };\n\n // add leaves\n const addLeaf = (\n parentGrouped: any,\n keys: any[],\n values: T[],\n level: number\n ) => {\n const levelSpec = levelSpecs[level] ?? levelSpecs[levelSpecs.length - 1];\n levelSpec!.addLeaf(\n parentGrouped,\n keyFn(keys),\n groupFn(values, keys),\n level\n );\n };\n\n const initialOutputObject = levelSpecs[0]!.createEmptySubgroup();\n return groupTraversal(grouped, initialOutputObject, [], addSubgroup, addLeaf);\n}\n","type NOptions<T> = {\n predicate?: (d: T, index: number, array: Iterable<T>) => boolean;\n};\n\n/**\n * Returns a function that computes the count over an array of items\n */\nexport function n<T>(options?: NOptions<T>) {\n if (options?.predicate) {\n const predicate = options.predicate;\n return (items: T[]) =>\n items.reduce((n, d, i) => (predicate(d, i, items) ? n + 1 : n), 0);\n }\n\n return (items: T[]) => items.length;\n}\n","import { fsum } from 'd3-array';\n\ntype SumOptions<T> = {\n predicate?: (d: T, index: number, array: Iterable<T>) => boolean;\n};\n\n/**\n * Returns a function that computes the sum over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function sum<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => number),\n options?: SumOptions<T>\n) {\n let keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n if (options?.predicate) {\n const originalKeyFn = keyFn;\n const predicate = options.predicate;\n keyFn = (d: T, index: number, array: Iterable<T>) =>\n predicate(d, index, array) ? originalKeyFn(d, index, array) : 0;\n }\n\n return (items: T[]) => fsum(items, keyFn);\n}\n","import { summarize } from './summarize';\nimport { n } from './summary/n';\nimport { sum } from './summary/sum';\nimport { TidyFn } from './types';\n\ntype TallyOptions = {\n readonly name?: string;\n readonly wt?: string;\n};\n\ntype TallyOutput<Options extends TallyOptions> = Options['name'] extends string\n ? { [K in Options['name']]: number }\n : { n: number };\n\nexport function tally<T extends object, Options extends TallyOptions>(\n options?: Options\n): TidyFn<T, TallyOutput<Options>> {\n const _tally: TidyFn<T, TallyOutput<Options>> = (\n items: T[]\n ): TallyOutput<Options>[] => {\n const { name = 'n', wt } = options ?? {};\n\n const summarized = summarize({ [name]: wt == null ? n() : sum(wt as any) })(\n items\n );\n return summarized as TallyOutput<Options>[];\n };\n\n return _tally;\n}\n","import { arrange, desc } from './arrange';\nimport { groupBy } from './groupBy';\nimport { identity } from './helpers/identity';\nimport { SingleOrArray } from './helpers/singleOrArray';\nimport { tally } from './tally';\nimport { tidy } from './tidy';\nimport { KeyOrFn } from './types';\n\ntype CountOptions = {\n name?: string;\n sort?: boolean;\n wt?: string;\n};\n\n/**\n * Tallies the number distinct values for the specified keys and adds\n * the count as a new key (default `n`). Optionally sorts by the count.\n */\nexport function count<T extends object, Keys extends SingleOrArray<KeyOrFn<T>>>(\n groupKeys: Keys,\n options?: CountOptions | null | undefined\n) {\n const _count = (items: T[]) => {\n options = options ?? {};\n const { name = 'n', sort } = options;\n\n const results = tidy(\n items,\n groupBy(groupKeys, [tally(options)]),\n sort ? arrange(desc(name)) : identity\n );\n\n return results;\n };\n\n return _count;\n}\n","import { O } from 'ts-toolbelt';\nimport { TidyFn } from './types';\n\ntype RenameSpec<T> = Partial<\n {\n [K in keyof T]: string;\n }\n>;\n\n// helper types\ntype OutputT<T extends object, Spec extends RenameSpec<T>> = O.Merge<\n Omit<T, keyof Spec>,\n {\n [NewKey in Exclude<Spec[keyof Spec], undefined>]: T[O.SelectKeys<\n Spec,\n NewKey\n >];\n }\n>;\n\n/**\n * Renames properties/columns in collection\n *\n * @param renameSpec Mapping of current name to new name { currKey: newKey }\n */\nexport function rename<T extends object, Spec extends RenameSpec<T>>(\n renameSpec: Spec\n): TidyFn<T, OutputT<T, Spec>> {\n type Output = OutputT<T, Spec>;\n const _rename: TidyFn<T, Output> = (items: T[]): Output[] => {\n return items.map((d) => {\n const mapped = {} as any;\n const keys = Object.keys(d) as (keyof T)[];\n for (const key of keys) {\n const newKey: keyof Output =\n ((renameSpec[key] as unknown) as keyof Output) ?? key;\n mapped[newKey] = d[key];\n }\n\n return mapped as Output;\n });\n };\n\n return _rename;\n}\n","import { shuffle } from 'd3-array';\nimport { arrange, desc } from './arrange';\nimport { SingleOrArray } from './helpers/singleOrArray';\nimport { Comparator, Key, TidyFn } from './types';\n\n/**\n * Truncates the array to the specified range\n */\nexport function slice<T extends object>(\n start: number,\n end?: number\n): TidyFn<T> {\n const _slice: TidyFn<T> = (items: T[]): T[] => items.slice(start, end);\n\n return _slice;\n}\n\n// -------------------------------------------------------------------\n/**\n * Truncates the array to the first N items\n */\nexport const sliceHead = <T extends object>(n: number) => slice<T>(0, n);\n\n// -------------------------------------------------------------------\n/**\n * Truncates the array to the last N items\n */\nexport const sliceTail = <T extends object>(n: number) => slice<T>(-n);\n\n// -------------------------------------------------------------------\n\n/**\n * Truncates the array to the first N items ordered by some key\n */\nexport function sliceMin<T extends object>(\n n: number,\n orderBy: SingleOrArray<Key | Comparator<T>>\n): TidyFn<T> {\n const _sliceMin: TidyFn<T> = (items: T[]): T[] =>\n arrange<T>(orderBy)(items).slice(0, n);\n\n return _sliceMin;\n}\n\n// -------------------------------------------------------------------\n\n/**\n * Truncates the array to the last N items ordered by some key\n */\nexport function sliceMax<T extends object>(\n n: number,\n orderBy: SingleOrArray<Key | Comparator<T>>\n): TidyFn<T> {\n // note: we use desc() so we get proper handling of nullish values\n // unless they provided an explicit comparator.\n const _sliceMax: TidyFn<T> = (items: T[]): T[] =>\n typeof orderBy === 'function'\n ? arrange<T>(orderBy)(items).slice(-n).reverse()\n : arrange<T>(desc(orderBy as any))(items).slice(0, n);\n\n return _sliceMax;\n}\n\n// -------------------------------------------------------------------\n\ntype SampleOptions = {\n replace?: boolean;\n};\n/**\n * Truncates the array to the last N items ordered by some key\n */\nexport function sliceSample<T extends object>(\n n: number,\n options?: SampleOptions | null | undefined\n): TidyFn<T> {\n options = options ?? {};\n const { replace } = options;\n\n const _sliceSample: TidyFn<T> = (items: T[]) => {\n if (!items.length) return items.slice();\n\n // sample items with replacement\n if (replace) {\n const sliced = [];\n for (let i = 0; i < n; ++i) {\n sliced.push(items[Math.floor(Math.random() * items.length)]);\n }\n return sliced;\n }\n\n // sample items without replacement\n return shuffle(items.slice()).slice(0, n);\n };\n\n return _sliceSample;\n}\n","import { O } from 'ts-toolbelt';\nimport { TidyFn, Datum } from './types';\n\ntype ByMap<JoinT extends Datum, T extends Datum> = Partial<\n Record<keyof JoinT, keyof T>\n>;\n\nexport type JoinOptions<JoinT extends Datum, T extends Datum> = {\n by?: keyof T | (keyof T)[] | ByMap<JoinT, T>;\n};\n\n/**\n * Compares first two sets of items to find overlapping keys\n * Naively looks at first element... could cause problems if first\n * elements don't have all keys, but scanning each entire set seems\n * unnecessarily slow for most cases.\n */\nexport function autodetectByMap<A, B>(itemsA: A[], itemsB: B[]) {\n if (itemsA.length === 0 || itemsB.length === 0) return {};\n\n // intersection of shared keys\n const keysA = Object.keys(itemsA[0]);\n const keysB = Object.keys(itemsB[0]);\n\n // naive linear intersection, but we don't expect objects to have tons of keys\n // so it's probably fine.\n const byMap: any = {};\n for (const key of keysA) {\n if (keysB.includes(key)) {\n byMap[key] = key;\n }\n }\n\n return byMap;\n}\n\n// convert by option in to a map from JoinT to T key\nexport function makeByMap<T extends Datum, JoinT extends Datum>(\n by: JoinOptions<JoinT, T>['by']\n): ByMap<JoinT, T> {\n // convert by option in to a map from JoinT to T key\n if (Array.isArray(by)) {\n const byMap: ByMap<JoinT, T> = {};\n for (const key of by) {\n byMap[key as any] = key;\n }\n return byMap;\n } else if (typeof by === 'object') {\n return by;\n }\n return { [by as keyof JoinT]: by as keyof T } as ByMap<JoinT, T>;\n}\n\nexport function isMatch<T extends object, JoinT extends object>(\n d: T,\n j: JoinT,\n byMap: ByMap<JoinT, T>\n) {\n for (const jKey in byMap) {\n const dKey = byMap[jKey];\n if ((d[dKey as keyof T] as any) !== j[jKey as keyof JoinT]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Performs an inner join on two collections\n * @param itemsToJoin The rows/items to be appended to end of collection\n */\nexport function innerJoin<T extends object, JoinT extends object>(\n itemsToJoin: JoinT[],\n options?: JoinOptions<JoinT, T> | null | undefined\n): TidyFn<T, O.Merge<T, JoinT>> {\n const _innerJoin: TidyFn<T, O.Merge<T, JoinT>> = (\n items: T[]\n ): O.Merge<T, JoinT>[] => {\n // convert by option in to a map from JoinT to T key\n const byMap =\n options?.by == null\n ? autodetectByMap(items, itemsToJoin)\n : makeByMap(options.by);\n\n const joined = items.flatMap((d: T) => {\n const matches = itemsToJoin.filter((j: JoinT) => isMatch(d, j, byMap));\n return matches.map((j: JoinT) => ({ ...d, ...j }));\n });\n\n return joined as O.Merge<T, JoinT>[];\n };\n return _innerJoin;\n}\n","import { Datum, TidyFn } from './types';\nimport { isMatch, makeByMap, autodetectByMap, JoinOptions } from './innerJoin';\nimport { O } from 'ts-toolbelt';\n\n/**\n * Performs a left join on two collections\n * @param itemsToJoin The rows/items to be appended to end of collection\n */\nexport function leftJoin<T extends Datum, JoinT extends Datum>(\n itemsToJoin: JoinT[],\n options?: JoinOptions<JoinT, T> | null | undefined\n): TidyFn<T, O.Merge<T, Partial<JoinT>>> {\n const _leftJoin: TidyFn<T, O.Merge<T, Partial<JoinT>>> = (\n items: T[]\n ): O.Merge<T, Partial<JoinT>>[] => {\n if (!itemsToJoin.length) return items as any;\n\n // convert by option in to a map from T key to JoinT key\n const byMap =\n options?.by == null\n ? autodetectByMap(items, itemsToJoin)\n : makeByMap(options.by);\n\n // when we miss a join, we want to explicitly add in undefined\n // so our rows all have the same keys. get those keys here.\n const joinObjectKeys = Object.keys(itemsToJoin[0]);\n\n const joined = items.flatMap((d: T) => {\n const matches = itemsToJoin.filter((j: JoinT) => isMatch(d, j, byMap));\n if (matches.length) {\n return matches.map((j: JoinT) => ({ ...d, ...j }));\n }\n\n // add in missing keys explicitly as undefined without\n // overriding existing values and while maintaining order\n // of keys\n const undefinedFill = Object.fromEntries(\n joinObjectKeys\n .filter((key) => d[key] == null)\n .map((key) => [key, undefined])\n );\n\n return { ...d, ...undefinedFill };\n });\n\n return joined;\n };\n return _leftJoin;\n}\n","import { Datum, TidyFn } from './types';\nimport { isMatch, makeByMap, autodetectByMap, JoinOptions } from './innerJoin';\nimport { O } from 'ts-toolbelt';\n\n/**\n * Performs a full join on two collections\n * @param itemsToJoin The rows/items to be appended to end of collection\n */\nexport function fullJoin<T extends Datum, JoinT extends Datum>(\n itemsToJoin: JoinT[],\n options?: JoinOptions<JoinT, T> | null | undefined\n): TidyFn<T, O.Merge<T, Partial<JoinT>>> {\n const _fullJoin: TidyFn<T, O.Merge<T, Partial<JoinT>>> = (\n items: T[]\n ): O.Merge<T, Partial<JoinT>>[] => {\n if (!itemsToJoin.length) return items as any;\n if (!items.length) return itemsToJoin as any;\n\n // convert by option in to a map from T key to JoinT key\n const byMap =\n options?.by == null\n ? autodetectByMap(items, itemsToJoin)\n : makeByMap(options.by);\n\n // keep track of what has been matched\n const matchMap = new Map();\n\n // when we miss a join, we want to explicitly add in undefined\n // so our rows all have the same keys. get those keys here.\n const joinObjectKeys = Object.keys(itemsToJoin[0]);\n\n const joined = items.flatMap((d: T) => {\n const matches = itemsToJoin.filter((j: JoinT) => {\n const matched = isMatch(d, j, byMap);\n if (matched) {\n matchMap.set(j, true);\n }\n return matched;\n });\n\n if (matches.length) {\n return matches.map((j: JoinT) => ({ ...d, ...j }));\n }\n\n // add in missing keys explicitly as undefined without\n // overriding existing values and while maintaining order\n // of keys\n const undefinedFill = Object.fromEntries(\n joinObjectKeys\n .filter((key) => d[key] == null)\n .map((key) => [key, undefined])\n );\n\n return { ...d, ...undefinedFill };\n });\n\n // add in the ones we missed\n if (matchMap.size < itemsToJoin.length) {\n const leftEmptyObject = Object.fromEntries(\n Object.keys(items[0]).map((key) => [key, undefined])\n );\n for (const item of itemsToJoin) {\n if (!matchMap.has(item)) {\n joined.push({ ...leftEmptyObject, ...item });\n }\n }\n }\n\n return joined;\n };\n return _fullJoin;\n}\n","import { TidyFn, NonFunctionValue, Key } from './types';\nimport { A } from 'ts-toolbelt';\n\ntype MutateSpecValue<T, O = any> = ((items: T[]) => O[] | O) | NonFunctionValue;\nexport type MutateSummarySpec<T> = Record<Key, MutateSpecValue<T>>;\nexport type ResolvedObj<Obj extends Record<Key, MutateSpecValue<any>>> = {\n [K in keyof Obj]: Obj[K] extends (...args: any) => any\n ? ReturnType<Obj[K]> extends any[]\n ? ReturnType<Obj[K]>[number]\n : ReturnType<Obj[K]> extends Float64Array\n ? number\n : ReturnType<Obj[K]>\n : Obj[K];\n};\n\ntype Mutated<T, MSpec extends MutateSummarySpec<T>> = T & ResolvedObj<MSpec>;\n\ntype Compute<T> = A.Compute<T>;\n\n/**\n * Mutates items, looking at multiple items at a time to enable summarization.\n * For simpler, item by item mutations, use mutate.\n * @param mutateSpec\n */\nexport function mutateWithSummary<\n T extends object,\n MSpec extends MutateSummarySpec<T>\n>(mutateSpec: MSpec): TidyFn<T, Compute<Mutated<T, MSpec>>> {\n type MutatedT = Mutated<T, MSpec>;\n // use Compute for better intellisense (reveals all keys in obj)\n const _mutate: TidyFn<T, Compute<MutatedT>> = (\n items: T[]\n ): Compute<MutatedT>[] => {\n // create the base items to merge mutated values into\n const mutatedItems: MutatedT[] = items.map((d) => ({ ...d })) as MutatedT[];\n\n // create vectors for each mutated value\n for (const key in mutateSpec) {\n // convert individual values to a vector of the same value\n // this allows mutate functions to return single numbers and still work\n const mutateSpecValue = mutateSpec[key];\n const mutatedResult =\n typeof mutateSpecValue === 'function'\n ? mutateSpecValue(mutatedItems)\n : mutateSpecValue;\n const mutatedVector =\n mutatedResult?.[Symbol.iterator] && typeof mutatedResult !== 'string'\n ? mutatedResult\n : items.map(() => mutatedResult);\n\n // merge the mutated vector into the mutated items\n let i = -1;\n for (const mutatedItem of mutatedItems) {\n mutatedItem[key as keyof MutatedT] = mutatedVector[++i];\n }\n }\n\n return mutatedItems as Compute<MutatedT>[];\n };\n\n return _mutate;\n}\n","/**\n * Helper to get keys from a collection of items.\n * For now, it naively just looks at the first item, but a more complete\n * solution involves looking at all of them (in case keys are omitted).\n * This isn't very efficient though, so perhaps there's a future where\n * the keys are stored sneakily on the object somewhere and that set\n * is updated after each tidy fn is called (if we can do it efficiently)\n *\n * Or perhaps this function can be memoized in a smart way where we don't\n * call it more than necessary?\n */\nexport function keysFromItems<T extends object>(items: T[]): (keyof T)[] {\n if (items.length < 1) return [];\n const keys = Object.keys(items[0]) as (keyof T)[];\n return keys;\n}\n","import { keysFromItems } from '../helpers/keysFromItems';\n\n/**\n * Returns all keys\n */\nexport function everything<T extends object>() {\n return (items: T[]) => {\n const keys = keysFromItems(items);\n return keys;\n };\n}\n","import { Datum, TidyFn, Key } from './types';\nimport { singleOrArray } from './helpers/singleOrArray';\nimport { everything } from './selectors/everything';\nimport { O, U } from 'ts-toolbelt';\n\ntype DropKey<T extends Datum> = keyof T extends string | number\n ? `-${keyof T}`\n : never;\n// type KeysInput1<T> = readonly (keyof T)[] | keyof T;\nexport type KeysInput<T> =\n | (Key | ((items: T[]) => Key[]))[]\n | readonly DropKey<T>[]\n | readonly (keyof T)[]\n | DropKey<T>\n | keyof T;\n\ntype Output<\n T extends object,\n KS extends KeysInput<T>\n // is it an array of drop keys?\n> = KS extends readonly DropKey<T>[]\n ? O.Pick<\n T,\n {\n [TK in keyof T]: `-${U.Intersect<TK, string>}` extends KS[number]\n ? never\n : TK;\n }[keyof T]\n >\n : // is an array of keys?\n KS extends readonly Key[]\n ? O.Pick<T, KS[number]>\n : // is a single drop key?\n KS extends DropKey<T>\n ? O.Pick<\n T,\n {\n [TK in keyof T]: `-${U.Intersect<TK, string>}` extends KS ? never : TK;\n }[keyof T]\n >\n : // is a single key?\n KS extends Key\n ? O.Pick<T, U.Intersect<KS, keyof T>>\n : // any other case, just be dumb and say T was returned\n T;\n\nexport function processSelectors<T extends object, Keys extends KeysInput<T>>(\n items: T[],\n selectKeys: Keys\n): string[] {\n let processedSelectKeys: string[] = [];\n // expand them all to a flat list of keys\n for (const keyInput of singleOrArray(selectKeys as any)) {\n if (typeof keyInput === 'function') {\n processedSelectKeys.push(...(keyInput(items) as string[]));\n } else {\n processedSelectKeys.push(keyInput);\n }\n }\n\n // if the first key is negative, add in everything at the front\n if (processedSelectKeys.length && processedSelectKeys[0][0] === '-') {\n processedSelectKeys = [...everything()(items), ...processedSelectKeys];\n }\n\n const negationMap: any = {};\n const keysWithoutNegations = [];\n // go through the list backwards and remove negations\n for (let k = processedSelectKeys.length - 1; k >= 0; k--) {\n const key: any = processedSelectKeys[k];\n if (key[0] === '-') {\n negationMap[key.substring(1)] = true;\n continue;\n }\n if (negationMap[key]) {\n negationMap[key] = false;\n continue;\n }\n keysWithoutNegations.unshift(key);\n }\n\n // remove duplicates\n processedSelectKeys = Array.from(new Set(keysWithoutNegations));\n\n return processedSelectKeys;\n}\n\n/**\n * selects subparts of the objects (aka pick)\n * @param selectFn Returns true to keep the item, false to select out\n */\n// export function select<T extends object, Keys extends SingleOrArray<Key | ((items: T[]) => (keyof T)[])>>(\nexport function select<T extends object, Keys extends KeysInput<T>>(\n selectKeys: Keys\n): TidyFn<T, Output<T, Keys>> {\n type OutputT = Output<T, Keys>;\n const _select: TidyFn<T, OutputT> = (items: T[]): OutputT[] => {\n let processedSelectKeys: string[] = processSelectors(items, selectKeys);\n\n if (!processedSelectKeys.length) return items as OutputT[];\n\n // use the processed keys to create reduced objects\n return items.map((d: T) => {\n const mapped: any = {};\n for (const key of processedSelectKeys) {\n mapped[key] = d[key as keyof T];\n }\n\n return mapped;\n });\n };\n\n return _select;\n}\n","import { TidyFn } from './types';\nimport { mutate, MutateSpec, ResolvedObj } from './mutate';\nimport { select } from './select';\nimport { A } from 'ts-toolbelt';\n\n/**\n * Transmutes items\n * @param mutateSpec\n */\nexport function transmute<T extends object, MSpec extends MutateSpec<T>>(\n mutateSpec: MSpec\n): TidyFn<T, A.Compute<ResolvedObj<MSpec>>> {\n const _transmute: TidyFn<T, A.Compute<ResolvedObj<MSpec>>> = (items: T[]) => {\n const mutated = mutate<T, MSpec>(mutateSpec)(items);\n const picked = select(Object.keys(mutateSpec) as string[])(mutated);\n return picked as A.Compute<ResolvedObj<MSpec>>[];\n };\n\n return _transmute;\n}\n","import { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\nimport { TidyFn } from './types';\n\n/**\n * adds items to the end of the collection\n * @param itemsToAdd The rows/items to be appended to end of collection\n */\nexport function addRows<T extends object>(\n itemsToAdd: SingleOrArray<T> | ((items: T[]) => SingleOrArray<T>)\n): TidyFn<T> {\n const _addRows: TidyFn<T> = (items: T[]): T[] => {\n // TODO: allow options for specifying where it is inserted?\n if (typeof itemsToAdd === 'function') {\n return [...items, ...singleOrArray((itemsToAdd as Function)(items))];\n }\n\n return [...items, ...singleOrArray(itemsToAdd)];\n };\n\n return _addRows;\n}\n","import { groupBy } from './groupBy';\nimport { SingleOrArray } from './helpers/singleOrArray';\nimport { tidy } from './tidy';\nimport { Key, TidyFn } from './types';\n\ntype PivotOutput = Record<Key, any>;\n\ntype PivotWiderOptions<T extends object> = {\n namesFrom: SingleOrArray<keyof T>;\n namesSep?: string;\n valuesFrom: SingleOrArray<keyof T>;\n valuesFill?: any;\n valuesFillMap?: Partial<Record<Key, any>>;\n};\n\nexport function pivotWider<T extends object>(\n options: PivotWiderOptions<T>\n): TidyFn<T, PivotOutput> {\n const _pivotWider: TidyFn<T, PivotOutput> = (items: T[]): PivotOutput[] => {\n const {\n namesFrom,\n valuesFrom,\n valuesFill,\n valuesFillMap,\n namesSep = '_',\n } = options;\n\n const namesFromKeys: (keyof T)[] = Array.isArray(namesFrom)\n ? namesFrom\n : [namesFrom];\n const valuesFromKeys: (keyof T)[] = Array.isArray(valuesFrom)\n ? valuesFrom\n : [valuesFrom];\n const wider: PivotOutput[] = [];\n\n if (!items.length) return wider;\n\n // get all the keys that are left (id columns)\n const idColumns = Object.keys(items[0]).filter(\n (key) =>\n !namesFromKeys.includes(key as keyof T) &&\n !valuesFromKeys.includes(key as keyof T)\n ) as (keyof T)[];\n\n // get all possibilities for the name properties so we can fill them\n const nameValuesMap: any = {};\n for (const item of items) {\n for (const nameKey of namesFromKeys) {\n if (nameValuesMap[nameKey] == null) {\n nameValuesMap[nameKey] = {};\n }\n nameValuesMap[nameKey][item[nameKey]] = true;\n }\n }\n\n const nameValuesLists: string[][] = [];\n for (const nameKey in nameValuesMap) {\n nameValuesLists.push(Object.keys(nameValuesMap[nameKey]));\n }\n\n // prefill values if valuesFill is set for each name values combination\n const baseWideObj: any = {};\n const combos = makeCombinations(namesSep, nameValuesLists);\n\n for (const nameKey of combos) {\n if (valuesFromKeys.length === 1) {\n baseWideObj[nameKey] =\n valuesFillMap != null\n ? valuesFillMap[valuesFromKeys[0] as any]\n : valuesFill;\n continue;\n }\n\n for (const valueKey of valuesFromKeys) {\n baseWideObj[`${valueKey}${namesSep}${nameKey}`] =\n valuesFillMap != null ? valuesFillMap[valueKey as any] : valuesFill;\n }\n }\n\n // given a collection of items, widen\n function widenItems(items: T[]) {\n if (!items.length) return [];\n\n const wide: PivotOutput = { ...baseWideObj };\n\n // add the id columns (same for each object, so just look at first)\n for (const idKey of idColumns) {\n wide[idKey as keyof PivotOutput] = items[0][idKey];\n }\n\n // go through each object and widen their values\n for (const item of items) {\n const nameKey = namesFromKeys.map((key) => item[key]).join(namesSep);\n\n if (valuesFromKeys.length === 1) {\n wide[nameKey] = item[valuesFromKeys[0]];\n continue;\n }\n\n for (const valueKey of valuesFromKeys) {\n wide[`${valueKey}${namesSep}${nameKey}`] = item[valueKey];\n }\n }\n return [wide];\n }\n\n // no id columns, don't do any grouping, just widen and return\n if (!idColumns.length) {\n return widenItems(items);\n }\n\n // group by the id columns\n // for each group, widen/flatten to a single value\n const finish = tidy(items, groupBy(idColumns, [widenItems]));\n return finish;\n };\n\n return _pivotWider;\n}\n\n/*\n Recursively compute key combinations\n*/\nfunction makeCombinations(separator = '_', arrays: string[][]): string[] {\n function combine(\n accum: string[],\n prefix: string | null,\n remainingArrays: string[][]\n ) {\n if (!remainingArrays.length && prefix != null) {\n accum.push(prefix);\n return;\n }\n\n const array = remainingArrays[0];\n const newRemainingArrays = remainingArrays.slice(1);\n for (const item of array) {\n combine(\n accum,\n prefix == null ? item : `${prefix}${separator}${item}`,\n newRemainingArrays\n );\n }\n }\n\n const result: string[] = [];\n combine(result, null, arrays);\n return result;\n}\n","import { SingleOrArray } from './helpers/singleOrArray';\nimport { TidyFn, Key } from './types';\nimport { processSelectors } from './select';\n\ntype PivotLongerOptions = {\n cols?: any; // Typescript gives me max call stack failed if I use KeysInput from `select`\n namesTo: SingleOrArray<Key>;\n namesSep?: string;\n valuesTo: SingleOrArray<Key>;\n};\n\ntype PivotOutput = Record<Key, any>;\n\nexport function pivotLonger<T extends object>(\n options: PivotLongerOptions\n): TidyFn<T, PivotOutput> {\n const _pivotLonger: TidyFn<T, PivotOutput> = (items: T[]): PivotOutput[] => {\n const { namesTo, valuesTo, namesSep = '_' } = options;\n const cols = options.cols ?? [];\n const colsKeys = processSelectors(items, cols) as (keyof T)[];\n\n const namesToKeys = Array.isArray(namesTo) ? namesTo : [namesTo];\n const valuesToKeys = Array.isArray(valuesTo) ? valuesTo : [valuesTo];\n const hasMultipleNamesTo = namesToKeys.length > 1;\n const hasMultipleValuesTo = valuesToKeys.length > 1;\n\n const longer: PivotOutput[] = [];\n\n // expand each item into multiple items\n for (const item of items) {\n // keys not included in colsKeys must be kept\n const remainingKeys = Object.keys(item).filter(\n (key) => !colsKeys.includes(key as keyof T)\n ) as (keyof T)[];\n\n // the keys not in `cols` are the same for each row\n const baseObj = {} as PivotOutput;\n for (const key of remainingKeys) {\n baseObj[key as keyof PivotOutput] = item[key];\n }\n\n // remove the `${valueKey}_` prefix when we have multiple values\n const nameValueKeysWithoutValuePrefix = hasMultipleValuesTo\n ? Array.from(\n new Set(\n colsKeys.map((key) =>\n (key as string).substring((key as string).indexOf(namesSep) + 1)\n )\n )\n )\n : colsKeys;\n\n // e.g. `nameValue` or `nameValue1_nameValue2`\n for (const nameValue of nameValueKeysWithoutValuePrefix) {\n const entryObj = { ...baseObj };\n for (const valueKey of valuesToKeys) {\n // e.g. `valueKey_nameValue1_nameValue2`\n const itemKey = hasMultipleValuesTo\n ? `${valueKey}${namesSep}${nameValue}`\n : nameValue;\n const nameValueParts = hasMultipleNamesTo\n ? (nameValue as string).split(namesSep)\n : [nameValue];\n\n let i = 0;\n for (const nameKey of namesToKeys) {\n const nameValuePart = nameValueParts[i++];\n entryObj[nameKey] = nameValuePart;\n entryObj[valueKey] = item[itemKey as keyof T];\n }\n }\n\n longer.push(entryObj);\n }\n }\n\n return longer;\n };\n\n return _pivotLonger;\n}\n","import { A, O } from 'ts-toolbelt';\nimport { SingleOrArray } from './helpers/singleOrArray';\nimport { Key, TidyFn } from './types';\n\n// helper types\nexport type KeyMap<T extends object = any> = Partial<\n {\n [key in keyof T]: keyof T | Array<T[key]> | ((items: T[]) => T[key][]);\n }\n>;\n\n/**\n * Expands a set of items to include all combinations of the specified keys.\n */\n// prettier-ignore\nexport function expand<T extends object = any, K extends keyof T = keyof T>(expandKeys: K): TidyFn<T, A.Compute<Pick<T, K>>>;\n// prettier-ignore\nexport function expand<T extends object = any, K extends (keyof T)[] = (keyof T)[]>(expandKeys: K): TidyFn<T, A.Compute<Pick<T, K[number]>>>;\n// prettier-ignore\nexport function expand<T extends object = any, K extends KeyMap<T> = KeyMap<T>>(expandKeys: K): TidyFn<T, O.Pick<T, keyof K>>\n// prettier-ignore\nexport function expand<T extends object>(expandKeys: SingleOrArray<Key> | KeyMap<T>): TidyFn<T> {\n const _expand: TidyFn<T> = (items: T[]) => {\n const keyMap = makeKeyMap(expandKeys);\n\n // for each key, get all distinct values or use the provided values\n const vectors = [];\n for (const key in keyMap) {\n const keyValue = keyMap[key];\n let values;\n if (typeof keyValue === 'function') {\n values = keyValue(items);\n } else if (Array.isArray(keyValue)) {\n values = keyValue;\n } else {\n // read distinct values from the key in the data\n values = Array.from(new Set(items.map((d) => d[key as keyof T])));\n }\n\n vectors.push(values.map((value: any) => ({ [key]: value })));\n }\n\n // make all combinations of all value sets\n return makeCombinations(vectors);\n };\n\n return _expand;\n}\n\n/*\n Recursively compute key combinations\n*/\nfunction makeCombinations(vectors: any[][]): any[] {\n function combine(accum: any[], baseObj: any, remainingVectors: any[][]) {\n if (!remainingVectors.length && baseObj != null) {\n accum.push(baseObj);\n return;\n }\n\n const vector = remainingVectors[0];\n const newRemainingArrays = remainingVectors.slice(1);\n for (const item of vector) {\n combine(accum, { ...baseObj, ...item }, newRemainingArrays);\n }\n }\n\n const result: any[] = [];\n combine(result, null, vectors);\n return result;\n}\n\n// convert by option in to a map from T key to JoinT key\nexport function makeKeyMap(keys: SingleOrArray<Key> | KeyMap): KeyMap {\n if (Array.isArray(keys)) {\n const keyMap: KeyMap = {};\n for (const key of keys) {\n keyMap[key as any] = key;\n }\n return keyMap;\n } else if (typeof keys === 'object') {\n return keys;\n }\n\n return { [keys]: keys as any } as KeyMap;\n}\n","import { extent } from 'd3-array';\nimport { Granularity } from '../types';\n\n/**\n * Create a full sequence given a vector of values\n */\nexport function vectorSeq(values: number[], period: number = 1): number[] {\n let [min, max] = extent(values) as [number, number];\n\n const sequence: number[] = [];\n let value = min;\n while (value <= max) {\n sequence.push(value);\n value += period;\n }\n\n return sequence;\n}\n\n/**\n * Create a full sequence given a vector of values\n */\nexport function vectorSeqDate(\n values: Date[],\n granularity: Granularity = 'day',\n period: number = 1\n): Date[] {\n let [min, max] = extent(values) as [Date, Date];\n\n const sequence: Date[] = [];\n let value = new Date(min);\n while (value <= max) {\n sequence.push(new Date(value));\n\n // increment date\n if (\n granularity === 'second' ||\n granularity === 's' ||\n granularity === 'seconds'\n ) {\n value.setUTCSeconds(value.getUTCSeconds() + 1 * period);\n } else if (\n granularity === 'minute' ||\n granularity === 'min' ||\n granularity === 'minutes'\n ) {\n value.setUTCMinutes(value.getUTCMinutes() + 1 * period);\n } else if (\n granularity === 'day' ||\n granularity === 'd' ||\n granularity === 'days'\n ) {\n value.setUTCDate(value.getUTCDate() + 1 * period);\n } else if (\n granularity === 'week' ||\n granularity === 'w' ||\n granularity === 'weeks'\n ) {\n value.setUTCDate(value.getUTCDate() + 7 * period);\n } else if (\n granularity === 'month' ||\n granularity === 'm' ||\n granularity === 'months'\n ) {\n value.setUTCMonth(value.getUTCMonth() + 1 * period);\n } else if (\n granularity === 'year' ||\n granularity === 'y' ||\n granularity === 'years'\n ) {\n value.setUTCFullYear(value.getUTCFullYear() + 1 * period);\n } else {\n throw new Error('Invalid granularity for date sequence: ' + granularity);\n }\n }\n\n return sequence;\n}\n\n/**\n * Create a full sequence given a set of data.\n * @param items\n * @param key\n */\nexport function fullSeq<T extends object>(\n key: keyof T | ((d: T) => number),\n period?: number | null | undefined\n): (items: T[]) => number[] {\n return function fullSeqInner(items: T[]): number[] {\n period = period ?? 1;\n\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return vectorSeq(items.map(keyFn), period);\n };\n}\n\nexport function fullSeqDate<T extends object>(\n key: keyof T | ((d: T) => Date),\n granularity?: Granularity | null | undefined,\n period?: number | null | undefined\n): (items: T[]) => Date[] {\n return function fullSeqDateInner(items: T[]): Date[] {\n granularity = granularity ?? 'day';\n period = period ?? 1;\n\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as Date;\n\n return vectorSeqDate(items.map(keyFn), granularity, period);\n };\n}\n\nexport function fullSeqDateISOString<T extends object>(\n key: keyof T | ((d: T) => string),\n granularity?: Granularity | null | undefined,\n period?: number | null | undefined\n): (items: T[]) => string[] {\n return function fullSeqDateISOStringInner(items: T[]): string[] {\n granularity = granularity ?? 'day';\n period = period ?? 1;\n\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as string;\n\n return vectorSeqDate(\n items.map((d) => new Date(keyFn(d))),\n granularity,\n period\n ).map((date) => date.toISOString());\n };\n}\n","import { O } from 'ts-toolbelt';\nimport { TidyFn } from './types';\n\ntype Spec<T extends object> = {\n [K in keyof T]: T[K];\n};\n\ntype Output<T extends object, ReplaceSpec extends Partial<Spec<T>>> = O.Merge<\n Omit<T, keyof ReplaceSpec>,\n {\n [K in keyof ReplaceSpec]: K extends keyof T\n ? Exclude<T[K], null | undefined> | ReplaceSpec[K]\n : ReplaceSpec[K];\n }\n>;\n\n/**\n * Replaces nully values with what is specified in the spec\n */\nexport function replaceNully<\n T extends object,\n ReplaceSpec extends Spec<Partial<T>> = Spec<Partial<T>>\n>(replaceSpec: ReplaceSpec): TidyFn<T, Output<T, ReplaceSpec>> {\n const _replaceNully: TidyFn<T, Output<T, ReplaceSpec>> = (\n items: T[]\n ): Output<T, ReplaceSpec>[] => {\n const replacedItems: Output<T, ReplaceSpec>[] = [];\n\n for (const d of items) {\n const obj = { ...d } as any;\n for (const key in replaceSpec) {\n if (obj[(key as unknown) as keyof T] == null) {\n obj[(key as unknown) as keyof T] = replaceSpec[key] as any;\n }\n }\n replacedItems.push(obj);\n }\n\n return replacedItems;\n };\n\n return _replaceNully;\n}\n","import { expand, KeyMap } from './expand';\nimport { leftJoin } from './leftJoin';\nimport { Key, TidyFn } from './types';\nimport { replaceNully } from './replaceNully';\nimport { SingleOrArray } from './helpers/singleOrArray';\n\n/**\n * Complete a collection with missing combinations of data\n * @param expandKeys The keys to expand to all combinations of\n * @param replaceNullySpec a map from key name to value of how to deal with undefined values\n */\nexport function complete<T extends object>(\n expandKeys: SingleOrArray<Key> | KeyMap<T>,\n replaceNullySpec?: Partial<T> | null | undefined\n): TidyFn<T> {\n const _complete: TidyFn<T> = (items: T[]): T[] => {\n const expanded = expand<T, any>(expandKeys)(items);\n const joined = leftJoin(items)(expanded) as T[]; // actually may have some undefineds...\n return replaceNullySpec\n ? (replaceNully(replaceNullySpec)(joined) as T[])\n : joined;\n };\n\n return _complete;\n}\n","import { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\nimport { Key, TidyFn } from './types';\n\n/**\n * Fills values for the specified keys to match the last seen value in the collection.\n */\nexport function fill<T extends object>(keys: SingleOrArray<Key>): TidyFn<T> {\n const _fill: TidyFn<T> = (items: T[]): T[] => {\n const keysArray = singleOrArray(keys);\n\n const replaceMap: Partial<T> = {};\n\n return items.map((d) => {\n const obj = { ...d };\n for (const key of keysArray) {\n if (obj[key as keyof T] != null) {\n replaceMap[key as keyof T] = obj[key as keyof T];\n } else if (replaceMap[key as keyof T] != null) {\n obj[key as keyof T] = replaceMap[key as keyof T] as any;\n }\n }\n return obj;\n });\n };\n\n return _fill;\n}\n","import { TidyContext, TidyFn } from './types';\n\ntype Options = {\n limit?: number | null;\n output?: 'log' | 'table';\n};\n\n/**\n * Debugs items\n */\nexport function debug<T extends object>(\n label?: string | null | undefined,\n options?: Options | null | undefined\n): TidyFn<T> {\n const _debug: TidyFn<T> = (items: T[], context?: TidyContext): T[] => {\n let prefix = '[tidy.debug';\n if (context?.groupKeys?.length) {\n const groupKeys = context.groupKeys;\n const groupKeyStrings = groupKeys\n .map((keyPair: any) => keyPair.join(': '))\n .join(', ');\n if (groupKeyStrings.length) {\n prefix += '|' + groupKeyStrings;\n }\n }\n options = options ?? {};\n const { limit = 10, output = 'table' } = options;\n\n // check for sneaky group keys as last arg\n const dashString =\n '--------------------------------------------------------------------------------';\n let numDashes = dashString.length;\n const prefixedLabel = prefix + ']' + (label == null ? '' : ' ' + label);\n numDashes = Math.max(0, numDashes - (prefixedLabel.length + 2));\n\n console.log(`${prefixedLabel} ${dashString.substring(0, numDashes)}`);\n console[output](\n limit == null || limit >= items.length ? items : items.slice(0, limit)\n );\n return items;\n };\n\n return _debug;\n}\n","/** Tidy math helpers */\n\n/** Compute a fraction while handling common edge cases */\nexport function rate(\n numerator: number | null | undefined,\n denominator: number | null | undefined,\n allowDivideByZero?: boolean\n): number | undefined {\n return numerator == null || denominator == null\n ? undefined\n : denominator === 0 && numerator === 0\n ? 0\n : !allowDivideByZero && denominator === 0\n ? undefined\n : numerator / denominator;\n}\n\nexport function subtract(\n a: number | null | undefined,\n b: number | null | undefined,\n nullyZero?: boolean\n) {\n return a == null || b == null\n ? nullyZero\n ? (a ?? 0) - (b ?? 0)\n : undefined\n : a - b;\n}\n\nexport function add(\n a: number | null | undefined,\n b: number | null | undefined,\n nullyZero?: boolean\n) {\n return a == null || b == null\n ? nullyZero\n ? (a ?? 0) + (b ?? 0)\n : undefined\n : a + b;\n}\n","import { rate as mathRate } from '../math/math';\n\ntype RateOptions<T> = {\n predicate?: (d: T, index: number, array: Iterable<T>) => boolean;\n allowDivideByZero?: boolean;\n};\n\n/**\n * Returns a function that computes a rate (numerator / denominator), setting the value to\n * 0 if denominator = 0 and numerator = 0.\n */\nexport function rate<T extends object>(\n numerator: keyof T | ((d: T, index: number, array: Iterable<T>) => number),\n denominator: keyof T | ((d: T, index: number, array: Iterable<T>) => number),\n options?: RateOptions<T>\n) {\n const numeratorFn =\n typeof numerator === 'function'\n ? numerator\n : (d: T) => (d[numerator] as unknown) as number;\n const denominatorFn =\n typeof denominator === 'function'\n ? denominator\n : (d: T) => (d[denominator] as unknown) as number;\n\n const { predicate, allowDivideByZero } = options ?? {};\n return predicate == null\n ? (d: T, index: number, array: Iterable<T>) => {\n const denom = denominatorFn(d, index, array);\n const numer = numeratorFn(d, index, array);\n return mathRate(numer, denom, allowDivideByZero);\n }\n : (d: T, index: number, array: Iterable<T>) => {\n if (!predicate(d, index, array)) return undefined;\n\n const denom = denominatorFn(d, index, array);\n const numer = numeratorFn(d, index, array);\n return mathRate(numer, denom, allowDivideByZero);\n };\n}\n","import { fsum, Adder } from 'd3-array';\n\n// See also https://observablehq.com/@fil/fcumsum\nexport function fcumsum<T>(\n items: T[],\n accessor: (element: T, i: number, array: Iterable<T>) => any\n): Float64Array {\n let sum = new Adder(),\n i = 0;\n\n return Float64Array.from(\n items,\n // we do not actually need to coerce the Adder to number,\n // as @Fil demonstrated here: https://github.com/pbeshai/tidy/pull/5\n // so we can just tell typescript to be quiet.\n (value: T): number =>\n (sum.add(+(accessor(value, i++, items) || 0)) as unknown) as number\n );\n}\n\nexport function mean<T>(\n items: T[],\n accessor: (element: T, i: number, array: Iterable<T>) => any\n): number | undefined {\n let n = 0;\n for (let i = 0; i < items.length; ++i) {\n const value = accessor(items[i], i, items);\n // count it if we have a valid number\n if (+value === value) {\n n += 1;\n }\n }\n\n return n ? fsum(items, accessor) / n : undefined;\n}\n","import { fcumsum } from '../helpers/summation';\n\nexport function cumsum<T extends object>(\n key:\n | keyof T\n | ((d: T, index: number, array: Iterable<T>) => number | null | undefined)\n) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n // note returns Float64Array not a normal array\n return (items: T[]) => fcumsum(items, keyFn);\n}\n","type RollOptions = {\n partial?: boolean;\n /** which direction the window is aligned to (default: right, looking back)\n * - right: current row is the last item [1,2,**3**]\n * - left: current row is the first item [**1**,2,3]\n * - center: current row is the center item [1,**2**,3]\n */\n align?: 'left' | 'center' | 'right';\n};\n\n/**\n * Returns a function that computes the a rolling value (e.g. moving average) by\n * applying a function over a window of data\n * @param width The size of the window\n * @param rollFn The function to apply to the window (should reduce to a single value)\n * @param options Options to configure roll. e.g. whether to run on partial windows.\n */\nexport function roll<T extends object>(\n width: number,\n rollFn: (itemsInWindow: T[], endIndex: number) => any,\n options?: RollOptions | undefined | null\n) {\n const { partial = false, align = 'right' } = options ?? {};\n\n const halfWidth = Math.floor(width / 2);\n\n return (items: any[]) => {\n return items.map((_, i) => {\n const endIndex =\n align === 'right'\n ? i\n : align === 'center'\n ? i + halfWidth\n : i + width - 1;\n\n // partial window and we don't allow partial computation, return undefined\n if (!partial && (endIndex - width + 1 < 0 || endIndex >= items.length)) {\n return undefined;\n }\n\n const startIndex = Math.max(0, endIndex - width + 1);\n const itemsInWindow = items.slice(startIndex, endIndex + 1);\n\n // reduce them to a single value\n return rollFn(itemsInWindow, endIndex);\n });\n };\n}\n","type LagOptions = {\n /** Number of positions to lag by (default: 1) */\n n?: number;\n /** The default value for non-existent rows. */\n default?: any;\n};\n\n/**\n * Returns a function that lags a vector by a specified offset (n). Useful for\n * finding previous values to compute deltas with later.\n * @param key The key or accessor to lag\n * @param options Options to configure roll. e.g. whether to run on partial windows.\n */\nexport function lag<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => any),\n options?: LagOptions | undefined | null\n) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n const { n = 1, default: defaultValue } = options ?? {};\n\n return (items: T[]) => {\n return items.map((_, i) => {\n const lagItem = items[i - n];\n return lagItem == null ? defaultValue : keyFn(lagItem, i, items);\n });\n };\n}\n","type LeadOptions = {\n /** Number of positions to lead by (default: 1) */\n n?: number;\n /** The default value for non-existent rows. */\n default?: any;\n};\n\n/**\n * Returns a functions that leads a vector by a specified offset (n). Useful for\n * finding next values for computing deltas with.\n * @param key The key or accessor to lead\n * @param options Options to configure roll. e.g. whether to run on partial windows.\n */\nexport function lead<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => any),\n options?: LeadOptions | undefined | null\n) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n const { n = 1, default: defaultValue } = options ?? {};\n\n return (items: T[]) => {\n return items.map((_, i) => {\n const leadItem = items[i + n];\n return leadItem == null ? defaultValue : keyFn(leadItem, i, items);\n });\n };\n}\n","type RowNumberOptions = {\n /** what to start row numbers at, default is 0 */\n startAt?: number;\n};\n\n/**\n * Returns a vector of row numbers, starting at 0\n */\nexport function rowNumber<T>(options?: RowNumberOptions) {\n const startAt = options?.startAt ?? 0;\n return (items: T[]) => {\n return items.map((_, i) => i + startAt);\n };\n}\n","import { min as d3min } from 'd3-array';\n\n/**\n * Returns a function that computes the min over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function min<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => number)\n) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3min(items, keyFn);\n}\n","import { max as d3max } from 'd3-array';\n\n/**\n * Returns a function that computes the max over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function max<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => number)\n) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3max(items, keyFn);\n}\n","import { mean as meanInternal } from '../helpers/summation';\n\n/**\n * Returns a function that computes the mean over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function mean<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => number)\n) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => meanInternal(items, keyFn);\n}\n","import { fsum } from 'd3-array';\nimport { rate } from '../math/math';\n\n/**\n * Returns a function that computes the mean of a rate over an array of items\n * @param numerator A string key of the object or an accessor converting the object to a number\n * @param denominator A string key of the object or an accessor converting the object to a number\n */\nexport function meanRate<T extends object>(\n numerator: keyof T | ((d: T, index: number, array: Iterable<T>) => number),\n denominator: keyof T | ((d: T, index: number, array: Iterable<T>) => number)\n) {\n const numeratorFn =\n typeof numerator === 'function'\n ? numerator\n : (d: T) => (d[numerator] as unknown) as number;\n const denominatorFn =\n typeof denominator === 'function'\n ? denominator\n : (d: T) => (d[denominator] as unknown) as number;\n\n return (items: T[]) => {\n const numerator = fsum(items, numeratorFn);\n const denominator = fsum(items, denominatorFn);\n return rate(numerator, denominator);\n };\n}\n","import { median as d3median } from 'd3-array';\n\n/**\n * Returns a function that computes the median over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function median<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => number)\n) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3median(items, keyFn);\n}\n","import { deviation as d3deviation } from 'd3-array';\n\n/**\n * Returns a function that computes the deviation over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function deviation<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => number)\n) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3deviation(items, keyFn);\n}\n","import { variance as d3variance } from 'd3-array';\n\n/**\n * Returns a function that computes the variance over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function variance<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => number)\n) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3variance(items, keyFn);\n}\n","/**\n * Returns a function that computes the distinct count for a key\n * over an array of items. By default it counts nulls but not undefined\n */\nexport function nDistinct<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => any),\n options: { includeNull?: boolean; includeUndefined?: boolean } = {}\n) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n return (items: T[]) => {\n const uniques = new Map();\n let count = 0;\n\n let i = 0;\n for (const item of items) {\n const value = keyFn(item, i++, items);\n\n if (!uniques.has(value)) {\n // default includes null but not undefined\n if (\n (!options.includeUndefined && value === undefined) ||\n (options.includeNull === false && value === null)\n ) {\n continue;\n }\n\n count += 1;\n uniques.set(value, true);\n }\n }\n\n return count;\n };\n}\n","/**\n * Returns a function that returns the first value for the specified key\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function first<T extends object>(key: keyof T | ((d: T) => any)) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n return (items: T[]) => (items.length ? keyFn(items[0]) : undefined);\n}\n","/**\n * Returns a function that returns the last value for the specified key\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function last<T extends object>(key: keyof T | ((d: T) => any)) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n return (items: T[]) =>\n items.length ? keyFn(items[items.length - 1]) : undefined;\n}\n","import { keysFromItems } from '../helpers/keysFromItems';\n\n/**\n * Returns all keys that start with the specified prefix\n */\nexport function startsWith<T extends object>(\n prefix: string,\n ignoreCase: boolean = true\n) {\n return (items: T[]) => {\n const regex = new RegExp(`^${prefix}`, ignoreCase ? 'i' : undefined);\n const keys = keysFromItems(items);\n return keys.filter((d) => regex.test(d as string));\n };\n}\n","import { keysFromItems } from '../helpers/keysFromItems';\n\n/**\n * Returns all keys that end with the specified suffix\n */\nexport function endsWith<T extends object>(\n suffix: string,\n ignoreCase: boolean = true\n) {\n return (items: T[]) => {\n const regex = new RegExp(`${suffix}$`, ignoreCase ? 'i' : undefined);\n const keys = keysFromItems(items);\n return keys.filter((d) => regex.test(d as string));\n };\n}\n","import { keysFromItems } from '../helpers/keysFromItems';\n\n/**\n * Returns all keys that contain the specified substring\n */\nexport function contains<T extends object>(\n substring: string,\n ignoreCase: boolean = true\n) {\n return (items: T[]) => {\n const regex = new RegExp(substring, ignoreCase ? 'i' : undefined);\n const keys = keysFromItems(items);\n return keys.filter((d) => regex.test(d as string));\n };\n}\n","import { keysFromItems } from '../helpers/keysFromItems';\n\n/**\n * Returns all keys that match the specified regex\n */\nexport function matches<T extends object>(regex: RegExp) {\n return (items: T[]) => {\n const keys = keysFromItems(items);\n return keys.filter((d) => regex.test(d as string));\n };\n}\n","import { keysFromItems } from '../helpers/keysFromItems';\n\n/**\n * Returns all keys that match the prefix + num range.\n * e.g., wk, [10, 15], width=3 -> wk010, wk011, wk012, wk013, wk014, wk015\n */\nexport function numRange<T extends object>(\n prefix: string,\n range: [number, number],\n width?: number\n) {\n return (items: T[]) => {\n const keys = keysFromItems(items);\n const matchKeys: string[] = [];\n for (let i = range[0]; i <= range[1]; ++i) {\n const num = width == null ? i : new String('00000000' + i).slice(-width);\n matchKeys.push(`${prefix}${num}`);\n }\n\n return keys.filter((d) => (matchKeys as (keyof T)[]).includes(d));\n };\n}\n","import { SingleOrArray, singleOrArray } from '../helpers/singleOrArray';\n\n/**\n * Given a set of selectors, inverts their output to be drop keys. e.g.,\n * `key` becomes `-key`.\n */\nexport function negate<T extends object>(\n selectors: SingleOrArray<keyof T | ((items: T[]) => (keyof T)[])>\n) {\n return (items: T[]) => {\n let keySet = new Set<keyof T>();\n for (const selector of singleOrArray(selectors as any)) {\n if (typeof selector === 'function') {\n const keys = selector(items) as (keyof T)[];\n for (const key of keys) {\n keySet.add(key);\n }\n } else {\n keySet.add(selector);\n }\n }\n const keys = Array.from(keySet).map((key) => `-${key}`);\n return keys as (keyof T)[];\n };\n}\n"],"names":["ascending","group","fsum","shuffle","makeCombinations","extent","mathRate","Adder","d3min","d3max","meanInternal","d3median","d3deviation","d3variance"],"mappings":"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"}
|