2023-04-25 14:56:37 +00:00
/ * C o p y r i g h t 2 0 1 7 G o o g l e I n c . A l l R i g h t s R e s e r v e d .
Distributed under MIT license .
See file LICENSE for detail or copy at https : //opensource.org/licenses/MIT
* /
interface BrotliDecodeOptions {
customDictionary : Int8Array | null ;
}
/* GENERATED CODE BEGIN */
const MAX_HUFFMAN_TABLE_SIZE : Int32Array = Int32Array . from ( [ 256 , 402 , 436 , 468 , 500 , 534 , 566 , 598 , 630 , 662 , 694 , 726 , 758 , 790 , 822 , 854 , 886 , 920 , 952 , 984 , 1016 , 1048 , 1080 ] ) ;
const CODE_LENGTH_CODE_ORDER : Int32Array = Int32Array . from ( [ 1 , 2 , 3 , 4 , 0 , 5 , 17 , 6 , 16 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ] ) ;
const DISTANCE_SHORT_CODE_INDEX_OFFSET : Int32Array = Int32Array . from ( [ 0 , 3 , 2 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 3 , 3 , 3 , 3 , 3 ] ) ;
const DISTANCE_SHORT_CODE_VALUE_OFFSET : Int32Array = Int32Array . from ( [ 0 , 0 , 0 , 0 , - 1 , 1 , - 2 , 2 , - 3 , 3 , - 1 , 1 , - 2 , 2 , - 3 , 3 ] ) ;
const FIXED_TABLE : Int32Array = Int32Array . from ( [ 0x020000 , 0x020004 , 0x020003 , 0x030002 , 0x020000 , 0x020004 , 0x020003 , 0x040001 , 0x020000 , 0x020004 , 0x020003 , 0x030002 , 0x020000 , 0x020004 , 0x020003 , 0x040005 ] ) ;
const BLOCK_LENGTH_OFFSET : Int32Array = Int32Array . from ( [ 1 , 5 , 9 , 13 , 17 , 25 , 33 , 41 , 49 , 65 , 81 , 97 , 113 , 145 , 177 , 209 , 241 , 305 , 369 , 497 , 753 , 1265 , 2289 , 4337 , 8433 , 16625 ] ) ;
const BLOCK_LENGTH_N_BITS : Int32Array = Int32Array . from ( [ 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 24 ] ) ;
const INSERT_LENGTH_N_BITS : Int16Array = Int16Array . from ( [ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x01 , 0x02 , 0x02 , 0x03 , 0x03 , 0x04 , 0x04 , 0x05 , 0x05 , 0x06 , 0x07 , 0x08 , 0x09 , 0x0A , 0x0C , 0x0E , 0x18 ] ) ;
const COPY_LENGTH_N_BITS : Int16Array = Int16Array . from ( [ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x01 , 0x02 , 0x02 , 0x03 , 0x03 , 0x04 , 0x04 , 0x05 , 0x05 , 0x06 , 0x07 , 0x08 , 0x09 , 0x0A , 0x18 ] ) ;
const CMD_LOOKUP = new Int16Array ( 2816 ) ;
{
unpackCommandLookupTable ( CMD_LOOKUP ) ;
}
function log2floor ( i : number ) : number {
let result : number = - 1 ;
let step = 16 ;
2024-02-02 11:26:05 +00:00
let v : number = i ;
2023-04-25 14:56:37 +00:00
while ( step > 0 ) {
2024-02-02 11:26:05 +00:00
let next : number = v >>> step ;
if ( next !== 0 ) {
2023-04-25 14:56:37 +00:00
result += step ;
2024-02-02 11:26:05 +00:00
v = next ;
2023-04-25 14:56:37 +00:00
}
step = step >> 1 ;
}
2024-02-02 11:26:05 +00:00
return result + v ;
2023-04-25 14:56:37 +00:00
}
function calculateDistanceAlphabetSize ( npostfix : number , ndirect : number , maxndistbits : number ) : number {
return 16 + ndirect + 2 * ( maxndistbits << npostfix ) ;
}
function calculateDistanceAlphabetLimit ( maxDistance : number , npostfix : number , ndirect : number ) : number {
if ( maxDistance < ndirect + ( 2 << npostfix ) ) {
throw new Error ( "maxDistance is too small" ) ;
}
const offset : number = ( ( maxDistance - ndirect ) >> npostfix ) + 4 ;
const ndistbits : number = log2floor ( offset ) - 1 ;
const group : number = ( ( ndistbits - 1 ) << 1 ) | ( ( offset >> ndistbits ) & 1 ) ;
return ( ( group - 1 ) << npostfix ) + ( 1 << npostfix ) + ndirect + 16 ;
}
function unpackCommandLookupTable ( cmdLookup : Int16Array ) : void {
2024-02-02 11:26:05 +00:00
const insertLengthOffsets = new Int32Array ( 24 ) ;
const copyLengthOffsets = new Int32Array ( 24 ) ;
2023-04-25 14:56:37 +00:00
copyLengthOffsets [ 0 ] = 2 ;
for ( let i = 0 ; i < 23 ; ++ i ) {
2024-02-02 11:26:05 +00:00
insertLengthOffsets [ i + 1 ] = insertLengthOffsets [ i ] + ( 1 << INSERT_LENGTH_N_BITS [ i ] ) ;
copyLengthOffsets [ i + 1 ] = copyLengthOffsets [ i ] + ( 1 << COPY_LENGTH_N_BITS [ i ] ) ;
2023-04-25 14:56:37 +00:00
}
for ( let cmdCode = 0 ; cmdCode < 704 ; ++ cmdCode ) {
let rangeIdx : number = cmdCode >>> 6 ;
let distanceContextOffset : number = - 4 ;
if ( rangeIdx >= 2 ) {
rangeIdx -= 2 ;
distanceContextOffset = 0 ;
}
const insertCode : number = ( ( ( 0x29850 >>> ( rangeIdx * 2 ) ) & 0x3 ) << 3 ) | ( ( cmdCode >>> 3 ) & 7 ) ;
const copyCode : number = ( ( ( 0x26244 >>> ( rangeIdx * 2 ) ) & 0x3 ) << 3 ) | ( cmdCode & 7 ) ;
const copyLengthOffset : number = copyLengthOffsets [ copyCode ] ;
2024-02-02 11:26:05 +00:00
const distanceContext : number = distanceContextOffset + ( copyLengthOffset > 4 ? 3 : ( copyLengthOffset - 2 ) ) ;
2023-04-25 14:56:37 +00:00
const index : number = cmdCode * 4 ;
2024-02-02 11:26:05 +00:00
cmdLookup [ index ] = INSERT_LENGTH_N_BITS [ insertCode ] | ( COPY_LENGTH_N_BITS [ copyCode ] << 8 ) ;
2023-04-25 14:56:37 +00:00
cmdLookup [ index + 1 ] = insertLengthOffsets [ insertCode ] ;
cmdLookup [ index + 2 ] = copyLengthOffsets [ copyCode ] ;
cmdLookup [ index + 3 ] = distanceContext ;
}
}
function decodeWindowBits ( s : State ) : number {
const largeWindowEnabled : number = s . isLargeWindow ;
s . isLargeWindow = 0 ;
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
if ( readFewBits ( s , 1 ) === 0 ) {
return 16 ;
}
let n : number = readFewBits ( s , 3 ) ;
if ( n !== 0 ) {
return 17 + n ;
}
n = readFewBits ( s , 3 ) ;
if ( n !== 0 ) {
if ( n === 1 ) {
if ( largeWindowEnabled === 0 ) {
return - 1 ;
}
s . isLargeWindow = 1 ;
if ( readFewBits ( s , 1 ) === 1 ) {
return - 1 ;
}
n = readFewBits ( s , 6 ) ;
if ( n < 10 || n > 30 ) {
return - 1 ;
}
return n ;
} else {
return 8 + n ;
}
}
return 17 ;
}
function enableEagerOutput ( s : State ) : void {
if ( s . runningState !== 1 ) {
throw new Error ( "State MUST be freshly initialized" ) ;
}
s . isEager = 1 ;
}
function enableLargeWindow ( s : State ) : void {
if ( s . runningState !== 1 ) {
throw new Error ( "State MUST be freshly initialized" ) ;
}
s . isLargeWindow = 1 ;
}
function attachDictionaryChunk ( s : State , data : Int8Array ) : void {
if ( s . runningState !== 1 ) {
throw new Error ( "State MUST be freshly initialized" ) ;
}
if ( s . cdNumChunks === 0 ) {
s . cdChunks = new Array ( 16 ) ;
s . cdChunkOffsets = new Int32Array ( 16 ) ;
s . cdBlockBits = - 1 ;
}
if ( s . cdNumChunks === 15 ) {
throw new Error ( "Too many dictionary chunks" ) ;
}
s . cdChunks [ s . cdNumChunks ] = data ;
s . cdNumChunks ++ ;
s . cdTotalSize += data . length ;
s . cdChunkOffsets [ s . cdNumChunks ] = s . cdTotalSize ;
}
2023-11-29 18:47:47 +00:00
function initState ( s : State ) : void {
2023-04-25 14:56:37 +00:00
if ( s . runningState !== 0 ) {
throw new Error ( "State MUST be uninitialized" ) ;
}
s . blockTrees = new Int32Array ( 3091 ) ;
s . blockTrees [ 0 ] = 7 ;
s . distRbIdx = 3 ;
const maxDistanceAlphabetLimit : number = calculateDistanceAlphabetLimit ( 0x7FFFFFFC , 3 , 120 ) ;
s . distExtraBits = new Int8Array ( maxDistanceAlphabetLimit ) ;
s . distOffset = new Int32Array ( maxDistanceAlphabetLimit ) ;
initBitReader ( s ) ;
s . runningState = 1 ;
}
function close ( s : State ) : void {
if ( s . runningState === 0 ) {
throw new Error ( "State MUST be initialized" ) ;
}
if ( s . runningState === 11 ) {
return ;
}
s . runningState = 11 ;
2024-02-02 11:26:05 +00:00
s . input = new InputStream ( new Int8Array ( 0 ) ) ;
2023-04-25 14:56:37 +00:00
}
function decodeVarLenUnsignedByte ( s : State ) : number {
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
if ( readFewBits ( s , 1 ) !== 0 ) {
const n : number = readFewBits ( s , 3 ) ;
if ( n === 0 ) {
return 1 ;
} else {
return readFewBits ( s , n ) + ( 1 << n ) ;
}
}
return 0 ;
}
function decodeMetaBlockLength ( s : State ) : void {
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
s . inputEnd = readFewBits ( s , 1 ) ;
s . metaBlockLength = 0 ;
s . isUncompressed = 0 ;
s . isMetadata = 0 ;
if ( ( s . inputEnd !== 0 ) && readFewBits ( s , 1 ) !== 0 ) {
return ;
}
const sizeNibbles : number = readFewBits ( s , 2 ) + 4 ;
if ( sizeNibbles === 7 ) {
s . isMetadata = 1 ;
if ( readFewBits ( s , 1 ) !== 0 ) {
throw new Error ( "Corrupted reserved bit" ) ;
}
const sizeBytes : number = readFewBits ( s , 2 ) ;
if ( sizeBytes === 0 ) {
return ;
}
2024-02-02 11:26:05 +00:00
for ( let i = 0 ; i < sizeBytes ; ++ i ) {
2023-04-25 14:56:37 +00:00
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
const bits : number = readFewBits ( s , 8 ) ;
if ( bits === 0 && i + 1 === sizeBytes && sizeBytes > 1 ) {
throw new Error ( "Exuberant nibble" ) ;
}
2024-02-02 11:26:05 +00:00
s . metaBlockLength += bits << ( i * 8 ) ;
2023-04-25 14:56:37 +00:00
}
} else {
2024-02-02 11:26:05 +00:00
for ( let i = 0 ; i < sizeNibbles ; ++ i ) {
2023-04-25 14:56:37 +00:00
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
const bits : number = readFewBits ( s , 4 ) ;
if ( bits === 0 && i + 1 === sizeNibbles && sizeNibbles > 4 ) {
throw new Error ( "Exuberant nibble" ) ;
}
2024-02-02 11:26:05 +00:00
s . metaBlockLength += bits << ( i * 4 ) ;
2023-04-25 14:56:37 +00:00
}
}
s . metaBlockLength ++ ;
if ( s . inputEnd === 0 ) {
s . isUncompressed = readFewBits ( s , 1 ) ;
}
}
function readSymbol ( tableGroup : Int32Array , tableIdx : number , s : State ) : number {
let offset : number = tableGroup [ tableIdx ] ;
2024-02-02 11:26:05 +00:00
const v : number = s . accumulator32 >>> s . bitOffset ;
offset += v & 0xFF ;
2023-04-25 14:56:37 +00:00
const bits : number = tableGroup [ offset ] >> 16 ;
const sym : number = tableGroup [ offset ] & 0xFFFF ;
if ( bits <= 8 ) {
s . bitOffset += bits ;
return sym ;
}
offset += sym ;
const mask : number = ( 1 << bits ) - 1 ;
2024-02-02 11:26:05 +00:00
offset += ( v & mask ) >>> 8 ;
s . bitOffset += ( tableGroup [ offset ] >> 16 ) + 8 ;
2023-04-25 14:56:37 +00:00
return tableGroup [ offset ] & 0xFFFF ;
}
function readBlockLength ( tableGroup : Int32Array , tableIdx : number , s : State ) : number {
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
const code : number = readSymbol ( tableGroup , tableIdx , s ) ;
const n : number = BLOCK_LENGTH_N_BITS [ code ] ;
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
return BLOCK_LENGTH_OFFSET [ code ] + ( ( n <= 16 ) ? readFewBits ( s , n ) : readManyBits ( s , n ) ) ;
}
function moveToFront ( v : Int32Array , index : number ) : void {
2024-02-02 11:26:05 +00:00
let i : number = index ;
const value : number = v [ i ] ;
while ( i > 0 ) {
v [ i ] = v [ i - 1 ] ;
i -- ;
2023-04-25 14:56:37 +00:00
}
v [ 0 ] = value ;
}
function inverseMoveToFrontTransform ( v : Int8Array , vLen : number ) : void {
const mtf = new Int32Array ( 256 ) ;
2024-02-02 11:26:05 +00:00
for ( let i = 0 ; i < 256 ; ++ i ) {
2023-04-25 14:56:37 +00:00
mtf [ i ] = i ;
}
2024-02-02 11:26:05 +00:00
for ( let i = 0 ; i < vLen ; ++ i ) {
2023-04-25 14:56:37 +00:00
const index : number = v [ i ] & 0xFF ;
v [ i ] = mtf [ index ] ;
if ( index !== 0 ) {
moveToFront ( mtf , index ) ;
}
}
}
function readHuffmanCodeLengths ( codeLengthCodeLengths : Int32Array , numSymbols : number , codeLengths : Int32Array , s : State ) : void {
let symbol = 0 ;
let prevCodeLen = 8 ;
let repeat = 0 ;
let repeatCodeLen = 0 ;
let space = 32768 ;
const table = new Int32Array ( 33 ) ;
const tableIdx : number = table . length - 1 ;
buildHuffmanTable ( table , tableIdx , 5 , codeLengthCodeLengths , 18 ) ;
while ( symbol < numSymbols && space > 0 ) {
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
const p : number = ( s . accumulator32 >>> s . bitOffset ) & 31 ;
s . bitOffset += table [ p ] >> 16 ;
const codeLen : number = table [ p ] & 0xFFFF ;
if ( codeLen < 16 ) {
repeat = 0 ;
codeLengths [ symbol ++ ] = codeLen ;
if ( codeLen !== 0 ) {
prevCodeLen = codeLen ;
space -= 32768 >> codeLen ;
}
} else {
const extraBits : number = codeLen - 14 ;
let newLen = 0 ;
if ( codeLen === 16 ) {
newLen = prevCodeLen ;
}
if ( repeatCodeLen !== newLen ) {
repeat = 0 ;
repeatCodeLen = newLen ;
}
const oldRepeat : number = repeat ;
if ( repeat > 0 ) {
repeat -= 2 ;
2024-02-02 11:26:05 +00:00
repeat = repeat << extraBits ;
2023-04-25 14:56:37 +00:00
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
repeat += readFewBits ( s , extraBits ) + 3 ;
const repeatDelta : number = repeat - oldRepeat ;
if ( symbol + repeatDelta > numSymbols ) {
throw new Error ( "symbol + repeatDelta > numSymbols" ) ;
}
2024-02-02 11:26:05 +00:00
for ( let i = 0 ; i < repeatDelta ; ++ i ) {
2023-04-25 14:56:37 +00:00
codeLengths [ symbol ++ ] = repeatCodeLen ;
}
if ( repeatCodeLen !== 0 ) {
space -= repeatDelta << ( 15 - repeatCodeLen ) ;
}
}
}
if ( space !== 0 ) {
throw new Error ( "Unused space" ) ;
}
codeLengths . fill ( 0 , symbol , numSymbols ) ;
}
function checkDupes ( symbols : Int32Array , length : number ) : void {
for ( let i = 0 ; i < length - 1 ; ++ i ) {
for ( let j : number = i + 1 ; j < length ; ++ j ) {
if ( symbols [ i ] === symbols [ j ] ) {
throw new Error ( "Duplicate simple Huffman code symbol" ) ;
}
}
}
}
function readSimpleHuffmanCode ( alphabetSizeMax : number , alphabetSizeLimit : number , tableGroup : Int32Array , tableIdx : number , s : State ) : number {
const codeLengths = new Int32Array ( alphabetSizeLimit ) ;
const symbols = new Int32Array ( 4 ) ;
const maxBits : number = 1 + log2floor ( alphabetSizeMax - 1 ) ;
const numSymbols : number = readFewBits ( s , 2 ) + 1 ;
2024-02-02 11:26:05 +00:00
for ( let i = 0 ; i < numSymbols ; ++ i ) {
2023-04-25 14:56:37 +00:00
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
const symbol : number = readFewBits ( s , maxBits ) ;
if ( symbol >= alphabetSizeLimit ) {
throw new Error ( "Can't readHuffmanCode" ) ;
}
symbols [ i ] = symbol ;
}
checkDupes ( symbols , numSymbols ) ;
let histogramId : number = numSymbols ;
if ( numSymbols === 4 ) {
histogramId += readFewBits ( s , 1 ) ;
}
switch ( histogramId ) {
case 1 :
codeLengths [ symbols [ 0 ] ] = 1 ;
break ;
case 2 :
codeLengths [ symbols [ 0 ] ] = 1 ;
codeLengths [ symbols [ 1 ] ] = 1 ;
break ;
case 3 :
codeLengths [ symbols [ 0 ] ] = 1 ;
codeLengths [ symbols [ 1 ] ] = 2 ;
codeLengths [ symbols [ 2 ] ] = 2 ;
break ;
case 4 :
codeLengths [ symbols [ 0 ] ] = 2 ;
codeLengths [ symbols [ 1 ] ] = 2 ;
codeLengths [ symbols [ 2 ] ] = 2 ;
codeLengths [ symbols [ 3 ] ] = 2 ;
break ;
case 5 :
codeLengths [ symbols [ 0 ] ] = 1 ;
codeLengths [ symbols [ 1 ] ] = 2 ;
codeLengths [ symbols [ 2 ] ] = 3 ;
codeLengths [ symbols [ 3 ] ] = 3 ;
break ;
default :
break ;
}
return buildHuffmanTable ( tableGroup , tableIdx , 8 , codeLengths , alphabetSizeLimit ) ;
}
function readComplexHuffmanCode ( alphabetSizeLimit : number , skip : number , tableGroup : Int32Array , tableIdx : number , s : State ) : number {
const codeLengths = new Int32Array ( alphabetSizeLimit ) ;
const codeLengthCodeLengths = new Int32Array ( 18 ) ;
let space = 32 ;
let numCodes = 0 ;
2024-02-02 11:26:05 +00:00
for ( let i : number = skip ; i < 18 ; ++ i ) {
2023-04-25 14:56:37 +00:00
const codeLenIdx : number = CODE_LENGTH_CODE_ORDER [ i ] ;
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
const p : number = ( s . accumulator32 >>> s . bitOffset ) & 15 ;
s . bitOffset += FIXED_TABLE [ p ] >> 16 ;
const v : number = FIXED_TABLE [ p ] & 0xFFFF ;
codeLengthCodeLengths [ codeLenIdx ] = v ;
if ( v !== 0 ) {
2024-02-02 11:26:05 +00:00
space -= 32 >> v ;
2023-04-25 14:56:37 +00:00
numCodes ++ ;
2024-02-02 11:26:05 +00:00
if ( space <= 0 )
break ;
2023-04-25 14:56:37 +00:00
}
}
if ( space !== 0 && numCodes !== 1 ) {
throw new Error ( "Corrupted Huffman code histogram" ) ;
}
readHuffmanCodeLengths ( codeLengthCodeLengths , alphabetSizeLimit , codeLengths , s ) ;
return buildHuffmanTable ( tableGroup , tableIdx , 8 , codeLengths , alphabetSizeLimit ) ;
}
function readHuffmanCode ( alphabetSizeMax : number , alphabetSizeLimit : number , tableGroup : Int32Array , tableIdx : number , s : State ) : number {
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
const simpleCodeOrSkip : number = readFewBits ( s , 2 ) ;
if ( simpleCodeOrSkip === 1 ) {
return readSimpleHuffmanCode ( alphabetSizeMax , alphabetSizeLimit , tableGroup , tableIdx , s ) ;
} else {
return readComplexHuffmanCode ( alphabetSizeLimit , simpleCodeOrSkip , tableGroup , tableIdx , s ) ;
}
}
function decodeContextMap ( contextMapSize : number , contextMap : Int8Array , s : State ) : number {
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
const numTrees : number = decodeVarLenUnsignedByte ( s ) + 1 ;
if ( numTrees === 1 ) {
contextMap . fill ( 0 , 0 , contextMapSize ) ;
return numTrees ;
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
const useRleForZeros : number = readFewBits ( s , 1 ) ;
let maxRunLengthPrefix = 0 ;
if ( useRleForZeros !== 0 ) {
maxRunLengthPrefix = readFewBits ( s , 4 ) + 1 ;
}
const alphabetSize : number = numTrees + maxRunLengthPrefix ;
const tableSize : number = MAX_HUFFMAN_TABLE_SIZE [ ( alphabetSize + 31 ) >> 5 ] ;
const table = new Int32Array ( tableSize + 1 ) ;
const tableIdx : number = table . length - 1 ;
readHuffmanCode ( alphabetSize , alphabetSize , table , tableIdx , s ) ;
2024-02-02 11:26:05 +00:00
let i = 0 ;
while ( i < contextMapSize ) {
2023-04-25 14:56:37 +00:00
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
const code : number = readSymbol ( table , tableIdx , s ) ;
if ( code === 0 ) {
contextMap [ i ] = 0 ;
i ++ ;
} else if ( code <= maxRunLengthPrefix ) {
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
let reps : number = ( 1 << code ) + readFewBits ( s , code ) ;
while ( reps !== 0 ) {
if ( i >= contextMapSize ) {
throw new Error ( "Corrupted context map" ) ;
}
contextMap [ i ] = 0 ;
i ++ ;
reps -- ;
}
} else {
2024-02-02 11:26:05 +00:00
contextMap [ i ] = code - maxRunLengthPrefix ;
2023-04-25 14:56:37 +00:00
i ++ ;
}
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
if ( readFewBits ( s , 1 ) === 1 ) {
inverseMoveToFrontTransform ( contextMap , contextMapSize ) ;
}
return numTrees ;
}
function decodeBlockTypeAndLength ( s : State , treeType : number , numBlockTypes : number ) : number {
const ringBuffers : Int32Array = s . rings ;
const offset : number = 4 + treeType * 2 ;
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
let blockType : number = readSymbol ( s . blockTrees , 2 * treeType , s ) ;
const result : number = readBlockLength ( s . blockTrees , 2 * treeType + 1 , s ) ;
if ( blockType === 1 ) {
blockType = ringBuffers [ offset + 1 ] + 1 ;
} else if ( blockType === 0 ) {
blockType = ringBuffers [ offset ] ;
} else {
blockType -= 2 ;
}
if ( blockType >= numBlockTypes ) {
blockType -= numBlockTypes ;
}
ringBuffers [ offset ] = ringBuffers [ offset + 1 ] ;
ringBuffers [ offset + 1 ] = blockType ;
return result ;
}
function decodeLiteralBlockSwitch ( s : State ) : void {
s . literalBlockLength = decodeBlockTypeAndLength ( s , 0 , s . numLiteralBlockTypes ) ;
const literalBlockType : number = s . rings [ 5 ] ;
s . contextMapSlice = literalBlockType << 6 ;
s . literalTreeIdx = s . contextMap [ s . contextMapSlice ] & 0xFF ;
const contextMode : number = s . contextModes [ literalBlockType ] ;
s . contextLookupOffset1 = contextMode << 9 ;
s . contextLookupOffset2 = s . contextLookupOffset1 + 256 ;
}
function decodeCommandBlockSwitch ( s : State ) : void {
s . commandBlockLength = decodeBlockTypeAndLength ( s , 1 , s . numCommandBlockTypes ) ;
s . commandTreeIdx = s . rings [ 7 ] ;
}
function decodeDistanceBlockSwitch ( s : State ) : void {
s . distanceBlockLength = decodeBlockTypeAndLength ( s , 2 , s . numDistanceBlockTypes ) ;
s . distContextMapSlice = s . rings [ 9 ] << 2 ;
}
function maybeReallocateRingBuffer ( s : State ) : void {
let newSize : number = s . maxRingBufferSize ;
if ( newSize > s . expectedTotalSize ) {
const minimalNewSize : number = s . expectedTotalSize ;
while ( ( newSize >> 1 ) > minimalNewSize ) {
2024-02-02 11:26:05 +00:00
newSize = newSize >> 1 ;
2023-04-25 14:56:37 +00:00
}
if ( ( s . inputEnd === 0 ) && newSize < 16384 && s . maxRingBufferSize >= 16384 ) {
newSize = 16384 ;
}
}
if ( newSize <= s . ringBufferSize ) {
return ;
}
const ringBufferSizeWithSlack : number = newSize + 37 ;
const newBuffer = new Int8Array ( ringBufferSizeWithSlack ) ;
2024-02-02 11:26:05 +00:00
const oldBuffer : Int8Array = s . ringBuffer ;
if ( oldBuffer . length !== 0 ) {
newBuffer . set ( oldBuffer . subarray ( 0 , s . ringBufferSize ) , 0 ) ;
2023-04-25 14:56:37 +00:00
}
s . ringBuffer = newBuffer ;
s . ringBufferSize = newSize ;
}
function readNextMetablockHeader ( s : State ) : void {
if ( s . inputEnd !== 0 ) {
s . nextRunningState = 10 ;
s . runningState = 12 ;
return ;
}
s . literalTreeGroup = new Int32Array ( 0 ) ;
s . commandTreeGroup = new Int32Array ( 0 ) ;
s . distanceTreeGroup = new Int32Array ( 0 ) ;
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
decodeMetaBlockLength ( s ) ;
if ( ( s . metaBlockLength === 0 ) && ( s . isMetadata === 0 ) ) {
return ;
}
if ( ( s . isUncompressed !== 0 ) || ( s . isMetadata !== 0 ) ) {
jumpToByteBoundary ( s ) ;
s . runningState = ( s . isMetadata !== 0 ) ? 5 : 6 ;
} else {
s . runningState = 3 ;
}
if ( s . isMetadata !== 0 ) {
return ;
}
s . expectedTotalSize += s . metaBlockLength ;
if ( s . expectedTotalSize > 1 << 30 ) {
s . expectedTotalSize = 1 << 30 ;
}
if ( s . ringBufferSize < s . maxRingBufferSize ) {
maybeReallocateRingBuffer ( s ) ;
}
}
function readMetablockPartition ( s : State , treeType : number , numBlockTypes : number ) : number {
let offset : number = s . blockTrees [ 2 * treeType ] ;
if ( numBlockTypes <= 1 ) {
s . blockTrees [ 2 * treeType + 1 ] = offset ;
s . blockTrees [ 2 * treeType + 2 ] = offset ;
return 1 << 28 ;
}
const blockTypeAlphabetSize : number = numBlockTypes + 2 ;
offset += readHuffmanCode ( blockTypeAlphabetSize , blockTypeAlphabetSize , s . blockTrees , 2 * treeType , s ) ;
s . blockTrees [ 2 * treeType + 1 ] = offset ;
const blockLengthAlphabetSize = 26 ;
offset += readHuffmanCode ( blockLengthAlphabetSize , blockLengthAlphabetSize , s . blockTrees , 2 * treeType + 1 , s ) ;
s . blockTrees [ 2 * treeType + 2 ] = offset ;
return readBlockLength ( s . blockTrees , 2 * treeType + 1 , s ) ;
}
function calculateDistanceLut ( s : State , alphabetSizeLimit : number ) : void {
const distExtraBits : Int8Array = s . distExtraBits ;
const distOffset : Int32Array = s . distOffset ;
const npostfix : number = s . distancePostfixBits ;
const ndirect : number = s . numDirectDistanceCodes ;
const postfix : number = 1 << npostfix ;
let bits = 1 ;
let half = 0 ;
let i = 16 ;
for ( let j = 0 ; j < ndirect ; ++ j ) {
distExtraBits [ i ] = 0 ;
distOffset [ i ] = j + 1 ;
++ i ;
}
while ( i < alphabetSizeLimit ) {
const base : number = ndirect + ( ( ( ( 2 + half ) << bits ) - 4 ) << npostfix ) + 1 ;
for ( let j = 0 ; j < postfix ; ++ j ) {
distExtraBits [ i ] = bits ;
distOffset [ i ] = base + j ;
++ i ;
}
bits = bits + half ;
half = half ^ 1 ;
}
}
function readMetablockHuffmanCodesAndContextMaps ( s : State ) : void {
s . numLiteralBlockTypes = decodeVarLenUnsignedByte ( s ) + 1 ;
s . literalBlockLength = readMetablockPartition ( s , 0 , s . numLiteralBlockTypes ) ;
s . numCommandBlockTypes = decodeVarLenUnsignedByte ( s ) + 1 ;
s . commandBlockLength = readMetablockPartition ( s , 1 , s . numCommandBlockTypes ) ;
s . numDistanceBlockTypes = decodeVarLenUnsignedByte ( s ) + 1 ;
s . distanceBlockLength = readMetablockPartition ( s , 2 , s . numDistanceBlockTypes ) ;
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
s . distancePostfixBits = readFewBits ( s , 2 ) ;
s . numDirectDistanceCodes = readFewBits ( s , 4 ) << s . distancePostfixBits ;
s . contextModes = new Int8Array ( s . numLiteralBlockTypes ) ;
2024-02-02 11:26:05 +00:00
let i = 0 ;
while ( i < s . numLiteralBlockTypes ) {
2023-04-25 14:56:37 +00:00
const limit : number = Math . min ( i + 96 , s . numLiteralBlockTypes ) ;
2024-02-02 11:26:05 +00:00
while ( i < limit ) {
2023-04-25 14:56:37 +00:00
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
s . contextModes [ i ] = readFewBits ( s , 2 ) ;
2024-02-02 11:26:05 +00:00
i ++ ;
2023-04-25 14:56:37 +00:00
}
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
}
2024-02-02 11:26:05 +00:00
const contextMapLength : number = s . numLiteralBlockTypes << 6 ;
s . contextMap = new Int8Array ( contextMapLength ) ;
const numLiteralTrees : number = decodeContextMap ( contextMapLength , s . contextMap , s ) ;
2023-04-25 14:56:37 +00:00
s . trivialLiteralContext = 1 ;
2024-02-02 11:26:05 +00:00
for ( let j = 0 ; j < contextMapLength ; ++ j ) {
2023-04-25 14:56:37 +00:00
if ( s . contextMap [ j ] !== j >> 6 ) {
s . trivialLiteralContext = 0 ;
break ;
}
}
s . distContextMap = new Int8Array ( s . numDistanceBlockTypes << 2 ) ;
const numDistTrees : number = decodeContextMap ( s . numDistanceBlockTypes << 2 , s . distContextMap , s ) ;
s . literalTreeGroup = decodeHuffmanTreeGroup ( 256 , 256 , numLiteralTrees , s ) ;
s . commandTreeGroup = decodeHuffmanTreeGroup ( 704 , 704 , s . numCommandBlockTypes , s ) ;
let distanceAlphabetSizeMax : number = calculateDistanceAlphabetSize ( s . distancePostfixBits , s . numDirectDistanceCodes , 24 ) ;
let distanceAlphabetSizeLimit : number = distanceAlphabetSizeMax ;
if ( s . isLargeWindow === 1 ) {
distanceAlphabetSizeMax = calculateDistanceAlphabetSize ( s . distancePostfixBits , s . numDirectDistanceCodes , 62 ) ;
distanceAlphabetSizeLimit = calculateDistanceAlphabetLimit ( 0x7FFFFFFC , s . distancePostfixBits , s . numDirectDistanceCodes ) ;
}
s . distanceTreeGroup = decodeHuffmanTreeGroup ( distanceAlphabetSizeMax , distanceAlphabetSizeLimit , numDistTrees , s ) ;
calculateDistanceLut ( s , distanceAlphabetSizeLimit ) ;
s . contextMapSlice = 0 ;
s . distContextMapSlice = 0 ;
s . contextLookupOffset1 = s . contextModes [ 0 ] * 512 ;
s . contextLookupOffset2 = s . contextLookupOffset1 + 256 ;
s . literalTreeIdx = 0 ;
s . commandTreeIdx = 0 ;
s . rings [ 4 ] = 1 ;
s . rings [ 5 ] = 0 ;
s . rings [ 6 ] = 1 ;
s . rings [ 7 ] = 0 ;
s . rings [ 8 ] = 1 ;
s . rings [ 9 ] = 0 ;
}
function copyUncompressedData ( s : State ) : void {
const ringBuffer : Int8Array = s . ringBuffer ;
if ( s . metaBlockLength <= 0 ) {
reload ( s ) ;
s . runningState = 2 ;
return ;
}
const chunkLength : number = Math . min ( s . ringBufferSize - s . pos , s . metaBlockLength ) ;
copyRawBytes ( s , ringBuffer , s . pos , chunkLength ) ;
s . metaBlockLength -= chunkLength ;
s . pos += chunkLength ;
if ( s . pos === s . ringBufferSize ) {
s . nextRunningState = 6 ;
s . runningState = 12 ;
return ;
}
reload ( s ) ;
s . runningState = 2 ;
}
function writeRingBuffer ( s : State ) : number {
const toWrite : number = Math . min ( s . outputLength - s . outputUsed , s . ringBufferBytesReady - s . ringBufferBytesWritten ) ;
if ( toWrite !== 0 ) {
s . output . set ( s . ringBuffer . subarray ( s . ringBufferBytesWritten , s . ringBufferBytesWritten + toWrite ) , s . outputOffset + s . outputUsed ) ;
s . outputUsed += toWrite ;
s . ringBufferBytesWritten += toWrite ;
}
if ( s . outputUsed < s . outputLength ) {
return 1 ;
} else {
return 0 ;
}
}
function decodeHuffmanTreeGroup ( alphabetSizeMax : number , alphabetSizeLimit : number , n : number , s : State ) : Int32Array {
const maxTableSize : number = MAX_HUFFMAN_TABLE_SIZE [ ( alphabetSizeLimit + 31 ) >> 5 ] ;
const group = new Int32Array ( n + n * maxTableSize ) ;
let next : number = n ;
for ( let i = 0 ; i < n ; ++ i ) {
group [ i ] = next ;
next += readHuffmanCode ( alphabetSizeMax , alphabetSizeLimit , group , i , s ) ;
}
return group ;
}
function calculateFence ( s : State ) : number {
let result : number = s . ringBufferSize ;
if ( s . isEager !== 0 ) {
result = Math . min ( result , s . ringBufferBytesWritten + s . outputLength - s . outputUsed ) ;
}
return result ;
}
function doUseDictionary ( s : State , fence : number ) : void {
if ( s . distance > 0x7FFFFFFC ) {
throw new Error ( "Invalid backward reference" ) ;
}
const address : number = s . distance - s . maxDistance - 1 - s . cdTotalSize ;
if ( address < 0 ) {
initializeCompoundDictionaryCopy ( s , - address - 1 , s . copyLength ) ;
s . runningState = 14 ;
} else {
const dictionaryData : ByteBuffer = data ;
const wordLength : number = s . copyLength ;
if ( wordLength > 31 ) {
throw new Error ( "Invalid backward reference" ) ;
}
const shift : number = sizeBits [ wordLength ] ;
if ( shift === 0 ) {
throw new Error ( "Invalid backward reference" ) ;
}
let offset : number = offsets [ wordLength ] ;
const mask : number = ( 1 << shift ) - 1 ;
const wordIdx : number = address & mask ;
const transformIdx : number = address >>> shift ;
offset += wordIdx * wordLength ;
const transforms : Transforms = RFC_TRANSFORMS ;
if ( transformIdx >= transforms . numTransforms ) {
throw new Error ( "Invalid backward reference" ) ;
}
const len : number = transformDictionaryWord ( s . ringBuffer , s . pos , dictionaryData , offset , wordLength , transforms , transformIdx ) ;
s . pos += len ;
s . metaBlockLength -= len ;
if ( s . pos >= fence ) {
s . nextRunningState = 4 ;
s . runningState = 12 ;
return ;
}
s . runningState = 4 ;
}
}
function initializeCompoundDictionary ( s : State ) : void {
s . cdBlockMap = new Int8Array ( 256 ) ;
let blockBits = 8 ;
while ( ( ( s . cdTotalSize - 1 ) >>> blockBits ) !== 0 ) {
blockBits ++ ;
}
blockBits -= 8 ;
s . cdBlockBits = blockBits ;
let cursor = 0 ;
let index = 0 ;
while ( cursor < s . cdTotalSize ) {
while ( s . cdChunkOffsets [ index + 1 ] < cursor ) {
index ++ ;
}
s . cdBlockMap [ cursor >>> blockBits ] = index ;
cursor += 1 << blockBits ;
}
}
function initializeCompoundDictionaryCopy ( s : State , address : number , length : number ) : void {
if ( s . cdBlockBits === - 1 ) {
initializeCompoundDictionary ( s ) ;
}
let index : number = s . cdBlockMap [ address >>> s . cdBlockBits ] ;
while ( address >= s . cdChunkOffsets [ index + 1 ] ) {
index ++ ;
}
if ( s . cdTotalSize > address + length ) {
throw new Error ( "Invalid backward reference" ) ;
}
s . distRbIdx = ( s . distRbIdx + 1 ) & 0x3 ;
s . rings [ s . distRbIdx ] = s . distance ;
s . metaBlockLength -= length ;
s . cdBrIndex = index ;
s . cdBrOffset = address - s . cdChunkOffsets [ index ] ;
s . cdBrLength = length ;
s . cdBrCopied = 0 ;
}
function copyFromCompoundDictionary ( s : State , fence : number ) : number {
let pos : number = s . pos ;
const origPos : number = pos ;
while ( s . cdBrLength !== s . cdBrCopied ) {
const space : number = fence - pos ;
const chunkLength : number = s . cdChunkOffsets [ s . cdBrIndex + 1 ] - s . cdChunkOffsets [ s . cdBrIndex ] ;
const remChunkLength : number = chunkLength - s . cdBrOffset ;
let length : number = s . cdBrLength - s . cdBrCopied ;
if ( length > remChunkLength ) {
length = remChunkLength ;
}
if ( length > space ) {
length = space ;
}
s . ringBuffer . set ( s . cdChunks [ s . cdBrIndex ] . slice ( s . cdBrOffset , s . cdBrOffset + length ) , pos ) ;
pos += length ;
s . cdBrOffset += length ;
s . cdBrCopied += length ;
if ( length === remChunkLength ) {
s . cdBrIndex ++ ;
s . cdBrOffset = 0 ;
}
if ( pos >= fence ) {
break ;
}
}
return pos - origPos ;
}
function decompress ( s : State ) : void {
if ( s . runningState === 0 ) {
throw new Error ( "Can't decompress until initialized" ) ;
}
if ( s . runningState === 11 ) {
throw new Error ( "Can't decompress after close" ) ;
}
if ( s . runningState === 1 ) {
const windowBits : number = decodeWindowBits ( s ) ;
if ( windowBits === - 1 ) {
throw new Error ( "Invalid 'windowBits' code" ) ;
}
s . maxRingBufferSize = 1 << windowBits ;
s . maxBackwardDistance = s . maxRingBufferSize - 16 ;
s . runningState = 2 ;
}
let fence : number = calculateFence ( s ) ;
let ringBufferMask : number = s . ringBufferSize - 1 ;
let ringBuffer : Int8Array = s . ringBuffer ;
while ( s . runningState !== 10 ) {
switch ( s . runningState ) {
case 2 :
if ( s . metaBlockLength < 0 ) {
throw new Error ( "Invalid metablock length" ) ;
}
readNextMetablockHeader ( s ) ;
fence = calculateFence ( s ) ;
ringBufferMask = s . ringBufferSize - 1 ;
ringBuffer = s . ringBuffer ;
continue ;
2023-08-10 11:45:38 +00:00
// Fallthrough case in switch is intentional.
// tslint:disable-next-line:ban-ts-suppressions
// @ts-ignore error TS7029: Fallthrough case in switch.
2023-04-25 14:56:37 +00:00
case 3 :
readMetablockHuffmanCodesAndContextMaps ( s ) ;
s . runningState = 4 ;
2023-08-10 11:45:38 +00:00
// Fallthrough case in switch is intentional.
// tslint:disable-next-line:ban-ts-suppressions
// @ts-ignore error TS7029: Fallthrough case in switch.
2023-04-25 14:56:37 +00:00
case 4 :
if ( s . metaBlockLength <= 0 ) {
s . runningState = 2 ;
continue ;
}
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . commandBlockLength === 0 ) {
decodeCommandBlockSwitch ( s ) ;
}
s . commandBlockLength -- ;
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
const cmdCode : number = readSymbol ( s . commandTreeGroup , s . commandTreeIdx , s ) << 2 ;
const insertAndCopyExtraBits : number = CMD_LOOKUP [ cmdCode ] ;
const insertLengthOffset : number = CMD_LOOKUP [ cmdCode + 1 ] ;
const copyLengthOffset : number = CMD_LOOKUP [ cmdCode + 2 ] ;
s . distanceCode = CMD_LOOKUP [ cmdCode + 3 ] ;
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
const insertLengthExtraBits : number = insertAndCopyExtraBits & 0xFF ;
s . insertLength = insertLengthOffset + ( ( insertLengthExtraBits <= 16 ) ? readFewBits ( s , insertLengthExtraBits ) : readManyBits ( s , insertLengthExtraBits ) ) ;
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
const copyLengthExtraBits : number = insertAndCopyExtraBits >> 8 ;
s . copyLength = copyLengthOffset + ( ( copyLengthExtraBits <= 16 ) ? readFewBits ( s , copyLengthExtraBits ) : readManyBits ( s , copyLengthExtraBits ) ) ;
s . j = 0 ;
s . runningState = 7 ;
2023-08-10 11:45:38 +00:00
// Fallthrough case in switch is intentional.
// tslint:disable-next-line:ban-ts-suppressions
// @ts-ignore error TS7029: Fallthrough case in switch.
2023-04-25 14:56:37 +00:00
case 7 :
if ( s . trivialLiteralContext !== 0 ) {
while ( s . j < s . insertLength ) {
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . literalBlockLength === 0 ) {
decodeLiteralBlockSwitch ( s ) ;
}
s . literalBlockLength -- ;
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
ringBuffer [ s . pos ] = readSymbol ( s . literalTreeGroup , s . literalTreeIdx , s ) ;
s . pos ++ ;
s . j ++ ;
if ( s . pos >= fence ) {
s . nextRunningState = 7 ;
s . runningState = 12 ;
break ;
}
}
} else {
let prevByte1 : number = ringBuffer [ ( s . pos - 1 ) & ringBufferMask ] & 0xFF ;
let prevByte2 : number = ringBuffer [ ( s . pos - 2 ) & ringBufferMask ] & 0xFF ;
while ( s . j < s . insertLength ) {
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . literalBlockLength === 0 ) {
decodeLiteralBlockSwitch ( s ) ;
}
const literalContext : number = LOOKUP [ s . contextLookupOffset1 + prevByte1 ] | LOOKUP [ s . contextLookupOffset2 + prevByte2 ] ;
const literalTreeIdx : number = s . contextMap [ s . contextMapSlice + literalContext ] & 0xFF ;
s . literalBlockLength -- ;
prevByte2 = prevByte1 ;
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
prevByte1 = readSymbol ( s . literalTreeGroup , literalTreeIdx , s ) ;
ringBuffer [ s . pos ] = prevByte1 ;
s . pos ++ ;
s . j ++ ;
if ( s . pos >= fence ) {
s . nextRunningState = 7 ;
s . runningState = 12 ;
break ;
}
}
}
if ( s . runningState !== 7 ) {
continue ;
}
s . metaBlockLength -= s . insertLength ;
if ( s . metaBlockLength <= 0 ) {
s . runningState = 4 ;
continue ;
}
let distanceCode : number = s . distanceCode ;
if ( distanceCode < 0 ) {
s . distance = s . rings [ s . distRbIdx ] ;
} else {
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . distanceBlockLength === 0 ) {
decodeDistanceBlockSwitch ( s ) ;
}
s . distanceBlockLength -- ;
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
const distTreeIdx : number = s . distContextMap [ s . distContextMapSlice + distanceCode ] & 0xFF ;
distanceCode = readSymbol ( s . distanceTreeGroup , distTreeIdx , s ) ;
if ( distanceCode < 16 ) {
const index : number = ( s . distRbIdx + DISTANCE_SHORT_CODE_INDEX_OFFSET [ distanceCode ] ) & 0x3 ;
s . distance = s . rings [ index ] + DISTANCE_SHORT_CODE_VALUE_OFFSET [ distanceCode ] ;
if ( s . distance < 0 ) {
throw new Error ( "Negative distance" ) ;
}
} else {
const extraBits : number = s . distExtraBits [ distanceCode ] ;
let bits : number ;
if ( s . bitOffset + extraBits <= 32 ) {
bits = readFewBits ( s , extraBits ) ;
} else {
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
bits = ( extraBits <= 16 ) ? readFewBits ( s , extraBits ) : readManyBits ( s , extraBits ) ;
}
s . distance = s . distOffset [ distanceCode ] + ( bits << s . distancePostfixBits ) ;
}
}
if ( s . maxDistance !== s . maxBackwardDistance && s . pos < s . maxBackwardDistance ) {
s . maxDistance = s . pos ;
} else {
s . maxDistance = s . maxBackwardDistance ;
}
if ( s . distance > s . maxDistance ) {
s . runningState = 9 ;
continue ;
}
if ( distanceCode > 0 ) {
s . distRbIdx = ( s . distRbIdx + 1 ) & 0x3 ;
s . rings [ s . distRbIdx ] = s . distance ;
}
if ( s . copyLength > s . metaBlockLength ) {
throw new Error ( "Invalid backward reference" ) ;
}
s . j = 0 ;
s . runningState = 8 ;
case 8 :
let src : number = ( s . pos - s . distance ) & ringBufferMask ;
let dst : number = s . pos ;
const copyLength : number = s . copyLength - s . j ;
const srcEnd : number = src + copyLength ;
const dstEnd : number = dst + copyLength ;
if ( ( srcEnd < ringBufferMask ) && ( dstEnd < ringBufferMask ) ) {
if ( copyLength < 12 || ( srcEnd > dst && dstEnd > src ) ) {
2024-02-02 11:26:05 +00:00
const numQuads : number = ( copyLength + 3 ) >> 2 ;
for ( let k = 0 ; k < numQuads ; ++ k ) {
2023-04-25 14:56:37 +00:00
ringBuffer [ dst ++ ] = ringBuffer [ src ++ ] ;
ringBuffer [ dst ++ ] = ringBuffer [ src ++ ] ;
ringBuffer [ dst ++ ] = ringBuffer [ src ++ ] ;
ringBuffer [ dst ++ ] = ringBuffer [ src ++ ] ;
}
} else {
ringBuffer . copyWithin ( dst , src , srcEnd ) ;
}
s . j += copyLength ;
s . metaBlockLength -= copyLength ;
s . pos += copyLength ;
} else {
2024-02-02 11:26:05 +00:00
while ( s . j < s . copyLength ) {
2023-04-25 14:56:37 +00:00
ringBuffer [ s . pos ] = ringBuffer [ ( s . pos - s . distance ) & ringBufferMask ] ;
s . metaBlockLength -- ;
s . pos ++ ;
s . j ++ ;
if ( s . pos >= fence ) {
s . nextRunningState = 8 ;
s . runningState = 12 ;
break ;
}
}
}
if ( s . runningState === 8 ) {
s . runningState = 4 ;
}
continue ;
case 9 :
doUseDictionary ( s , fence ) ;
continue ;
case 14 :
s . pos += copyFromCompoundDictionary ( s , fence ) ;
if ( s . pos >= fence ) {
s . nextRunningState = 14 ;
s . runningState = 12 ;
return ;
}
s . runningState = 4 ;
continue ;
case 5 :
while ( s . metaBlockLength > 0 ) {
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
readFewBits ( s , 8 ) ;
s . metaBlockLength -- ;
}
s . runningState = 2 ;
continue ;
case 6 :
copyUncompressedData ( s ) ;
continue ;
2023-08-10 11:45:38 +00:00
// Fallthrough case in switch is intentional.
// tslint:disable-next-line:ban-ts-suppressions
// @ts-ignore error TS7029: Fallthrough case in switch.
2023-04-25 14:56:37 +00:00
case 12 :
s . ringBufferBytesReady = Math . min ( s . pos , s . ringBufferSize ) ;
s . runningState = 13 ;
case 13 :
if ( writeRingBuffer ( s ) === 0 ) {
return ;
}
if ( s . pos >= s . maxBackwardDistance ) {
s . maxDistance = s . maxBackwardDistance ;
}
if ( s . pos >= s . ringBufferSize ) {
if ( s . pos > s . ringBufferSize ) {
ringBuffer . copyWithin ( 0 , s . ringBufferSize , s . pos ) ;
}
2024-02-02 11:26:05 +00:00
s . pos = s . pos & ringBufferMask ;
2023-04-25 14:56:37 +00:00
s . ringBufferBytesWritten = 0 ;
}
s . runningState = s . nextRunningState ;
continue ;
default :
throw new Error ( "Unexpected state " + valueOf ( s . runningState ) ) ;
}
}
if ( s . runningState === 10 ) {
if ( s . metaBlockLength < 0 ) {
throw new Error ( "Invalid metablock length" ) ;
}
jumpToByteBoundary ( s ) ;
checkHealth ( s , 1 ) ;
}
}
class Transforms {
numTransforms = 0 ;
triplets = new Int32Array ( 0 ) ;
prefixSuffixStorage = new Int8Array ( 0 ) ;
prefixSuffixHeads = new Int32Array ( 0 ) ;
params = new Int16Array ( 0 ) ;
constructor ( numTransforms : number , prefixSuffixLen : number , prefixSuffixCount : number ) {
this . numTransforms = numTransforms ;
this . triplets = new Int32Array ( numTransforms * 3 ) ;
this . params = new Int16Array ( numTransforms ) ;
this . prefixSuffixStorage = new Int8Array ( prefixSuffixLen ) ;
this . prefixSuffixHeads = new Int32Array ( prefixSuffixCount + 1 ) ;
}
}
const RFC_TRANSFORMS = new Transforms ( 121 , 167 , 50 ) ;
function unpackTransforms ( prefixSuffix : Int8Array , prefixSuffixHeads : Int32Array , transforms : Int32Array , prefixSuffixSrc : string , transformsSrc : string ) : void {
const n : number = prefixSuffixSrc . length ;
let index = 1 ;
let j = 0 ;
for ( let i = 0 ; i < n ; ++ i ) {
const c : number = prefixSuffixSrc . charCodeAt ( i ) ;
if ( c === 35 ) {
prefixSuffixHeads [ index ++ ] = j ;
} else {
prefixSuffix [ j ++ ] = c ;
}
}
for ( let i = 0 ; i < 363 ; ++ i ) {
transforms [ i ] = transformsSrc . charCodeAt ( i ) - 32 ;
}
}
{
unpackTransforms ( RFC_TRANSFORMS . prefixSuffixStorage , RFC_TRANSFORMS . prefixSuffixHeads , RFC_TRANSFORMS . triplets , "# #s #, #e #.# the #.com/#\xC2\xA0# of # and # in # to #\"#\">#\n#]# for # a # that #. # with #'# from # by #. The # on # as # is #ing #\n\t#:#ed #(# at #ly #=\"# of the #. This #,# not #er #al #='#ful #ive #less #est #ize #ous #" , " !! ! , *! &! \" ! ) * * - ! # ! #!*! + ,$ ! - % . / # 0 1 . \" 2 3!* 4% ! # / 5 6 7 8 0 1 & $ 9 + : ; < ' != > ?! 4 @ 4 2 & A *# ( B C& ) % ) !*# *-% A +! *. D! %' & E *6 F G% ! *A *% H! D I!+! J!+ K +- *4! A L!*4 M N +6 O!*% +.! K *G P +%( ! G *D +D Q +# *K!*G!+D!+# +G +A +4!+% +K!+4!*D!+K!*K" ) ;
}
2024-02-02 11:26:05 +00:00
function transformDictionaryWord ( dst : Int8Array , dstOffset : number , src : ByteBuffer , srcOffset : number , wordLen : number , transforms : Transforms , transformIndex : number ) : number {
2023-04-25 14:56:37 +00:00
let offset : number = dstOffset ;
const triplets : Int32Array = transforms . triplets ;
const prefixSuffixStorage : Int8Array = transforms . prefixSuffixStorage ;
const prefixSuffixHeads : Int32Array = transforms . prefixSuffixHeads ;
const transformOffset : number = 3 * transformIndex ;
const prefixIdx : number = triplets [ transformOffset ] ;
const transformType : number = triplets [ transformOffset + 1 ] ;
const suffixIdx : number = triplets [ transformOffset + 2 ] ;
let prefix : number = prefixSuffixHeads [ prefixIdx ] ;
const prefixEnd : number = prefixSuffixHeads [ prefixIdx + 1 ] ;
let suffix : number = prefixSuffixHeads [ suffixIdx ] ;
const suffixEnd : number = prefixSuffixHeads [ suffixIdx + 1 ] ;
let omitFirst : number = transformType - 11 ;
let omitLast : number = transformType ;
if ( omitFirst < 1 || omitFirst > 9 ) {
omitFirst = 0 ;
}
if ( omitLast < 1 || omitLast > 9 ) {
omitLast = 0 ;
}
while ( prefix !== prefixEnd ) {
dst [ offset ++ ] = prefixSuffixStorage [ prefix ++ ] ;
}
2024-02-02 11:26:05 +00:00
let len : number = wordLen ;
2023-04-25 14:56:37 +00:00
if ( omitFirst > len ) {
omitFirst = len ;
}
2024-02-02 11:26:05 +00:00
let dictOffset : number = srcOffset + omitFirst ;
2023-04-25 14:56:37 +00:00
len -= omitFirst ;
len -= omitLast ;
let i : number = len ;
while ( i > 0 ) {
2024-02-02 11:26:05 +00:00
dst [ offset ++ ] = src [ dictOffset ++ ] ;
2023-04-25 14:56:37 +00:00
i -- ;
}
if ( transformType === 10 || transformType === 11 ) {
let uppercaseOffset : number = offset - len ;
if ( transformType === 10 ) {
len = 1 ;
}
while ( len > 0 ) {
const c0 : number = dst [ uppercaseOffset ] & 0xFF ;
if ( c0 < 0xC0 ) {
if ( c0 >= 97 && c0 <= 122 ) {
2024-02-02 11:26:05 +00:00
dst [ uppercaseOffset ] = dst [ uppercaseOffset ] ^ 32 ;
2023-04-25 14:56:37 +00:00
}
uppercaseOffset += 1 ;
len -= 1 ;
} else if ( c0 < 0xE0 ) {
2024-02-02 11:26:05 +00:00
dst [ uppercaseOffset + 1 ] = dst [ uppercaseOffset + 1 ] ^ 32 ;
2023-04-25 14:56:37 +00:00
uppercaseOffset += 2 ;
len -= 2 ;
} else {
2024-02-02 11:26:05 +00:00
dst [ uppercaseOffset + 2 ] = dst [ uppercaseOffset + 2 ] ^ 5 ;
2023-04-25 14:56:37 +00:00
uppercaseOffset += 3 ;
len -= 3 ;
}
}
} else if ( transformType === 21 || transformType === 22 ) {
let shiftOffset : number = offset - len ;
const param : number = transforms . params [ transformIndex ] ;
let scalar : number = ( param & 0x7FFF ) + ( 0x1000000 - ( param & 0x8000 ) ) ;
while ( len > 0 ) {
let step = 1 ;
const c0 : number = dst [ shiftOffset ] & 0xFF ;
if ( c0 < 0x80 ) {
scalar += c0 ;
2024-02-02 11:26:05 +00:00
dst [ shiftOffset ] = scalar & 0x7F ;
2023-04-25 14:56:37 +00:00
} else if ( c0 < 0xC0 ) {
} else if ( c0 < 0xE0 ) {
if ( len >= 2 ) {
const c1 : number = dst [ shiftOffset + 1 ] ;
scalar += ( c1 & 0x3F ) | ( ( c0 & 0x1F ) << 6 ) ;
2024-02-02 11:26:05 +00:00
dst [ shiftOffset ] = 0xC0 | ( ( scalar >> 6 ) & 0x1F ) ;
dst [ shiftOffset + 1 ] = ( c1 & 0xC0 ) | ( scalar & 0x3F ) ;
2023-04-25 14:56:37 +00:00
step = 2 ;
} else {
step = len ;
}
} else if ( c0 < 0xF0 ) {
if ( len >= 3 ) {
const c1 : number = dst [ shiftOffset + 1 ] ;
const c2 : number = dst [ shiftOffset + 2 ] ;
scalar += ( c2 & 0x3F ) | ( ( c1 & 0x3F ) << 6 ) | ( ( c0 & 0x0F ) << 12 ) ;
2024-02-02 11:26:05 +00:00
dst [ shiftOffset ] = 0xE0 | ( ( scalar >> 12 ) & 0x0F ) ;
dst [ shiftOffset + 1 ] = ( c1 & 0xC0 ) | ( ( scalar >> 6 ) & 0x3F ) ;
dst [ shiftOffset + 2 ] = ( c2 & 0xC0 ) | ( scalar & 0x3F ) ;
2023-04-25 14:56:37 +00:00
step = 3 ;
} else {
step = len ;
}
} else if ( c0 < 0xF8 ) {
if ( len >= 4 ) {
const c1 : number = dst [ shiftOffset + 1 ] ;
const c2 : number = dst [ shiftOffset + 2 ] ;
const c3 : number = dst [ shiftOffset + 3 ] ;
scalar += ( c3 & 0x3F ) | ( ( c2 & 0x3F ) << 6 ) | ( ( c1 & 0x3F ) << 12 ) | ( ( c0 & 0x07 ) << 18 ) ;
2024-02-02 11:26:05 +00:00
dst [ shiftOffset ] = 0xF0 | ( ( scalar >> 18 ) & 0x07 ) ;
dst [ shiftOffset + 1 ] = ( c1 & 0xC0 ) | ( ( scalar >> 12 ) & 0x3F ) ;
dst [ shiftOffset + 2 ] = ( c2 & 0xC0 ) | ( ( scalar >> 6 ) & 0x3F ) ;
dst [ shiftOffset + 3 ] = ( c3 & 0xC0 ) | ( scalar & 0x3F ) ;
2023-04-25 14:56:37 +00:00
step = 4 ;
} else {
step = len ;
}
}
shiftOffset += step ;
len -= step ;
if ( transformType === 21 ) {
len = 0 ;
}
}
}
while ( suffix !== suffixEnd ) {
dst [ offset ++ ] = prefixSuffixStorage [ suffix ++ ] ;
}
return offset - dstOffset ;
}
function getNextKey ( key : number , len : number ) : number {
let step : number = 1 << ( len - 1 ) ;
while ( ( key & step ) !== 0 ) {
2024-02-02 11:26:05 +00:00
step = step >> 1 ;
2023-04-25 14:56:37 +00:00
}
return ( key & ( step - 1 ) ) + step ;
}
function replicateValue ( table : Int32Array , offset : number , step : number , end : number , item : number ) : void {
2024-02-02 11:26:05 +00:00
let pos : number = end ;
2023-04-25 14:56:37 +00:00
do {
2024-02-02 11:26:05 +00:00
pos -= step ;
table [ offset + pos ] = item ;
} while ( pos > 0 ) ;
2023-04-25 14:56:37 +00:00
}
function nextTableBitSize ( count : Int32Array , len : number , rootBits : number ) : number {
2024-02-02 11:26:05 +00:00
let bits : number = len ;
let left : number = 1 << ( bits - rootBits ) ;
while ( bits < 15 ) {
left -= count [ bits ] ;
2023-04-25 14:56:37 +00:00
if ( left <= 0 ) {
break ;
}
2024-02-02 11:26:05 +00:00
bits ++ ;
left = left << 1 ;
2023-04-25 14:56:37 +00:00
}
2024-02-02 11:26:05 +00:00
return bits - rootBits ;
2023-04-25 14:56:37 +00:00
}
function buildHuffmanTable ( tableGroup : Int32Array , tableIdx : number , rootBits : number , codeLengths : Int32Array , codeLengthsSize : number ) : number {
const tableOffset : number = tableGroup [ tableIdx ] ;
const sorted = new Int32Array ( codeLengthsSize ) ;
const count = new Int32Array ( 16 ) ;
const offset = new Int32Array ( 16 ) ;
2024-02-02 11:26:05 +00:00
for ( let sym = 0 ; sym < codeLengthsSize ; ++ sym ) {
count [ codeLengths [ sym ] ] ++ ;
2023-04-25 14:56:37 +00:00
}
offset [ 1 ] = 0 ;
2024-02-02 11:26:05 +00:00
for ( let len = 1 ; len < 15 ; ++ len ) {
2023-04-25 14:56:37 +00:00
offset [ len + 1 ] = offset [ len ] + count [ len ] ;
}
2024-02-02 11:26:05 +00:00
for ( let sym = 0 ; sym < codeLengthsSize ; ++ sym ) {
if ( codeLengths [ sym ] !== 0 ) {
sorted [ offset [ codeLengths [ sym ] ] ++ ] = sym ;
2023-04-25 14:56:37 +00:00
}
}
let tableBits : number = rootBits ;
let tableSize : number = 1 << tableBits ;
let totalSize : number = tableSize ;
if ( offset [ 15 ] === 1 ) {
2024-02-02 11:26:05 +00:00
for ( let k = 0 ; k < totalSize ; ++ k ) {
tableGroup [ tableOffset + k ] = sorted [ 0 ] ;
2023-04-25 14:56:37 +00:00
}
return totalSize ;
}
2024-02-02 11:26:05 +00:00
let key = 0 ;
let symbol = 0 ;
let step = 1 ;
for ( let len = 1 ; len <= rootBits ; ++ len ) {
step = step << 1 ;
while ( count [ len ] > 0 ) {
2023-04-25 14:56:37 +00:00
replicateValue ( tableGroup , tableOffset + key , step , tableSize , len << 16 | sorted [ symbol ++ ] ) ;
key = getNextKey ( key , len ) ;
2024-02-02 11:26:05 +00:00
count [ len ] -- ;
2023-04-25 14:56:37 +00:00
}
}
const mask : number = totalSize - 1 ;
let low : number = - 1 ;
let currentOffset : number = tableOffset ;
2024-02-02 11:26:05 +00:00
step = 1 ;
for ( let len : number = rootBits + 1 ; len <= 15 ; ++ len ) {
step = step << 1 ;
while ( count [ len ] > 0 ) {
2023-04-25 14:56:37 +00:00
if ( ( key & mask ) !== low ) {
currentOffset += tableSize ;
tableBits = nextTableBitSize ( count , len , rootBits ) ;
tableSize = 1 << tableBits ;
totalSize += tableSize ;
low = key & mask ;
tableGroup [ tableOffset + low ] = ( tableBits + rootBits ) << 16 | ( currentOffset - tableOffset - low ) ;
}
replicateValue ( tableGroup , currentOffset + ( key >> rootBits ) , step , tableSize , ( len - rootBits ) << 16 | sorted [ symbol ++ ] ) ;
key = getNextKey ( key , len ) ;
2024-02-02 11:26:05 +00:00
count [ len ] -- ;
2023-04-25 14:56:37 +00:00
}
}
return totalSize ;
}
function doReadMoreInput ( s : State ) : void {
if ( s . endOfStreamReached !== 0 ) {
if ( halfAvailable ( s ) >= - 2 ) {
return ;
}
throw new Error ( "No more input" ) ;
}
const readOffset : number = s . halfOffset << 1 ;
let bytesInBuffer : number = 4096 - readOffset ;
s . byteBuffer . copyWithin ( 0 , readOffset , 4096 ) ;
s . halfOffset = 0 ;
while ( bytesInBuffer < 4096 ) {
const spaceLeft : number = 4096 - bytesInBuffer ;
2023-11-29 18:47:47 +00:00
const len : number = readInput ( s , s . byteBuffer , bytesInBuffer , spaceLeft ) ;
2023-04-25 14:56:37 +00:00
if ( len <= 0 ) {
s . endOfStreamReached = 1 ;
s . tailBytes = bytesInBuffer ;
bytesInBuffer += 1 ;
break ;
}
bytesInBuffer += len ;
}
bytesToNibbles ( s , bytesInBuffer ) ;
}
function checkHealth ( s : State , endOfStream : number ) : void {
if ( s . endOfStreamReached === 0 ) {
return ;
}
const byteOffset : number = ( s . halfOffset << 1 ) + ( ( s . bitOffset + 7 ) >> 3 ) - 4 ;
if ( byteOffset > s . tailBytes ) {
throw new Error ( "Read after end" ) ;
}
if ( ( endOfStream !== 0 ) && ( byteOffset !== s . tailBytes ) ) {
throw new Error ( "Unused bytes after end" ) ;
}
}
function readFewBits ( s : State , n : number ) : number {
2024-02-02 11:26:05 +00:00
const v : number = ( s . accumulator32 >>> s . bitOffset ) & ( ( 1 << n ) - 1 ) ;
2023-04-25 14:56:37 +00:00
s . bitOffset += n ;
2024-02-02 11:26:05 +00:00
return v ;
2023-04-25 14:56:37 +00:00
}
function readManyBits ( s : State , n : number ) : number {
const low : number = readFewBits ( s , 16 ) ;
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
return low | ( readFewBits ( s , n - 16 ) << 16 ) ;
}
function initBitReader ( s : State ) : void {
s . byteBuffer = new Int8Array ( 4160 ) ;
s . accumulator32 = 0 ;
s . shortBuffer = new Int16Array ( 2080 ) ;
s . bitOffset = 32 ;
s . halfOffset = 2048 ;
s . endOfStreamReached = 0 ;
prepare ( s ) ;
}
function prepare ( s : State ) : void {
if ( s . halfOffset > 2030 ) {
doReadMoreInput ( s ) ;
}
checkHealth ( s , 0 ) ;
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
function reload ( s : State ) : void {
if ( s . bitOffset === 32 ) {
prepare ( s ) ;
}
}
function jumpToByteBoundary ( s : State ) : void {
const padding : number = ( 32 - s . bitOffset ) & 7 ;
if ( padding !== 0 ) {
const paddingBits : number = readFewBits ( s , padding ) ;
if ( paddingBits !== 0 ) {
throw new Error ( "Corrupted padding bits" ) ;
}
}
}
function halfAvailable ( s : State ) : number {
let limit = 2048 ;
if ( s . endOfStreamReached !== 0 ) {
limit = ( s . tailBytes + 1 ) >> 1 ;
}
return limit - s . halfOffset ;
}
function copyRawBytes ( s : State , data : Int8Array , offset : number , length : number ) : void {
2024-02-02 11:26:05 +00:00
let pos : number = offset ;
let len : number = length ;
2023-04-25 14:56:37 +00:00
if ( ( s . bitOffset & 7 ) !== 0 ) {
throw new Error ( "Unaligned copyBytes" ) ;
}
2024-02-02 11:26:05 +00:00
while ( ( s . bitOffset !== 32 ) && ( len !== 0 ) ) {
data [ pos ++ ] = s . accumulator32 >>> s . bitOffset ;
2023-04-25 14:56:37 +00:00
s . bitOffset += 8 ;
2024-02-02 11:26:05 +00:00
len -- ;
2023-04-25 14:56:37 +00:00
}
2024-02-02 11:26:05 +00:00
if ( len === 0 ) {
2023-04-25 14:56:37 +00:00
return ;
}
2024-02-02 11:26:05 +00:00
const copyNibbles : number = Math . min ( halfAvailable ( s ) , len >> 1 ) ;
2023-04-25 14:56:37 +00:00
if ( copyNibbles > 0 ) {
const readOffset : number = s . halfOffset << 1 ;
const delta : number = copyNibbles << 1 ;
2024-02-02 11:26:05 +00:00
data . set ( s . byteBuffer . subarray ( readOffset , readOffset + delta ) , pos ) ;
pos += delta ;
len -= delta ;
2023-04-25 14:56:37 +00:00
s . halfOffset += copyNibbles ;
}
2024-02-02 11:26:05 +00:00
if ( len === 0 ) {
2023-04-25 14:56:37 +00:00
return ;
}
if ( halfAvailable ( s ) > 0 ) {
if ( s . bitOffset >= 16 ) {
s . accumulator32 = ( s . shortBuffer [ s . halfOffset ++ ] << 16 ) | ( s . accumulator32 >>> 16 ) ;
s . bitOffset -= 16 ;
}
2024-02-02 11:26:05 +00:00
while ( len !== 0 ) {
data [ pos ++ ] = s . accumulator32 >>> s . bitOffset ;
2023-04-25 14:56:37 +00:00
s . bitOffset += 8 ;
2024-02-02 11:26:05 +00:00
len -- ;
2023-04-25 14:56:37 +00:00
}
checkHealth ( s , 0 ) ;
return ;
}
2024-02-02 11:26:05 +00:00
while ( len > 0 ) {
const chunkLen : number = readInput ( s , data , pos , len ) ;
if ( chunkLen === - 1 ) {
2023-04-25 14:56:37 +00:00
throw new Error ( "Unexpected end of input" ) ;
}
2024-02-02 11:26:05 +00:00
pos += chunkLen ;
len -= chunkLen ;
2023-04-25 14:56:37 +00:00
}
}
function bytesToNibbles ( s : State , byteLen : number ) : void {
const byteBuffer : Int8Array = s . byteBuffer ;
const halfLen : number = byteLen >> 1 ;
const shortBuffer : Int16Array = s . shortBuffer ;
for ( let i = 0 ; i < halfLen ; ++ i ) {
2024-02-02 11:26:05 +00:00
shortBuffer [ i ] = ( byteBuffer [ i * 2 ] & 0xFF ) | ( ( byteBuffer [ ( i * 2 ) + 1 ] & 0xFF ) << 8 ) ;
2023-04-25 14:56:37 +00:00
}
}
const LOOKUP = new Int32Array ( 2048 ) ;
function unpackLookupTable ( lookup : Int32Array , map : string , rle : string ) : void {
for ( let i = 0 ; i < 256 ; ++ i ) {
lookup [ i ] = i & 0x3F ;
lookup [ 512 + i ] = i >> 2 ;
lookup [ 1792 + i ] = 2 + ( i >> 6 ) ;
}
for ( let i = 0 ; i < 128 ; ++ i ) {
lookup [ 1024 + i ] = 4 * ( map . charCodeAt ( i ) - 32 ) ;
}
for ( let i = 0 ; i < 64 ; ++ i ) {
lookup [ 1152 + i ] = i & 1 ;
lookup [ 1216 + i ] = 2 + ( i & 1 ) ;
}
let offset = 1280 ;
for ( let k = 0 ; k < 19 ; ++ k ) {
const value : number = k & 3 ;
const rep : number = rle . charCodeAt ( k ) - 32 ;
for ( let i = 0 ; i < rep ; ++ i ) {
lookup [ offset ++ ] = value ;
}
}
for ( let i = 0 ; i < 16 ; ++ i ) {
lookup [ 1792 + i ] = 1 ;
lookup [ 2032 + i ] = 6 ;
}
lookup [ 1792 ] = 0 ;
lookup [ 2047 ] = 7 ;
for ( let i = 0 ; i < 256 ; ++ i ) {
lookup [ 1536 + i ] = lookup [ 1792 + i ] << 3 ;
}
}
{
unpackLookupTable ( LOOKUP , " !! ! \"#$##%#$&'##(#)#++++++++++((&*'##,---,---,-----,-----,-----&#'###.///.///./////./////./////&#'# " , "A/* ': & : $ \x81 @" ) ;
}
class State {
ringBuffer = new Int8Array ( 0 ) ;
contextModes = new Int8Array ( 0 ) ;
contextMap = new Int8Array ( 0 ) ;
distContextMap = new Int8Array ( 0 ) ;
distExtraBits = new Int8Array ( 0 ) ;
output = new Int8Array ( 0 ) ;
byteBuffer = new Int8Array ( 0 ) ;
shortBuffer = new Int16Array ( 0 ) ;
intBuffer = new Int32Array ( 0 ) ;
rings = new Int32Array ( 0 ) ;
blockTrees = new Int32Array ( 0 ) ;
literalTreeGroup = new Int32Array ( 0 ) ;
commandTreeGroup = new Int32Array ( 0 ) ;
distanceTreeGroup = new Int32Array ( 0 ) ;
distOffset = new Int32Array ( 0 ) ;
accumulator64 = 0 ;
runningState = 0 ;
nextRunningState = 0 ;
accumulator32 = 0 ;
bitOffset = 0 ;
halfOffset = 0 ;
tailBytes = 0 ;
endOfStreamReached = 0 ;
metaBlockLength = 0 ;
inputEnd = 0 ;
isUncompressed = 0 ;
isMetadata = 0 ;
literalBlockLength = 0 ;
numLiteralBlockTypes = 0 ;
commandBlockLength = 0 ;
numCommandBlockTypes = 0 ;
distanceBlockLength = 0 ;
numDistanceBlockTypes = 0 ;
pos = 0 ;
maxDistance = 0 ;
distRbIdx = 0 ;
trivialLiteralContext = 0 ;
literalTreeIdx = 0 ;
commandTreeIdx = 0 ;
j = 0 ;
insertLength = 0 ;
contextMapSlice = 0 ;
distContextMapSlice = 0 ;
contextLookupOffset1 = 0 ;
contextLookupOffset2 = 0 ;
distanceCode = 0 ;
numDirectDistanceCodes = 0 ;
distancePostfixBits = 0 ;
distance = 0 ;
copyLength = 0 ;
maxBackwardDistance = 0 ;
maxRingBufferSize = 0 ;
ringBufferSize = 0 ;
expectedTotalSize = 0 ;
outputOffset = 0 ;
outputLength = 0 ;
outputUsed = 0 ;
ringBufferBytesWritten = 0 ;
ringBufferBytesReady = 0 ;
isEager = 0 ;
isLargeWindow = 0 ;
cdNumChunks = 0 ;
cdTotalSize = 0 ;
cdBrIndex = 0 ;
cdBrOffset = 0 ;
cdBrLength = 0 ;
cdBrCopied = 0 ;
cdChunks = new Array ( 0 ) ;
cdChunkOffsets = new Int32Array ( 0 ) ;
cdBlockBits = 0 ;
cdBlockMap = new Int8Array ( 0 ) ;
2024-02-02 11:26:05 +00:00
input = new InputStream ( new Int8Array ( 0 ) ) ;
2023-04-25 14:56:37 +00:00
constructor ( ) {
this . ringBuffer = new Int8Array ( 0 ) ;
this . rings = new Int32Array ( 10 ) ;
this . rings [ 0 ] = 16 ;
this . rings [ 1 ] = 15 ;
this . rings [ 2 ] = 11 ;
this . rings [ 3 ] = 4 ;
}
}
let data = new Int8Array ( 0 ) ;
const offsets = new Int32Array ( 32 ) ;
const sizeBits = new Int32Array ( 32 ) ;
function setData ( newData : ByteBuffer , newSizeBits : Int32Array ) : void {
if ( newSizeBits . length > 31 ) {
throw new Error ( "sizeBits length must be at most " + valueOf ( 31 ) ) ;
}
for ( let i = 0 ; i < 4 ; ++ i ) {
if ( newSizeBits [ i ] !== 0 ) {
throw new Error ( "first " + valueOf ( 4 ) + " must be 0" ) ;
}
}
const dictionaryOffsets : Int32Array = offsets ;
const dictionarySizeBits : Int32Array = sizeBits ;
dictionarySizeBits . set ( newSizeBits . subarray ( 0 , newSizeBits . length ) , 0 ) ;
let pos = 0 ;
const limit : number = newData . length ;
for ( let i = 0 ; i < newSizeBits . length ; ++ i ) {
dictionaryOffsets [ i ] = pos ;
const bits : number = dictionarySizeBits [ i ] ;
if ( bits !== 0 ) {
if ( bits >= 31 ) {
throw new Error ( "newSizeBits values must be less than 31" ) ;
}
pos += i << bits ;
if ( pos <= 0 || pos > limit ) {
throw new Error ( "newSizeBits is inconsistent: overflow" ) ;
}
}
}
for ( let i : number = newSizeBits . length ; i < 32 ; ++ i ) {
dictionaryOffsets [ i ] = pos ;
}
if ( pos !== limit ) {
throw new Error ( "newSizeBits is inconsistent: underflow" ) ;
}
data = newData ;
}
function unpackDictionaryData ( dictionary : ByteBuffer , data0 : string , data1 : string , skipFlip : string , sizeBits : Int32Array , sizeBitsData : string ) : void {
const dict : Int8Array = toUsAsciiBytes ( data0 + data1 ) ;
if ( dict . length !== dictionary . length ) {
throw new Error ( "Corrupted brotli dictionary" ) ;
}
let offset = 0 ;
2024-02-02 11:26:05 +00:00
const n : number = skipFlip . length >> 1 ;
for ( let i = 0 ; i < n ; ++ i ) {
const skip : number = skipFlip . charCodeAt ( 2 * i ) - 36 ;
const flip : number = skipFlip . charCodeAt ( 2 * i + 1 ) - 36 ;
2023-04-25 14:56:37 +00:00
for ( let j = 0 ; j < skip ; ++ j ) {
2024-02-02 11:26:05 +00:00
dict [ offset ] = dict [ offset ] ^ 3 ;
2023-04-25 14:56:37 +00:00
offset ++ ;
}
for ( let j = 0 ; j < flip ; ++ j ) {
2024-02-02 11:26:05 +00:00
dict [ offset ] = dict [ offset ] ^ 236 ;
2023-04-25 14:56:37 +00:00
offset ++ ;
}
}
for ( let i = 0 ; i < sizeBitsData . length ; ++ i ) {
sizeBits [ i ] = sizeBitsData . charCodeAt ( i ) - 65 ;
}
dictionary . set ( dict ) ;
}
{
const dictionaryData = new Int8Array ( 122784 ) ;
const dictionarySizeBits = new Int32Array ( 25 ) ;
unpackDictionaryData ( dictionaryData , "wjnfgltmojefofewab`h`lgfgbwbpkltlmozpjwf`jwzlsfmivpwojhfeqfftlqhwf{wzfbqlufqalgzolufelqnallhsobzojufojmfkfosklnfpjgfnlqftlqgolmdwkfnujftejmgsbdfgbzpevookfbgwfqnfb`kbqfbeqlnwqvfnbqhbaofvslmkjdkgbwfobmgmftpfufmmf{w`bpfalwkslpwvpfgnbgfkbmgkfqftkbwmbnfOjmhaoldpjyfabpfkfognbhfnbjmvpfq$*#(klogfmgptjwkMftpqfbgtfqfpjdmwbhfkbufdbnfpffm`boosbwktfoosovpnfmvejonsbqwiljmwkjpojpwdllgmffgtbzptfpwilapnjmgboploldlqj`kvpfpobpwwfbnbqnzellghjmdtjoofbpwtbqgafpwejqfSbdfhmltbtbz-smdnlufwkbmolbgdjufpfoemlwfnv`keffgnbmzql`hj`lmlm`follhkjgfgjfgKlnfqvofklpwbib{jmel`ovaobtpofppkboeplnfpv`kylmf233&lmfp`bqfWjnfqb`faovfelvqtffheb`fklsfdbufkbqgolpwtkfmsbqhhfswsbpppkjsqllnKWNOsobmWzsfglmfpbufhffseobdojmhplogejufwllhqbwfwltmivnswkvpgbqh`bqgejofefbqpwbzhjoowkbweboobvwlfufq-`lnwbohpklsulwfgffsnlgfqfpwwvqmalqmabmgefooqlpfvqo+phjmqlof`lnfb`wpbdfpnffwdlog-isdjwfnubqzefowwkfmpfmggqlsUjft`lsz2-3!?,b=pwlsfopfojfpwlvqsb`h-djesbpw`pp<dqbznfbm%dw8qjgfpklwobwfpbjgqlbgubq#effoilkmqj`hslqwebpw$VB.gfbg?,a=sllqajoowzsfV-P-tllgnvpw1s{8JmelqbmhtjgftbmwtbooofbgX3^8sbvotbufpvqf'+$ tbjwnbppbqnpdlfpdbjmobmdsbjg\"..#ol`hvmjwqllwtbohejqntjef{no!plmdwfpw13s{hjmgqltpwlloelmwnbjopbefpwbqnbsp`lqfqbjmeoltabazpsbmpbzp7s{85s{8bqwpellwqfbotjhjkfbwpwfswqjslqd,obhftfbhwlogElqn`bpwebmpabmhufqzqvmpivozwbph2s{8dlbodqftpoltfgdfjg>!pfwp6s{8-ip<73s{je#+pllmpfbwmlmfwvafyfqlpfmwqffgeb`wjmwldjewkbqn2;s{`bnfkjooalogyllnuljgfbpzqjmdejoosfbhjmjw`lpw0s{8ib`hwbdpajwpqloofgjwhmftmfbq?\"..dqltIPLMgvwzMbnfpbofzlv#olwpsbjmibyy`logfzfpejpkttt-qjphwbapsqfu23s{qjpf16s{Aovfgjmd033/abooelqgfbqmtjogal{-ebjqob`hufqpsbjqivmfwf`kje+\"sj`hfujo'+! tbqnolqgglfpsvoo/333jgfbgqbtkvdfpslwevmgavqmkqfe`foohfzpwj`hklvqolppevfo21s{pvjwgfboQPP!bdfgdqfzDFW!fbpfbjnpdjqobjgp;s{8mbuzdqjgwjsp :::tbqpobgz`bqp*8#~sks<kfoowbootklnyk9\t),\x0E\t#233kboo-\t\tB4s{8svpk`kbw3s{8`qft),?,kbpk46s{eobwqbqf#%%#wfoo`bnslmwlobjgnjppphjswfmwejmfnbofdfwpsolw733/\x0E\t\x0E\t`lloeffw-sks?aq=fqj`nlpwdvjgafoogfp`kbjqnbwkbwln,jnd% ;1ov`h`fmw3338wjmzdlmfkwnopfoogqvdEQFFmlgfmj`h<jg>olpfmvooubpwtjmgQPP#tfbqqfozaffmpbnfgvhfmbpb`bsftjpkdvoeW109kjwppolwdbwfhj`haovqwkfz26s{$$*8*8!=npjftjmpajqgplqwafwbpffhW2;9lqgpwqffnboo53s{ebqn\x0ElupalzpX3^-$*8!SLPWafbqhjgp*8~~nbqzwfmg+VH*rvbgyk9\n.pjy....sqls$*8\x0EojewW2:9uj`fbmgzgfaw=QPPsllomf`haoltW259gllqfuboW249ofwpebjolqbosloomlub`lopdfmf#\x0Elxplewqlnfwjooqlpp?k0=slvqebgfsjmh?wq=njmj*\x7F\"+njmfyk9\x04abqpkfbq33*8njoh#..=jqlmeqfggjphtfmwpljosvwp,ip,klozW119JPAMW139bgbnpffp?k1=iplm$/#$`lmwW129#QPPollsbpjbnllm?,s=plvoOJMFelqw`bqwW279?k2=;3s{\"..?:s{8W379njhf975Ymj`fjm`kZlqhqj`fyk9\b$**8svqfnbdfsbqbwlmfalmg904Y\\le\\$^*8333/yk9\x0Bwbmhzbqgaltoavpk965YIbub03s{\t\x7F~\t&@0&907YifeeF[SJ`bpkujpbdloepmltyk9\x05rvfq-`pppj`hnfbwnjm-ajmggfookjqfsj`pqfmw905YKWWS.132elwltloeFMG#{al{967YALGZgj`h8\t~\tf{jw906Yubqpafbw$~*8gjfw:::8bmmf~~?,Xj^-Obmdhn.^tjqfwlzpbggppfbobof{8\t\n~f`klmjmf-lqd336*wlmziftppbmgofdpqlle333*#133tjmfdfbqgldpallwdbqz`vwpwzofwfnswjlm-{no`l`hdbmd'+$-63s{Sk-Gnjp`bobmolbmgfphnjofqzbmvmj{gjp`*8~\tgvpw`ojs*-\t\t43s{.133GUGp4^=?wbsfgfnlj((*tbdffvqlskjolswpklofEBRpbpjm.15WobapsfwpVQO#avoh`llh8~\x0E\tKFBGX3^*baaqivbm+2:;ofpkwtjm?,j=plmzdvzpev`hsjsf\x7F.\t\" 331 * mgltX2 ^ 8 X ^ 8 \ tOld # pbow \ x0E \ t \ n \ nabmdwqjnabwk * x \ x0E \ t33s { \ t ~ * 8 hl9 \ 0 effpbg = \ x0Ep9 , , # X ^ 8 wloosovd + * x \ tx \ x0E \ t # - ip $133sgvboalbw - ISD * 8 \ t ~ rvlw * 8 \ t \ t $ * 8 \ t \ x0E \ t ~ \ x0E1327132613251324132 ; 132 :13131312131113101317131613151314131 ; 131 :130313021301130013071306130513041320132113221323133 : 133 ; 133413351336133713301331133213332 : : : 2 : : ; 2 : : 42 : : 52 : : 62 : : 72 : : 02 : : 12 : : 22 : : 32 : ; : 2 : ; ; 2 : ; 42 : ; 52 : ; 62 : ; 72 : ; 02 : ; 12 : ; 22 : ; 32 :4 : 2 :4 ; 2 :442 : 452 :462 : 472 :402 : 412 :422 : 432 :5 : 2 :5 ; 2 :542 : 552 :562 : 572 :502 : 512 :522 : 532 :6 : 2 :6 ; 2 :642 : 652 :662 : 672 :602 : 612 :622 : 632333231720 :73333 : : : : ` lnln/Mpfpwffpwbsfqlwlglkb ` f ` bgbb/]lajfmg/Abbp/Aujgb ` bpllwqlelqlplollwqb ` vbogjilpjgldqbmwjslwfnbgfafbodlrv/Efpwlmbgbwqfpsl ` l ` bpbabilwlgbpjmlbdvbsvfpvmlpbmwfgj ` fovjpfoobnbzlylmbbnlqsjpllaqb ` oj ` foolgjlpklqb ` bpj<[< \\ <Q< \\ <R<P=l< \\ =l=o=n< \\ <Q<Y<S<R<R=n<T<[<Q<R<X<R=n<R<Z<Y<R<Q<T=i<q< \\ <Y<Y<]=g<P=g<~=g=m<R<^=g<^<R<q<R<R<]<s<R<W<T<Q<T<L<H<q<Y<p=g=n=g<r<Q<T<P<X< \\ <{< \\ <x< \\ <q=o<r<]=n<Y<t<[<Y<U<Q=o<P<P<N=g=o<Z5m5f4
setData ( dictionaryData , dictionarySizeBits ) ;
}
class InputStream {
data = new Int8Array ( 0 ) ;
offset = 0 ;
constructor ( data : Int8Array ) {
this . data = data ;
}
}
function valueOf ( x : number ) : string {
return x . toString ( ) ;
}
2023-11-29 18:47:47 +00:00
function readInput ( s : State , dst : Int8Array , offset : number , length : number ) : number {
if ( s . input === null ) {
2023-04-25 14:56:37 +00:00
return - 1 ;
}
2023-11-29 18:47:47 +00:00
const src : InputStream = s . input ;
2023-04-25 14:56:37 +00:00
const end : number = Math . min ( src . offset + length , src . data . length ) ;
const bytesRead : number = end - src . offset ;
dst . set ( src . data . subarray ( src . offset , end ) , offset ) ;
src . offset += bytesRead ;
return bytesRead ;
}
function toUsAsciiBytes ( src : string ) : Int8Array {
const n : number = src . length ;
const result = new Int8Array ( n ) ;
for ( let i = 0 ; i < n ; ++ i ) {
result [ i ] = src . charCodeAt ( i ) ;
}
return result ;
}
/* GENERATED CODE END */
type ByteBuffer = Int8Array ;
/ * *
* Decodes brotli stream .
* /
export function brotliDecode (
bytes : Int8Array , options? : BrotliDecodeOptions ) : Int8Array {
const s = new State ( ) ;
2023-11-29 18:47:47 +00:00
s . input = new InputStream ( bytes ) ;
initState ( s ) ;
2023-04-25 14:56:37 +00:00
if ( options ) {
const customDictionary : Int8Array | null = options . customDictionary ;
if ( customDictionary ) attachDictionaryChunk ( s , customDictionary ) ;
}
let totalOutput = 0 ;
const chunks : Int8Array [ ] = [ ] ;
while ( true ) {
const chunk = new Int8Array ( 16384 ) ;
chunks . push ( chunk ) ;
s . output = chunk ;
s . outputOffset = 0 ;
s . outputLength = 16384 ;
s . outputUsed = 0 ;
decompress ( s ) ;
totalOutput += s . outputUsed ;
if ( s . outputUsed < 16384 ) break ;
}
close ( s ) ;
const result = new Int8Array ( totalOutput ) ;
let offset = 0 ;
for ( let i = 0 ; i < chunks . length ; ++ i ) {
const chunk : Int8Array = chunks [ i ] ;
const end : number = Math . min ( totalOutput , offset + 16384 ) ;
const len : number = end - offset ;
if ( len < 16384 ) {
result . set ( chunk . subarray ( 0 , len ) , offset ) ;
} else {
result . set ( chunk , offset ) ;
}
offset += len ;
}
return result ;
}