const LEFT_BRACKETS = [ '(' , '{' ] as const ; const RIGHT_BRACKETS = [ ')' , '}' ] as const ; type LeftBracket = typeof LEFT_BRACKETS [ number ] ; type RightBracket = typeof RIGHT_BRACKETS [ number ] ; type Bracket = LeftBracket | RightBracket ; export function findMatchingBracketPosition ( contents , bracket , offset = 0 ) { const firstBracketPos = contents . indexOf ( bracket , offset ) ; if ( firstBracketPos < 0 ) { return - 1 ; } let stackCounter = 0 ; const matchingBracket = getMatchingBracket ( bracket ) ; if ( isLeftBracket ( bracket ) ) { const contentsLength = contents . length ; for ( let i = firstBracketPos + 1 ; i < contentsLength ; ++ i ) { const c = contents [ i ] ; if ( c === bracket ) { stackCounter += 1 ; } else if ( c === matchingBracket ) { if ( stackCounter === 0 ) { return i ; } stackCounter -= 1 ; } } } else { for ( let i = firstBracketPos - 1 ; i >= 0 ; -- i ) { const c = contents [ i ] ; if ( c === bracket ) { stackCounter += 1 ; } else if ( c === matchingBracket ) { if ( stackCounter === 0 ) { return i ; } stackCounter -= 1 ; } } } return - 1 ; } function isLeftBracket ( bracket ) { const leftBracketList = LEFT_BRACKETS ; return leftBracketList . includes ( bracket ) ; } function getMatchingBracket ( bracket ) { switch ( bracket ) { case '(' : return ')' ; case ')' : return '(' ; case '{' : return '}' ; case '}' : return '{' ; default : throw new Error ( `Unsupported bracket - ${ bracket }` ) ; } }