import type { Reducer , Transducer } from "@thi.ng/transducers" ; import { compR } from "@thi.ng/transducers/compr" ; import { iterator , iterator1 , __iter } from "@thi.ng/transducers/iterator" ; import { isReduced , reduced } from "@thi.ng/transducers/reduced" ; const B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ; const B64_SAFE = B64_CHARS . substr ( 0 , 62 ) + "-_" ; /**
 * Stateful transducer. Decodes base64 chars into bytes.
 * Supports URL safe & unsafe flavors.
 */ export function base64Decode ( ) ; export function base64Decode ( src ) ; export function base64Decode ( src ? ) { return src ? new Uint8Array ( [ ... iterator1 ( base64Decode ( ) , src ) ] ) : ( rfn ) => { const r = rfn [ 2 ] ; let bc = 0 , bs = 0 ; return compR ( rfn , ( acc , x ) => { switch ( x ) { case "-" : x = "+" ; break ; case "_" : x = "/" ; break ; case "=" : return reduced ( acc ) ; default : } const y = B64_CHARS . indexOf ( x ) ; bs = bc & 3 ? ( bs << 6 ) + y : y ; if ( bc ++ & 3 ) { acc = r ( acc , 255 & ( bs >> ( ( - 2 * bc ) & 6 ) ) ) ; } return acc ; } ) ; } ; } export interface Base64EncodeOpts { safe : boolean ; buffer : number ; } param urlSafe param bufSize export function base64Encode ( ) ; export function base64Encode ( opts ) ; export function base64Encode ( src ) ; export function base64Encode ( opts , src ) ; export function base64Encode ( ... args ) { const iter = __iter ( base64Encode , args , iterator ) ; if ( iter ) { return [ ... iter ] . join ( "" ) ; } return ( [ init , complete , reduce ] ) => { let state = 0 ; let b ; const opts = { safe : false , buffer : 1024 , ... args [ 0 ] } ; const chars = opts . safe ? B64_SAFE : B64_CHARS ; const buf = [ ] ; return < Reducer < any , number > > [ init , ( acc ) => { switch ( state ) { case 1 : buf . push ( chars [ ( b >> 18 ) & 0x3f ] , chars [ ( b >> 12 ) & 0x3f ] , "=" , "=" ) ; break ; case 2 : buf . push ( chars [ ( b >> 18 ) & 0x3f ] , chars [ ( b >> 12 ) & 0x3f ] , chars [ ( b >> 6 ) & 0x3f ] , "=" ) ; break ; default : } while ( buf . length && ! isReduced ( acc ) ) { acc = reduce ( acc , buf . shift ( ) ! ) ; } return complete ( acc ) ; } , ( acc , x ) => { switch ( state ) { case 0 : state = 1 ; b = x << 16 ; break ; case 1 : state = 2 ; b += x << 8 ; break ; default : state = 0 ; b += x ; buf . push ( chars [ ( b >> 18 ) & 0x3f ] , chars [ ( b >> 12 ) & 0x3f ] , chars [ ( b >> 6 ) & 0x3f ] , chars [ b & 0x3f ] ) ; if ( buf . length >= opts . buffer ) { for ( let i = 0 , n = buf . length ; i < n && ! isReduced ( acc ) ; i ++ ) { acc = reduce ( acc , buf [ i ] ) ; } buf . length = 0 ; } } return acc ; } , ] ; } ; }