Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | 38x 138x 230x 230x 230x 83x 83x 83x 147x 138x 38x 88x 58x 30x 30x 298x 298x 298x 298x 1x 297x 29x 29x 38x 13x 13x 13x 38x 153x 153x 153x 153x 153x 45x 45x 45x 153x 153x 153x 153x 216x 152x | export type Cache<T> = {[id: string]: T}; export const cached = <T>( cache: Cache<T>, getThing: () => T, ): () => T => { const getter = (): T => { const getThingIdent = `${getThing.name}-${getThing.toString()}`; const cachedThing = cache[getThingIdent]; if (cachedThing === undefined) { const newThing = getThing(); cache[getThingIdent] = newThing; return newThing; } return cachedThing; }; return getter; }; export type Lookup = {[id: string]: string}; export type MappingWithLookup<T> = {[id: string]: T|string|Lookup}; export const getLookup = <T>( mapping: MappingWithLookup<T>, getLookupKey?: (value: T) => string, ): Lookup => { if (mapping._lookup) { return mapping._lookup as Lookup; } const lookup: Lookup = {}; Object.keys(mapping) .filter((mappingKey) => mappingKey.substr(0, 1) !== '_') .forEach((mappingKey) => { const mappingValue = mapping[mappingKey]; const lookupKey = getLookupKey ? getLookupKey(mappingValue as T) : (mappingValue as string); if (lookupKey in lookup) { throw new Error(`Duplicate lookup key: ${lookupKey}`); } lookup[lookupKey] = mappingKey; }); mapping._lookup = lookup; return lookup; }; export const waitFor = <T>( milliseconds: number, value?: T, ): Promise<T|undefined> => { const promise: Promise<T|undefined> = new Promise((resolve) => { setTimeout(() => resolve(value), milliseconds); }); return promise; }; export interface BinarySearchOptions<L, T> { getLength?: (list: L) => number; getItemAtIndex?: (list: L, index: number) => T|undefined; getNewRange?: (list: L, item: T, start: number, end: number) => [number, number]; } export const binarySearch = <L, T>( list: L, item: T, options: BinarySearchOptions<L, T> = {}, ): number => { const defaultGetLength = (list_: L): number => ((list_ as unknown) as T[]).length; const getLength = options.getLength || defaultGetLength; const defaultGetItemAtIndex = (list_: L, index: number): T => ((list_ as unknown) as T[])[index]; const getItemAtIndex = options.getItemAtIndex || defaultGetItemAtIndex; const defaultGetNewRange = (list_: L, item_: T, start: number, end: number): [number, number] => { const mid = Math.floor((start + end) / 2); const midItem = getItemAtIndex(list_, mid)!; return (item_ <= midItem) ? [start, mid] : [mid + 1, end]; }; const getNewRange = options.getNewRange || defaultGetNewRange; let start = 0; let end = getLength(list); while (start < end) { [start, end] = getNewRange(list, item, start, end); } return start; }; |