export const doClick = async (el?: Element | null, timeout?: number) => { if (!el) return if (el.classList?.add) { el.classList.add('active') } // eslint-disable-next-line @typescript-eslint/no-explicit-any const { click } = el as any if (typeof click === 'function') { const r = click() if (r instanceof Promise) { await r } else if (timeout) { await new Promise((resolve) => setTimeout(resolve, timeout)) } else { return } } if (el.classList?.remove) { el.classList.remove('active') } } export const doMapKeypress = ( evt: KeyboardEvent, map: Record void) | string | HTMLElement> ) => { let action = map[evt.key] while (typeof action === 'string') { action = map[action] } if (typeof action === 'function') { action() } else if (action instanceof HTMLElement) { doClick(action) } } /** * Shuffles array in place. ES6 version * @param {Array} a items An array containing the items. */ export function shuffle(a: T[]) { for (let i = a.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)) ;[a[i], a[j]] = [a[j]!, a[i]!] } return a } export function sample(arr: T[], size: number): T[] { const allN = Array(arr.length) .fill(null) .map((_, i) => i) const outN: number[] = [] while (allN.length && outN.length < size) { outN.push(...allN.splice(Math.floor(Math.random() * allN.length), 1)) } return outN.map((n) => arr[n]!) } export function capitalize(s: string): string { if (s.includes(' ')) { return s .split(' ') .map((s0) => capitalize(s0)) .join(' ') } if (!s) return s return s[0]!.toLocaleUpperCase() + s.substr(1) } export function jsonClone(o: T): T { return JSON.parse(JSON.stringify(o)) }