export function utf8Slice ( buf , start , end ) { end = Math . min ( buf . length , end ) ; const res = [ ] ; let i = start ; while ( i < end ) { const firstByte = buf [ i ] ; let codePoint = null ; let bytesPerSequence = ( firstByte > 0xEF ) ? 4 : ( firstByte > 0xDF ) ? 3 : ( firstByte > 0xBF ) ? 2 : 1 ; if ( i + bytesPerSequence <= end ) { let secondByte , thirdByte , fourthByte , tempCodePoint ; switch ( bytesPerSequence ) { case 1 : if ( firstByte < 0x80 ) { codePoint = firstByte ; } break ; case 2 : secondByte = buf [ i + 1 ] ; if ( ( secondByte & 0xC0 ) === 0x80 ) { tempCodePoint = ( firstByte & 0x1F ) << 0x6 | ( secondByte & 0x3F ) ; if ( tempCodePoint > 0x7F ) { codePoint = tempCodePoint ; } } break ; case 3 : secondByte = buf [ i + 1 ] ; thirdByte = buf [ i + 2 ] ; if ( ( secondByte & 0xC0 ) === 0x80 && ( thirdByte & 0xC0 ) === 0x80 ) { tempCodePoint = ( firstByte & 0xF ) << 0xC | ( secondByte & 0x3F ) << 0x6 | ( thirdByte & 0x3F ) ; if ( tempCodePoint > 0x7FF && ( tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF ) ) { codePoint = tempCodePoint ; } } break ; case 4 : secondByte = buf [ i + 1 ] ; thirdByte = buf [ i + 2 ] ; fourthByte = buf [ i + 3 ] ; if ( ( secondByte & 0xC0 ) === 0x80 && ( thirdByte & 0xC0 ) === 0x80 && ( fourthByte & 0xC0 ) === 0x80 ) { tempCodePoint = ( firstByte & 0xF ) << 0x12 | ( secondByte & 0x3F ) << 0xC | ( thirdByte & 0x3F ) << 0x6 | ( fourthByte & 0x3F ) ; if ( tempCodePoint > 0xFFFF && tempCodePoint < 0x110000 ) { codePoint = tempCodePoint ; } } } } if ( codePoint === null ) { codePoint = 0xFFFD ; bytesPerSequence = 1 ; } else if ( codePoint > 0xFFFF ) { codePoint -= 0x10000 ; res . push ( codePoint >>> 10 & 0x3FF | 0xD800 ) ; codePoint = 0xDC00 | codePoint & 0x3FF ; } res . push ( codePoint ) ; i += bytesPerSequence ; } return decodeCodePointsArray ( res ) ; } const MAX_ARGUMENTS_LENGTH = 0x1000 ; function decodeCodePointsArray ( codePoints ) { const len = codePoints . length ; if ( len <= MAX_ARGUMENTS_LENGTH ) { return String . fromCharCode . apply ( String , codePoints ) ; } let res = '' ; let i = 0 ; while ( i < len ) { res += String . fromCharCode . apply ( String , codePoints . slice ( i , i += MAX_ARGUMENTS_LENGTH ) ) ; } return res ; }