import { IHeadingNode , IPageNode , isPageNode } from "@documentalist/client" ; import * as React from "react" ; /**
 * Removes leading indents from a template string without removing all leading whitespace.
 * Trims resulting string to remove blank first/last lines caused by ` location.
 */ export function dedent ( strings , ... values ) { let fullString = strings . reduce ( ( accumulator , str , i ) => { return accumulator + values [ i - 1 ] . toString ( ) + str ; } ) ; const match = fullString . match ( /^[ \t]*(?=\S)/gm ) ! ; const indent = Math . min ( ... match . map ( el => el . length ) ) ; const regexp = new RegExp ( "^[ \\t]{" + indent + "}" , "gm" ) ; fullString = indent > 0 ? fullString . replace ( regexp , "" ) : fullString ; return fullString . trim ( ) ; } export function smartSearch ( query , ... content ) { const terms = query . toLowerCase ( ) . split ( " " ) ; const dataToSearch = content . map ( s => s . toLowerCase ( ) ) ; return terms . every ( term => dataToSearch . some ( d => d . indexOf ( term ) >= 0 ) ) ; } export interface IKeyEventMap < T = HTMLElement > { /** event handler invoked on all events */ all ? : React . KeyboardEventHandler < T > ; /** map keycodes to specific event handlers */ [ keyCode ] : React . KeyboardEventHandler < T > ; } export function createKeyEventHandler < T = HTMLElement > ( actions , preventDefault = false ) { return ( e ) => { for ( const k of Object . keys ( actions ) ) { const key = Number ( k ) ; if ( e . which === key ) { if ( preventDefault ) { e . preventDefault ( ) ; } actions [ key ] ( e ) ; } } actions . all ?. ( e ) ; } ; } /**
 * Performs an in-order traversal of the layout tree, invoking the callback for each node.
 * Callback receives an array of ancestors with direct parent first in the list.
 */ export function eachLayoutNode ( layout , callback , parents = [ ] ) { layout . forEach ( node => { callback ( node , parents ) ; if ( isPageNode ( node ) ) { eachLayoutNode ( node . children , callback , [ node , ... parents ] ) ; } } ) ; }