all repos — NoPaste @ 570667fb0563e0bc1ab1c31cabd7aff1c7fbb4d1

Resurrected - The PussTheCat.org fork of NoPaste

scripts/lzma_worker.js (view raw)

   1/// © 2015 Nathan Rugg <nmrugg@gmail.com> | MIT
   2/// See LICENSE for more details.
   3
   4/* jshint noarg:true, boss:true, unused:strict, strict:true, undef:true, noarg: true, forin:true, evil:true, newcap:false, -W041, -W021, worker:true, browser:true, node:true */
   5
   6/* global setImmediate, setTimeout, window, onmessage */
   7
   8/** xs */
   9///NOTE: This is the master file that is used to generate lzma-c.js and lzma-d.js.
  10///      Comments are used to determine which parts are to be removed.
  11///
  12/// cs-ce (compression start-end)
  13/// ds-de (decompression start-end)
  14/// xs-xe (only in this file start-end)
  15/// co    (compression only)
  16/// do    (decompression only)
  17/** xe */
  18
  19var LZMA = (function () {
  20    
  21    "use strict";
  22    
  23    var /** cs */
  24        action_compress   = 1,
  25        /** ce */
  26        /** ds */
  27        action_decompress = 2,
  28        /** de */
  29        action_progress   = 3,
  30        wait = typeof setImmediate == "function" ? setImmediate : setTimeout,
  31        __4294967296 = 4294967296,
  32        N1_longLit = [4294967295, -__4294967296],
  33        /** cs */
  34        MIN_VALUE = [0, -9223372036854775808],
  35        /** ce */
  36        P0_longLit = [0, 0],
  37        P1_longLit = [1, 0];
  38    
  39    function update_progress(percent, cbn) {
  40        postMessage({
  41            action: action_progress,
  42            cbn: cbn,
  43            result: percent
  44        });
  45    }
  46    
  47    function initDim(len) {
  48        ///NOTE: This is MUCH faster than "new Array(len)" in newer versions of v8 (starting with Node.js 0.11.15, which uses v8 3.28.73).
  49        var a = [];
  50        a[len - 1] = undefined;
  51        return a;
  52    }
  53    
  54    function add(a, b) {
  55        return create(a[0] + b[0], a[1] + b[1]);
  56    }
  57    
  58    /** cs */
  59    function and(a, b) {
  60        return makeFromBits(~~Math.max(Math.min(a[1] / __4294967296, 2147483647), -2147483648) & ~~Math.max(Math.min(b[1] / __4294967296, 2147483647), -2147483648), lowBits_0(a) & lowBits_0(b));
  61    }
  62    /** ce */
  63    
  64    function compare(a, b) {
  65        var nega, negb;
  66        if (a[0] == b[0] && a[1] == b[1]) {
  67            return 0;
  68        }
  69        nega = a[1] < 0;
  70        negb = b[1] < 0;
  71        if (nega && !negb) {
  72            return -1;
  73        }
  74        if (!nega && negb) {
  75            return 1;
  76        }
  77        if (sub(a, b)[1] < 0) {
  78            return -1;
  79        }
  80        return 1;
  81    }
  82    
  83    function create(valueLow, valueHigh) {
  84        var diffHigh, diffLow;
  85        valueHigh %= 1.8446744073709552E19;
  86        valueLow %= 1.8446744073709552E19;
  87        diffHigh = valueHigh % __4294967296;
  88        diffLow = Math.floor(valueLow / __4294967296) * __4294967296;
  89        valueHigh = valueHigh - diffHigh + diffLow;
  90        valueLow = valueLow - diffLow + diffHigh;
  91        while (valueLow < 0) {
  92            valueLow += __4294967296;
  93            valueHigh -= __4294967296;
  94        }
  95        while (valueLow > 4294967295) {
  96            valueLow -= __4294967296;
  97            valueHigh += __4294967296;
  98        }
  99        valueHigh = valueHigh % 1.8446744073709552E19;
 100        while (valueHigh > 9223372032559808512) {
 101            valueHigh -= 1.8446744073709552E19;
 102        }
 103        while (valueHigh < -9223372036854775808) {
 104            valueHigh += 1.8446744073709552E19;
 105        }
 106        return [valueLow, valueHigh];
 107    }
 108    
 109    /** cs */
 110    function eq(a, b) {
 111        return a[0] == b[0] && a[1] == b[1];
 112    }
 113    /** ce */
 114    function fromInt(value) {
 115        if (value >= 0) {
 116            return [value, 0];
 117        } else {
 118            return [value + __4294967296, -__4294967296];
 119        }
 120    }
 121    
 122    function lowBits_0(a) {
 123        if (a[0] >= 2147483648) {
 124            return ~~Math.max(Math.min(a[0] - __4294967296, 2147483647), -2147483648);
 125        } else {
 126            return ~~Math.max(Math.min(a[0], 2147483647), -2147483648);
 127        }
 128    }
 129    /** cs */
 130    function makeFromBits(highBits, lowBits) {
 131        var high, low;
 132        high = highBits * __4294967296;
 133        low = lowBits;
 134        if (lowBits < 0) {
 135            low += __4294967296;
 136        }
 137        return [low, high];
 138    }
 139    
 140    function pwrAsDouble(n) {
 141        if (n <= 30) {
 142            return 1 << n;
 143        } else {
 144            return pwrAsDouble(30) * pwrAsDouble(n - 30);
 145        }
 146    }
 147    
 148    function shl(a, n) {
 149        var diff, newHigh, newLow, twoToN;
 150        n &= 63;
 151        if (eq(a, MIN_VALUE)) {
 152            if (!n) {
 153                return a;
 154            }
 155            return P0_longLit;
 156        }
 157        if (a[1] < 0) {
 158            throw new Error("Neg");
 159        }
 160        twoToN = pwrAsDouble(n);
 161        newHigh = a[1] * twoToN % 1.8446744073709552E19;
 162        newLow = a[0] * twoToN;
 163        diff = newLow - newLow % __4294967296;
 164        newHigh += diff;
 165        newLow -= diff;
 166        if (newHigh >= 9223372036854775807) {
 167            newHigh -= 1.8446744073709552E19;
 168        }
 169        return [newLow, newHigh];
 170    }
 171    
 172    function shr(a, n) {
 173        var shiftFact;
 174        n &= 63;
 175        shiftFact = pwrAsDouble(n);
 176        return create(Math.floor(a[0] / shiftFact), a[1] / shiftFact);
 177    }
 178    
 179    function shru(a, n) {
 180        var sr;
 181        n &= 63;
 182        sr = shr(a, n);
 183        if (a[1] < 0) {
 184            sr = add(sr, shl([2, 0], 63 - n));
 185        }
 186        return sr;
 187    }
 188    
 189    /** ce */
 190    
 191    function sub(a, b) {
 192        return create(a[0] - b[0], a[1] - b[1]);
 193    }
 194    
 195    function $ByteArrayInputStream(this$static, buf) {
 196        this$static.buf = buf;
 197        this$static.pos = 0;
 198        this$static.count = buf.length;
 199        return this$static;
 200    }
 201    
 202    /** ds */
 203    function $read(this$static) {
 204        if (this$static.pos >= this$static.count)
 205            return -1;
 206        return this$static.buf[this$static.pos++] & 255;
 207    }
 208    /** de */
 209    /** cs */
 210    function $read_0(this$static, buf, off, len) {
 211        if (this$static.pos >= this$static.count)
 212            return -1;
 213        len = Math.min(len, this$static.count - this$static.pos);
 214        arraycopy(this$static.buf, this$static.pos, buf, off, len);
 215        this$static.pos += len;
 216        return len;
 217    }
 218    /** ce */
 219    
 220    function $ByteArrayOutputStream(this$static) {
 221        this$static.buf = initDim(32);
 222        this$static.count = 0;
 223        return this$static;
 224    }
 225    
 226    function $toByteArray(this$static) {
 227        var data = this$static.buf;
 228        data.length = this$static.count;
 229        return data;
 230    }
 231    
 232    /** cs */
 233    function $write(this$static, b) {
 234        this$static.buf[this$static.count++] = b << 24 >> 24;
 235    }
 236    /** ce */
 237    
 238    function $write_0(this$static, buf, off, len) {
 239        arraycopy(buf, off, this$static.buf, this$static.count, len);
 240        this$static.count += len;
 241    }
 242    
 243    /** cs */
 244    function $getChars(this$static, srcBegin, srcEnd, dst, dstBegin) {
 245        var srcIdx;
 246        for (srcIdx = srcBegin; srcIdx < srcEnd; ++srcIdx) {
 247            dst[dstBegin++] = this$static.charCodeAt(srcIdx);
 248        }
 249    }
 250    /** ce */
 251    
 252    function arraycopy(src, srcOfs, dest, destOfs, len) {
 253        for (var i = 0; i < len; ++i) {
 254            dest[destOfs + i] = src[srcOfs + i];
 255        }
 256    }
 257    
 258    /** cs */
 259    function $configure(this$static, encoder) {
 260        $SetDictionarySize_0(encoder, 1 << this$static.s);
 261        encoder._numFastBytes = this$static.f;
 262        $SetMatchFinder(encoder, this$static.m);
 263        
 264        /// lc is always 3
 265        /// lp is always 0
 266        /// pb is always 2
 267        encoder._numLiteralPosStateBits = 0;
 268        encoder._numLiteralContextBits = 3;
 269        encoder._posStateBits = 2;
 270        ///this$static._posStateMask = (1 << pb) - 1;
 271        encoder._posStateMask = 3;
 272    }
 273    
 274    function $init(this$static, input, output, length_0, mode) {
 275        var encoder, i;
 276        if (compare(length_0, N1_longLit) < 0)
 277            throw new Error("invalid length " + length_0);
 278        this$static.length_0 = length_0;
 279        encoder = $Encoder({});
 280        $configure(mode, encoder);
 281        encoder._writeEndMark = typeof LZMA.disableEndMark == "undefined";
 282        $WriteCoderProperties(encoder, output);
 283        for (i = 0; i < 64; i += 8)
 284            $write(output, lowBits_0(shr(length_0, i)) & 255);
 285        this$static.chunker = (encoder._needReleaseMFStream = 0 , (encoder._inStream = input , encoder._finished = 0 , $Create_2(encoder) , encoder._rangeEncoder.Stream = output , $Init_4(encoder) , $FillDistancesPrices(encoder) , $FillAlignPrices(encoder) , encoder._lenEncoder._tableSize = encoder._numFastBytes + 1 - 2 , $UpdateTables(encoder._lenEncoder, 1 << encoder._posStateBits) , encoder._repMatchLenEncoder._tableSize = encoder._numFastBytes + 1 - 2 , $UpdateTables(encoder._repMatchLenEncoder, 1 << encoder._posStateBits) , encoder.nowPos64 = P0_longLit , undefined) , $Chunker_0({}, encoder));
 286    }
 287    
 288    function $LZMAByteArrayCompressor(this$static, data, mode) {
 289        this$static.output = $ByteArrayOutputStream({});
 290        $init(this$static, $ByteArrayInputStream({}, data), this$static.output, fromInt(data.length), mode);
 291        return this$static;
 292    }
 293    /** ce */
 294    
 295    /** ds */
 296    function $init_0(this$static, input, output) {
 297        var decoder,
 298            hex_length = "",
 299            i,
 300            properties = [],
 301            r,
 302            tmp_length;
 303        
 304        for (i = 0; i < 5; ++i) {
 305            r = $read(input);
 306            if (r == -1)
 307                throw new Error("truncated input");
 308            properties[i] = r << 24 >> 24;
 309        }
 310        
 311        decoder = $Decoder({});
 312        if (!$SetDecoderProperties(decoder, properties)) {
 313            throw new Error("corrupted input");
 314        }
 315        for (i = 0; i < 64; i += 8) {
 316            r = $read(input);
 317            if (r == -1)
 318                throw new Error("truncated input");
 319            r = r.toString(16);
 320            if (r.length == 1) r = "0" + r;
 321            hex_length = r + "" + hex_length;
 322        }
 323        
 324        /// Was the length set in the header (if it was compressed from a stream, the length is all f"s).
 325        if (/^0+$|^f+$/i.test(hex_length)) {
 326            /// The length is unknown, so set to -1.
 327            this$static.length_0 = N1_longLit;
 328        } else {
 329            ///NOTE: If there is a problem with the decoder because of the length, you can always set the length to -1 (N1_longLit) which means unknown.
 330            tmp_length = parseInt(hex_length, 16);
 331            /// If the length is too long to handle, just set it to unknown.
 332            if (tmp_length > 4294967295) {
 333                this$static.length_0 = N1_longLit;
 334            } else {
 335                this$static.length_0 = fromInt(tmp_length);
 336            }
 337        }
 338        
 339        this$static.chunker = $CodeInChunks(decoder, input, output, this$static.length_0);
 340    }
 341    
 342    function $LZMAByteArrayDecompressor(this$static, data) {
 343        this$static.output = $ByteArrayOutputStream({});
 344        $init_0(this$static, $ByteArrayInputStream({}, data), this$static.output);
 345        return this$static;
 346    }
 347    /** de */
 348    /** cs */
 349    function $Create_4(this$static, keepSizeBefore, keepSizeAfter, keepSizeReserv) {
 350        var blockSize;
 351        this$static._keepSizeBefore = keepSizeBefore;
 352        this$static._keepSizeAfter = keepSizeAfter;
 353        blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
 354        if (this$static._bufferBase == null || this$static._blockSize != blockSize) {
 355            this$static._bufferBase = null;
 356            this$static._blockSize = blockSize;
 357            this$static._bufferBase = initDim(this$static._blockSize);
 358        }
 359        this$static._pointerToLastSafePosition = this$static._blockSize - keepSizeAfter;
 360    }
 361    
 362    function $GetIndexByte(this$static, index) {
 363        return this$static._bufferBase[this$static._bufferOffset + this$static._pos + index];
 364    }
 365    
 366    function $GetMatchLen(this$static, index, distance, limit) {
 367        var i, pby;
 368        if (this$static._streamEndWasReached) {
 369            if (this$static._pos + index + limit > this$static._streamPos) {
 370                limit = this$static._streamPos - (this$static._pos + index);
 371            }
 372        }
 373        ++distance;
 374        pby = this$static._bufferOffset + this$static._pos + index;
 375        for (i = 0; i < limit && this$static._bufferBase[pby + i] == this$static._bufferBase[pby + i - distance]; ++i) {
 376        }
 377        return i;
 378    }
 379    
 380    function $GetNumAvailableBytes(this$static) {
 381        return this$static._streamPos - this$static._pos;
 382    }
 383    
 384    function $MoveBlock(this$static) {
 385        var i, numBytes, offset;
 386        offset = this$static._bufferOffset + this$static._pos - this$static._keepSizeBefore;
 387        if (offset > 0) {
 388            --offset;
 389        }
 390        numBytes = this$static._bufferOffset + this$static._streamPos - offset;
 391        for (i = 0; i < numBytes; ++i) {
 392            this$static._bufferBase[i] = this$static._bufferBase[offset + i];
 393        }
 394        this$static._bufferOffset -= offset;
 395    }
 396    
 397    function $MovePos_1(this$static) {
 398        var pointerToPostion;
 399        ++this$static._pos;
 400        if (this$static._pos > this$static._posLimit) {
 401            pointerToPostion = this$static._bufferOffset + this$static._pos;
 402            if (pointerToPostion > this$static._pointerToLastSafePosition) {
 403                $MoveBlock(this$static);
 404            }
 405            $ReadBlock(this$static);
 406        }
 407    }
 408    
 409    function $ReadBlock(this$static) {
 410        var numReadBytes, pointerToPostion, size;
 411        if (this$static._streamEndWasReached)
 412            return;
 413        while (1) {
 414            size = -this$static._bufferOffset + this$static._blockSize - this$static._streamPos;
 415            if (!size)
 416                return;
 417            numReadBytes = $read_0(this$static._stream, this$static._bufferBase, this$static._bufferOffset + this$static._streamPos, size);
 418            if (numReadBytes == -1) {
 419                this$static._posLimit = this$static._streamPos;
 420                pointerToPostion = this$static._bufferOffset + this$static._posLimit;
 421                if (pointerToPostion > this$static._pointerToLastSafePosition) {
 422                    this$static._posLimit = this$static._pointerToLastSafePosition - this$static._bufferOffset;
 423                }
 424                this$static._streamEndWasReached = 1;
 425                return;
 426            }
 427            this$static._streamPos += numReadBytes;
 428            if (this$static._streamPos >= this$static._pos + this$static._keepSizeAfter) {
 429                this$static._posLimit = this$static._streamPos - this$static._keepSizeAfter;
 430            }
 431        }
 432    }
 433    
 434    function $ReduceOffsets(this$static, subValue) {
 435        this$static._bufferOffset += subValue;
 436        this$static._posLimit -= subValue;
 437        this$static._pos -= subValue;
 438        this$static._streamPos -= subValue;
 439    }
 440    
 441    var CrcTable = (function () {
 442        var i, j, r, CrcTable = [];
 443        for (i = 0; i < 256; ++i) {
 444            r = i;
 445            for (j = 0; j < 8; ++j)
 446            if ((r & 1) != 0) {
 447                r = r >>> 1 ^ -306674912;
 448            } else {
 449                r >>>= 1;
 450            }
 451            CrcTable[i] = r;
 452        }
 453        return CrcTable;
 454    }());
 455    
 456    function $Create_3(this$static, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter) {
 457        var cyclicBufferSize, hs, windowReservSize;
 458        if (historySize < 1073741567) {
 459            this$static._cutValue = 16 + (matchMaxLen >> 1);
 460            windowReservSize = ~~((historySize + keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2) + 256;
 461            $Create_4(this$static, historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize);
 462            this$static._matchMaxLen = matchMaxLen;
 463            cyclicBufferSize = historySize + 1;
 464            if (this$static._cyclicBufferSize != cyclicBufferSize) {
 465                this$static._son = initDim((this$static._cyclicBufferSize = cyclicBufferSize) * 2);
 466            }
 467    
 468            hs = 65536;
 469            if (this$static.HASH_ARRAY) {
 470                hs = historySize - 1;
 471                hs |= hs >> 1;
 472                hs |= hs >> 2;
 473                hs |= hs >> 4;
 474                hs |= hs >> 8;
 475                hs >>= 1;
 476                hs |= 65535;
 477                if (hs > 16777216)
 478                hs >>= 1;
 479                this$static._hashMask = hs;
 480                ++hs;
 481                hs += this$static.kFixHashSize;
 482            }
 483            
 484            if (hs != this$static._hashSizeSum) {
 485                this$static._hash = initDim(this$static._hashSizeSum = hs);
 486            }
 487        }
 488    }
 489    
 490    function $GetMatches(this$static, distances) {
 491        var count, cur, curMatch, curMatch2, curMatch3, cyclicPos, delta, hash2Value, hash3Value, hashValue, len, len0, len1, lenLimit, matchMinPos, maxLen, offset, pby1, ptr0, ptr1, temp;
 492        if (this$static._pos + this$static._matchMaxLen <= this$static._streamPos) {
 493            lenLimit = this$static._matchMaxLen;
 494        } else {
 495            lenLimit = this$static._streamPos - this$static._pos;
 496            if (lenLimit < this$static.kMinMatchCheck) {
 497                $MovePos_0(this$static);
 498                return 0;
 499            }
 500        }
 501        offset = 0;
 502        matchMinPos = this$static._pos > this$static._cyclicBufferSize?this$static._pos - this$static._cyclicBufferSize:0;
 503        cur = this$static._bufferOffset + this$static._pos;
 504        maxLen = 1;
 505        hash2Value = 0;
 506        hash3Value = 0;
 507        if (this$static.HASH_ARRAY) {
 508            temp = CrcTable[this$static._bufferBase[cur] & 255] ^ this$static._bufferBase[cur + 1] & 255;
 509            hash2Value = temp & 1023;
 510            temp ^= (this$static._bufferBase[cur + 2] & 255) << 8;
 511            hash3Value = temp & 65535;
 512            hashValue = (temp ^ CrcTable[this$static._bufferBase[cur + 3] & 255] << 5) & this$static._hashMask;
 513        } else {
 514            hashValue = this$static._bufferBase[cur] & 255 ^ (this$static._bufferBase[cur + 1] & 255) << 8;
 515        }
 516
 517        curMatch = this$static._hash[this$static.kFixHashSize + hashValue] || 0;
 518        if (this$static.HASH_ARRAY) {
 519            curMatch2 = this$static._hash[hash2Value] || 0;
 520            curMatch3 = this$static._hash[1024 + hash3Value] || 0;
 521            this$static._hash[hash2Value] = this$static._pos;
 522            this$static._hash[1024 + hash3Value] = this$static._pos;
 523            if (curMatch2 > matchMinPos) {
 524                if (this$static._bufferBase[this$static._bufferOffset + curMatch2] == this$static._bufferBase[cur]) {
 525                    distances[offset++] = maxLen = 2;
 526                    distances[offset++] = this$static._pos - curMatch2 - 1;
 527                }
 528            }
 529            if (curMatch3 > matchMinPos) {
 530                if (this$static._bufferBase[this$static._bufferOffset + curMatch3] == this$static._bufferBase[cur]) {
 531                    if (curMatch3 == curMatch2) {
 532                        offset -= 2;
 533                    }
 534                    distances[offset++] = maxLen = 3;
 535                    distances[offset++] = this$static._pos - curMatch3 - 1;
 536                    curMatch2 = curMatch3;
 537                }
 538            }
 539            if (offset != 0 && curMatch2 == curMatch) {
 540                offset -= 2;
 541                maxLen = 1;
 542            }
 543        }
 544        this$static._hash[this$static.kFixHashSize + hashValue] = this$static._pos;
 545        ptr0 = (this$static._cyclicBufferPos << 1) + 1;
 546        ptr1 = this$static._cyclicBufferPos << 1;
 547        len0 = len1 = this$static.kNumHashDirectBytes;
 548        if (this$static.kNumHashDirectBytes != 0) {
 549            if (curMatch > matchMinPos) {
 550                if (this$static._bufferBase[this$static._bufferOffset + curMatch + this$static.kNumHashDirectBytes] != this$static._bufferBase[cur + this$static.kNumHashDirectBytes]) {
 551                    distances[offset++] = maxLen = this$static.kNumHashDirectBytes;
 552                    distances[offset++] = this$static._pos - curMatch - 1;
 553                }
 554            }
 555        }
 556        count = this$static._cutValue;
 557        while (1) {
 558            if (curMatch <= matchMinPos || count-- == 0) {
 559                this$static._son[ptr0] = this$static._son[ptr1] = 0;
 560                break;
 561            }
 562            delta = this$static._pos - curMatch;
 563            cyclicPos = (delta <= this$static._cyclicBufferPos?this$static._cyclicBufferPos - delta:this$static._cyclicBufferPos - delta + this$static._cyclicBufferSize) << 1;
 564            pby1 = this$static._bufferOffset + curMatch;
 565            len = len0 < len1?len0:len1;
 566            if (this$static._bufferBase[pby1 + len] == this$static._bufferBase[cur + len]) {
 567                while (++len != lenLimit) {
 568                    if (this$static._bufferBase[pby1 + len] != this$static._bufferBase[cur + len]) {
 569                        break;
 570                    }
 571                }
 572                if (maxLen < len) {
 573                    distances[offset++] = maxLen = len;
 574                    distances[offset++] = delta - 1;
 575                    if (len == lenLimit) {
 576                    this$static._son[ptr1] = this$static._son[cyclicPos];
 577                    this$static._son[ptr0] = this$static._son[cyclicPos + 1];
 578                    break;
 579                    }
 580                }
 581            }
 582            if ((this$static._bufferBase[pby1 + len] & 255) < (this$static._bufferBase[cur + len] & 255)) {
 583                this$static._son[ptr1] = curMatch;
 584                ptr1 = cyclicPos + 1;
 585                curMatch = this$static._son[ptr1];
 586                len1 = len;
 587            } else {
 588                this$static._son[ptr0] = curMatch;
 589                ptr0 = cyclicPos;
 590                curMatch = this$static._son[ptr0];
 591                len0 = len;
 592            }
 593        }
 594        $MovePos_0(this$static);
 595        return offset;
 596    }
 597    
 598    function $Init_5(this$static) {
 599        this$static._bufferOffset = 0;
 600        this$static._pos = 0;
 601        this$static._streamPos = 0;
 602        this$static._streamEndWasReached = 0;
 603        $ReadBlock(this$static);
 604        this$static._cyclicBufferPos = 0;
 605        $ReduceOffsets(this$static, -1);
 606    }
 607    
 608    function $MovePos_0(this$static) {
 609        var subValue;
 610        if (++this$static._cyclicBufferPos >= this$static._cyclicBufferSize) {
 611            this$static._cyclicBufferPos = 0;
 612        }
 613        $MovePos_1(this$static);
 614        if (this$static._pos == 1073741823) {
 615            subValue = this$static._pos - this$static._cyclicBufferSize;
 616            $NormalizeLinks(this$static._son, this$static._cyclicBufferSize * 2, subValue);
 617            $NormalizeLinks(this$static._hash, this$static._hashSizeSum, subValue);
 618            $ReduceOffsets(this$static, subValue);
 619        }
 620    }
 621    
 622    ///NOTE: This is only called after reading one whole gigabyte.
 623    function $NormalizeLinks(items, numItems, subValue) {
 624        var i, value;
 625        for (i = 0; i < numItems; ++i) {
 626            value = items[i] || 0;
 627            if (value <= subValue) {
 628                value = 0;
 629            } else {
 630                value -= subValue;
 631            }
 632            items[i] = value;
 633        }
 634    }
 635    
 636    function $SetType(this$static, numHashBytes) {
 637        this$static.HASH_ARRAY = numHashBytes > 2;
 638        if (this$static.HASH_ARRAY) {
 639            this$static.kNumHashDirectBytes = 0;
 640            this$static.kMinMatchCheck = 4;
 641            this$static.kFixHashSize = 66560;
 642        } else {
 643            this$static.kNumHashDirectBytes = 2;
 644            this$static.kMinMatchCheck = 3;
 645            this$static.kFixHashSize = 0;
 646        }
 647    }
 648    
 649    function $Skip(this$static, num) {
 650        var count, cur, curMatch, cyclicPos, delta, hash2Value, hash3Value, hashValue, len, len0, len1, lenLimit, matchMinPos, pby1, ptr0, ptr1, temp;
 651        do {
 652            if (this$static._pos + this$static._matchMaxLen <= this$static._streamPos) {
 653                lenLimit = this$static._matchMaxLen;
 654            } else {
 655                lenLimit = this$static._streamPos - this$static._pos;
 656                if (lenLimit < this$static.kMinMatchCheck) {
 657                    $MovePos_0(this$static);
 658                    continue;
 659                }
 660            }
 661            matchMinPos = this$static._pos > this$static._cyclicBufferSize?this$static._pos - this$static._cyclicBufferSize:0;
 662            cur = this$static._bufferOffset + this$static._pos;
 663            if (this$static.HASH_ARRAY) {
 664                temp = CrcTable[this$static._bufferBase[cur] & 255] ^ this$static._bufferBase[cur + 1] & 255;
 665                hash2Value = temp & 1023;
 666                this$static._hash[hash2Value] = this$static._pos;
 667                temp ^= (this$static._bufferBase[cur + 2] & 255) << 8;
 668                hash3Value = temp & 65535;
 669                this$static._hash[1024 + hash3Value] = this$static._pos;
 670                hashValue = (temp ^ CrcTable[this$static._bufferBase[cur + 3] & 255] << 5) & this$static._hashMask;
 671            } else {
 672                hashValue = this$static._bufferBase[cur] & 255 ^ (this$static._bufferBase[cur + 1] & 255) << 8;
 673            }
 674            curMatch = this$static._hash[this$static.kFixHashSize + hashValue];
 675            this$static._hash[this$static.kFixHashSize + hashValue] = this$static._pos;
 676            ptr0 = (this$static._cyclicBufferPos << 1) + 1;
 677            ptr1 = this$static._cyclicBufferPos << 1;
 678            len0 = len1 = this$static.kNumHashDirectBytes;
 679            count = this$static._cutValue;
 680            while (1) {
 681                if (curMatch <= matchMinPos || count-- == 0) {
 682                    this$static._son[ptr0] = this$static._son[ptr1] = 0;
 683                    break;
 684                }
 685                delta = this$static._pos - curMatch;
 686                cyclicPos = (delta <= this$static._cyclicBufferPos?this$static._cyclicBufferPos - delta:this$static._cyclicBufferPos - delta + this$static._cyclicBufferSize) << 1;
 687                pby1 = this$static._bufferOffset + curMatch;
 688                len = len0 < len1?len0:len1;
 689                if (this$static._bufferBase[pby1 + len] == this$static._bufferBase[cur + len]) {
 690                    while (++len != lenLimit) {
 691                        if (this$static._bufferBase[pby1 + len] != this$static._bufferBase[cur + len]) {
 692                            break;
 693                        }
 694                    }
 695                    if (len == lenLimit) {
 696                        this$static._son[ptr1] = this$static._son[cyclicPos];
 697                        this$static._son[ptr0] = this$static._son[cyclicPos + 1];
 698                        break;
 699                    }
 700                }
 701                if ((this$static._bufferBase[pby1 + len] & 255) < (this$static._bufferBase[cur + len] & 255)) {
 702                    this$static._son[ptr1] = curMatch;
 703                    ptr1 = cyclicPos + 1;
 704                    curMatch = this$static._son[ptr1];
 705                    len1 = len;
 706                } else {
 707                    this$static._son[ptr0] = curMatch;
 708                    ptr0 = cyclicPos;
 709                    curMatch = this$static._son[ptr0];
 710                    len0 = len;
 711                }
 712            }
 713            $MovePos_0(this$static);
 714        }
 715        while (--num != 0);
 716    }
 717    
 718    /** ce */
 719    /** ds */
 720    function $CopyBlock(this$static, distance, len) {
 721        var pos = this$static._pos - distance - 1;
 722        if (pos < 0) {
 723            pos += this$static._windowSize;
 724        }
 725        for (; len != 0; --len) {
 726            if (pos >= this$static._windowSize) {
 727                pos = 0;
 728            }
 729            this$static._buffer[this$static._pos++] = this$static._buffer[pos++];
 730            if (this$static._pos >= this$static._windowSize) {
 731                $Flush_0(this$static);
 732            }
 733        }
 734    }
 735    
 736    function $Create_5(this$static, windowSize) {
 737        if (this$static._buffer == null || this$static._windowSize != windowSize) {
 738            this$static._buffer = initDim(windowSize);
 739        }
 740        this$static._windowSize = windowSize;
 741        this$static._pos = 0;
 742        this$static._streamPos = 0;
 743    }
 744    
 745    function $Flush_0(this$static) {
 746        var size = this$static._pos - this$static._streamPos;
 747        if (!size) {
 748            return;
 749        }
 750        $write_0(this$static._stream, this$static._buffer, this$static._streamPos, size);
 751        if (this$static._pos >= this$static._windowSize) {
 752            this$static._pos = 0;
 753        }
 754        this$static._streamPos = this$static._pos;
 755    }
 756    
 757    function $GetByte(this$static, distance) {
 758        var pos = this$static._pos - distance - 1;
 759        if (pos < 0) {
 760            pos += this$static._windowSize;
 761        }
 762        return this$static._buffer[pos];
 763    }
 764    
 765    function $PutByte(this$static, b) {
 766        this$static._buffer[this$static._pos++] = b;
 767        if (this$static._pos >= this$static._windowSize) {
 768            $Flush_0(this$static);
 769        }
 770    }
 771    
 772    function $ReleaseStream(this$static) {
 773        $Flush_0(this$static);
 774        this$static._stream = null;
 775    }
 776    /** de */
 777    
 778    function GetLenToPosState(len) {
 779        len -= 2;
 780        if (len < 4) {
 781            return len;
 782        }
 783        return 3;
 784    }
 785    
 786    function StateUpdateChar(index) {
 787        if (index < 4) {
 788            return 0;
 789        }
 790        if (index < 10) {
 791            return index - 3;
 792        }
 793        return index - 6;
 794    }
 795    
 796    /** cs */
 797    function $Chunker_0(this$static, encoder) {
 798        this$static.encoder = encoder;
 799        this$static.decoder = null;
 800        this$static.alive = 1;
 801        return this$static;
 802    }
 803    /** ce */
 804    /** ds */
 805    function $Chunker(this$static, decoder) {
 806        this$static.decoder = decoder;
 807        this$static.encoder = null;
 808        this$static.alive = 1;
 809        return this$static;
 810    }
 811    /** de */
 812    
 813    function $processChunk(this$static) {
 814        if (!this$static.alive) {
 815            throw new Error("bad state");
 816        }
 817        
 818        if (this$static.encoder) {
 819            /// do:throw new Error("No encoding");
 820            /** cs */
 821            $processEncoderChunk(this$static);
 822            /** ce */
 823        } else {
 824            /// co:throw new Error("No decoding");
 825            /** ds */
 826            $processDecoderChunk(this$static);
 827            /** de */
 828        }
 829        return this$static.alive;
 830    }
 831    
 832    /** ds */
 833    function $processDecoderChunk(this$static) {
 834        var result = $CodeOneChunk(this$static.decoder);
 835        if (result == -1) {
 836            throw new Error("corrupted input");
 837        }
 838        this$static.inBytesProcessed = N1_longLit;
 839        this$static.outBytesProcessed = this$static.decoder.nowPos64;
 840        if (result || compare(this$static.decoder.outSize, P0_longLit) >= 0 && compare(this$static.decoder.nowPos64, this$static.decoder.outSize) >= 0) {
 841            $Flush_0(this$static.decoder.m_OutWindow);
 842            $ReleaseStream(this$static.decoder.m_OutWindow);
 843            this$static.decoder.m_RangeDecoder.Stream = null;
 844            this$static.alive = 0;
 845        }
 846    }
 847    /** de */
 848    /** cs */
 849    function $processEncoderChunk(this$static) {
 850        $CodeOneBlock(this$static.encoder, this$static.encoder.processedInSize, this$static.encoder.processedOutSize, this$static.encoder.finished);
 851        this$static.inBytesProcessed = this$static.encoder.processedInSize[0];
 852        if (this$static.encoder.finished[0]) {
 853            $ReleaseStreams(this$static.encoder);
 854            this$static.alive = 0;
 855        }
 856    }
 857    /** ce */
 858    
 859    /** ds */
 860    function $CodeInChunks(this$static, inStream, outStream, outSize) {
 861        this$static.m_RangeDecoder.Stream = inStream;
 862        $ReleaseStream(this$static.m_OutWindow);
 863        this$static.m_OutWindow._stream = outStream;
 864        $Init_1(this$static);
 865        this$static.state = 0;
 866        this$static.rep0 = 0;
 867        this$static.rep1 = 0;
 868        this$static.rep2 = 0;
 869        this$static.rep3 = 0;
 870        this$static.outSize = outSize;
 871        this$static.nowPos64 = P0_longLit;
 872        this$static.prevByte = 0;
 873        return $Chunker({}, this$static);
 874    }
 875    
 876    function $CodeOneChunk(this$static) {
 877        var decoder2, distance, len, numDirectBits, posSlot, posState;
 878        posState = lowBits_0(this$static.nowPos64) & this$static.m_PosStateMask;
 879        if (!$DecodeBit(this$static.m_RangeDecoder, this$static.m_IsMatchDecoders, (this$static.state << 4) + posState)) {
 880            decoder2 = $GetDecoder(this$static.m_LiteralDecoder, lowBits_0(this$static.nowPos64), this$static.prevByte);
 881            if (this$static.state < 7) {
 882                this$static.prevByte = $DecodeNormal(decoder2, this$static.m_RangeDecoder);
 883            } else {
 884                this$static.prevByte = $DecodeWithMatchByte(decoder2, this$static.m_RangeDecoder, $GetByte(this$static.m_OutWindow, this$static.rep0));
 885            }
 886            $PutByte(this$static.m_OutWindow, this$static.prevByte);
 887            this$static.state = StateUpdateChar(this$static.state);
 888            this$static.nowPos64 = add(this$static.nowPos64, P1_longLit);
 889        } else {
 890            if ($DecodeBit(this$static.m_RangeDecoder, this$static.m_IsRepDecoders, this$static.state)) {
 891                len = 0;
 892                if (!$DecodeBit(this$static.m_RangeDecoder, this$static.m_IsRepG0Decoders, this$static.state)) {
 893                    if (!$DecodeBit(this$static.m_RangeDecoder, this$static.m_IsRep0LongDecoders, (this$static.state << 4) + posState)) {
 894                        this$static.state = this$static.state < 7?9:11;
 895                        len = 1;
 896                    }
 897                } else {
 898                    if (!$DecodeBit(this$static.m_RangeDecoder, this$static.m_IsRepG1Decoders, this$static.state)) {
 899                        distance = this$static.rep1;
 900                    } else {
 901                        if (!$DecodeBit(this$static.m_RangeDecoder, this$static.m_IsRepG2Decoders, this$static.state)) {
 902                            distance = this$static.rep2;
 903                        } else {
 904                            distance = this$static.rep3;
 905                            this$static.rep3 = this$static.rep2;
 906                        }
 907                        this$static.rep2 = this$static.rep1;
 908                    }
 909                    this$static.rep1 = this$static.rep0;
 910                    this$static.rep0 = distance;
 911                }
 912                if (!len) {
 913                    len = $Decode(this$static.m_RepLenDecoder, this$static.m_RangeDecoder, posState) + 2;
 914                    this$static.state = this$static.state < 7?8:11;
 915                }
 916            } else {
 917                this$static.rep3 = this$static.rep2;
 918                this$static.rep2 = this$static.rep1;
 919                this$static.rep1 = this$static.rep0;
 920                len = 2 + $Decode(this$static.m_LenDecoder, this$static.m_RangeDecoder, posState);
 921                this$static.state = this$static.state < 7?7:10;
 922                posSlot = $Decode_0(this$static.m_PosSlotDecoder[GetLenToPosState(len)], this$static.m_RangeDecoder);
 923                if (posSlot >= 4) {
 924                    numDirectBits = (posSlot >> 1) - 1;
 925                    this$static.rep0 = (2 | posSlot & 1) << numDirectBits;
 926                    if (posSlot < 14) {
 927                        this$static.rep0 += ReverseDecode(this$static.m_PosDecoders, this$static.rep0 - posSlot - 1, this$static.m_RangeDecoder, numDirectBits);
 928                    } else {
 929                        this$static.rep0 += $DecodeDirectBits(this$static.m_RangeDecoder, numDirectBits - 4) << 4;
 930                        this$static.rep0 += $ReverseDecode(this$static.m_PosAlignDecoder, this$static.m_RangeDecoder);
 931                        if (this$static.rep0 < 0) {
 932                            if (this$static.rep0 == -1) {
 933                                return 1;
 934                            }
 935                            return -1;
 936                        }
 937                    }
 938                } else 
 939                    this$static.rep0 = posSlot;
 940            }
 941            if (compare(fromInt(this$static.rep0), this$static.nowPos64) >= 0 || this$static.rep0 >= this$static.m_DictionarySizeCheck) {
 942                return -1;
 943            }
 944            $CopyBlock(this$static.m_OutWindow, this$static.rep0, len);
 945            this$static.nowPos64 = add(this$static.nowPos64, fromInt(len));
 946            this$static.prevByte = $GetByte(this$static.m_OutWindow, 0);
 947        }
 948        return 0;
 949    }
 950    
 951    function $Decoder(this$static) {
 952        this$static.m_OutWindow = {};
 953        this$static.m_RangeDecoder = {};
 954        this$static.m_IsMatchDecoders = initDim(192);
 955        this$static.m_IsRepDecoders = initDim(12);
 956        this$static.m_IsRepG0Decoders = initDim(12);
 957        this$static.m_IsRepG1Decoders = initDim(12);
 958        this$static.m_IsRepG2Decoders = initDim(12);
 959        this$static.m_IsRep0LongDecoders = initDim(192);
 960        this$static.m_PosSlotDecoder = initDim(4);
 961        this$static.m_PosDecoders = initDim(114);
 962        this$static.m_PosAlignDecoder = $BitTreeDecoder({}, 4);
 963        this$static.m_LenDecoder = $Decoder$LenDecoder({});
 964        this$static.m_RepLenDecoder = $Decoder$LenDecoder({});
 965        this$static.m_LiteralDecoder = {};
 966        for (var i = 0; i < 4; ++i) {
 967            this$static.m_PosSlotDecoder[i] = $BitTreeDecoder({}, 6);
 968        }
 969        return this$static;
 970    }
 971    
 972    function $Init_1(this$static) {
 973        this$static.m_OutWindow._streamPos = 0;
 974        this$static.m_OutWindow._pos = 0;
 975        InitBitModels(this$static.m_IsMatchDecoders);
 976        InitBitModels(this$static.m_IsRep0LongDecoders);
 977        InitBitModels(this$static.m_IsRepDecoders);
 978        InitBitModels(this$static.m_IsRepG0Decoders);
 979        InitBitModels(this$static.m_IsRepG1Decoders);
 980        InitBitModels(this$static.m_IsRepG2Decoders);
 981        InitBitModels(this$static.m_PosDecoders);
 982        $Init_0(this$static.m_LiteralDecoder);
 983        for (var i = 0; i < 4; ++i) {
 984            InitBitModels(this$static.m_PosSlotDecoder[i].Models);
 985        }
 986        $Init(this$static.m_LenDecoder);
 987        $Init(this$static.m_RepLenDecoder);
 988        InitBitModels(this$static.m_PosAlignDecoder.Models);
 989        $Init_8(this$static.m_RangeDecoder);
 990    }
 991    
 992    function $SetDecoderProperties(this$static, properties) {
 993        var dictionarySize, i, lc, lp, pb, remainder, val;
 994        if (properties.length < 5)
 995            return 0;
 996        val = properties[0] & 255;
 997        lc = val % 9;
 998        remainder = ~~(val / 9);
 999        lp = remainder % 5;
1000        pb = ~~(remainder / 5);
1001        dictionarySize = 0;
1002        for (i = 0; i < 4; ++i) {
1003            dictionarySize += (properties[1 + i] & 255) << i * 8;
1004        }
1005        ///NOTE: If the input is bad, it might call for an insanely large dictionary size, which would crash the script.
1006        if (dictionarySize > 99999999 || !$SetLcLpPb(this$static, lc, lp, pb)) {
1007            return 0;
1008        }
1009        return $SetDictionarySize(this$static, dictionarySize);
1010    }
1011    
1012    function $SetDictionarySize(this$static, dictionarySize) {
1013        if (dictionarySize < 0) {
1014            return 0;
1015        }
1016        if (this$static.m_DictionarySize != dictionarySize) {
1017            this$static.m_DictionarySize = dictionarySize;
1018            this$static.m_DictionarySizeCheck = Math.max(this$static.m_DictionarySize, 1);
1019            $Create_5(this$static.m_OutWindow, Math.max(this$static.m_DictionarySizeCheck, 4096));
1020        }
1021        return 1;
1022    }
1023    
1024    function $SetLcLpPb(this$static, lc, lp, pb) {
1025        if (lc > 8 || lp > 4 || pb > 4) {
1026            return 0;
1027        }
1028        $Create_0(this$static.m_LiteralDecoder, lp, lc);
1029        var numPosStates = 1 << pb;
1030        $Create(this$static.m_LenDecoder, numPosStates);
1031        $Create(this$static.m_RepLenDecoder, numPosStates);
1032        this$static.m_PosStateMask = numPosStates - 1;
1033        return 1;
1034    }
1035    
1036    function $Create(this$static, numPosStates) {
1037        for (; this$static.m_NumPosStates < numPosStates; ++this$static.m_NumPosStates) {
1038            this$static.m_LowCoder[this$static.m_NumPosStates] = $BitTreeDecoder({}, 3);
1039            this$static.m_MidCoder[this$static.m_NumPosStates] = $BitTreeDecoder({}, 3);
1040        }
1041    }
1042    
1043    function $Decode(this$static, rangeDecoder, posState) {
1044        if (!$DecodeBit(rangeDecoder, this$static.m_Choice, 0)) {
1045            return $Decode_0(this$static.m_LowCoder[posState], rangeDecoder);
1046        }
1047        var symbol = 8;
1048        if (!$DecodeBit(rangeDecoder, this$static.m_Choice, 1)) {
1049            symbol += $Decode_0(this$static.m_MidCoder[posState], rangeDecoder);
1050        } else {
1051            symbol += 8 + $Decode_0(this$static.m_HighCoder, rangeDecoder);
1052        }
1053        return symbol;
1054    }
1055    
1056    function $Decoder$LenDecoder(this$static) {
1057        this$static.m_Choice = initDim(2);
1058        this$static.m_LowCoder = initDim(16);
1059        this$static.m_MidCoder = initDim(16);
1060        this$static.m_HighCoder = $BitTreeDecoder({}, 8);
1061        this$static.m_NumPosStates = 0;
1062        return this$static;
1063    }
1064    
1065    function $Init(this$static) {
1066        InitBitModels(this$static.m_Choice);
1067        for (var posState = 0; posState < this$static.m_NumPosStates; ++posState) {
1068            InitBitModels(this$static.m_LowCoder[posState].Models);
1069            InitBitModels(this$static.m_MidCoder[posState].Models);
1070        }
1071        InitBitModels(this$static.m_HighCoder.Models);
1072    }
1073    
1074    
1075    function $Create_0(this$static, numPosBits, numPrevBits) {
1076        var i, numStates;
1077        if (this$static.m_Coders != null && this$static.m_NumPrevBits == numPrevBits && this$static.m_NumPosBits == numPosBits)
1078            return;
1079        this$static.m_NumPosBits = numPosBits;
1080        this$static.m_PosMask = (1 << numPosBits) - 1;
1081        this$static.m_NumPrevBits = numPrevBits;
1082        numStates = 1 << this$static.m_NumPrevBits + this$static.m_NumPosBits;
1083        this$static.m_Coders = initDim(numStates);
1084        for (i = 0; i < numStates; ++i)
1085            this$static.m_Coders[i] = $Decoder$LiteralDecoder$Decoder2({});
1086    }
1087    
1088    function $GetDecoder(this$static, pos, prevByte) {
1089        return this$static.m_Coders[((pos & this$static.m_PosMask) << this$static.m_NumPrevBits) + ((prevByte & 255) >>> 8 - this$static.m_NumPrevBits)];
1090    }
1091    
1092    function $Init_0(this$static) {
1093        var i, numStates;
1094        numStates = 1 << this$static.m_NumPrevBits + this$static.m_NumPosBits;
1095        for (i = 0; i < numStates; ++i) {
1096            InitBitModels(this$static.m_Coders[i].m_Decoders);
1097        }
1098    }
1099    
1100    
1101    function $DecodeNormal(this$static, rangeDecoder) {
1102        var symbol = 1;
1103        do {
1104            symbol = symbol << 1 | $DecodeBit(rangeDecoder, this$static.m_Decoders, symbol);
1105        } while (symbol < 256);
1106        return symbol << 24 >> 24;
1107    }
1108    
1109    function $DecodeWithMatchByte(this$static, rangeDecoder, matchByte) {
1110        var bit, matchBit, symbol = 1;
1111        do {
1112            matchBit = matchByte >> 7 & 1;
1113            matchByte <<= 1;
1114            bit = $DecodeBit(rangeDecoder, this$static.m_Decoders, (1 + matchBit << 8) + symbol);
1115            symbol = symbol << 1 | bit;
1116            if (matchBit != bit) {
1117                while (symbol < 256) {
1118                    symbol = symbol << 1 | $DecodeBit(rangeDecoder, this$static.m_Decoders, symbol);
1119                }
1120            break;
1121            }
1122        } while (symbol < 256);
1123        return symbol << 24 >> 24;
1124    }
1125    
1126    function $Decoder$LiteralDecoder$Decoder2(this$static) {
1127        this$static.m_Decoders = initDim(768);
1128        return this$static;
1129    }
1130    
1131    /** de */
1132    /** cs */
1133    var g_FastPos = (function () {
1134        var j, k, slotFast, c = 2, g_FastPos = [0, 1];
1135        for (slotFast = 2; slotFast < 22; ++slotFast) {
1136            k = 1 << (slotFast >> 1) - 1;
1137            for (j = 0; j < k; ++j , ++c)
1138                g_FastPos[c] = slotFast << 24 >> 24;
1139        }
1140        return g_FastPos;
1141    }());
1142    
1143    function $Backward(this$static, cur) {
1144        var backCur, backMem, posMem, posPrev;
1145        this$static._optimumEndIndex = cur;
1146        posMem = this$static._optimum[cur].PosPrev;
1147        backMem = this$static._optimum[cur].BackPrev;
1148        do {
1149            if (this$static._optimum[cur].Prev1IsChar) {
1150                $MakeAsChar(this$static._optimum[posMem]);
1151                this$static._optimum[posMem].PosPrev = posMem - 1;
1152                if (this$static._optimum[cur].Prev2) {
1153                    this$static._optimum[posMem - 1].Prev1IsChar = 0;
1154                    this$static._optimum[posMem - 1].PosPrev = this$static._optimum[cur].PosPrev2;
1155                    this$static._optimum[posMem - 1].BackPrev = this$static._optimum[cur].BackPrev2;
1156                }
1157            }
1158            posPrev = posMem;
1159            backCur = backMem;
1160            backMem = this$static._optimum[posPrev].BackPrev;
1161            posMem = this$static._optimum[posPrev].PosPrev;
1162            this$static._optimum[posPrev].BackPrev = backCur;
1163            this$static._optimum[posPrev].PosPrev = cur;
1164            cur = posPrev;
1165        } while (cur > 0);
1166        this$static.backRes = this$static._optimum[0].BackPrev;
1167        this$static._optimumCurrentIndex = this$static._optimum[0].PosPrev;
1168        return this$static._optimumCurrentIndex;
1169    }
1170    
1171    function $BaseInit(this$static) {
1172        this$static._state = 0;
1173        this$static._previousByte = 0;
1174        for (var i = 0; i < 4; ++i) {
1175            this$static._repDistances[i] = 0;
1176        }
1177    }
1178    
1179    function $CodeOneBlock(this$static, inSize, outSize, finished) {
1180        var baseVal, complexState, curByte, distance, footerBits, i, len, lenToPosState, matchByte, pos, posReduced, posSlot, posState, progressPosValuePrev, subCoder;
1181        inSize[0] = P0_longLit;
1182        outSize[0] = P0_longLit;
1183        finished[0] = 1;
1184        if (this$static._inStream) {
1185            this$static._matchFinder._stream = this$static._inStream;
1186            $Init_5(this$static._matchFinder);
1187            this$static._needReleaseMFStream = 1;
1188            this$static._inStream = null;
1189        }
1190        if (this$static._finished) {
1191            return;
1192        }
1193        this$static._finished = 1;
1194        progressPosValuePrev = this$static.nowPos64;
1195        if (eq(this$static.nowPos64, P0_longLit)) {
1196            if (!$GetNumAvailableBytes(this$static._matchFinder)) {
1197                $Flush(this$static, lowBits_0(this$static.nowPos64));
1198                return;
1199            }
1200            $ReadMatchDistances(this$static);
1201            posState = lowBits_0(this$static.nowPos64) & this$static._posStateMask;
1202            $Encode_3(this$static._rangeEncoder, this$static._isMatch, (this$static._state << 4) + posState, 0);
1203            this$static._state = StateUpdateChar(this$static._state);
1204            curByte = $GetIndexByte(this$static._matchFinder, -this$static._additionalOffset);
1205            $Encode_1($GetSubCoder(this$static._literalEncoder, lowBits_0(this$static.nowPos64), this$static._previousByte), this$static._rangeEncoder, curByte);
1206            this$static._previousByte = curByte;
1207            --this$static._additionalOffset;
1208            this$static.nowPos64 = add(this$static.nowPos64, P1_longLit);
1209        }
1210        if (!$GetNumAvailableBytes(this$static._matchFinder)) {
1211            $Flush(this$static, lowBits_0(this$static.nowPos64));
1212            return;
1213        }
1214        while (1) {
1215            len = $GetOptimum(this$static, lowBits_0(this$static.nowPos64));
1216            pos = this$static.backRes;
1217            posState = lowBits_0(this$static.nowPos64) & this$static._posStateMask;
1218            complexState = (this$static._state << 4) + posState;
1219            if (len == 1 && pos == -1) {
1220                $Encode_3(this$static._rangeEncoder, this$static._isMatch, complexState, 0);
1221                curByte = $GetIndexByte(this$static._matchFinder, -this$static._additionalOffset);
1222                subCoder = $GetSubCoder(this$static._literalEncoder, lowBits_0(this$static.nowPos64), this$static._previousByte);
1223                if (this$static._state < 7) {
1224                    $Encode_1(subCoder, this$static._rangeEncoder, curByte);
1225                } else {
1226                    matchByte = $GetIndexByte(this$static._matchFinder, -this$static._repDistances[0] - 1 - this$static._additionalOffset);
1227                    $EncodeMatched(subCoder, this$static._rangeEncoder, matchByte, curByte);
1228                }
1229                this$static._previousByte = curByte;
1230                this$static._state = StateUpdateChar(this$static._state);
1231            } else {
1232                $Encode_3(this$static._rangeEncoder, this$static._isMatch, complexState, 1);
1233                if (pos < 4) {
1234                    $Encode_3(this$static._rangeEncoder, this$static._isRep, this$static._state, 1);
1235                    if (!pos) {
1236                        $Encode_3(this$static._rangeEncoder, this$static._isRepG0, this$static._state, 0);
1237                        if (len == 1) {
1238                            $Encode_3(this$static._rangeEncoder, this$static._isRep0Long, complexState, 0);
1239                        } else {
1240                            $Encode_3(this$static._rangeEncoder, this$static._isRep0Long, complexState, 1);
1241                        }
1242                    } else {
1243                        $Encode_3(this$static._rangeEncoder, this$static._isRepG0, this$static._state, 1);
1244                        if (pos == 1) {
1245                            $Encode_3(this$static._rangeEncoder, this$static._isRepG1, this$static._state, 0);
1246                        } else {
1247                            $Encode_3(this$static._rangeEncoder, this$static._isRepG1, this$static._state, 1);
1248                            $Encode_3(this$static._rangeEncoder, this$static._isRepG2, this$static._state, pos - 2);
1249                        }
1250                    }
1251                    if (len == 1) {
1252                        this$static._state = this$static._state < 7?9:11;
1253                    } else {
1254                        $Encode_0(this$static._repMatchLenEncoder, this$static._rangeEncoder, len - 2, posState);
1255                        this$static._state = this$static._state < 7?8:11;
1256                    }
1257                    distance = this$static._repDistances[pos];
1258                    if (pos != 0) {
1259                        for (i = pos; i >= 1; --i) {
1260                            this$static._repDistances[i] = this$static._repDistances[i - 1];
1261                        }
1262                        this$static._repDistances[0] = distance;
1263                    }
1264                } else {
1265                    $Encode_3(this$static._rangeEncoder, this$static._isRep, this$static._state, 0);
1266                    this$static._state = this$static._state < 7?7:10;
1267                    $Encode_0(this$static._lenEncoder, this$static._rangeEncoder, len - 2, posState);
1268                    pos -= 4;
1269                    posSlot = GetPosSlot(pos);
1270                    lenToPosState = GetLenToPosState(len);
1271                    $Encode_2(this$static._posSlotEncoder[lenToPosState], this$static._rangeEncoder, posSlot);
1272                    if (posSlot >= 4) {
1273                        footerBits = (posSlot >> 1) - 1;
1274                        baseVal = (2 | posSlot & 1) << footerBits;
1275                        posReduced = pos - baseVal;
1276                        if (posSlot < 14) {
1277                            ReverseEncode(this$static._posEncoders, baseVal - posSlot - 1, this$static._rangeEncoder, footerBits, posReduced);
1278                        } else {
1279                            $EncodeDirectBits(this$static._rangeEncoder, posReduced >> 4, footerBits - 4);
1280                            $ReverseEncode(this$static._posAlignEncoder, this$static._rangeEncoder, posReduced & 15);
1281                            ++this$static._alignPriceCount;
1282                        }
1283                    }
1284                    distance = pos;
1285                    for (i = 3; i >= 1; --i) {
1286                        this$static._repDistances[i] = this$static._repDistances[i - 1];
1287                    }
1288                    this$static._repDistances[0] = distance;
1289                    ++this$static._matchPriceCount;
1290                }
1291                this$static._previousByte = $GetIndexByte(this$static._matchFinder, len - 1 - this$static._additionalOffset);
1292            }
1293            this$static._additionalOffset -= len;
1294            this$static.nowPos64 = add(this$static.nowPos64, fromInt(len));
1295            if (!this$static._additionalOffset) {
1296                if (this$static._matchPriceCount >= 128) {
1297                    $FillDistancesPrices(this$static);
1298                }
1299                if (this$static._alignPriceCount >= 16) {
1300                    $FillAlignPrices(this$static);
1301                }
1302                inSize[0] = this$static.nowPos64;
1303                outSize[0] = $GetProcessedSizeAdd(this$static._rangeEncoder);
1304                if (!$GetNumAvailableBytes(this$static._matchFinder)) {
1305                    $Flush(this$static, lowBits_0(this$static.nowPos64));
1306                    return;
1307                }
1308                if (compare(sub(this$static.nowPos64, progressPosValuePrev), [4096, 0]) >= 0) {
1309                    this$static._finished = 0;
1310                    finished[0] = 0;
1311                    return;
1312                }
1313            }
1314        }
1315    }
1316    
1317    function $Create_2(this$static) {
1318        var bt, numHashBytes;
1319        if (!this$static._matchFinder) {
1320            bt = {};
1321            numHashBytes = 4;
1322            if (!this$static._matchFinderType) {
1323                numHashBytes = 2;
1324            }
1325            $SetType(bt, numHashBytes);
1326            this$static._matchFinder = bt;
1327        }
1328        $Create_1(this$static._literalEncoder, this$static._numLiteralPosStateBits, this$static._numLiteralContextBits);
1329        if (this$static._dictionarySize == this$static._dictionarySizePrev && this$static._numFastBytesPrev == this$static._numFastBytes) {
1330            return;
1331        }
1332        $Create_3(this$static._matchFinder, this$static._dictionarySize, 4096, this$static._numFastBytes, 274);
1333        this$static._dictionarySizePrev = this$static._dictionarySize;
1334        this$static._numFastBytesPrev = this$static._numFastBytes;
1335    }
1336    
1337    function $Encoder(this$static) {
1338        var i;
1339        this$static._repDistances = initDim(4);
1340        this$static._optimum = [];
1341        this$static._rangeEncoder = {};
1342        this$static._isMatch = initDim(192);
1343        this$static._isRep = initDim(12);
1344        this$static._isRepG0 = initDim(12);
1345        this$static._isRepG1 = initDim(12);
1346        this$static._isRepG2 = initDim(12);
1347        this$static._isRep0Long = initDim(192);
1348        this$static._posSlotEncoder = [];
1349        this$static._posEncoders = initDim(114);
1350        this$static._posAlignEncoder = $BitTreeEncoder({}, 4);
1351        this$static._lenEncoder = $Encoder$LenPriceTableEncoder({});
1352        this$static._repMatchLenEncoder = $Encoder$LenPriceTableEncoder({});
1353        this$static._literalEncoder = {};
1354        this$static._matchDistances = [];
1355        this$static._posSlotPrices = [];
1356        this$static._distancesPrices = [];
1357        this$static._alignPrices = initDim(16);
1358        this$static.reps = initDim(4);
1359        this$static.repLens = initDim(4);
1360        this$static.processedInSize = [P0_longLit];
1361        this$static.processedOutSize = [P0_longLit];
1362        this$static.finished = [0];
1363        this$static.properties = initDim(5);
1364        this$static.tempPrices = initDim(128);
1365        this$static._longestMatchLength = 0;
1366        this$static._matchFinderType = 1;
1367        this$static._numDistancePairs = 0;
1368        this$static._numFastBytesPrev = -1;
1369        this$static.backRes = 0;
1370        for (i = 0; i < 4096; ++i) {
1371            this$static._optimum[i] = {};
1372        }
1373        for (i = 0; i < 4; ++i) {
1374            this$static._posSlotEncoder[i] = $BitTreeEncoder({}, 6);
1375        }
1376        return this$static;
1377    }
1378    
1379    function $FillAlignPrices(this$static) {
1380        for (var i = 0; i < 16; ++i) {
1381            this$static._alignPrices[i] = $ReverseGetPrice(this$static._posAlignEncoder, i);
1382        }
1383        this$static._alignPriceCount = 0;
1384    }
1385    
1386    function $FillDistancesPrices(this$static) {
1387        var baseVal, encoder, footerBits, i, lenToPosState, posSlot, st, st2;
1388        for (i = 4; i < 128; ++i) {
1389            posSlot = GetPosSlot(i);
1390            footerBits = (posSlot >> 1) - 1;
1391            baseVal = (2 | posSlot & 1) << footerBits;
1392            this$static.tempPrices[i] = ReverseGetPrice(this$static._posEncoders, baseVal - posSlot - 1, footerBits, i - baseVal);
1393        }
1394        for (lenToPosState = 0; lenToPosState < 4; ++lenToPosState) {
1395            encoder = this$static._posSlotEncoder[lenToPosState];
1396            st = lenToPosState << 6;
1397            for (posSlot = 0; posSlot < this$static._distTableSize; ++posSlot) {
1398                this$static._posSlotPrices[st + posSlot] = $GetPrice_1(encoder, posSlot);
1399            }
1400            for (posSlot = 14; posSlot < this$static._distTableSize; ++posSlot) {
1401                this$static._posSlotPrices[st + posSlot] += (posSlot >> 1) - 1 - 4 << 6;
1402            }
1403            st2 = lenToPosState * 128;
1404            for (i = 0; i < 4; ++i) {
1405                this$static._distancesPrices[st2 + i] = this$static._posSlotPrices[st + i];
1406            }
1407            for (; i < 128; ++i) {
1408                this$static._distancesPrices[st2 + i] = this$static._posSlotPrices[st + GetPosSlot(i)] + this$static.tempPrices[i];
1409            }
1410        }
1411        this$static._matchPriceCount = 0;
1412    }
1413    
1414    function $Flush(this$static, nowPos) {
1415        $ReleaseMFStream(this$static);
1416        $WriteEndMarker(this$static, nowPos & this$static._posStateMask);
1417        for (var i = 0; i < 5; ++i) {
1418            $ShiftLow(this$static._rangeEncoder);
1419        }
1420    }
1421    
1422    function $GetOptimum(this$static, position) {
1423        var cur, curAnd1Price, curAndLenCharPrice, curAndLenPrice, curBack, curPrice, currentByte, distance, i, len, lenEnd, lenMain, lenRes, lenTest, lenTest2, lenTestTemp, matchByte, matchPrice, newLen, nextIsChar, nextMatchPrice, nextOptimum, nextRepMatchPrice, normalMatchPrice, numAvailableBytes, numAvailableBytesFull, numDistancePairs, offs, offset, opt, optimum, pos, posPrev, posState, posStateNext, price_4, repIndex, repLen, repMatchPrice, repMaxIndex, shortRepPrice, startLen, state, state2, t, price, price_0, price_1, price_2, price_3;
1424        if (this$static._optimumEndIndex != this$static._optimumCurrentIndex) {
1425            lenRes = this$static._optimum[this$static._optimumCurrentIndex].PosPrev - this$static._optimumCurrentIndex;
1426            this$static.backRes = this$static._optimum[this$static._optimumCurrentIndex].BackPrev;
1427            this$static._optimumCurrentIndex = this$static._optimum[this$static._optimumCurrentIndex].PosPrev;
1428            return lenRes;
1429        }
1430        this$static._optimumCurrentIndex = this$static._optimumEndIndex = 0;
1431        if (this$static._longestMatchWasFound) {
1432            lenMain = this$static._longestMatchLength;
1433            this$static._longestMatchWasFound = 0;
1434        } else {
1435            lenMain = $ReadMatchDistances(this$static);
1436        }
1437        numDistancePairs = this$static._numDistancePairs;
1438        numAvailableBytes = $GetNumAvailableBytes(this$static._matchFinder) + 1;
1439        if (numAvailableBytes < 2) {
1440            this$static.backRes = -1;
1441            return 1;
1442        }
1443        if (numAvailableBytes > 273) {
1444            numAvailableBytes = 273;
1445        }
1446        repMaxIndex = 0;
1447        for (i = 0; i < 4; ++i) {
1448            this$static.reps[i] = this$static._repDistances[i];
1449            this$static.repLens[i] = $GetMatchLen(this$static._matchFinder, -1, this$static.reps[i], 273);
1450            if (this$static.repLens[i] > this$static.repLens[repMaxIndex]) {
1451                repMaxIndex = i;
1452            }
1453        }
1454        if (this$static.repLens[repMaxIndex] >= this$static._numFastBytes) {
1455            this$static.backRes = repMaxIndex;
1456            lenRes = this$static.repLens[repMaxIndex];
1457            $MovePos(this$static, lenRes - 1);
1458            return lenRes;
1459        }
1460        if (lenMain >= this$static._numFastBytes) {
1461            this$static.backRes = this$static._matchDistances[numDistancePairs - 1] + 4;
1462            $MovePos(this$static, lenMain - 1);
1463            return lenMain;
1464        }
1465        currentByte = $GetIndexByte(this$static._matchFinder, -1);
1466        matchByte = $GetIndexByte(this$static._matchFinder, -this$static._repDistances[0] - 1 - 1);
1467        if (lenMain < 2 && currentByte != matchByte && this$static.repLens[repMaxIndex] < 2) {
1468            this$static.backRes = -1;
1469            return 1;
1470        }
1471        this$static._optimum[0].State = this$static._state;
1472        posState = position & this$static._posStateMask;
1473        this$static._optimum[1].Price = ProbPrices[this$static._isMatch[(this$static._state << 4) + posState] >>> 2] + $GetPrice_0($GetSubCoder(this$static._literalEncoder, position, this$static._previousByte), this$static._state >= 7, matchByte, currentByte);
1474        $MakeAsChar(this$static._optimum[1]);
1475        matchPrice = ProbPrices[2048 - this$static._isMatch[(this$static._state << 4) + posState] >>> 2];
1476        repMatchPrice = matchPrice + ProbPrices[2048 - this$static._isRep[this$static._state] >>> 2];
1477        if (matchByte == currentByte) {
1478            shortRepPrice = repMatchPrice + $GetRepLen1Price(this$static, this$static._state, posState);
1479            if (shortRepPrice < this$static._optimum[1].Price) {
1480                this$static._optimum[1].Price = shortRepPrice;
1481                $MakeAsShortRep(this$static._optimum[1]);
1482            }
1483        }
1484        lenEnd = lenMain >= this$static.repLens[repMaxIndex]?lenMain:this$static.repLens[repMaxIndex];
1485        if (lenEnd < 2) {
1486            this$static.backRes = this$static._optimum[1].BackPrev;
1487            return 1;
1488        }
1489        this$static._optimum[1].PosPrev = 0;
1490        this$static._optimum[0].Backs0 = this$static.reps[0];
1491        this$static._optimum[0].Backs1 = this$static.reps[1];
1492        this$static._optimum[0].Backs2 = this$static.reps[2];
1493        this$static._optimum[0].Backs3 = this$static.reps[3];
1494        len = lenEnd;
1495        do {
1496            this$static._optimum[len--].Price = 268435455;
1497        } while (len >= 2);
1498        for (i = 0; i < 4; ++i) {
1499            repLen = this$static.repLens[i];
1500            if (repLen < 2) {
1501                continue;
1502            }
1503            price_4 = repMatchPrice + $GetPureRepPrice(this$static, i, this$static._state, posState);
1504            do {
1505                curAndLenPrice = price_4 + $GetPrice(this$static._repMatchLenEncoder, repLen - 2, posState);
1506                optimum = this$static._optimum[repLen];
1507                if (curAndLenPrice < optimum.Price) {
1508                    optimum.Price = curAndLenPrice;
1509                    optimum.PosPrev = 0;
1510                    optimum.BackPrev = i;
1511                    optimum.Prev1IsChar = 0;
1512                }
1513            } while (--repLen >= 2);
1514        }
1515        normalMatchPrice = matchPrice + ProbPrices[this$static._isRep[this$static._state] >>> 2];
1516        len = this$static.repLens[0] >= 2?this$static.repLens[0] + 1:2;
1517        if (len <= lenMain) {
1518            offs = 0;
1519            while (len > this$static._matchDistances[offs]) {
1520                offs += 2;
1521            }
1522            for (;; ++len) {
1523                distance = this$static._matchDistances[offs + 1];
1524                curAndLenPrice = normalMatchPrice + $GetPosLenPrice(this$static, distance, len, posState);
1525                optimum = this$static._optimum[len];
1526                if (curAndLenPrice < optimum.Price) {
1527                    optimum.Price = curAndLenPrice;
1528                    optimum.PosPrev = 0;
1529                    optimum.BackPrev = distance + 4;
1530                    optimum.Prev1IsChar = 0;
1531                }
1532                if (len == this$static._matchDistances[offs]) {
1533                    offs += 2;
1534                    if (offs == numDistancePairs) {
1535                        break;
1536                    }
1537                }
1538            }
1539        }
1540        cur = 0;
1541        while (1) {
1542            ++cur;
1543            if (cur == lenEnd) {
1544                return $Backward(this$static, cur);
1545            }
1546            newLen = $ReadMatchDistances(this$static);
1547            numDistancePairs = this$static._numDistancePairs;
1548            if (newLen >= this$static._numFastBytes) {
1549                this$static._longestMatchLength = newLen;
1550                this$static._longestMatchWasFound = 1;
1551                return $Backward(this$static, cur);
1552            }
1553            ++position;
1554            posPrev = this$static._optimum[cur].PosPrev;
1555            if (this$static._optimum[cur].Prev1IsChar) {
1556                --posPrev;
1557                if (this$static._optimum[cur].Prev2) {
1558                    state = this$static._optimum[this$static._optimum[cur].PosPrev2].State;
1559                    if (this$static._optimum[cur].BackPrev2 < 4) {
1560                        state = (state < 7) ? 8 : 11;
1561                    } else {
1562                        state = (state < 7) ? 7 : 10;
1563                    }
1564                } else {
1565                    state = this$static._optimum[posPrev].State;
1566                }
1567                state = StateUpdateChar(state);
1568            } else {
1569                state = this$static._optimum[posPrev].State;
1570            }
1571            if (posPrev == cur - 1) {
1572                if (!this$static._optimum[cur].BackPrev) {
1573                    state = state < 7?9:11;
1574                } else {
1575                    state = StateUpdateChar(state);
1576                }
1577            } else {
1578                if (this$static._optimum[cur].Prev1IsChar && this$static._optimum[cur].Prev2) {
1579                    posPrev = this$static._optimum[cur].PosPrev2;
1580                    pos = this$static._optimum[cur].BackPrev2;
1581                    state = state < 7?8:11;
1582                } else {
1583                    pos = this$static._optimum[cur].BackPrev;
1584                    if (pos < 4) {
1585                        state = state < 7?8:11;
1586                    } else {
1587                        state = state < 7?7:10;
1588                    }
1589                }
1590                opt = this$static._optimum[posPrev];
1591                if (pos < 4) {
1592                    if (!pos) {
1593                        this$static.reps[0] = opt.Backs0;
1594                        this$static.reps[1] = opt.Backs1;
1595                        this$static.reps[2] = opt.Backs2;
1596                        this$static.reps[3] = opt.Backs3;
1597                    } else if (pos == 1) {
1598                        this$static.reps[0] = opt.Backs1;
1599                        this$static.reps[1] = opt.Backs0;
1600                        this$static.reps[2] = opt.Backs2;
1601                        this$static.reps[3] = opt.Backs3;
1602                    } else if (pos == 2) {
1603                        this$static.reps[0] = opt.Backs2;
1604                        this$static.reps[1] = opt.Backs0;
1605                        this$static.reps[2] = opt.Backs1;
1606                        this$static.reps[3] = opt.Backs3;
1607                    } else {
1608                        this$static.reps[0] = opt.Backs3;
1609                        this$static.reps[1] = opt.Backs0;
1610                        this$static.reps[2] = opt.Backs1;
1611                        this$static.reps[3] = opt.Backs2;
1612                    }
1613                } else {
1614                    this$static.reps[0] = pos - 4;
1615                    this$static.reps[1] = opt.Backs0;
1616                    this$static.reps[2] = opt.Backs1;
1617                    this$static.reps[3] = opt.Backs2;
1618                }
1619            }
1620            this$static._optimum[cur].State = state;
1621            this$static._optimum[cur].Backs0 = this$static.reps[0];
1622            this$static._optimum[cur].Backs1 = this$static.reps[1];
1623            this$static._optimum[cur].Backs2 = this$static.reps[2];
1624            this$static._optimum[cur].Backs3 = this$static.reps[3];
1625            curPrice = this$static._optimum[cur].Price;
1626            currentByte = $GetIndexByte(this$static._matchFinder, -1);
1627            matchByte = $GetIndexByte(this$static._matchFinder, -this$static.reps[0] - 1 - 1);
1628            posState = position & this$static._posStateMask;
1629            curAnd1Price = curPrice + ProbPrices[this$static._isMatch[(state << 4) + posState] >>> 2] + $GetPrice_0($GetSubCoder(this$static._literalEncoder, position, $GetIndexByte(this$static._matchFinder, -2)), state >= 7, matchByte, currentByte);
1630            nextOptimum = this$static._optimum[cur + 1];
1631            nextIsChar = 0;
1632            if (curAnd1Price < nextOptimum.Price) {
1633                nextOptimum.Price = curAnd1Price;
1634                nextOptimum.PosPrev = cur;
1635                nextOptimum.BackPrev = -1;
1636                nextOptimum.Prev1IsChar = 0;
1637                nextIsChar = 1;
1638            }
1639            matchPrice = curPrice + ProbPrices[2048 - this$static._isMatch[(state << 4) + posState] >>> 2];
1640            repMatchPrice = matchPrice + ProbPrices[2048 - this$static._isRep[state] >>> 2];
1641            if (matchByte == currentByte && !(nextOptimum.PosPrev < cur && !nextOptimum.BackPrev)) {
1642                shortRepPrice = repMatchPrice + (ProbPrices[this$static._isRepG0[state] >>> 2] + ProbPrices[this$static._isRep0Long[(state << 4) + posState] >>> 2]);
1643                if (shortRepPrice <= nextOptimum.Price) {
1644                    nextOptimum.Price = shortRepPrice;
1645                    nextOptimum.PosPrev = cur;
1646                    nextOptimum.BackPrev = 0;
1647                    nextOptimum.Prev1IsChar = 0;
1648                    nextIsChar = 1;
1649                }
1650            }
1651            numAvailableBytesFull = $GetNumAvailableBytes(this$static._matchFinder) + 1;
1652            numAvailableBytesFull = 4095 - cur < numAvailableBytesFull?4095 - cur:numAvailableBytesFull;
1653            numAvailableBytes = numAvailableBytesFull;
1654            if (numAvailableBytes < 2) {
1655                continue;
1656            }
1657            if (numAvailableBytes > this$static._numFastBytes) {
1658                numAvailableBytes = this$static._numFastBytes;
1659            }
1660            if (!nextIsChar && matchByte != currentByte) {
1661                t = Math.min(numAvailableBytesFull - 1, this$static._numFastBytes);
1662                lenTest2 = $GetMatchLen(this$static._matchFinder, 0, this$static.reps[0], t);
1663                if (lenTest2 >= 2) {
1664                    state2 = StateUpdateChar(state);
1665                    posStateNext = position + 1 & this$static._posStateMask;
1666                    nextRepMatchPrice = curAnd1Price + ProbPrices[2048 - this$static._isMatch[(state2 << 4) + posStateNext] >>> 2] + ProbPrices[2048 - this$static._isRep[state2] >>> 2];
1667                    offset = cur + 1 + lenTest2;
1668                    while (lenEnd < offset) {
1669                        this$static._optimum[++lenEnd].Price = 268435455;
1670                    }
1671                    curAndLenPrice = nextRepMatchPrice + (price = $GetPrice(this$static._repMatchLenEncoder, lenTest2 - 2, posStateNext) , price + $GetPureRepPrice(this$static, 0, state2, posStateNext));
1672                    optimum = this$static._optimum[offset];
1673                    if (curAndLenPrice < optimum.Price) {
1674                        optimum.Price = curAndLenPrice;
1675                        optimum.PosPrev = cur + 1;
1676                        optimum.BackPrev = 0;
1677                        optimum.Prev1IsChar = 1;
1678                        optimum.Prev2 = 0;
1679                    }
1680                }
1681            }
1682            startLen = 2;
1683            for (repIndex = 0; repIndex < 4; ++repIndex) {
1684                lenTest = $GetMatchLen(this$static._matchFinder, -1, this$static.reps[repIndex], numAvailableBytes);
1685                if (lenTest < 2) {
1686                    continue;
1687                }
1688                lenTestTemp = lenTest;
1689                do {
1690                    while (lenEnd < cur + lenTest) {
1691                        this$static._optimum[++lenEnd].Price = 268435455;
1692                    }
1693                    curAndLenPrice = repMatchPrice + (price_0 = $GetPrice(this$static._repMatchLenEncoder, lenTest - 2, posState) , price_0 + $GetPureRepPrice(this$static, repIndex, state, posState));
1694                    optimum = this$static._optimum[cur + lenTest];
1695                    if (curAndLenPrice < optimum.Price) {
1696                        optimum.Price = curAndLenPrice;
1697                        optimum.PosPrev = cur;
1698                        optimum.BackPrev = repIndex;
1699                        optimum.Prev1IsChar = 0;
1700                    }
1701                } while (--lenTest >= 2);
1702                lenTest = lenTestTemp;
1703                if (!repIndex) {
1704                    startLen = lenTest + 1;
1705                }
1706                if (lenTest < numAvailableBytesFull) {
1707                    t = Math.min(numAvailableBytesFull - 1 - lenTest, this$static._numFastBytes);
1708                    lenTest2 = $GetMatchLen(this$static._matchFinder, lenTest, this$static.reps[repIndex], t);
1709                    if (lenTest2 >= 2) {
1710                        state2 = state < 7?8:11;
1711                        posStateNext = position + lenTest & this$static._posStateMask;
1712                        curAndLenCharPrice = repMatchPrice + (price_1 = $GetPrice(this$static._repMatchLenEncoder, lenTest - 2, posState) , price_1 + $GetPureRepPrice(this$static, repIndex, state, posState)) + ProbPrices[this$static._isMatch[(state2 << 4) + posStateNext] >>> 2] + $GetPrice_0($GetSubCoder(this$static._literalEncoder, position + lenTest, $GetIndexByte(this$static._matchFinder, lenTest - 1 - 1)), 1, $GetIndexByte(this$static._matchFinder, lenTest - 1 - (this$static.reps[repIndex] + 1)), $GetIndexByte(this$static._matchFinder, lenTest - 1));
1713                        state2 = StateUpdateChar(state2);
1714                        posStateNext = position + lenTest + 1 & this$static._posStateMask;
1715                        nextMatchPrice = curAndLenCharPrice + ProbPrices[2048 - this$static._isMatch[(state2 << 4) + posStateNext] >>> 2];
1716                        nextRepMatchPrice = nextMatchPrice + ProbPrices[2048 - this$static._isRep[state2] >>> 2];
1717                        offset = lenTest + 1 + lenTest2;
1718                        while (lenEnd < cur + offset) {
1719                            this$static._optimum[++lenEnd].Price = 268435455;
1720                        }
1721                        curAndLenPrice = nextRepMatchPrice + (price_2 = $GetPrice(this$static._repMatchLenEncoder, lenTest2 - 2, posStateNext) , price_2 + $GetPureRepPrice(this$static, 0, state2, posStateNext));
1722                        optimum = this$static._optimum[cur + offset];
1723                        if (curAndLenPrice < optimum.Price) {
1724                            optimum.Price = curAndLenPrice;
1725                            optimum.PosPrev = cur + lenTest + 1;
1726                            optimum.BackPrev = 0;
1727                            optimum.Prev1IsChar = 1;
1728                            optimum.Prev2 = 1;
1729                            optimum.PosPrev2 = cur;
1730                            optimum.BackPrev2 = repIndex;
1731                        }
1732                    }
1733                }
1734            }
1735            if (newLen > numAvailableBytes) {
1736                newLen = numAvailableBytes;
1737                for (numDistancePairs = 0; newLen > this$static._matchDistances[numDistancePairs]; numDistancePairs += 2) {}
1738                this$static._matchDistances[numDistancePairs] = newLen;
1739                numDistancePairs += 2;
1740            }
1741            if (newLen >= startLen) {
1742            normalMatchPrice = matchPrice + ProbPrices[this$static._isRep[state] >>> 2];
1743            while (lenEnd < cur + newLen) {
1744                this$static._optimum[++lenEnd].Price = 268435455;
1745            }
1746            offs = 0;
1747            while (startLen > this$static._matchDistances[offs]) {
1748                offs += 2;
1749            }
1750            for (lenTest = startLen;; ++lenTest) {
1751                curBack = this$static._matchDistances[offs + 1];
1752                curAndLenPrice = normalMatchPrice + $GetPosLenPrice(this$static, curBack, lenTest, posState);
1753                optimum = this$static._optimum[cur + lenTest];
1754                if (curAndLenPrice < optimum.Price) {
1755                    optimum.Price = curAndLenPrice;
1756                    optimum.PosPrev = cur;
1757                    optimum.BackPrev = curBack + 4;
1758                    optimum.Prev1IsChar = 0;
1759                }
1760                if (lenTest == this$static._matchDistances[offs]) {
1761                    if (lenTest < numAvailableBytesFull) {
1762                        t = Math.min(numAvailableBytesFull - 1 - lenTest, this$static._numFastBytes);
1763                        lenTest2 = $GetMatchLen(this$static._matchFinder, lenTest, curBack, t);
1764                        if (lenTest2 >= 2) {
1765                            state2 = state < 7?7:10;
1766                            posStateNext = position + lenTest & this$static._posStateMask;
1767                            curAndLenCharPrice = curAndLenPrice + ProbPrices[this$static._isMatch[(state2 << 4) + posStateNext] >>> 2] + $GetPrice_0($GetSubCoder(this$static._literalEncoder, position + lenTest, $GetIndexByte(this$static._matchFinder, lenTest - 1 - 1)), 1, $GetIndexByte(this$static._matchFinder, lenTest - (curBack + 1) - 1), $GetIndexByte(this$static._matchFinder, lenTest - 1));
1768                            state2 = StateUpdateChar(state2);
1769                            posStateNext = position + lenTest + 1 & this$static._posStateMask;
1770                            nextMatchPrice = curAndLenCharPrice + ProbPrices[2048 - this$static._isMatch[(state2 << 4) + posStateNext] >>> 2];
1771                            nextRepMatchPrice = nextMatchPrice + ProbPrices[2048 - this$static._isRep[state2] >>> 2];
1772                            offset = lenTest + 1 + lenTest2;
1773                            while (lenEnd < cur + offset) {
1774                                this$static._optimum[++lenEnd].Price = 268435455;
1775                            }
1776                            curAndLenPrice = nextRepMatchPrice + (price_3 = $GetPrice(this$static._repMatchLenEncoder, lenTest2 - 2, posStateNext) , price_3 + $GetPureRepPrice(this$static, 0, state2, posStateNext));
1777                            optimum = this$static._optimum[cur + offset];
1778                            if (curAndLenPrice < optimum.Price) {
1779                                optimum.Price = curAndLenPrice;
1780                                optimum.PosPrev = cur + lenTest + 1;
1781                                optimum.BackPrev = 0;
1782                                optimum.Prev1IsChar = 1;
1783                                optimum.Prev2 = 1;
1784                                optimum.PosPrev2 = cur;
1785                                optimum.BackPrev2 = curBack + 4;
1786                            }
1787                        }
1788                    }
1789                    offs += 2;
1790                    if (offs == numDistancePairs)
1791                        break;
1792                    }
1793                }
1794            }
1795        }
1796    }
1797    
1798    function $GetPosLenPrice(this$static, pos, len, posState) {
1799        var price, lenToPosState = GetLenToPosState(len);
1800        if (pos < 128) {
1801            price = this$static._distancesPrices[lenToPosState * 128 + pos];
1802        } else {
1803            price = this$static._posSlotPrices[(lenToPosState << 6) + GetPosSlot2(pos)] + this$static._alignPrices[pos & 15];
1804        }
1805        return price + $GetPrice(this$static._lenEncoder, len - 2, posState);
1806    }
1807    
1808    function $GetPureRepPrice(this$static, repIndex, state, posState) {
1809        var price;
1810        if (!repIndex) {
1811            price = ProbPrices[this$static._isRepG0[state] >>> 2];
1812            price += ProbPrices[2048 - this$static._isRep0Long[(state << 4) + posState] >>> 2];
1813        } else {
1814            price = ProbPrices[2048 - this$static._isRepG0[state] >>> 2];
1815            if (repIndex == 1) {
1816                price += ProbPrices[this$static._isRepG1[state] >>> 2];
1817            } else {
1818                price += ProbPrices[2048 - this$static._isRepG1[state] >>> 2];
1819                price += GetPrice(this$static._isRepG2[state], repIndex - 2);
1820            }
1821        }
1822        return price;
1823    }
1824    
1825    function $GetRepLen1Price(this$static, state, posState) {
1826        return ProbPrices[this$static._isRepG0[state] >>> 2] + ProbPrices[this$static._isRep0Long[(state << 4) + posState] >>> 2];
1827    }
1828    
1829    function $Init_4(this$static) {
1830        $BaseInit(this$static);
1831        $Init_9(this$static._rangeEncoder);
1832        InitBitModels(this$static._isMatch);
1833        InitBitModels(this$static._isRep0Long);
1834        InitBitModels(this$static._isRep);
1835        InitBitModels(this$static._isRepG0);
1836        InitBitModels(this$static._isRepG1);
1837        InitBitModels(this$static._isRepG2);
1838        InitBitModels(this$static._posEncoders);
1839        $Init_3(this$static._literalEncoder);
1840        for (var i = 0; i < 4; ++i) {
1841            InitBitModels(this$static._posSlotEncoder[i].Models);
1842        }
1843        $Init_2(this$static._lenEncoder, 1 << this$static._posStateBits);
1844        $Init_2(this$static._repMatchLenEncoder, 1 << this$static._posStateBits);
1845        InitBitModels(this$static._posAlignEncoder.Models);
1846        this$static._longestMatchWasFound = 0;
1847        this$static._optimumEndIndex = 0;
1848        this$static._optimumCurrentIndex = 0;
1849        this$static._additionalOffset = 0;
1850    }
1851    
1852    function $MovePos(this$static, num) {
1853        if (num > 0) {
1854            $Skip(this$static._matchFinder, num);
1855            this$static._additionalOffset += num;
1856        }
1857    }
1858    
1859    function $ReadMatchDistances(this$static) {
1860        var lenRes = 0;
1861        this$static._numDistancePairs = $GetMatches(this$static._matchFinder, this$static._matchDistances);
1862        if (this$static._numDistancePairs > 0) {
1863            lenRes = this$static._matchDistances[this$static._numDistancePairs - 2];
1864            if (lenRes == this$static._numFastBytes)
1865            lenRes += $GetMatchLen(this$static._matchFinder, lenRes - 1, this$static._matchDistances[this$static._numDistancePairs - 1], 273 - lenRes);
1866        }
1867        ++this$static._additionalOffset;
1868        return lenRes;
1869    }
1870    
1871    function $ReleaseMFStream(this$static) {
1872        if (this$static._matchFinder && this$static._needReleaseMFStream) {
1873            this$static._matchFinder._stream = null;
1874            this$static._needReleaseMFStream = 0;
1875        }
1876    }
1877    
1878    function $ReleaseStreams(this$static) {
1879        $ReleaseMFStream(this$static);
1880        this$static._rangeEncoder.Stream = null;
1881    }
1882    
1883    function $SetDictionarySize_0(this$static, dictionarySize) {
1884        this$static._dictionarySize = dictionarySize;
1885        for (var dicLogSize = 0; dictionarySize > 1 << dicLogSize; ++dicLogSize) {}
1886        this$static._distTableSize = dicLogSize * 2;
1887    }
1888    
1889    function $SetMatchFinder(this$static, matchFinderIndex) {
1890        var matchFinderIndexPrev = this$static._matchFinderType;
1891        this$static._matchFinderType = matchFinderIndex;
1892        if (this$static._matchFinder && matchFinderIndexPrev != this$static._matchFinderType) {
1893            this$static._dictionarySizePrev = -1;
1894            this$static._matchFinder = null;
1895        }
1896    }
1897    
1898    function $WriteCoderProperties(this$static, outStream) {
1899        this$static.properties[0] = (this$static._posStateBits * 5 + this$static._numLiteralPosStateBits) * 9 + this$static._numLiteralContextBits << 24 >> 24;
1900        for (var i = 0; i < 4; ++i) {
1901            this$static.properties[1 + i] = this$static._dictionarySize >> 8 * i << 24 >> 24;
1902        }
1903        $write_0(outStream, this$static.properties, 0, 5);
1904    }
1905    
1906    function $WriteEndMarker(this$static, posState) {
1907        if (!this$static._writeEndMark) {
1908            return;
1909        }
1910        $Encode_3(this$static._rangeEncoder, this$static._isMatch, (this$static._state << 4) + posState, 1);
1911        $Encode_3(this$static._rangeEncoder, this$static._isRep, this$static._state, 0);
1912        this$static._state = this$static._state < 7?7:10;
1913        $Encode_0(this$static._lenEncoder, this$static._rangeEncoder, 0, posState);
1914        var lenToPosState = GetLenToPosState(2);
1915        $Encode_2(this$static._posSlotEncoder[lenToPosState], this$static._rangeEncoder, 63);
1916        $EncodeDirectBits(this$static._rangeEncoder, 67108863, 26);
1917        $ReverseEncode(this$static._posAlignEncoder, this$static._rangeEncoder, 15);
1918    }
1919    
1920    function GetPosSlot(pos) {
1921        if (pos < 2048) {
1922            return g_FastPos[pos];
1923        }
1924        if (pos < 2097152) {
1925            return g_FastPos[pos >> 10] + 20;
1926        }
1927        return g_FastPos[pos >> 20] + 40;
1928    }
1929    
1930    function GetPosSlot2(pos) {
1931        if (pos < 131072) {
1932            return g_FastPos[pos >> 6] + 12;
1933        }
1934        if (pos < 134217728) {
1935            return g_FastPos[pos >> 16] + 32;
1936        }
1937        return g_FastPos[pos >> 26] + 52;
1938    }
1939    
1940    function $Encode(this$static, rangeEncoder, symbol, posState) {
1941        if (symbol < 8) {
1942            $Encode_3(rangeEncoder, this$static._choice, 0, 0);
1943            $Encode_2(this$static._lowCoder[posState], rangeEncoder, symbol);
1944        } else {
1945            symbol -= 8;
1946            $Encode_3(rangeEncoder, this$static._choice, 0, 1);
1947            if (symbol < 8) {
1948                $Encode_3(rangeEncoder, this$static._choice, 1, 0);
1949                $Encode_2(this$static._midCoder[posState], rangeEncoder, symbol);
1950            } else {
1951                $Encode_3(rangeEncoder, this$static._choice, 1, 1);
1952                $Encode_2(this$static._highCoder, rangeEncoder, symbol - 8);
1953            }
1954        }
1955    }
1956    
1957    function $Encoder$LenEncoder(this$static) {
1958        this$static._choice = initDim(2);
1959        this$static._lowCoder = initDim(16);
1960        this$static._midCoder = initDim(16);
1961        this$static._highCoder = $BitTreeEncoder({}, 8);
1962        for (var posState = 0; posState < 16; ++posState) {
1963            this$static._lowCoder[posState] = $BitTreeEncoder({}, 3);
1964            this$static._midCoder[posState] = $BitTreeEncoder({}, 3);
1965        }
1966        return this$static;
1967    }
1968    
1969    function $Init_2(this$static, numPosStates) {
1970        InitBitModels(this$static._choice);
1971        for (var posState = 0; posState < numPosStates; ++posState) {
1972            InitBitModels(this$static._lowCoder[posState].Models);
1973            InitBitModels(this$static._midCoder[posState].Models);
1974        }
1975        InitBitModels(this$static._highCoder.Models);
1976    }
1977    
1978    function $SetPrices(this$static, posState, numSymbols, prices, st) {
1979        var a0, a1, b0, b1, i;
1980        a0 = ProbPrices[this$static._choice[0] >>> 2];
1981        a1 = ProbPrices[2048 - this$static._choice[0] >>> 2];
1982        b0 = a1 + ProbPrices[this$static._choice[1] >>> 2];
1983        b1 = a1 + ProbPrices[2048 - this$static._choice[1] >>> 2];
1984        i = 0;
1985        for (i = 0; i < 8; ++i) {
1986            if (i >= numSymbols)
1987            return;
1988            prices[st + i] = a0 + $GetPrice_1(this$static._lowCoder[posState], i);
1989        }
1990        for (; i < 16; ++i) {
1991            if (i >= numSymbols)
1992            return;
1993            prices[st + i] = b0 + $GetPrice_1(this$static._midCoder[posState], i - 8);
1994        }
1995        for (; i < numSymbols; ++i) {
1996            prices[st + i] = b1 + $GetPrice_1(this$static._highCoder, i - 8 - 8);
1997        }
1998    }
1999    
2000    function $Encode_0(this$static, rangeEncoder, symbol, posState) {
2001        $Encode(this$static, rangeEncoder, symbol, posState);
2002        if (--this$static._counters[posState] == 0) {
2003            $SetPrices(this$static, posState, this$static._tableSize, this$static._prices, posState * 272);
2004            this$static._counters[posState] = this$static._tableSize;
2005        }
2006    }
2007    
2008    function $Encoder$LenPriceTableEncoder(this$static) {
2009        $Encoder$LenEncoder(this$static);
2010        this$static._prices = [];
2011        this$static._counters = [];
2012        return this$static;
2013    }
2014    
2015    function $GetPrice(this$static, symbol, posState) {
2016        return this$static._prices[posState * 272 + symbol];
2017    }
2018    
2019    function $UpdateTables(this$static, numPosStates) {
2020        for (var posState = 0; posState < numPosStates; ++posState) {
2021            $SetPrices(this$static, posState, this$static._tableSize, this$static._prices, posState * 272);
2022            this$static._counters[posState] = this$static._tableSize;
2023        }
2024    }
2025    
2026    function $Create_1(this$static, numPosBits, numPrevBits) {
2027        var i, numStates;
2028        if (this$static.m_Coders != null && this$static.m_NumPrevBits == numPrevBits && this$static.m_NumPosBits == numPosBits) {
2029            return;
2030        }
2031        this$static.m_NumPosBits = numPosBits;
2032        this$static.m_PosMask = (1 << numPosBits) - 1;
2033        this$static.m_NumPrevBits = numPrevBits;
2034        numStates = 1 << this$static.m_NumPrevBits + this$static.m_NumPosBits;
2035        this$static.m_Coders = initDim(numStates);
2036        for (i = 0; i < numStates; ++i) {
2037            this$static.m_Coders[i] = $Encoder$LiteralEncoder$Encoder2({});
2038        }
2039    }
2040    
2041    function $GetSubCoder(this$static, pos, prevByte) {
2042        return this$static.m_Coders[((pos & this$static.m_PosMask) << this$static.m_NumPrevBits) + ((prevByte & 255) >>> 8 - this$static.m_NumPrevBits)];
2043    }
2044    
2045    function $Init_3(this$static) {
2046        var i, numStates = 1 << this$static.m_NumPrevBits + this$static.m_NumPosBits;
2047        for (i = 0; i < numStates; ++i) {
2048            InitBitModels(this$static.m_Coders[i].m_Encoders);
2049        }
2050    }
2051    
2052    function $Encode_1(this$static, rangeEncoder, symbol) {
2053        var bit, i, context = 1;
2054        for (i = 7; i >= 0; --i) {
2055            bit = symbol >> i & 1;
2056            $Encode_3(rangeEncoder, this$static.m_Encoders, context, bit);
2057            context = context << 1 | bit;
2058        }
2059    }
2060    
2061    function $EncodeMatched(this$static, rangeEncoder, matchByte, symbol) {
2062        var bit, i, matchBit, state, same = 1, context = 1;
2063        for (i = 7; i >= 0; --i) {
2064            bit = symbol >> i & 1;
2065            state = context;
2066            if (same) {
2067                matchBit = matchByte >> i & 1;
2068                state += 1 + matchBit << 8;
2069                same = matchBit == bit;
2070            }
2071            $Encode_3(rangeEncoder, this$static.m_Encoders, state, bit);
2072            context = context << 1 | bit;
2073        }
2074    }
2075    
2076    function $Encoder$LiteralEncoder$Encoder2(this$static) {
2077        this$static.m_Encoders = initDim(768);
2078        return this$static;
2079    }
2080    
2081    function $GetPrice_0(this$static, matchMode, matchByte, symbol) {
2082        var bit, context = 1, i = 7, matchBit, price = 0;
2083        if (matchMode) {
2084            for (; i >= 0; --i) {
2085                matchBit = matchByte >> i & 1;
2086                bit = symbol >> i & 1;
2087                price += GetPrice(this$static.m_Encoders[(1 + matchBit << 8) + context], bit);
2088                context = context << 1 | bit;
2089                if (matchBit != bit) {
2090                    --i;
2091                    break;
2092                }
2093            }
2094        }
2095        for (; i >= 0; --i) {
2096            bit = symbol >> i & 1;
2097            price += GetPrice(this$static.m_Encoders[context], bit);
2098            context = context << 1 | bit;
2099        }
2100        return price;
2101    }
2102    
2103    function $MakeAsChar(this$static) {
2104        this$static.BackPrev = -1;
2105        this$static.Prev1IsChar = 0;
2106    }
2107    
2108    function $MakeAsShortRep(this$static) {
2109        this$static.BackPrev = 0;
2110        this$static.Prev1IsChar = 0;
2111    }
2112    /** ce */
2113    /** ds */
2114    function $BitTreeDecoder(this$static, numBitLevels) {
2115        this$static.NumBitLevels = numBitLevels;
2116        this$static.Models = initDim(1 << numBitLevels);
2117        return this$static;
2118    }
2119    
2120    function $Decode_0(this$static, rangeDecoder) {
2121        var bitIndex, m = 1;
2122        for (bitIndex = this$static.NumBitLevels; bitIndex != 0; --bitIndex) {
2123            m = (m << 1) + $DecodeBit(rangeDecoder, this$static.Models, m);
2124        }
2125        return m - (1 << this$static.NumBitLevels);
2126    }
2127    
2128    function $ReverseDecode(this$static, rangeDecoder) {
2129        var bit, bitIndex, m = 1, symbol = 0;
2130        for (bitIndex = 0; bitIndex < this$static.NumBitLevels; ++bitIndex) {
2131            bit = $DecodeBit(rangeDecoder, this$static.Models, m);
2132            m <<= 1;
2133            m += bit;
2134            symbol |= bit << bitIndex;
2135        }
2136        return symbol;
2137    }
2138    
2139    function ReverseDecode(Models, startIndex, rangeDecoder, NumBitLevels) {
2140        var bit, bitIndex, m = 1, symbol = 0;
2141        for (bitIndex = 0; bitIndex < NumBitLevels; ++bitIndex) {
2142            bit = $DecodeBit(rangeDecoder, Models, startIndex + m);
2143            m <<= 1;
2144            m += bit;
2145            symbol |= bit << bitIndex;
2146        }
2147        return symbol;
2148    }
2149    /** de */
2150    /** cs */
2151    function $BitTreeEncoder(this$static, numBitLevels) {
2152        this$static.NumBitLevels = numBitLevels;
2153        this$static.Models = initDim(1 << numBitLevels);
2154        return this$static;
2155    }
2156    
2157    function $Encode_2(this$static, rangeEncoder, symbol) {
2158        var bit, bitIndex, m = 1;
2159        for (bitIndex = this$static.NumBitLevels; bitIndex != 0;) {
2160            --bitIndex;
2161            bit = symbol >>> bitIndex & 1;
2162            $Encode_3(rangeEncoder, this$static.Models, m, bit);
2163            m = m << 1 | bit;
2164        }
2165    }
2166    
2167    function $GetPrice_1(this$static, symbol) {
2168        var bit, bitIndex, m = 1, price = 0;
2169        for (bitIndex = this$static.NumBitLevels; bitIndex != 0;) {
2170            --bitIndex;
2171            bit = symbol >>> bitIndex & 1;
2172            price += GetPrice(this$static.Models[m], bit);
2173            m = (m << 1) + bit;
2174        }
2175        return price;
2176    }
2177    
2178    function $ReverseEncode(this$static, rangeEncoder, symbol) {
2179        var bit, i, m = 1;
2180        for (i = 0; i < this$static.NumBitLevels; ++i) {
2181            bit = symbol & 1;
2182            $Encode_3(rangeEncoder, this$static.Models, m, bit);
2183            m = m << 1 | bit;
2184            symbol >>= 1;
2185        }
2186    }
2187    
2188    function $ReverseGetPrice(this$static, symbol) {
2189        var bit, i, m = 1, price = 0;
2190        for (i = this$static.NumBitLevels; i != 0; --i) {
2191            bit = symbol & 1;
2192            symbol >>>= 1;
2193            price += GetPrice(this$static.Models[m], bit);
2194            m = m << 1 | bit;
2195        }
2196        return price;
2197    }
2198    
2199    function ReverseEncode(Models, startIndex, rangeEncoder, NumBitLevels, symbol) {
2200        var bit, i, m = 1;
2201        for (i = 0; i < NumBitLevels; ++i) {
2202            bit = symbol & 1;
2203            $Encode_3(rangeEncoder, Models, startIndex + m, bit);
2204            m = m << 1 | bit;
2205            symbol >>= 1;
2206        }
2207    }
2208    
2209    function ReverseGetPrice(Models, startIndex, NumBitLevels, symbol) {
2210        var bit, i, m = 1, price = 0;
2211        for (i = NumBitLevels; i != 0; --i) {
2212            bit = symbol & 1;
2213            symbol >>>= 1;
2214            price += ProbPrices[((Models[startIndex + m] - bit ^ -bit) & 2047) >>> 2];
2215            m = m << 1 | bit;
2216        }
2217        return price;
2218    }
2219    /** ce */
2220    /** ds */
2221    function $DecodeBit(this$static, probs, index) {
2222        var newBound, prob = probs[index];
2223        newBound = (this$static.Range >>> 11) * prob;
2224        if ((this$static.Code ^ -2147483648) < (newBound ^ -2147483648)) {
2225            this$static.Range = newBound;
2226            probs[index] = prob + (2048 - prob >>> 5) << 16 >> 16;
2227            if (!(this$static.Range & -16777216)) {
2228                this$static.Code = this$static.Code << 8 | $read(this$static.Stream);
2229                this$static.Range <<= 8;
2230            }
2231            return 0;
2232        } else {
2233            this$static.Range -= newBound;
2234            this$static.Code -= newBound;
2235            probs[index] = prob - (prob >>> 5) << 16 >> 16;
2236            if (!(this$static.Range & -16777216)) {
2237                this$static.Code = this$static.Code << 8 | $read(this$static.Stream);
2238                this$static.Range <<= 8;
2239            }
2240            return 1;
2241        }
2242    }
2243    
2244    function $DecodeDirectBits(this$static, numTotalBits) {
2245        var i, t, result = 0;
2246        for (i = numTotalBits; i != 0; --i) {
2247            this$static.Range >>>= 1;
2248            t = this$static.Code - this$static.Range >>> 31;
2249            this$static.Code -= this$static.Range & t - 1;
2250            result = result << 1 | 1 - t;
2251            if (!(this$static.Range & -16777216)) {
2252                this$static.Code = this$static.Code << 8 | $read(this$static.Stream);
2253                this$static.Range <<= 8;
2254            }
2255        }
2256        return result;
2257    }
2258    
2259    function $Init_8(this$static) {
2260        this$static.Code = 0;
2261        this$static.Range = -1;
2262        for (var i = 0; i < 5; ++i) {
2263            this$static.Code = this$static.Code << 8 | $read(this$static.Stream);
2264        }
2265    }
2266    /** de */
2267    
2268    function InitBitModels(probs) {
2269        for (var i = probs.length - 1; i >= 0; --i) {
2270            probs[i] = 1024;
2271        }
2272    }
2273    /** cs */
2274    var ProbPrices = (function () {
2275        var end, i, j, start, ProbPrices = [];
2276        for (i = 8; i >= 0; --i) {
2277            start = 1 << 9 - i - 1;
2278            end = 1 << 9 - i;
2279            for (j = start; j < end; ++j) {
2280                ProbPrices[j] = (i << 6) + (end - j << 6 >>> 9 - i - 1);
2281            }
2282        }
2283        return ProbPrices;
2284    }());
2285    
2286    function $Encode_3(this$static, probs, index, symbol) {
2287        var newBound, prob = probs[index];
2288        newBound = (this$static.Range >>> 11) * prob;
2289        if (!symbol) {
2290            this$static.Range = newBound;
2291            probs[index] = prob + (2048 - prob >>> 5) << 16 >> 16;
2292        } else {
2293            this$static.Low = add(this$static.Low, and(fromInt(newBound), [4294967295, 0]));
2294            this$static.Range -= newBound;
2295            probs[index] = prob - (prob >>> 5) << 16 >> 16;
2296        }
2297        if (!(this$static.Range & -16777216)) {
2298            this$static.Range <<= 8;
2299            $ShiftLow(this$static);
2300        }
2301    }
2302    
2303    function $EncodeDirectBits(this$static, v, numTotalBits) {
2304        for (var i = numTotalBits - 1; i >= 0; --i) {
2305            this$static.Range >>>= 1;
2306            if ((v >>> i & 1) == 1) {
2307                this$static.Low = add(this$static.Low, fromInt(this$static.Range));
2308            }
2309            if (!(this$static.Range & -16777216)) {
2310                this$static.Range <<= 8;
2311                $ShiftLow(this$static);
2312            }
2313        }
2314    }
2315    
2316    function $GetProcessedSizeAdd(this$static) {
2317        return add(add(fromInt(this$static._cacheSize), this$static._position), [4, 0]);
2318    }
2319    
2320    function $Init_9(this$static) {
2321        this$static._position = P0_longLit;
2322        this$static.Low = P0_longLit;
2323        this$static.Range = -1;
2324        this$static._cacheSize = 1;
2325        this$static._cache = 0;
2326    }
2327    
2328    function $ShiftLow(this$static) {
2329        var temp, LowHi = lowBits_0(shru(this$static.Low, 32));
2330        if (LowHi != 0 || compare(this$static.Low, [4278190080, 0]) < 0) {
2331            this$static._position = add(this$static._position, fromInt(this$static._cacheSize));
2332            temp = this$static._cache;
2333            do {
2334                $write(this$static.Stream, temp + LowHi);
2335                temp = 255;
2336            } while (--this$static._cacheSize != 0);
2337            this$static._cache = lowBits_0(this$static.Low) >>> 24;
2338        }
2339        ++this$static._cacheSize;
2340        this$static.Low = shl(and(this$static.Low, [16777215, 0]), 8);
2341    }
2342    
2343    function GetPrice(Prob, symbol) {
2344        return ProbPrices[((Prob - symbol ^ -symbol) & 2047) >>> 2];
2345    }
2346    
2347    /** ce */
2348    /** ds */
2349    function decode(utf) {
2350        var i = 0, j = 0, x, y, z, l = utf.length, buf = [], charCodes = [];
2351        for (; i < l; ++i, ++j) {
2352            x = utf[i] & 255;
2353            if (!(x & 128)) {
2354                if (!x) {
2355                    /// It appears that this is binary data, so it cannot be converted to a string, so just send it back.
2356                    return utf;
2357                }
2358                charCodes[j] = x;
2359            } else if ((x & 224) == 192) {
2360                if (i + 1 >= l) {
2361                    /// It appears that this is binary data, so it cannot be converted to a string, so just send it back.
2362                    return utf;
2363                }
2364                y = utf[++i] & 255;
2365                if ((y & 192) != 128) {
2366                    /// It appears that this is binary data, so it cannot be converted to a string, so just send it back.
2367                    return utf;
2368                }
2369                charCodes[j] = ((x & 31) << 6) | (y & 63);
2370            } else if ((x & 240) == 224) {
2371                if (i + 2 >= l) {
2372                    /// It appears that this is binary data, so it cannot be converted to a string, so just send it back.
2373                    return utf;
2374                }
2375                y = utf[++i] & 255;
2376                if ((y & 192) != 128) {
2377                    /// It appears that this is binary data, so it cannot be converted to a string, so just send it back.
2378                    return utf;
2379                }
2380                z = utf[++i] & 255;
2381                if ((z & 192) != 128) {
2382                    /// It appears that this is binary data, so it cannot be converted to a string, so just send it back.
2383                    return utf;
2384                }
2385                charCodes[j] = ((x & 15) << 12) | ((y & 63) << 6) | (z & 63);
2386            } else {
2387                /// It appears that this is binary data, so it cannot be converted to a string, so just send it back.
2388                return utf;
2389            }
2390            if (j == 16383) {
2391                buf.push(String.fromCharCode.apply(String, charCodes));
2392                j = -1;
2393            }
2394        }
2395        if (j > 0) {
2396            charCodes.length = j;
2397            buf.push(String.fromCharCode.apply(String, charCodes));
2398        }
2399        return buf.join("");
2400    }
2401    /** de */
2402    /** cs */
2403    function encode(s) {
2404        var ch, chars = [], data, elen = 0, i, l = s.length;
2405        /// Be able to handle binary arrays and buffers.
2406        if (typeof s == "object") {
2407            return s;
2408        } else {
2409            $getChars(s, 0, l, chars, 0);
2410        }
2411        /// Add extra spaces in the array to break up the unicode symbols.
2412        for (i = 0; i < l; ++i) {
2413            ch = chars[i];
2414            if (ch >= 1 && ch <= 127) {
2415                ++elen;
2416            } else if (!ch || ch >= 128 && ch <= 2047) {
2417                elen += 2;
2418            } else {
2419                elen += 3;
2420            }
2421        }
2422        data = [];
2423        elen = 0;
2424        for (i = 0; i < l; ++i) {
2425            ch = chars[i];
2426            if (ch >= 1 && ch <= 127) {
2427                data[elen++] = ch << 24 >> 24;
2428            } else if (!ch || ch >= 128 && ch <= 2047) {
2429                data[elen++] = (192 | ch >> 6 & 31) << 24 >> 24;
2430                data[elen++] = (128 | ch & 63) << 24 >> 24;
2431            } else {
2432                data[elen++] = (224 | ch >> 12 & 15) << 24 >> 24;
2433                data[elen++] = (128 | ch >> 6 & 63) << 24 >> 24;
2434                data[elen++] = (128 | ch & 63) << 24 >> 24;
2435            }
2436        }
2437        return data;
2438    }
2439    /** ce */
2440    
2441    function toDouble(a) {
2442        return a[1] + a[0];
2443    }
2444    
2445    /** cs */
2446    function compress(str, mode, on_finish, on_progress) {
2447        var this$static = {},
2448            percent,
2449            cbn, /// A callback number should be supplied instead of on_finish() if we are using Web Workers.
2450            sync = typeof on_finish == "undefined" && typeof on_progress == "undefined";
2451        
2452        if (typeof on_finish != "function") {
2453            cbn = on_finish;
2454            on_finish = on_progress = 0;
2455        }
2456        
2457        on_progress = on_progress || function(percent) {
2458            if (typeof cbn == "undefined")
2459                return;
2460            
2461            return update_progress(percent, cbn);
2462        };
2463        
2464        on_finish = on_finish || function(res, err) {
2465            if (typeof cbn == "undefined")
2466                return;
2467            
2468            return postMessage({
2469                action: action_compress,
2470                cbn: cbn,
2471                result: res,
2472                error: err
2473            });
2474        };
2475
2476        if (sync) {
2477            this$static.c = $LZMAByteArrayCompressor({}, encode(str), get_mode_obj(mode));
2478            while ($processChunk(this$static.c.chunker));
2479            return $toByteArray(this$static.c.output);
2480        }
2481        
2482        try {
2483            this$static.c = $LZMAByteArrayCompressor({}, encode(str), get_mode_obj(mode));
2484            
2485            on_progress(0);
2486        } catch (err) {
2487            return on_finish(null, err);
2488        }
2489        
2490        function do_action() {
2491            try {
2492                var res, start = (new Date()).getTime();
2493                
2494                while ($processChunk(this$static.c.chunker)) {
2495                    percent = toDouble(this$static.c.chunker.inBytesProcessed) / toDouble(this$static.c.length_0);
2496                    /// If about 200 miliseconds have passed, update the progress.
2497                    if ((new Date()).getTime() - start > 200) {
2498                        on_progress(percent);
2499                        
2500                        wait(do_action, 0);
2501                        return 0;
2502                    }
2503                }
2504                
2505                on_progress(1);
2506                
2507                res = $toByteArray(this$static.c.output);
2508                
2509                /// delay so we don’t catch errors from the on_finish handler
2510                wait(on_finish.bind(null, res), 0);
2511            } catch (err) {
2512                on_finish(null, err);
2513            }
2514        }
2515        
2516        ///NOTE: We need to wait to make sure it is always async.
2517        wait(do_action, 0);
2518    }
2519    /** ce */
2520    /** ds */
2521    function decompress(byte_arr, on_finish, on_progress) {
2522        var this$static = {},
2523            percent,
2524            cbn, /// A callback number should be supplied instead of on_finish() if we are using Web Workers.
2525            has_progress,
2526            len,
2527            sync = typeof on_finish == "undefined" && typeof on_progress == "undefined";
2528
2529        if (typeof on_finish != "function") {
2530            cbn = on_finish;
2531            on_finish = on_progress = 0;
2532        }
2533        
2534        on_progress = on_progress || function(percent) {
2535            if (typeof cbn == "undefined")
2536                return;
2537            
2538            return update_progress(has_progress ? percent : -1, cbn);
2539        };
2540        
2541        on_finish = on_finish || function(res, err) {
2542            if (typeof cbn == "undefined")
2543                return;
2544            
2545            return postMessage({
2546                action: action_decompress,
2547                cbn: cbn,
2548                result: res,
2549                error: err
2550            });
2551        };
2552
2553        if (sync) {
2554            this$static.d = $LZMAByteArrayDecompressor({}, byte_arr);
2555            while ($processChunk(this$static.d.chunker));
2556            return decode($toByteArray(this$static.d.output));
2557        }
2558        
2559        try {
2560            this$static.d = $LZMAByteArrayDecompressor({}, byte_arr);
2561            
2562            len = toDouble(this$static.d.length_0);
2563            
2564            ///NOTE: If the data was created via a stream, it will not have a length value, and therefore we can't calculate the progress.
2565            has_progress = len > -1;
2566            
2567            on_progress(0);
2568        } catch (err) {
2569            return on_finish(null, err);
2570        }
2571        
2572        function do_action() {
2573            try {
2574                var res, i = 0, start = (new Date()).getTime();
2575                while ($processChunk(this$static.d.chunker)) {
2576                    if (++i % 1000 == 0 && (new Date()).getTime() - start > 200) {
2577                        if (has_progress) {
2578                            percent = toDouble(this$static.d.chunker.decoder.nowPos64) / len;
2579                            /// If about 200 miliseconds have passed, update the progress.
2580                            on_progress(percent);
2581                        }
2582                        
2583                        ///NOTE: This allows other code to run, like the browser to update.
2584                        wait(do_action, 0);
2585                        return 0;
2586                    }
2587                }
2588                
2589                on_progress(1);
2590                
2591                res = decode($toByteArray(this$static.d.output));
2592                
2593                /// delay so we don’t catch errors from the on_finish handler
2594                wait(on_finish.bind(null, res), 0);
2595            } catch (err) {
2596                on_finish(null, err);
2597            }
2598        }
2599        
2600        ///NOTE: We need to wait to make sure it is always async.
2601        wait(do_action, 0);
2602    }
2603    /** de */
2604    /** cs */
2605    var get_mode_obj = (function () {
2606        /// s is dictionarySize
2607        /// f is fb
2608        /// m is matchFinder
2609        ///NOTE: Because some values are always the same, they have been removed.
2610        /// lc is always 3
2611        /// lp is always 0
2612        /// pb is always 2
2613        var modes = [
2614            {s: 16, f:  64, m: 0},
2615            {s: 20, f:  64, m: 0},
2616            {s: 19, f:  64, m: 1},
2617            {s: 20, f:  64, m: 1},
2618            {s: 21, f: 128, m: 1},
2619            {s: 22, f: 128, m: 1},
2620            {s: 23, f: 128, m: 1},
2621            {s: 24, f: 255, m: 1},
2622            {s: 25, f: 255, m: 1}
2623        ];
2624        
2625        return function (mode) {
2626            return modes[mode - 1] || modes[6];
2627        };
2628    }());
2629    /** ce */
2630    
2631    /// If we're in a Web Worker, create the onmessage() communication channel.
2632    ///NOTE: This seems to be the most reliable way to detect this.
2633    if (typeof onmessage != "undefined" && (typeof window == "undefined" || typeof window.document == "undefined")) {
2634        (function () {
2635            /* jshint -W020 */
2636            /// Create the global onmessage function.
2637            onmessage = function (e) {
2638                if (e && e.data) {
2639                    /** xs */
2640                    if (e.data.action == action_decompress) {
2641                        LZMA.decompress(e.data.data, e.data.cbn);
2642                    } else if (e.data.action == action_compress) {
2643                        LZMA.compress(e.data.data, e.data.mode, e.data.cbn);
2644                    }
2645                    /** xe */
2646                    /// co:if (e.data.action == action_compress) {
2647                    /// co:    LZMA.compress(e.data.data, e.data.mode, e.data.cbn);
2648                    /// co:}
2649                    /// do:if (e.data.action == action_decompress) {
2650                    /// do:    LZMA.decompress(e.data.data, e.data.cbn);
2651                    /// do:}
2652                }
2653            };
2654        }());
2655    }
2656        
2657    return {
2658        /** xs */
2659        compress:   compress,
2660        decompress: decompress,
2661        /** xe */
2662        /// co:compress:   compress
2663        /// do:decompress: decompress
2664    };
2665}());
2666
2667/// This is used by browsers that do not support web workers (and possibly Node.js).
2668this.LZMA = this.LZMA_WORKER = LZMA;