| 'use strict'; | 
| var globalThis = require('../internals/global-this'); | 
| var uncurryThis = require('../internals/function-uncurry-this'); | 
| var anObjectOrUndefined = require('../internals/an-object-or-undefined'); | 
| var aString = require('../internals/a-string'); | 
| var hasOwn = require('../internals/has-own-property'); | 
| var base64Map = require('../internals/base64-map'); | 
| var getAlphabetOption = require('../internals/get-alphabet-option'); | 
| var notDetached = require('../internals/array-buffer-not-detached'); | 
|   | 
| var base64Alphabet = base64Map.c2i; | 
| var base64UrlAlphabet = base64Map.c2iUrl; | 
|   | 
| var SyntaxError = globalThis.SyntaxError; | 
| var TypeError = globalThis.TypeError; | 
| var at = uncurryThis(''.charAt); | 
|   | 
| var skipAsciiWhitespace = function (string, index) { | 
|   var length = string.length; | 
|   for (;index < length; index++) { | 
|     var chr = at(string, index); | 
|     if (chr !== ' ' && chr !== '\t' && chr !== '\n' && chr !== '\f' && chr !== '\r') break; | 
|   } return index; | 
| }; | 
|   | 
| var decodeBase64Chunk = function (chunk, alphabet, throwOnExtraBits) { | 
|   var chunkLength = chunk.length; | 
|   | 
|   if (chunkLength < 4) { | 
|     chunk += chunkLength === 2 ? 'AA' : 'A'; | 
|   } | 
|   | 
|   var triplet = (alphabet[at(chunk, 0)] << 18) | 
|     + (alphabet[at(chunk, 1)] << 12) | 
|     + (alphabet[at(chunk, 2)] << 6) | 
|     + alphabet[at(chunk, 3)]; | 
|   | 
|   var chunkBytes = [ | 
|     (triplet >> 16) & 255, | 
|     (triplet >> 8) & 255, | 
|     triplet & 255 | 
|   ]; | 
|   | 
|   if (chunkLength === 2) { | 
|     if (throwOnExtraBits && chunkBytes[1] !== 0) { | 
|       throw new SyntaxError('Extra bits'); | 
|     } | 
|     return [chunkBytes[0]]; | 
|   } | 
|   | 
|   if (chunkLength === 3) { | 
|     if (throwOnExtraBits && chunkBytes[2] !== 0) { | 
|       throw new SyntaxError('Extra bits'); | 
|     } | 
|     return [chunkBytes[0], chunkBytes[1]]; | 
|   } | 
|   | 
|   return chunkBytes; | 
| }; | 
|   | 
| var writeBytes = function (bytes, elements, written) { | 
|   var elementsLength = elements.length; | 
|   for (var index = 0; index < elementsLength; index++) { | 
|     bytes[written + index] = elements[index]; | 
|   } | 
|   return written + elementsLength; | 
| }; | 
|   | 
| /* eslint-disable max-statements, max-depth -- TODO */ | 
| module.exports = function (string, options, into, maxLength) { | 
|   aString(string); | 
|   anObjectOrUndefined(options); | 
|   var alphabet = getAlphabetOption(options) === 'base64' ? base64Alphabet : base64UrlAlphabet; | 
|   var lastChunkHandling = options ? options.lastChunkHandling : undefined; | 
|   | 
|   if (lastChunkHandling === undefined) lastChunkHandling = 'loose'; | 
|   | 
|   if (lastChunkHandling !== 'loose' && lastChunkHandling !== 'strict' && lastChunkHandling !== 'stop-before-partial') { | 
|     throw new TypeError('Incorrect `lastChunkHandling` option'); | 
|   } | 
|   | 
|   if (into) notDetached(into.buffer); | 
|   | 
|   var bytes = into || []; | 
|   var written = 0; | 
|   var read = 0; | 
|   var chunk = ''; | 
|   var index = 0; | 
|   | 
|   if (maxLength) while (true) { | 
|     index = skipAsciiWhitespace(string, index); | 
|     if (index === string.length) { | 
|       if (chunk.length > 0) { | 
|         if (lastChunkHandling === 'stop-before-partial') { | 
|           break; | 
|         } | 
|         if (lastChunkHandling === 'loose') { | 
|           if (chunk.length === 1) { | 
|             throw new SyntaxError('Malformed padding: exactly one additional character'); | 
|           } | 
|           written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, false), written); | 
|         } else { | 
|           throw new SyntaxError('Missing padding'); | 
|         } | 
|       } | 
|       read = string.length; | 
|       break; | 
|     } | 
|     var chr = at(string, index); | 
|     ++index; | 
|     if (chr === '=') { | 
|       if (chunk.length < 2) { | 
|         throw new SyntaxError('Padding is too early'); | 
|       } | 
|       index = skipAsciiWhitespace(string, index); | 
|       if (chunk.length === 2) { | 
|         if (index === string.length) { | 
|           if (lastChunkHandling === 'stop-before-partial') { | 
|             break; | 
|           } | 
|           throw new SyntaxError('Malformed padding: only one ='); | 
|         } | 
|         if (at(string, index) === '=') { | 
|           ++index; | 
|           index = skipAsciiWhitespace(string, index); | 
|         } | 
|       } | 
|       if (index < string.length) { | 
|         throw new SyntaxError('Unexpected character after padding'); | 
|       } | 
|       written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, lastChunkHandling === 'strict'), written); | 
|       read = string.length; | 
|       break; | 
|     } | 
|     if (!hasOwn(alphabet, chr)) { | 
|       throw new SyntaxError('Unexpected character'); | 
|     } | 
|     var remainingBytes = maxLength - written; | 
|     if (remainingBytes === 1 && chunk.length === 2 || remainingBytes === 2 && chunk.length === 3) { | 
|       // special case: we can fit exactly the number of bytes currently represented by chunk, so we were just checking for `=` | 
|       break; | 
|     } | 
|   | 
|     chunk += chr; | 
|     if (chunk.length === 4) { | 
|       written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, false), written); | 
|       chunk = ''; | 
|       read = index; | 
|       if (written === maxLength) { | 
|         break; | 
|       } | 
|     } | 
|   } | 
|   | 
|   return { bytes: bytes, read: read, written: written }; | 
| }; |