/**
 * Class to help with base64 Encoding/Decoding.
 * Sourced from https://github.com/beatgammit/base64-js.
 */ export class Base64 { internal private static readonly _LOOKUP : string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ; internal private static readonly _REVERSE_LOOKUP : { [ id ] : number ; } = { "43" : 62 , "45" : 62 , "47" : 63 , "48" : 52 , "49" : 53 , "50" : 54 , "51" : 55 , "52" : 56 , "53" : 57 , "54" : 58 , "55" : 59 , "56" : 60 , "57" : 61 , "65" : 0 , "66" : 1 , "67" : 2 , "68" : 3 , "69" : 4 , "70" : 5 , "71" : 6 , "72" : 7 , "73" : 8 , "74" : 9 , "75" : 10 , "76" : 11 , "77" : 12 , "78" : 13 , "79" : 14 , "80" : 15 , "81" : 16 , "82" : 17 , "83" : 18 , "84" : 19 , "85" : 20 , "86" : 21 , "87" : 22 , "88" : 23 , "89" : 24 , "90" : 25 , "95" : 63 , "97" : 26 , "98" : 27 , "99" : 28 , "100" : 29 , "101" : 30 , "102" : 31 , "103" : 32 , "104" : 33 , "105" : 34 , "106" : 35 , "107" : 36 , "108" : 37 , "109" : 38 , "110" : 39 , "111" : 40 , "112" : 41 , "113" : 42 , "114" : 43 , "115" : 44 , "116" : 45 , "117" : 46 , "118" : 47 , "119" : 48 , "120" : 49 , "121" : 50 , "122" : 51 } ; param base64 returns public static byteLength ( base64 ) { const lens = Base64 . getLengths ( base64 ) ; return Base64 . calcByteLength ( lens [ 0 ] , lens [ 1 ] ) ; } param base64 returns public static decode ( base64 ) { let tmp ; const lens = Base64 . getLengths ( base64 ) ; const validLen = lens [ 0 ] ; const placeHoldersLen = lens [ 1 ] ; const arr = new Uint8Array ( Base64 . calcByteLength ( validLen , placeHoldersLen ) ) ; let curByte = 0 ; const len = placeHoldersLen > 0 ? validLen - 4 : validLen ; let i ; for ( i = 0 ; i < len ; i += 4 ) { tmp = ( Base64 . _REVERSE_LOOKUP [ base64 . charCodeAt ( i ) ] << 18 ) | ( Base64 . _REVERSE_LOOKUP [ base64 . charCodeAt ( i + 1 ) ] << 12 ) | ( Base64 . _REVERSE_LOOKUP [ base64 . charCodeAt ( i + 2 ) ] << 6 ) | Base64 . _REVERSE_LOOKUP [ base64 . charCodeAt ( i + 3 ) ] ; arr [ curByte ++ ] = ( tmp >> 16 ) & 0xff ; arr [ curByte ++ ] = ( tmp >> 8 ) & 0xff ; arr [ curByte ++ ] = tmp & 0xff ; } if ( placeHoldersLen === 2 ) { tmp = ( Base64 . _REVERSE_LOOKUP [ base64 . charCodeAt ( i ) ] << 2 ) | ( Base64 . _REVERSE_LOOKUP [ base64 . charCodeAt ( i + 1 ) ] >> 4 ) ; arr [ curByte ++ ] = tmp & 0xff ; } if ( placeHoldersLen === 1 ) { tmp = ( Base64 . _REVERSE_LOOKUP [ base64 . charCodeAt ( i ) ] << 10 ) | ( Base64 . _REVERSE_LOOKUP [ base64 . charCodeAt ( i + 1 ) ] << 4 ) | ( Base64 . _REVERSE_LOOKUP [ base64 . charCodeAt ( i + 2 ) ] >> 2 ) ; arr [ curByte ++ ] = ( tmp >> 8 ) & 0xff ; arr [ curByte ++ ] = tmp & 0xff ; } return arr ; } param bytes returns public static encode ( bytes ) { let tmp ; const len = bytes . length ; const extraBytes = len % 3 ; const parts = [ ] ; const maxChunkLength = 16383 ; for ( let i = 0 , len2 = len - extraBytes ; i < len2 ; i += maxChunkLength ) { parts . push ( Base64 . encodeChunk ( bytes , i , i + maxChunkLength > len2 ? len2 : i + maxChunkLength ) ) ; } if ( extraBytes === 1 ) { tmp = bytes [ len - 1 ] ; parts . push ( `${ Base64 . _LOOKUP [ tmp >> 2 ] + Base64 . _LOOKUP [ ( tmp << 4 ) & 0x3f ] }==` ) ; } else if ( extraBytes === 2 ) { tmp = ( bytes [ len - 2 ] << 8 ) + bytes [ len - 1 ] ; parts . push ( `${ Base64 . _LOOKUP [ tmp >> 10 ] + Base64 . _LOOKUP [ ( tmp >> 4 ) & 0x3f ] + Base64 . _LOOKUP [ ( tmp << 2 ) & 0x3f ] }=` ) ; } return parts . join ( "" ) ; } param validLen param placeHoldersLen returns internal private static calcByteLength ( validLen , placeHoldersLen ) { return ( ( validLen + placeHoldersLen ) * 3 ) / 4 - placeHoldersLen ; } param base64 returns internal private static getLengths ( base64 ) { const len = base64 . length ; if ( len % 4 > 0 ) { throw new Error ( "Invalid string. Length must be a multiple of 4" ) ; } let validLen = base64 . indexOf ( "=" ) ; if ( validLen === - 1 ) { validLen = len ; } const placeHoldersLen = validLen === len ? 0 : 4 - ( validLen % 4 ) ; return [ validLen , placeHoldersLen ] ; } param num returns internal private static tripletToBase64 ( num ) { return ( Base64 . _LOOKUP [ ( num >> 18 ) & 0x3f ] + Base64 . _LOOKUP [ ( num >> 12 ) & 0x3f ] + Base64 . _LOOKUP [ ( num >> 6 ) & 0x3f ] + Base64 . _LOOKUP [ num & 0x3f ] ) ; } param bytes param start param end returns internal private static encodeChunk ( bytes , start , end ) { let tmp ; const output = [ ] ; for ( let i = start ; i < end ; i += 3 ) { tmp = ( ( bytes [ i ] << 16 ) & 0xff0000 ) + ( ( bytes [ i + 1 ] << 8 ) & 0xff00 ) + ( bytes [ i + 2 ] & 0xff ) ; output . push ( Base64 . tripletToBase64 ( tmp ) ) ; } return output . join ( "" ) ; } }