├── .travis.yml ├── LICENSE ├── huffman_test.go ├── README.md ├── integers.go ├── huffman.go ├── static_table.go ├── huffman_codes.go ├── cmd └── generate_huffman_tables │ └── main.go ├── hpack.go ├── hpack_test.go └── huffman_tables.go /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.6 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2016 Chris Moos 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /huffman_test.go: -------------------------------------------------------------------------------- 1 | package hpack 2 | 3 | import ( 4 | "encoding/hex" 5 | "github.com/stretchr/testify/assert" 6 | "testing" 7 | ) 8 | 9 | func TestHuffmanEncoding(t *testing.T) { 10 | items := [][2]string{ 11 | {"a8eb10649cbf", "no-cache"}, 12 | {"f1e3c2e5f23a6ba0ab90f4ff", "www.example.com"}, 13 | {"25a849e95ba97d7f", "custom-key"}, 14 | {"25a849e95bb8e8b4bf", "custom-value"}, 15 | {"6402", "302"}, 16 | } 17 | 18 | for _, item := range items { 19 | encodedHex := []byte(item[0]) 20 | encoded := make([]byte, len(encodedHex)/2) 21 | _, err := hex.Decode(encoded, encodedHex) 22 | if err != nil { 23 | t.Error(err) 24 | } 25 | data := HuffmanEncode([]byte(item[1])) 26 | if err != nil { 27 | t.Error(err) 28 | } 29 | assert.Equal(t, encoded, data) 30 | } 31 | 32 | } 33 | 34 | func TestHuffmanDecoding(t *testing.T) { 35 | items := [][2]string{ 36 | {"a8eb10649cbf", "no-cache"}, 37 | {"f1e3c2e5f23a6ba0ab90f4ff", "www.example.com"}, 38 | {"25a849e95ba97d7f", "custom-key"}, 39 | {"25a849e95bb8e8b4bf", "custom-value"}, 40 | } 41 | 42 | for _, item := range items { 43 | encodedHex := []byte(item[0]) 44 | encoded := make([]byte, len(encodedHex)/2) 45 | _, err := hex.Decode(encoded, encodedHex) 46 | if err != nil { 47 | t.Error(err) 48 | } 49 | decoded, err := HuffmanDecode(encoded) 50 | if err != nil { 51 | t.Error(err) 52 | } 53 | assert.Equal(t, item[1], string(decoded)) 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HPACK library 2 | 3 | [![Build Status](https://travis-ci.org/chrismoos/hpack.svg?branch=master)](https://travis-ci.org/chrismoos/hpack) [![godoc](https://godoc.org/github.com/chrismoos/hpack?status.svg)](https://godoc.org/github.com/chrismoos/hpack) 4 | 5 | This library implements [RFC7541](https://tools.ietf.org/html/rfc7541), **HPACK: Header Compression for HTTP/2**, which includes: 6 | 7 | * Primitive Type Representations 8 | * Variable integer sizes (with prefix lengths) 9 | * String literals (incl. Huffman decoding) 10 | * Static & Dynamic indexes 11 | * Dynamic Table evictions 12 | * Header block parsing 13 | 14 | You can read about HPACK and this implementation [here](https://www.chrismoos.com/2016/02/19/hpack-compression-golang/). 15 | 16 | ## Usage 17 | 18 | Most users of this library will be implementing HTTP/2. 19 | 20 | decoder := hpack.NewDecoder(negotiatedDynamicTableSizeMax) 21 | headerBlock := recvHeaderBlockAndContinuations() 22 | headers, err := decoder.Decode(headerBlock) 23 | 24 | The `Decode` function expects a complete header block. HTTP/2 specifies that a header block can be split across multiple frames, in a **HEADER** or **PUSH_PROMISE** frame plus optional **CONTINUATION** frames. 25 | 26 | Users should concatenate the header block fragments together and only call `Decode` when a frame with the **END_HEADERS** flag is received. 27 | 28 | ## Development 29 | 30 | ### Generating Huffman lookup tables 31 | 32 | The lookup tables are code generated from the Huffman codes in the HPACK specification. This ensures the lookup tables are available at runtime with no initialization required. 33 | 34 | Run the following command to generate the lookup tables used for Huffman decoding: 35 | 36 | go run cmd/generate_huffman_tables/main.go | gofmt > huffman_tables.go 37 | 38 | ## License 39 | 40 | Copyright 2016 Chris Moos 41 | 42 | Licensed under the Apache License, Version 2.0 (the "License"); 43 | you may not use this file except in compliance with the License. 44 | You may obtain a copy of the License at 45 | 46 | http://www.apache.org/licenses/LICENSE-2.0 47 | 48 | Unless required by applicable law or agreed to in writing, software 49 | distributed under the License is distributed on an "AS IS" BASIS, 50 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 51 | See the License for the specific language governing permissions and 52 | limitations under the License. 53 | -------------------------------------------------------------------------------- /integers.go: -------------------------------------------------------------------------------- 1 | package hpack 2 | 3 | import ( 4 | "math" 5 | ) 6 | 7 | // Decodes an integer from buf with the specified prefix length in number of bits. 8 | // 9 | // This function returns the remaining buffer after fully parsing the integer, the first octet with a mask applied to remove the prefix, 10 | // the decoded number, and an error if an error occurred while parsing. 11 | // 12 | // See https://tools.ietf.org/html/rfc7541#section-5.1 13 | func (decoder *Decoder) DecodeInteger(buf []byte, prefixLength int) (remainingBuf []byte, maskedFirstOctet int, number int, err error) { 14 | return decodeInteger(buf, prefixLength, decoder.integerValueMax, decoder.integerEncodedLengthMax) 15 | } 16 | 17 | func decodeInteger(buf []byte, prefixLength int, integerMax int, encodedLengthMax int) (remainingBuf []byte, maskedFirstOctet int, number int, err error) { 18 | if prefixLength < 1 || prefixLength > 8 { 19 | panic("prefix length in bits must be >= 1 and <= 8") 20 | } 21 | mask := (1< integerMax { 36 | return nil, 0, 0, ErrIntegerValueTooLarge 37 | } 38 | return buf[idx+1:], prefix, n, nil 39 | } 40 | m += 7 41 | idx += 1 42 | if idx == encodedLengthMax { 43 | return nil, 0, 0, ErrIntegerEncodedLengthTooLong 44 | } 45 | } 46 | } 47 | } 48 | 49 | // Encodes number with the specified prefix length in number of bits. 50 | // 51 | // See https://tools.ietf.org/html/rfc7541#section-5.1 52 | func (encoder *Encoder) EncodeInteger(number int, prefixLength int) []byte { 53 | return encodeInteger(number, prefixLength) 54 | } 55 | 56 | func encodeInteger(number int, prefixLength int) []byte { 57 | if prefixLength < 1 || prefixLength > 8 { 58 | panic("prefix length in bits must be >= 1 and <= 8") 59 | } 60 | if number < int(math.Pow(2, float64(prefixLength)))-1 { 61 | return []byte{byte(number)} 62 | } else { 63 | i := number 64 | buf := []byte{byte(int(math.Pow(2, float64(prefixLength))) - 1)} 65 | i -= (int(math.Pow(2, float64(prefixLength))) - 1) 66 | for i >= 128 { 67 | buf = append(buf, byte((i%128)+128)) 68 | i /= 128 69 | } 70 | buf = append(buf, byte(i)) 71 | return buf 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /huffman.go: -------------------------------------------------------------------------------- 1 | package hpack 2 | 3 | import "errors" 4 | 5 | type bitReader struct { 6 | buf []byte 7 | index int 8 | bitIndex int 9 | } 10 | 11 | func newBitReader(buf []byte) *bitReader { 12 | return &bitReader{ 13 | buf: buf, 14 | index: 0, 15 | bitIndex: 0, 16 | } 17 | } 18 | 19 | var ErrHuffmanDecodeFailure = errors.New("invalid huffman code encountered") 20 | 21 | func (br *bitReader) PeekBits(numBits int) (int, int) { 22 | var n int = 0 23 | var idx int = br.index 24 | var bitIdx int = br.bitIndex 25 | for x := numBits; x >= 0; { 26 | for y := 0; y < 8; y++ { 27 | var bit int = 0 28 | if ((br.buf[idx] << uint(bitIdx)) & (1 << 7)) == (1 << 7) { 29 | bit = 1 30 | } 31 | n |= (bit << uint(x-1)) 32 | 33 | bitIdx += 1 34 | if bitIdx == 8 { 35 | bitIdx = 0 36 | idx += 1 37 | if idx == len(br.buf) { 38 | return n, (numBits - x + 1) 39 | } 40 | } 41 | x -= 1 42 | } 43 | } 44 | return n, numBits 45 | } 46 | 47 | func (br *bitReader) BitsAvailable() int { 48 | bytes := len(br.buf) - br.index 49 | return (8 * bytes) - br.bitIndex 50 | } 51 | 52 | func (br *bitReader) ConsumeBits(numBits int) { 53 | br.index += (numBits + br.bitIndex) / 8 54 | br.bitIndex = (numBits + br.bitIndex) % 8 55 | } 56 | 57 | // Encodes the specified data with Huffman codes in HPACK 58 | func HuffmanEncode(data []byte) []byte { 59 | encoded := make([]byte, 0) 60 | var currentByte byte = 0 61 | currentBits := 0 62 | for _, b := range data { 63 | entry := huffmanCodes[b] 64 | code := entry[0] 65 | bits := int(entry[1]) 66 | bitsRemaining := bits 67 | 68 | for bitsRemaining > 0 { 69 | if (code>>uint(bitsRemaining-1))&1 == 1 { 70 | currentByte |= 1 71 | } 72 | bitsRemaining -= 1 73 | currentBits += 1 74 | if currentBits == 8 { 75 | encoded = append(encoded, currentByte) 76 | currentByte = 0 77 | currentBits = 0 78 | } else { 79 | currentByte <<= 1 80 | } 81 | } 82 | } 83 | if currentBits > 0 && currentBits < 8 { 84 | padding := huffmanCodes[256] 85 | currentByte <<= 7 - uint(currentBits) 86 | currentByte |= byte(padding[0] >> (padding[1] - uint32(8-currentBits))) 87 | encoded = append(encoded, currentByte) 88 | } 89 | return encoded 90 | } 91 | 92 | // Decodes the huffman encoded data 93 | func HuffmanDecode(encoded []byte) ([]byte, error) { 94 | decoded := make([]byte, 0) 95 | 96 | bitReader := newBitReader(encoded) 97 | for bitReader.BitsAvailable() >= 5 { 98 | n, bitsRead := bitReader.PeekBits(32) 99 | code := int32(n) 100 | decode_success := false 101 | 102 | table := lookupTable 103 | for bitIdx := 0; bitIdx < 32; bitIdx += 8 { 104 | entry := table[(code>>(24-uint(bitIdx)))&0xff] 105 | if entry != nil { 106 | if entry.nextTable != nil { 107 | table = entry.nextTable 108 | } else { 109 | if bitsRead >= int(entry.bits) { 110 | decoded = append(decoded, []byte{byte(entry.symbol)}...) 111 | } 112 | bitReader.ConsumeBits(int(entry.bits)) 113 | decode_success = true 114 | break 115 | } 116 | } 117 | } 118 | if !decode_success { 119 | if bitsRead <= 7 { 120 | break 121 | } else { 122 | return nil, ErrHuffmanDecodeFailure 123 | } 124 | } 125 | } 126 | return decoded, nil 127 | } 128 | -------------------------------------------------------------------------------- /static_table.go: -------------------------------------------------------------------------------- 1 | package hpack 2 | 3 | var staticTable = [][2]string{ 4 | {":authority", ""}, 5 | {":method", "GET"}, 6 | {":method", "POST"}, 7 | {":path", "/"}, 8 | {":path", "/index.html"}, 9 | {":scheme", "http"}, 10 | {":scheme", "https"}, 11 | {":status", "200"}, 12 | {":status", "204"}, 13 | {":status", "206"}, 14 | {":status", "304"}, 15 | {":status", "400"}, 16 | {":status", "404"}, 17 | {":status", "500"}, 18 | {"accept-charset", ""}, 19 | {"accept-encoding", "gzip, deflate"}, 20 | {"accept-language", ""}, 21 | {"accept-ranges", ""}, 22 | {"accept", ""}, 23 | {"access-control-allow-origin", ""}, 24 | {"age", ""}, 25 | {"allow", ""}, 26 | {"authorization", ""}, 27 | {"cache-control", ""}, 28 | {"content-disposition", ""}, 29 | {"content-encoding", ""}, 30 | {"content-language", ""}, 31 | {"content-length", ""}, 32 | {"content-location", ""}, 33 | {"content-range", ""}, 34 | {"content-type", ""}, 35 | {"cookie", ""}, 36 | {"date", ""}, 37 | {"etag", ""}, 38 | {"expect", ""}, 39 | {"expires", ""}, 40 | {"from", ""}, 41 | {"host", ""}, 42 | {"if-match", ""}, 43 | {"if-modified-since", ""}, 44 | {"if-none-match", ""}, 45 | {"if-range", ""}, 46 | {"if-unmodified-since", ""}, 47 | {"last-modified", ""}, 48 | {"link", ""}, 49 | {"location", ""}, 50 | {"max-forwards", ""}, 51 | {"proxy-authenticate", ""}, 52 | {"proxy-authorization", ""}, 53 | {"range", ""}, 54 | {"referer", ""}, 55 | {"refresh", ""}, 56 | {"retry-after", ""}, 57 | {"server", ""}, 58 | {"set-cookie", ""}, 59 | {"strict-transport-security", ""}, 60 | {"transfer-encoding", ""}, 61 | {"user-agent", ""}, 62 | {"vary", ""}, 63 | {"via", ""}, 64 | {"www-authenticate", ""}, 65 | } 66 | 67 | var staticTableEncoding = map[string]int{ 68 | ":authority": 1, 69 | ":method": 2, 70 | ":path": 4, 71 | ":scheme": 6, 72 | ":status": 8, 73 | "accept-encoding": 16, 74 | "accept-charset": 15, 75 | "accept-language": 17, 76 | "accept-ranges": 18, 77 | "accept": 19, 78 | "access-control-allow-origin": 20, 79 | "age": 21, 80 | "allow": 22, 81 | "authorization": 23, 82 | "cache-control": 24, 83 | "content-disposition": 25, 84 | "content-encoding": 26, 85 | "content-language": 27, 86 | "content-length": 28, 87 | "content-location": 29, 88 | "content-range": 30, 89 | "content-type": 31, 90 | "cookie": 32, 91 | "date": 33, 92 | "etag": 34, 93 | "expect": 35, 94 | "expires": 36, 95 | "from": 37, 96 | "host": 38, 97 | "if-match": 39, 98 | "if-modified-since": 40, 99 | "if-none-match": 41, 100 | "if-range": 42, 101 | "if-unmodified-since": 43, 102 | "last-modified": 44, 103 | "link": 45, 104 | "location": 46, 105 | "max-forwards": 47, 106 | "proxy-authenticate": 48, 107 | "proxy-authorization": 49, 108 | "range": 50, 109 | "referer": 51, 110 | "refresh": 52, 111 | "retry-after": 53, 112 | "server": 54, 113 | "set-cookie": 55, 114 | "strict-transport-security": 56, 115 | "transfer-encoding": 57, 116 | "user-agent": 58, 117 | "vary": 59, 118 | "via": 60, 119 | "www-authenticate": 61, 120 | } 121 | 122 | var staticTableEncodingWithValues = map[string]int{ 123 | ":method:GET": 2, 124 | ":method:POST": 3, 125 | ":path:/": 4, 126 | ":path:/index.html": 5, 127 | ":scheme:http": 6, 128 | ":scheme:https": 7, 129 | ":status:200": 8, 130 | ":status:204": 9, 131 | ":status:206": 10, 132 | ":status:304": 11, 133 | ":status:400": 12, 134 | ":status:404": 13, 135 | ":status:500": 14, 136 | "accept-encoding:gzip, deflate": 16, 137 | } 138 | -------------------------------------------------------------------------------- /huffman_codes.go: -------------------------------------------------------------------------------- 1 | package hpack 2 | 3 | var huffmanCodes = [][2]uint32{ 4 | {0x1ff8, 13}, 5 | {0x7fffd8, 23}, 6 | {0xfffffe2, 28}, 7 | {0xfffffe3, 28}, 8 | {0xfffffe4, 28}, 9 | {0xfffffe5, 28}, 10 | {0xfffffe6, 28}, 11 | {0xfffffe7, 28}, 12 | {0xfffffe8, 28}, 13 | {0xffffea, 24}, 14 | {0x3ffffffc, 30}, 15 | {0xfffffe9, 28}, 16 | {0xfffffea, 28}, 17 | {0x3ffffffd, 30}, 18 | {0xfffffeb, 28}, 19 | {0xfffffec, 28}, 20 | {0xfffffed, 28}, 21 | {0xfffffee, 28}, 22 | {0xfffffef, 28}, 23 | {0xffffff0, 28}, 24 | {0xffffff1, 28}, 25 | {0xffffff2, 28}, 26 | {0x3ffffffe, 30}, 27 | {0xffffff3, 28}, 28 | {0xffffff4, 28}, 29 | {0xffffff5, 28}, 30 | {0xffffff6, 28}, 31 | {0xffffff7, 28}, 32 | {0xffffff8, 28}, 33 | {0xffffff9, 28}, 34 | {0xffffffa, 28}, 35 | {0xffffffb, 28}, 36 | {0x14, 6}, 37 | {0x3f8, 10}, 38 | {0x3f9, 10}, 39 | {0xffa, 12}, 40 | {0x1ff9, 13}, 41 | {0x15, 6}, 42 | {0xf8, 8}, 43 | {0x7fa, 11}, 44 | {0x3fa, 10}, 45 | {0x3fb, 10}, 46 | {0xf9, 8}, 47 | {0x7fb, 11}, 48 | {0xfa, 8}, 49 | {0x16, 6}, 50 | {0x17, 6}, 51 | {0x18, 6}, 52 | {0x0, 5}, 53 | {0x1, 5}, 54 | {0x2, 5}, 55 | {0x19, 6}, 56 | {0x1a, 6}, 57 | {0x1b, 6}, 58 | {0x1c, 6}, 59 | {0x1d, 6}, 60 | {0x1e, 6}, 61 | {0x1f, 6}, 62 | {0x5c, 7}, 63 | {0xfb, 8}, 64 | {0x7ffc, 15}, 65 | {0x20, 6}, 66 | {0xffb, 12}, 67 | {0x3fc, 10}, 68 | {0x1ffa, 13}, 69 | {0x21, 6}, 70 | {0x5d, 7}, 71 | {0x5e, 7}, 72 | {0x5f, 7}, 73 | {0x60, 7}, 74 | {0x61, 7}, 75 | {0x62, 7}, 76 | {0x63, 7}, 77 | {0x64, 7}, 78 | {0x65, 7}, 79 | {0x66, 7}, 80 | {0x67, 7}, 81 | {0x68, 7}, 82 | {0x69, 7}, 83 | {0x6a, 7}, 84 | {0x6b, 7}, 85 | {0x6c, 7}, 86 | {0x6d, 7}, 87 | {0x6e, 7}, 88 | {0x6f, 7}, 89 | {0x70, 7}, 90 | {0x71, 7}, 91 | {0x72, 7}, 92 | {0xfc, 8}, 93 | {0x73, 7}, 94 | {0xfd, 8}, 95 | {0x1ffb, 13}, 96 | {0x7fff0, 19}, 97 | {0x1ffc, 13}, 98 | {0x3ffc, 14}, 99 | {0x22, 6}, 100 | {0x7ffd, 15}, 101 | {0x3, 5}, 102 | {0x23, 6}, 103 | {0x4, 5}, 104 | {0x24, 6}, 105 | {0x5, 5}, 106 | {0x25, 6}, 107 | {0x26, 6}, 108 | {0x27, 6}, 109 | {0x6, 5}, 110 | {0x74, 7}, 111 | {0x75, 7}, 112 | {0x28, 6}, 113 | {0x29, 6}, 114 | {0x2a, 6}, 115 | {0x7, 5}, 116 | {0x2b, 6}, 117 | {0x76, 7}, 118 | {0x2c, 6}, 119 | {0x8, 5}, 120 | {0x9, 5}, 121 | {0x2d, 6}, 122 | {0x77, 7}, 123 | {0x78, 7}, 124 | {0x79, 7}, 125 | {0x7a, 7}, 126 | {0x7b, 7}, 127 | {0x7ffe, 15}, 128 | {0x7fc, 11}, 129 | {0x3ffd, 14}, 130 | {0x1ffd, 13}, 131 | {0xffffffc, 28}, 132 | {0xfffe6, 20}, 133 | {0x3fffd2, 22}, 134 | {0xfffe7, 20}, 135 | {0xfffe8, 20}, 136 | {0x3fffd3, 22}, 137 | {0x3fffd4, 22}, 138 | {0x3fffd5, 22}, 139 | {0x7fffd9, 23}, 140 | {0x3fffd6, 22}, 141 | {0x7fffda, 23}, 142 | {0x7fffdb, 23}, 143 | {0x7fffdc, 23}, 144 | {0x7fffdd, 23}, 145 | {0x7fffde, 23}, 146 | {0xffffeb, 24}, 147 | {0x7fffdf, 23}, 148 | {0xffffec, 24}, 149 | {0xffffed, 24}, 150 | {0x3fffd7, 22}, 151 | {0x7fffe0, 23}, 152 | {0xffffee, 24}, 153 | {0x7fffe1, 23}, 154 | {0x7fffe2, 23}, 155 | {0x7fffe3, 23}, 156 | {0x7fffe4, 23}, 157 | {0x1fffdc, 21}, 158 | {0x3fffd8, 22}, 159 | {0x7fffe5, 23}, 160 | {0x3fffd9, 22}, 161 | {0x7fffe6, 23}, 162 | {0x7fffe7, 23}, 163 | {0xffffef, 24}, 164 | {0x3fffda, 22}, 165 | {0x1fffdd, 21}, 166 | {0xfffe9, 20}, 167 | {0x3fffdb, 22}, 168 | {0x3fffdc, 22}, 169 | {0x7fffe8, 23}, 170 | {0x7fffe9, 23}, 171 | {0x1fffde, 21}, 172 | {0x7fffea, 23}, 173 | {0x3fffdd, 22}, 174 | {0x3fffde, 22}, 175 | {0xfffff0, 24}, 176 | {0x1fffdf, 21}, 177 | {0x3fffdf, 22}, 178 | {0x7fffeb, 23}, 179 | {0x7fffec, 23}, 180 | {0x1fffe0, 21}, 181 | {0x1fffe1, 21}, 182 | {0x3fffe0, 22}, 183 | {0x1fffe2, 21}, 184 | {0x7fffed, 23}, 185 | {0x3fffe1, 22}, 186 | {0x7fffee, 23}, 187 | {0x7fffef, 23}, 188 | {0xfffea, 20}, 189 | {0x3fffe2, 22}, 190 | {0x3fffe3, 22}, 191 | {0x3fffe4, 22}, 192 | {0x7ffff0, 23}, 193 | {0x3fffe5, 22}, 194 | {0x3fffe6, 22}, 195 | {0x7ffff1, 23}, 196 | {0x3ffffe0, 26}, 197 | {0x3ffffe1, 26}, 198 | {0xfffeb, 20}, 199 | {0x7fff1, 19}, 200 | {0x3fffe7, 22}, 201 | {0x7ffff2, 23}, 202 | {0x3fffe8, 22}, 203 | {0x1ffffec, 25}, 204 | {0x3ffffe2, 26}, 205 | {0x3ffffe3, 26}, 206 | {0x3ffffe4, 26}, 207 | {0x7ffffde, 27}, 208 | {0x7ffffdf, 27}, 209 | {0x3ffffe5, 26}, 210 | {0xfffff1, 24}, 211 | {0x1ffffed, 25}, 212 | {0x7fff2, 19}, 213 | {0x1fffe3, 21}, 214 | {0x3ffffe6, 26}, 215 | {0x7ffffe0, 27}, 216 | {0x7ffffe1, 27}, 217 | {0x3ffffe7, 26}, 218 | {0x7ffffe2, 27}, 219 | {0xfffff2, 24}, 220 | {0x1fffe4, 21}, 221 | {0x1fffe5, 21}, 222 | {0x3ffffe8, 26}, 223 | {0x3ffffe9, 26}, 224 | {0xffffffd, 28}, 225 | {0x7ffffe3, 27}, 226 | {0x7ffffe4, 27}, 227 | {0x7ffffe5, 27}, 228 | {0xfffec, 20}, 229 | {0xfffff3, 24}, 230 | {0xfffed, 20}, 231 | {0x1fffe6, 21}, 232 | {0x3fffe9, 22}, 233 | {0x1fffe7, 21}, 234 | {0x1fffe8, 21}, 235 | {0x7ffff3, 23}, 236 | {0x3fffea, 22}, 237 | {0x3fffeb, 22}, 238 | {0x1ffffee, 25}, 239 | {0x1ffffef, 25}, 240 | {0xfffff4, 24}, 241 | {0xfffff5, 24}, 242 | {0x3ffffea, 26}, 243 | {0x7ffff4, 23}, 244 | {0x3ffffeb, 26}, 245 | {0x7ffffe6, 27}, 246 | {0x3ffffec, 26}, 247 | {0x3ffffed, 26}, 248 | {0x7ffffe7, 27}, 249 | {0x7ffffe8, 27}, 250 | {0x7ffffe9, 27}, 251 | {0x7ffffea, 27}, 252 | {0x7ffffeb, 27}, 253 | {0xffffffe, 28}, 254 | {0x7ffffec, 27}, 255 | {0x7ffffed, 27}, 256 | {0x7ffffee, 27}, 257 | {0x7ffffef, 27}, 258 | {0x7fffff0, 27}, 259 | {0x3ffffee, 26}, 260 | {0x3fffffff, 30}, 261 | } 262 | -------------------------------------------------------------------------------- /cmd/generate_huffman_tables/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | import "math" 5 | 6 | type lookupTableEntry struct { 7 | symbol uint32 8 | bits uint8 9 | nextTable []*lookupTableEntry 10 | } 11 | 12 | var huffmanCodes = [][2]uint32{ 13 | {0x1ff8, 13}, 14 | {0x7fffd8, 23}, 15 | {0xfffffe2, 28}, 16 | {0xfffffe3, 28}, 17 | {0xfffffe4, 28}, 18 | {0xfffffe5, 28}, 19 | {0xfffffe6, 28}, 20 | {0xfffffe7, 28}, 21 | {0xfffffe8, 28}, 22 | {0xffffea, 24}, 23 | {0x3ffffffc, 30}, 24 | {0xfffffe9, 28}, 25 | {0xfffffea, 28}, 26 | {0x3ffffffd, 30}, 27 | {0xfffffeb, 28}, 28 | {0xfffffec, 28}, 29 | {0xfffffed, 28}, 30 | {0xfffffee, 28}, 31 | {0xfffffef, 28}, 32 | {0xffffff0, 28}, 33 | {0xffffff1, 28}, 34 | {0xffffff2, 28}, 35 | {0x3ffffffe, 30}, 36 | {0xffffff3, 28}, 37 | {0xffffff4, 28}, 38 | {0xffffff5, 28}, 39 | {0xffffff6, 28}, 40 | {0xffffff7, 28}, 41 | {0xffffff8, 28}, 42 | {0xffffff9, 28}, 43 | {0xffffffa, 28}, 44 | {0xffffffb, 28}, 45 | {0x14, 6}, 46 | {0x3f8, 10}, 47 | {0x3f9, 10}, 48 | {0xffa, 12}, 49 | {0x1ff9, 13}, 50 | {0x15, 6}, 51 | {0xf8, 8}, 52 | {0x7fa, 11}, 53 | {0x3fa, 10}, 54 | {0x3fb, 10}, 55 | {0xf9, 8}, 56 | {0x7fb, 11}, 57 | {0xfa, 8}, 58 | {0x16, 6}, 59 | {0x17, 6}, 60 | {0x18, 6}, 61 | {0x0, 5}, 62 | {0x1, 5}, 63 | {0x2, 5}, 64 | {0x19, 6}, 65 | {0x1a, 6}, 66 | {0x1b, 6}, 67 | {0x1c, 6}, 68 | {0x1d, 6}, 69 | {0x1e, 6}, 70 | {0x1f, 6}, 71 | {0x5c, 7}, 72 | {0xfb, 8}, 73 | {0x7ffc, 15}, 74 | {0x20, 6}, 75 | {0xffb, 12}, 76 | {0x3fc, 10}, 77 | {0x1ffa, 13}, 78 | {0x21, 6}, 79 | {0x5d, 7}, 80 | {0x5e, 7}, 81 | {0x5f, 7}, 82 | {0x60, 7}, 83 | {0x61, 7}, 84 | {0x62, 7}, 85 | {0x63, 7}, 86 | {0x64, 7}, 87 | {0x65, 7}, 88 | {0x66, 7}, 89 | {0x67, 7}, 90 | {0x68, 7}, 91 | {0x69, 7}, 92 | {0x6a, 7}, 93 | {0x6b, 7}, 94 | {0x6c, 7}, 95 | {0x6d, 7}, 96 | {0x6e, 7}, 97 | {0x6f, 7}, 98 | {0x70, 7}, 99 | {0x71, 7}, 100 | {0x72, 7}, 101 | {0xfc, 8}, 102 | {0x73, 7}, 103 | {0xfd, 8}, 104 | {0x1ffb, 13}, 105 | {0x7fff0, 19}, 106 | {0x1ffc, 13}, 107 | {0x3ffc, 14}, 108 | {0x22, 6}, 109 | {0x7ffd, 15}, 110 | {0x3, 5}, 111 | {0x23, 6}, 112 | {0x4, 5}, 113 | {0x24, 6}, 114 | {0x5, 5}, 115 | {0x25, 6}, 116 | {0x26, 6}, 117 | {0x27, 6}, 118 | {0x6, 5}, 119 | {0x74, 7}, 120 | {0x75, 7}, 121 | {0x28, 6}, 122 | {0x29, 6}, 123 | {0x2a, 6}, 124 | {0x7, 5}, 125 | {0x2b, 6}, 126 | {0x76, 7}, 127 | {0x2c, 6}, 128 | {0x8, 5}, 129 | {0x9, 5}, 130 | {0x2d, 6}, 131 | {0x77, 7}, 132 | {0x78, 7}, 133 | {0x79, 7}, 134 | {0x7a, 7}, 135 | {0x7b, 7}, 136 | {0x7ffe, 15}, 137 | {0x7fc, 11}, 138 | {0x3ffd, 14}, 139 | {0x1ffd, 13}, 140 | {0xffffffc, 28}, 141 | {0xfffe6, 20}, 142 | {0x3fffd2, 22}, 143 | {0xfffe7, 20}, 144 | {0xfffe8, 20}, 145 | {0x3fffd3, 22}, 146 | {0x3fffd4, 22}, 147 | {0x3fffd5, 22}, 148 | {0x7fffd9, 23}, 149 | {0x3fffd6, 22}, 150 | {0x7fffda, 23}, 151 | {0x7fffdb, 23}, 152 | {0x7fffdc, 23}, 153 | {0x7fffdd, 23}, 154 | {0x7fffde, 23}, 155 | {0xffffeb, 24}, 156 | {0x7fffdf, 23}, 157 | {0xffffec, 24}, 158 | {0xffffed, 24}, 159 | {0x3fffd7, 22}, 160 | {0x7fffe0, 23}, 161 | {0xffffee, 24}, 162 | {0x7fffe1, 23}, 163 | {0x7fffe2, 23}, 164 | {0x7fffe3, 23}, 165 | {0x7fffe4, 23}, 166 | {0x1fffdc, 21}, 167 | {0x3fffd8, 22}, 168 | {0x7fffe5, 23}, 169 | {0x3fffd9, 22}, 170 | {0x7fffe6, 23}, 171 | {0x7fffe7, 23}, 172 | {0xffffef, 24}, 173 | {0x3fffda, 22}, 174 | {0x1fffdd, 21}, 175 | {0xfffe9, 20}, 176 | {0x3fffdb, 22}, 177 | {0x3fffdc, 22}, 178 | {0x7fffe8, 23}, 179 | {0x7fffe9, 23}, 180 | {0x1fffde, 21}, 181 | {0x7fffea, 23}, 182 | {0x3fffdd, 22}, 183 | {0x3fffde, 22}, 184 | {0xfffff0, 24}, 185 | {0x1fffdf, 21}, 186 | {0x3fffdf, 22}, 187 | {0x7fffeb, 23}, 188 | {0x7fffec, 23}, 189 | {0x1fffe0, 21}, 190 | {0x1fffe1, 21}, 191 | {0x3fffe0, 22}, 192 | {0x1fffe2, 21}, 193 | {0x7fffed, 23}, 194 | {0x3fffe1, 22}, 195 | {0x7fffee, 23}, 196 | {0x7fffef, 23}, 197 | {0xfffea, 20}, 198 | {0x3fffe2, 22}, 199 | {0x3fffe3, 22}, 200 | {0x3fffe4, 22}, 201 | {0x7ffff0, 23}, 202 | {0x3fffe5, 22}, 203 | {0x3fffe6, 22}, 204 | {0x7ffff1, 23}, 205 | {0x3ffffe0, 26}, 206 | {0x3ffffe1, 26}, 207 | {0xfffeb, 20}, 208 | {0x7fff1, 19}, 209 | {0x3fffe7, 22}, 210 | {0x7ffff2, 23}, 211 | {0x3fffe8, 22}, 212 | {0x1ffffec, 25}, 213 | {0x3ffffe2, 26}, 214 | {0x3ffffe3, 26}, 215 | {0x3ffffe4, 26}, 216 | {0x7ffffde, 27}, 217 | {0x7ffffdf, 27}, 218 | {0x3ffffe5, 26}, 219 | {0xfffff1, 24}, 220 | {0x1ffffed, 25}, 221 | {0x7fff2, 19}, 222 | {0x1fffe3, 21}, 223 | {0x3ffffe6, 26}, 224 | {0x7ffffe0, 27}, 225 | {0x7ffffe1, 27}, 226 | {0x3ffffe7, 26}, 227 | {0x7ffffe2, 27}, 228 | {0xfffff2, 24}, 229 | {0x1fffe4, 21}, 230 | {0x1fffe5, 21}, 231 | {0x3ffffe8, 26}, 232 | {0x3ffffe9, 26}, 233 | {0xffffffd, 28}, 234 | {0x7ffffe3, 27}, 235 | {0x7ffffe4, 27}, 236 | {0x7ffffe5, 27}, 237 | {0xfffec, 20}, 238 | {0xfffff3, 24}, 239 | {0xfffed, 20}, 240 | {0x1fffe6, 21}, 241 | {0x3fffe9, 22}, 242 | {0x1fffe7, 21}, 243 | {0x1fffe8, 21}, 244 | {0x7ffff3, 23}, 245 | {0x3fffea, 22}, 246 | {0x3fffeb, 22}, 247 | {0x1ffffee, 25}, 248 | {0x1ffffef, 25}, 249 | {0xfffff4, 24}, 250 | {0xfffff5, 24}, 251 | {0x3ffffea, 26}, 252 | {0x7ffff4, 23}, 253 | {0x3ffffeb, 26}, 254 | {0x7ffffe6, 27}, 255 | {0x3ffffec, 26}, 256 | {0x3ffffed, 26}, 257 | {0x7ffffe7, 27}, 258 | {0x7ffffe8, 27}, 259 | {0x7ffffe9, 27}, 260 | {0x7ffffea, 27}, 261 | {0x7ffffeb, 27}, 262 | {0xffffffe, 28}, 263 | {0x7ffffec, 27}, 264 | {0x7ffffed, 27}, 265 | {0x7ffffee, 27}, 266 | {0x7ffffef, 27}, 267 | {0x7fffff0, 27}, 268 | {0x3ffffee, 26}, 269 | {0x3fffffff, 30}, 270 | } 271 | 272 | func main() { 273 | BuildlookupTable() 274 | table := GetlookupTable() 275 | fmt.Printf("package hpack\n\n") 276 | fmt.Printf( 277 | "type lookupTableEntry struct {\n" + 278 | "symbol uint32\n" + 279 | "bits uint8\n" + 280 | "nextTable []*lookupTableEntry\n" + 281 | "}\n") 282 | fmt.Printf("var lookupTable = ") 283 | dumpTable(table, 1) 284 | } 285 | 286 | func dumpTable(table []*lookupTableEntry, indent int) { 287 | for x := 0; x < indent-1; x++ { 288 | fmt.Printf(" ") 289 | } 290 | fmt.Printf("[]*lookupTableEntry{\n") 291 | for _, entry := range table { 292 | for x := 0; x < indent; x++ { 293 | fmt.Printf(" ") 294 | } 295 | if entry.nextTable == nil { 296 | fmt.Printf(" {%d, %d, nil},\n", entry.symbol, entry.bits) 297 | } else { 298 | fmt.Printf(" {%d, %d, \n", entry.symbol, entry.bits) 299 | dumpTable(entry.nextTable, indent+3) 300 | for x := 0; x < indent; x++ { 301 | fmt.Printf(" ") 302 | } 303 | fmt.Printf("},\n") 304 | } 305 | } 306 | for x := 0; x < indent-1; x++ { 307 | fmt.Printf(" ") 308 | } 309 | if indent == 1 { 310 | fmt.Printf("}\n") 311 | } else { 312 | fmt.Printf("},\n") 313 | } 314 | } 315 | 316 | var lookupTable1 = []*lookupTableEntry{} 317 | 318 | func GetlookupTable() []*lookupTableEntry { 319 | return lookupTable1 320 | } 321 | 322 | func doBuildlookupTable(parentTable []*lookupTableEntry, symbol uint32, code uint32, bits uint8) { 323 | //lookup := code 324 | table := parentTable 325 | for idx := uint32(((bits / 8) + 1) * 8); idx > 0; { 326 | shiftbits := (((idx / 8) - 1) * 8) 327 | var c uint32 328 | if shiftbits == 0 { 329 | c = code << (8 - bits) 330 | } else { 331 | c = (code >> shiftbits) & 0xff 332 | } 333 | 334 | idx -= 8 335 | 336 | // add entry to another table 337 | if idx > 0 { 338 | entry := table[c] 339 | if entry == nil { 340 | entry = &lookupTableEntry{ 341 | nextTable: make([]*lookupTableEntry, 256), 342 | } 343 | table[c] = entry 344 | table = entry.nextTable 345 | } 346 | } else { 347 | table[c] = &lookupTableEntry{ 348 | symbol: symbol, 349 | bits: bits, 350 | } 351 | } 352 | } 353 | } 354 | 355 | func alignHuffmanCodes() [][2]uint32 { 356 | codes := make([][2]uint32, len(huffmanCodes)) 357 | for x, item := range huffmanCodes { 358 | codes[x] = [2]uint32{item[0] << (32 - item[1]), item[1]} 359 | } 360 | return codes 361 | } 362 | 363 | func addEntriesForPrefix(table []*lookupTableEntry, symbol uint32, prefix uint32, bits uint8) { 364 | if bits%8 == 0 { 365 | table[prefix] = &lookupTableEntry{ 366 | symbol: symbol, 367 | bits: bits, 368 | } 369 | } else { 370 | for x := 0; x < int(math.Pow(2, float64(8-(bits%8)))); x++ { 371 | table[prefix+uint32(x)] = &lookupTableEntry{ 372 | symbol: symbol, 373 | bits: bits, 374 | } 375 | } 376 | } 377 | } 378 | 379 | func doBuildlookupTable1(parentTable []*lookupTableEntry) { 380 | codes := alignHuffmanCodes() 381 | for x, item := range codes { 382 | bitIdx := 0 383 | var table []*lookupTableEntry = parentTable 384 | for { 385 | lookup := (item[0] >> uint(24-bitIdx)) & 0xff 386 | 387 | bitIdx += 8 388 | if bitIdx < int(item[1]) { 389 | entry := table[lookup] 390 | if entry == nil { 391 | entry = &lookupTableEntry{ 392 | nextTable: make([]*lookupTableEntry, 256), 393 | } 394 | table[lookup] = entry 395 | } 396 | table = entry.nextTable 397 | } else { 398 | addEntriesForPrefix(table, uint32(x), lookup, uint8(item[1])) 399 | break 400 | } 401 | } 402 | } 403 | } 404 | 405 | func BuildlookupTable() { 406 | if len(lookupTable1) > 0 { 407 | return 408 | } 409 | lookupTable1 = make([]*lookupTableEntry, 256) 410 | doBuildlookupTable1(lookupTable1) 411 | return 412 | for x, item := range huffmanCodes { 413 | doBuildlookupTable(lookupTable1, uint32(x), item[0], uint8(item[1])) 414 | } 415 | } 416 | -------------------------------------------------------------------------------- /hpack.go: -------------------------------------------------------------------------------- 1 | // Implements the HPACK Header Compression specification 2 | // https://tools.ietf.org/html/rfc7541 3 | // 4 | // The Huffman decoding is implemented with multi-level lookup tables for high performance. 5 | package hpack 6 | 7 | import ( 8 | "errors" 9 | "fmt" 10 | ) 11 | 12 | type Header struct { 13 | Name string 14 | Value string 15 | 16 | Sensitive bool 17 | } 18 | 19 | var ErrIntegerValueTooLarge = errors.New("integer value larger than max value") 20 | var ErrIntegerEncodedLengthTooLong = errors.New("integer encoded length is too long") 21 | var ErrStringLiteralLengthTooLong = errors.New("string literal length is too long") 22 | 23 | var DefaultMaxIntegerValue = ((1 << 32) - 1) 24 | var DefaultMaxIntegerEncodedLength = 6 25 | var DefaultMaxStringLiteralLength = 1024 * 64 26 | 27 | type Encoder struct { 28 | dynamicTable []Header 29 | dynamicTableSizeMax int 30 | dynamicTableSizeCurrent int 31 | pendingDynamicTableSizeUpdate bool 32 | } 33 | 34 | // A decoder is stateful and updates the internal compression context during processing 35 | // of header blocks. 36 | // 37 | // If HTTP/2 is used, a single decoder instance must be used during the lifetime of a connection, see: 38 | // https://tools.ietf.org/html/rfc7540#section-4.3 39 | type Decoder struct { 40 | dynamicTable []Header 41 | dynamicTableSizeMax int 42 | dynamicTableSizeCurrent int 43 | 44 | integerValueMax int 45 | integerEncodedLengthMax int 46 | stringLiteralLengthMax int 47 | } 48 | 49 | const ( 50 | headerFieldIndexed = 128 51 | headerFieldLiteralIncrementalIndex = 64 52 | headerFieldDynamicSizeUpdate = 32 53 | headerFieldLiteralNeverIndexed = 16 54 | headerFieldLiteralNotIndexed = 0 55 | ) 56 | 57 | const ( 58 | huffmanEncoded = 1 << 7 59 | ) 60 | 61 | func NewEncoder(dynamicTableSizeMax int) *Encoder { 62 | return &Encoder{ 63 | dynamicTableSizeMax: dynamicTableSizeMax, 64 | dynamicTableSizeCurrent: 0, 65 | pendingDynamicTableSizeUpdate: false, 66 | } 67 | } 68 | 69 | func NewDecoder(dynamicTableSizeMax int) *Decoder { 70 | return &Decoder{ 71 | dynamicTableSizeMax: dynamicTableSizeMax, 72 | dynamicTableSizeCurrent: 0, 73 | integerEncodedLengthMax: DefaultMaxIntegerEncodedLength, 74 | integerValueMax: DefaultMaxIntegerValue, 75 | stringLiteralLengthMax: DefaultMaxStringLiteralLength, 76 | } 77 | } 78 | 79 | func (decoder *Decoder) readPrefixedLengthString(buf []byte, prefixLength int) (remainingBuf []byte, str string, err error) { 80 | rest, huffman, length, err := decoder.DecodeInteger(buf, prefixLength) 81 | if err != nil { 82 | return buf, "", err 83 | } 84 | 85 | if length > decoder.stringLiteralLengthMax { 86 | return buf, "", ErrStringLiteralLengthTooLong 87 | } 88 | 89 | if huffman&huffmanEncoded == huffmanEncoded { 90 | if len(rest) < length { 91 | return nil, "", fmt.Errorf("ran out of data while decoding huffman encoded data") 92 | } 93 | decoded, err := HuffmanDecode(rest[:length]) 94 | if err != nil { 95 | return rest, "", err 96 | } 97 | return rest[length:], string(decoded), nil 98 | } else { 99 | return rest[length:], string(rest[:length]), nil 100 | } 101 | } 102 | 103 | func (decoder *Decoder) getIndexedNameValue(index int) (string, string, error) { 104 | if index > len(staticTable) { 105 | dynamicIndex := index - len(staticTable) 106 | if dynamicIndex > len(decoder.dynamicTable) { 107 | return "", "", fmt.Errorf("index %d not found in dynamic table", index) 108 | } 109 | return decoder.dynamicTable[dynamicIndex-1].Name, decoder.dynamicTable[dynamicIndex-1].Value, nil 110 | } 111 | return staticTable[index-1][0], staticTable[index-1][1], nil 112 | } 113 | 114 | // Updates the decoder's dynamic table maximum size and evicts any 115 | // headers if more space is needed to resize to newMaxSize. 116 | func (decoder *Decoder) SetDynamicTableMaxSize(newMaxSize int) { 117 | decoder.dynamicTableSizeMax = newMaxSize 118 | decoder.evictEntries(0, newMaxSize) 119 | } 120 | 121 | // Sets the largest integer that is allowed, anything > value will result in an error 122 | func (decoder *Decoder) SetMaxIntegerValue(value int) { 123 | decoder.integerValueMax = value 124 | } 125 | 126 | // Sets the maximum bytes allowed for encoding a single integer 127 | func (decoder *Decoder) SetMaxIntegerEncodedLength(length int) { 128 | decoder.integerEncodedLengthMax = length 129 | } 130 | 131 | // Sets the maximum length of a string literal 132 | // For compressed string literals the length check will be against the 133 | // compressed length, not the uncompressed length 134 | func (decoder *Decoder) SetMaxStringLiteralLength(length int) { 135 | decoder.stringLiteralLengthMax = length 136 | } 137 | 138 | // Finds the header in the table. 139 | // Returns the index and a bool indicating if the entry includes the value also. 140 | // If the entry wasn't found the index returned is -1 141 | func (encoder *Encoder) findHeaderInTable(name string, value string) (int, bool) { 142 | var entry int 143 | var ok bool 144 | 145 | if value != "" { 146 | entry, ok = staticTableEncodingWithValues[name+":"+value] 147 | if ok { 148 | return entry, true 149 | } 150 | } 151 | 152 | for x, header := range encoder.dynamicTable { 153 | if header.Name == name && header.Value == value { 154 | return len(staticTable) + x + 1, true 155 | } 156 | } 157 | 158 | entry, ok = staticTableEncoding[name] 159 | if ok { 160 | return entry, false 161 | } 162 | return -1, false 163 | } 164 | 165 | // Updates the encoder's dynamic table maximum size and evicts any 166 | // headers if more space is needed to resize to newMaxSize. 167 | // 168 | // After this call the next header field that is encoded will include 169 | // a dynamic table size update 170 | func (encoder *Encoder) SetDynamicTableMaxSize(newMaxSize int) { 171 | encoder.dynamicTableSizeMax = newMaxSize 172 | encoder.evictEntries(0, newMaxSize) 173 | encoder.pendingDynamicTableSizeUpdate = true 174 | } 175 | 176 | func findStaticEntryInTable(name string) int { 177 | entry, ok := staticTableEncoding[name] 178 | if ok { 179 | return entry 180 | } 181 | return -1 182 | } 183 | 184 | // This is a convenience function that encodes a list of headers 185 | // into a header block using Huffman compression and with incremental 186 | // indexing enabled. 187 | // 188 | // If a header is marked as Sensitive it will be encoded as a 189 | // never indexed header field 190 | func (encoder *Encoder) Encode(headers []Header) ([]byte, error) { 191 | return encoder.encode(headers, true) 192 | } 193 | 194 | func encodeLiteralString(str string, prefixLength int, huffman bool) []byte { 195 | encoded := make([]byte, 0) 196 | 197 | var value []byte 198 | if huffman { 199 | value = HuffmanEncode([]byte(str)) 200 | } else { 201 | value = []byte(str) 202 | } 203 | valueLen := encodeInteger(len(value), prefixLength) 204 | 205 | if huffman { 206 | valueLen[0] |= huffmanEncoded 207 | } 208 | encoded = append(encoded, valueLen...) 209 | encoded = append(encoded, value...) 210 | return encoded 211 | } 212 | 213 | // Encodes a header without Indexing and returns the encoded header field 214 | // 215 | // https://tools.ietf.org/html/rfc7541#appendix-C.2.2 216 | func (encoder *Encoder) EncodeNoDynamicIndexing(header Header, huffman bool) ([]byte, error) { 217 | return encoder.encodeHeaderField(header, huffman, false) 218 | } 219 | 220 | // Encodes a header with Indexing and returns the encoded header field 221 | // 222 | // https://tools.ietf.org/html/rfc7541#appendix-C.2.1 223 | func (encoder *Encoder) EncodeIndexed(header Header, huffman bool) ([]byte, error) { 224 | return encoder.encodeHeaderField(header, huffman, true) 225 | } 226 | 227 | func (encoder *Encoder) encodeHeaderField(header Header, huffman bool, addDynamicIndex bool) ([]byte, error) { 228 | encoded := make([]byte, 0) 229 | 230 | if encoder.pendingDynamicTableSizeUpdate { 231 | newSize := encodeInteger(encoder.dynamicTableSizeMax, 5) 232 | newSize[0] |= headerFieldDynamicSizeUpdate 233 | encoded = append(encoded, newSize...) 234 | encoder.pendingDynamicTableSizeUpdate = false 235 | } 236 | 237 | if header.Sensitive { 238 | index := findStaticEntryInTable(header.Name) 239 | if index != -1 { 240 | indexed := encodeInteger(index, 4) 241 | indexed[0] |= headerFieldLiteralNeverIndexed 242 | encoded = append(encoded, indexed...) 243 | } else { 244 | indexed := encodeInteger(0, 4) 245 | indexed[0] |= headerFieldLiteralNeverIndexed 246 | encoded = append(encoded, indexed...) 247 | encoded = append(encoded, encodeLiteralString(header.Name, 7, huffman)...) 248 | } 249 | 250 | encoded = append(encoded, encodeLiteralString(header.Value, 7, huffman)...) 251 | } else { 252 | index, valueIndexed := encoder.findHeaderInTable(header.Name, header.Value) 253 | if index != -1 && valueIndexed { 254 | indexed := encodeInteger(index, 7) 255 | indexed[0] |= headerFieldIndexed 256 | encoded = append(encoded, indexed...) 257 | } else { 258 | var indexed []byte 259 | if index == -1 { 260 | indexed = encodeInteger(0, 6) 261 | } else { 262 | indexed = encodeInteger(index, 6) 263 | } 264 | 265 | if addDynamicIndex { 266 | indexed[0] |= headerFieldLiteralIncrementalIndex 267 | encoder.addNewDynamicEntry(header.Name, header.Value) 268 | } else { 269 | indexed[0] |= headerFieldLiteralNotIndexed 270 | } 271 | 272 | encoded = append(encoded, indexed...) 273 | if index == -1 { 274 | encoded = append(encoded, encodeLiteralString(header.Name, 7, huffman)...) 275 | } 276 | 277 | encoded = append(encoded, encodeLiteralString(header.Value, 7, huffman)...) 278 | } 279 | } 280 | return encoded, nil 281 | } 282 | 283 | func (encoder *Encoder) encode(headers []Header, huffman bool) ([]byte, error) { 284 | encoded := make([]byte, 0) 285 | for _, header := range headers { 286 | enc, err := encoder.EncodeIndexed(header, huffman) 287 | if err != nil { 288 | return nil, err 289 | } 290 | encoded = append(encoded, enc...) 291 | } 292 | return encoded, nil 293 | } 294 | 295 | // Parsers the HPACK header block and returns list of headers 296 | // with the order preserved from the order in the block. 297 | func (decoder *Decoder) Decode(block []byte) ([]Header, error) { 298 | headers := make([]Header, 0) 299 | buf := block 300 | for len(buf) > 0 { 301 | var header *Header 302 | var err error 303 | 304 | buf, header, err = decoder.parseHeaderField(buf) 305 | if err != nil { 306 | return nil, err 307 | } 308 | if header != nil { 309 | headers = append(headers, *header) 310 | } 311 | } 312 | return headers, nil 313 | } 314 | 315 | // Returns true if there is enough space to accomadate additionalSize 316 | func (encoder *Encoder) evictEntries(additionalSize int, maxSize int) bool { 317 | for encoder.dynamicTableSizeCurrent+additionalSize > maxSize { 318 | if len(encoder.dynamicTable) == 0 { 319 | return false 320 | } 321 | 322 | evictedEntry := encoder.dynamicTable[len(encoder.dynamicTable)-1] 323 | encoder.dynamicTableSizeCurrent -= (32 + len(evictedEntry.Name) + len(evictedEntry.Value)) 324 | encoder.dynamicTable = encoder.dynamicTable[:len(encoder.dynamicTable)-1] 325 | } 326 | return true 327 | } 328 | 329 | // Returns true if there is enough space to accomadate additionalSize 330 | func (decoder *Decoder) evictEntries(additionalSize int, maxSize int) bool { 331 | for decoder.dynamicTableSizeCurrent+additionalSize > maxSize { 332 | if len(decoder.dynamicTable) == 0 { 333 | return false 334 | } 335 | 336 | evictedEntry := decoder.dynamicTable[len(decoder.dynamicTable)-1] 337 | decoder.dynamicTableSizeCurrent -= (32 + len(evictedEntry.Name) + len(evictedEntry.Value)) 338 | decoder.dynamicTable = decoder.dynamicTable[:len(decoder.dynamicTable)-1] 339 | } 340 | return true 341 | } 342 | 343 | func (encoder *Encoder) addNewDynamicEntry(name string, value string) { 344 | entrySize := (32 + len(name) + len(value)) 345 | 346 | if !encoder.evictEntries(entrySize, encoder.dynamicTableSizeMax) { 347 | return 348 | } 349 | encoder.dynamicTableSizeCurrent += entrySize 350 | 351 | encoder.dynamicTable = append([]Header{ 352 | { 353 | Name: name, 354 | Value: value, 355 | }, 356 | }, encoder.dynamicTable...) 357 | } 358 | 359 | func (decoder *Decoder) addNewDynamicEntry(name string, value string) { 360 | entrySize := (32 + len(name) + len(value)) 361 | 362 | if !decoder.evictEntries(entrySize, decoder.dynamicTableSizeMax) { 363 | return 364 | } 365 | decoder.dynamicTableSizeCurrent += entrySize 366 | 367 | decoder.dynamicTable = append([]Header{ 368 | { 369 | Name: name, 370 | Value: value, 371 | }, 372 | }, decoder.dynamicTable...) 373 | } 374 | 375 | func (decoder *Decoder) parseHeaderFieldIndexed(encoded []byte) ([]byte, *Header, error) { 376 | rest, _, index, err := decoder.DecodeInteger(encoded, 7) 377 | if err != nil { 378 | return nil, nil, err 379 | } 380 | 381 | name, value, err := decoder.getIndexedNameValue(index) 382 | if err != nil { 383 | return nil, nil, err 384 | } 385 | return rest, &Header{Name: name, Value: value}, nil 386 | } 387 | 388 | func (decoder *Decoder) parseHeaderFieldIncrementalIndex(encoded []byte) ([]byte, *Header, error) { 389 | rest, _, index, err := decoder.DecodeInteger(encoded, 6) 390 | if err != nil { 391 | return nil, nil, err 392 | } 393 | 394 | var name string 395 | if index == 0 { 396 | rest, name, err = decoder.readPrefixedLengthString(rest, 7) 397 | if err != nil { 398 | return nil, nil, err 399 | } 400 | } else { 401 | name, _, err = decoder.getIndexedNameValue(index) 402 | if err != nil { 403 | return nil, nil, err 404 | } 405 | } 406 | 407 | rest, value, err := decoder.readPrefixedLengthString(rest, 7) 408 | if err != nil { 409 | return nil, nil, err 410 | } 411 | 412 | decoder.addNewDynamicEntry(name, value) 413 | return rest, &Header{Name: name, Value: value}, nil 414 | } 415 | 416 | func (decoder *Decoder) parseDynamicSizeUpdate(encoded []byte) ([]byte, error) { 417 | consumed, _, size, err := decoder.DecodeInteger(encoded, 5) 418 | if err != nil { 419 | return nil, err 420 | } 421 | if size > decoder.dynamicTableSizeMax { 422 | return consumed, fmt.Errorf("can't resize dynamic table to %d in an update to a value greater than the current size, %d", size, decoder.dynamicTableSizeCurrent) 423 | } 424 | decoder.SetDynamicTableMaxSize(size) 425 | return consumed, nil 426 | } 427 | 428 | func (decoder *Decoder) parseHeaderFieldNotIndexed(encoded []byte) ([]byte, *Header, error) { 429 | rest, _, index, err := decoder.DecodeInteger(encoded, 4) 430 | if err != nil { 431 | return nil, nil, err 432 | } 433 | if index == 0 { 434 | rest, name, err := decoder.readPrefixedLengthString(rest, 7) 435 | if err != nil { 436 | return nil, nil, err 437 | } 438 | 439 | rest, value, err := decoder.readPrefixedLengthString(rest, 7) 440 | if err != nil { 441 | return nil, nil, err 442 | } 443 | 444 | return rest, &Header{Name: name, Value: value}, nil 445 | 446 | } else { 447 | name, _, err := decoder.getIndexedNameValue(index) 448 | if err != nil { 449 | return nil, nil, err 450 | } 451 | 452 | rest, value, err := decoder.readPrefixedLengthString(rest, 7) 453 | if err != nil { 454 | return nil, nil, err 455 | } 456 | 457 | return rest, &Header{Name: name, Value: value}, nil 458 | } 459 | } 460 | 461 | func (decoder *Decoder) parseHeaderField(encoded []byte) ([]byte, *Header, error) { 462 | if encoded[0]&headerFieldIndexed == headerFieldIndexed { 463 | return decoder.parseHeaderFieldIndexed(encoded) 464 | } else if encoded[0]&headerFieldLiteralIncrementalIndex == headerFieldLiteralIncrementalIndex { 465 | return decoder.parseHeaderFieldIncrementalIndex(encoded) 466 | } else if encoded[0]&headerFieldDynamicSizeUpdate == headerFieldDynamicSizeUpdate { 467 | rest, err := decoder.parseDynamicSizeUpdate(encoded) 468 | if err != nil { 469 | return rest, nil, err 470 | } 471 | return rest, nil, nil 472 | } else if encoded[0]&headerFieldLiteralNeverIndexed == headerFieldLiteralNeverIndexed { 473 | rest, header, err := decoder.parseHeaderFieldNotIndexed(encoded) 474 | if err != nil { 475 | return rest, header, err 476 | } else { 477 | header.Sensitive = true 478 | return rest, header, err 479 | } 480 | } else if encoded[0]&headerFieldLiteralNotIndexed == headerFieldLiteralNotIndexed { 481 | return decoder.parseHeaderFieldNotIndexed(encoded) 482 | } else { 483 | panic(fmt.Errorf("unknown type: %02x", encoded[0])) 484 | } 485 | } 486 | -------------------------------------------------------------------------------- /hpack_test.go: -------------------------------------------------------------------------------- 1 | package hpack 2 | 3 | import ( 4 | "encoding/hex" 5 | "github.com/stretchr/testify/assert" 6 | "testing" 7 | ) 8 | 9 | func TestExampleC11ParseInteger(t *testing.T) { 10 | encoded := []byte{0x8A} 11 | decoder := NewDecoder(256) 12 | _, _, decoded, err := decoder.DecodeInteger(encoded, 5) 13 | if err != nil { 14 | t.Fatal(err) 15 | } 16 | assert.Equal(t, 10, decoded) 17 | } 18 | 19 | func TestExampleC11ParseWrite(t *testing.T) { 20 | assert.Equal(t, []byte{byte(10)}, encodeInteger(10, 5)) 21 | } 22 | 23 | func TestExampleC12ParseInteger(t *testing.T) { 24 | encoded := []byte{31, 154, 10} 25 | decoder := NewDecoder(256) 26 | _, _, decoded, err := decoder.DecodeInteger(encoded, 5) 27 | if err != nil { 28 | t.Fatal(err) 29 | } 30 | assert.Equal(t, 1337, decoded) 31 | } 32 | 33 | func TestExampleC12ParseWrite(t *testing.T) { 34 | assert.Equal(t, []byte{31, 154, 10}, encodeInteger(1337, 5)) 35 | } 36 | 37 | func TestExampleC13ParseInteger(t *testing.T) { 38 | encoded := []byte{42} 39 | decoder := NewDecoder(256) 40 | _, _, decoded, err := decoder.DecodeInteger(encoded, 8) 41 | if err != nil { 42 | t.Fatal(err) 43 | } 44 | assert.Equal(t, 42, decoded) 45 | } 46 | 47 | func TestExampleC13ParseWrite(t *testing.T) { 48 | assert.Equal(t, []byte{42}, encodeInteger(42, 8)) 49 | } 50 | 51 | func TestEncodeHeaderNeverIndexed(t *testing.T) { 52 | items := [][3]string{ 53 | {"100870617373776f726406736563726574", "password", "secret"}, 54 | } 55 | 56 | for _, item := range items { 57 | encoder := NewEncoder(256) 58 | encoded, err := encoder.EncodeIndexed(Header{Name: item[1], Value: item[2], Sensitive: true}, false) 59 | if err != nil { 60 | t.Fatal(err) 61 | } 62 | assert.Equal(t, item[0], hex.EncodeToString(encoded)) 63 | } 64 | } 65 | 66 | func TestParseHeaderNeverIndexed(t *testing.T) { 67 | items := [][3]string{ 68 | {"100870617373776f726406736563726574", "password", "secret"}, 69 | } 70 | 71 | for _, item := range items { 72 | encodedHex := []byte(item[0]) 73 | encoded := make([]byte, len(encodedHex)/2) 74 | _, err := hex.Decode(encoded, encodedHex) 75 | if err != nil { 76 | t.Fatal(err) 77 | } 78 | decoder := NewDecoder(256) 79 | _, header, err := decoder.parseHeaderField(encoded) 80 | if err != nil { 81 | t.Fatal(err) 82 | } 83 | assert.Equal(t, item[1], header.Name) 84 | assert.Equal(t, item[2], header.Value) 85 | assert.True(t, header.Sensitive) 86 | } 87 | } 88 | 89 | func TestParseHeaders(t *testing.T) { 90 | items := [][3]string{ 91 | {"400a637573746f6d2d6b65790d637573746f6d2d686561646572", "custom-key", "custom-header"}, 92 | {"040c2f73616d706c652f70617468", ":path", "/sample/path"}, 93 | {"100870617373776f726406736563726574", "password", "secret"}, 94 | {"82", ":method", "GET"}, 95 | } 96 | 97 | for _, item := range items { 98 | encodedHex := []byte(item[0]) 99 | encoded := make([]byte, len(encodedHex)/2) 100 | _, err := hex.Decode(encoded, encodedHex) 101 | if err != nil { 102 | t.Fatal(err) 103 | } 104 | decoder := NewDecoder(256) 105 | _, header, err := decoder.parseHeaderField(encoded) 106 | if err != nil { 107 | t.Fatal(err) 108 | } 109 | assert.Equal(t, item[1], header.Name) 110 | assert.Equal(t, item[2], header.Value) 111 | } 112 | } 113 | 114 | func testHeaderEncoding(t *testing.T, encodedHexValues []string, headers [][]Header, dynamicTable [][]Header, dynamicTableSize int, huffman bool, indexing bool) { 115 | encoder := NewEncoder(dynamicTableSize) 116 | for x, _ := range encodedHexValues { 117 | var encoded []byte 118 | if indexing { 119 | for _, header := range headers[x] { 120 | enc, err := encoder.EncodeIndexed(header, huffman) 121 | if err != nil { 122 | t.Fatal(err) 123 | } 124 | encoded = append(encoded, enc...) 125 | } 126 | } else { 127 | for _, header := range headers[x] { 128 | enc, err := encoder.EncodeNoDynamicIndexing(header, huffman) 129 | if err != nil { 130 | t.Fatal(err) 131 | } 132 | encoded = append(encoded, enc...) 133 | } 134 | } 135 | assert.Equal(t, encodedHexValues[x], hex.EncodeToString(encoded)) 136 | if dynamicTable != nil { 137 | assert.Equal(t, dynamicTable[x], encoder.dynamicTable) 138 | } 139 | } 140 | } 141 | 142 | func testHeaderParsing(t *testing.T, encodedHexValues []string, expected [][]Header, dynamicTable [][]Header, dynamicTableSize int) { 143 | decoder := NewDecoder(dynamicTableSize) 144 | for x, encodedHex := range encodedHexValues { 145 | encoded := make([]byte, len(encodedHex)/2) 146 | _, err := hex.Decode(encoded, []byte(encodedHex)) 147 | if err != nil { 148 | t.Fatal(err) 149 | } 150 | headers, err := decoder.Decode(encoded) 151 | if err != nil { 152 | t.Fatal(err) 153 | } 154 | assert.Equal(t, len(expected[x]), len(headers)) 155 | assert.Equal(t, expected[x], headers) 156 | if dynamicTable != nil { 157 | assert.Equal(t, dynamicTable[x], decoder.dynamicTable) 158 | } 159 | } 160 | } 161 | 162 | func TestEncodeWithNoIndexing(t *testing.T) { 163 | encodedHexValues := []string{ 164 | "040c2f73616d706c652f70617468", 165 | } 166 | headers := [][]Header{ 167 | { 168 | {":path", "/sample/path", false}, 169 | }, 170 | } 171 | 172 | testHeaderEncoding(t, encodedHexValues, headers, nil, 256, false, false) 173 | } 174 | 175 | func TestEncodeWithDynamicTableNoHuffman(t *testing.T) { 176 | encodedHexValues := []string{ 177 | "828684410f7777772e6578616d706c652e636f6d", 178 | "828684be58086e6f2d6361636865", 179 | "828785bf400a637573746f6d2d6b65790c637573746f6d2d76616c7565", 180 | } 181 | headers := [][]Header{ 182 | { 183 | {":method", "GET", false}, 184 | {":scheme", "http", false}, 185 | {":path", "/", false}, 186 | {":authority", "www.example.com", false}, 187 | }, 188 | { 189 | {":method", "GET", false}, 190 | {":scheme", "http", false}, 191 | {":path", "/", false}, 192 | {":authority", "www.example.com", false}, 193 | {"cache-control", "no-cache", false}, 194 | }, 195 | { 196 | {":method", "GET", false}, 197 | {":scheme", "https", false}, 198 | {":path", "/index.html", false}, 199 | {":authority", "www.example.com", false}, 200 | {"custom-key", "custom-value", false}, 201 | }, 202 | } 203 | 204 | testHeaderEncoding(t, encodedHexValues, headers, nil, 256, false, true) 205 | } 206 | 207 | func TestDecodeWithDynamicTableNoHuffman(t *testing.T) { 208 | encodedHexValues := []string{ 209 | "828684410f7777772e6578616d706c652e636f6d", 210 | "828684be58086e6f2d6361636865", 211 | "828785bf400a637573746f6d2d6b65790c637573746f6d2d76616c7565", 212 | } 213 | expected := [][]Header{ 214 | { 215 | {":method", "GET", false}, 216 | {":scheme", "http", false}, 217 | {":path", "/", false}, 218 | {":authority", "www.example.com", false}, 219 | }, 220 | { 221 | {":method", "GET", false}, 222 | {":scheme", "http", false}, 223 | {":path", "/", false}, 224 | {":authority", "www.example.com", false}, 225 | {"cache-control", "no-cache", false}, 226 | }, 227 | { 228 | {":method", "GET", false}, 229 | {":scheme", "https", false}, 230 | {":path", "/index.html", false}, 231 | {":authority", "www.example.com", false}, 232 | {"custom-key", "custom-value", false}, 233 | }, 234 | } 235 | 236 | testHeaderParsing(t, encodedHexValues, expected, nil, 256) 237 | } 238 | 239 | func TestEncodeWithDynamicTableHuffman(t *testing.T) { 240 | encodedHexValues := []string{ 241 | "828684418cf1e3c2e5f23a6ba0ab90f4ff", 242 | "828684be5886a8eb10649cbf", 243 | "828785bf408825a849e95ba97d7f8925a849e95bb8e8b4bf", 244 | } 245 | headers := [][]Header{ 246 | { 247 | {":method", "GET", false}, 248 | {":scheme", "http", false}, 249 | {":path", "/", false}, 250 | {":authority", "www.example.com", false}, 251 | }, 252 | { 253 | {":method", "GET", false}, 254 | {":scheme", "http", false}, 255 | {":path", "/", false}, 256 | {":authority", "www.example.com", false}, 257 | {"cache-control", "no-cache", false}, 258 | }, 259 | { 260 | {":method", "GET", false}, 261 | {":scheme", "https", false}, 262 | {":path", "/index.html", false}, 263 | {":authority", "www.example.com", false}, 264 | {"custom-key", "custom-value", false}, 265 | }, 266 | } 267 | 268 | testHeaderEncoding(t, encodedHexValues, headers, nil, 256, true, true) 269 | } 270 | 271 | func TestDecodeWithDynamicTableHuffman(t *testing.T) { 272 | encodedHexValues := []string{ 273 | "828684418cf1e3c2e5f23a6ba0ab90f4ff", 274 | "828684be5886a8eb10649cbf", 275 | "828785bf408825a849e95ba97d7f8925a849e95bb8e8b4bf", 276 | } 277 | expected := [][]Header{ 278 | { 279 | {":method", "GET", false}, 280 | {":scheme", "http", false}, 281 | {":path", "/", false}, 282 | {":authority", "www.example.com", false}, 283 | }, 284 | { 285 | {":method", "GET", false}, 286 | {":scheme", "http", false}, 287 | {":path", "/", false}, 288 | {":authority", "www.example.com", false}, 289 | {"cache-control", "no-cache", false}, 290 | }, 291 | { 292 | {":method", "GET", false}, 293 | {":scheme", "https", false}, 294 | {":path", "/index.html", false}, 295 | {":authority", "www.example.com", false}, 296 | {"custom-key", "custom-value", false}, 297 | }, 298 | } 299 | 300 | testHeaderParsing(t, encodedHexValues, expected, nil, 256) 301 | } 302 | 303 | func TestEncodeWithDynamicTableEvictionsHuffman(t *testing.T) { 304 | encodedHexValues := []string{ 305 | "488264025885aec3771a4b6196d07abe941054d444a8200595040b8166e082a62d1bff6e919d29ad171863c78f0b97c8e9ae82ae43d3", 306 | "4883640effc1c0bf", 307 | "88c16196d07abe941054d444a8200595040b8166e084a62d1bffc05a839bd9ab77ad94e7821dd7f2e6c7b335dfdfcd5b3960d5af27087f3672c1ab270fb5291f9587316065c003ed4ee5b1063d5007", 308 | } 309 | headers := [][]Header{ 310 | { 311 | {":status", "302", false}, 312 | {"cache-control", "private", false}, 313 | {"date", "Mon, 21 Oct 2013 20:13:21 GMT", false}, 314 | {"location", "https://www.example.com", false}, 315 | }, 316 | { 317 | {":status", "307", false}, 318 | {"cache-control", "private", false}, 319 | {"date", "Mon, 21 Oct 2013 20:13:21 GMT", false}, 320 | {"location", "https://www.example.com", false}, 321 | }, 322 | { 323 | {":status", "200", false}, 324 | {"cache-control", "private", false}, 325 | {"date", "Mon, 21 Oct 2013 20:13:22 GMT", false}, 326 | {"location", "https://www.example.com", false}, 327 | {"content-encoding", "gzip", false}, 328 | {"set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", false}, 329 | }, 330 | } 331 | dynamicTable := [][]Header{ 332 | { 333 | {"location", "https://www.example.com", false}, 334 | {"date", "Mon, 21 Oct 2013 20:13:21 GMT", false}, 335 | {"cache-control", "private", false}, 336 | {":status", "302", false}, 337 | }, 338 | { 339 | {":status", "307", false}, 340 | {"location", "https://www.example.com", false}, 341 | {"date", "Mon, 21 Oct 2013 20:13:21 GMT", false}, 342 | {"cache-control", "private", false}, 343 | }, 344 | { 345 | {"set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", false}, 346 | {"content-encoding", "gzip", false}, 347 | {"date", "Mon, 21 Oct 2013 20:13:22 GMT", false}, 348 | }, 349 | } 350 | 351 | testHeaderEncoding(t, encodedHexValues, headers, dynamicTable, 256, true, true) 352 | } 353 | 354 | func TestDecodeWithDynamicTableEvictionsHuffman(t *testing.T) { 355 | encodedHexValues := []string{ 356 | "488264025885aec3771a4b6196d07abe941054d444a8200595040b8166e082a62d1bff6e919d29ad171863c78f0b97c8e9ae82ae43d3", 357 | "4883640effc1c0bf", 358 | "88c16196d07abe941054d444a8200595040b8166e084a62d1bffc05a839bd9ab77ad94e7821dd7f2e6c7b335dfdfcd5b3960d5af27087f3672c1ab270fb5291f9587316065c003ed4ee5b1063d5007", 359 | } 360 | expected := [][]Header{ 361 | { 362 | {":status", "302", false}, 363 | {"cache-control", "private", false}, 364 | {"date", "Mon, 21 Oct 2013 20:13:21 GMT", false}, 365 | {"location", "https://www.example.com", false}, 366 | }, 367 | { 368 | {":status", "307", false}, 369 | {"cache-control", "private", false}, 370 | {"date", "Mon, 21 Oct 2013 20:13:21 GMT", false}, 371 | {"location", "https://www.example.com", false}, 372 | }, 373 | { 374 | {":status", "200", false}, 375 | {"cache-control", "private", false}, 376 | {"date", "Mon, 21 Oct 2013 20:13:22 GMT", false}, 377 | {"location", "https://www.example.com", false}, 378 | {"content-encoding", "gzip", false}, 379 | {"set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", false}, 380 | }, 381 | } 382 | dynamicTable := [][]Header{ 383 | { 384 | {"location", "https://www.example.com", false}, 385 | {"date", "Mon, 21 Oct 2013 20:13:21 GMT", false}, 386 | {"cache-control", "private", false}, 387 | {":status", "302", false}, 388 | }, 389 | { 390 | {":status", "307", false}, 391 | {"location", "https://www.example.com", false}, 392 | {"date", "Mon, 21 Oct 2013 20:13:21 GMT", false}, 393 | {"cache-control", "private", false}, 394 | }, 395 | { 396 | {"set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", false}, 397 | {"content-encoding", "gzip", false}, 398 | {"date", "Mon, 21 Oct 2013 20:13:22 GMT", false}, 399 | }, 400 | } 401 | 402 | testHeaderParsing(t, encodedHexValues, expected, dynamicTable, 256) 403 | } 404 | 405 | func TestDecodeWithDynamicTableEvictionsNoHuffman(t *testing.T) { 406 | encodedHexValues := []string{ 407 | "4803333032580770726976617465611d4d6f6e2c203231204f637420323031332032303a31333a323120474d546e1768747470733a2f2f7777772e6578616d706c652e636f6d", 408 | "4803333037c1c0bf", 409 | "88c1611d4d6f6e2c203231204f637420323031332032303a31333a323220474d54c05a04677a69707738666f6f3d4153444a4b48514b425a584f5157454f50495541585157454f49553b206d61782d6167653d333630303b2076657273696f6e3d31", 410 | } 411 | expected := [][]Header{ 412 | { 413 | {":status", "302", false}, 414 | {"cache-control", "private", false}, 415 | {"date", "Mon, 21 Oct 2013 20:13:21 GMT", false}, 416 | {"location", "https://www.example.com", false}, 417 | }, 418 | { 419 | {":status", "307", false}, 420 | {"cache-control", "private", false}, 421 | {"date", "Mon, 21 Oct 2013 20:13:21 GMT", false}, 422 | {"location", "https://www.example.com", false}, 423 | }, 424 | { 425 | {":status", "200", false}, 426 | {"cache-control", "private", false}, 427 | {"date", "Mon, 21 Oct 2013 20:13:22 GMT", false}, 428 | {"location", "https://www.example.com", false}, 429 | {"content-encoding", "gzip", false}, 430 | {"set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", false}, 431 | }, 432 | } 433 | dynamicTable := [][]Header{ 434 | { 435 | {"location", "https://www.example.com", false}, 436 | {"date", "Mon, 21 Oct 2013 20:13:21 GMT", false}, 437 | {"cache-control", "private", false}, 438 | {":status", "302", false}, 439 | }, 440 | { 441 | {":status", "307", false}, 442 | {"location", "https://www.example.com", false}, 443 | {"date", "Mon, 21 Oct 2013 20:13:21 GMT", false}, 444 | {"cache-control", "private", false}, 445 | }, 446 | { 447 | {"set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", false}, 448 | {"content-encoding", "gzip", false}, 449 | {"date", "Mon, 21 Oct 2013 20:13:22 GMT", false}, 450 | }, 451 | } 452 | 453 | testHeaderParsing(t, encodedHexValues, expected, dynamicTable, 256) 454 | } 455 | 456 | func TestDynamicTableResizingEncoding(t *testing.T) { 457 | encoder := NewEncoder(64 + 4) 458 | encoder.addNewDynamicEntry("a", "b") 459 | encoder.addNewDynamicEntry("b", "c") 460 | assert.Equal(t, []Header{{"b", "c", false}, {"a", "b", false}}, encoder.dynamicTable) 461 | encoder.SetDynamicTableMaxSize(63) 462 | encoded, err := encoder.Encode([]Header{{"b", "c", false}}) 463 | if err != nil { 464 | t.Fatal(err) 465 | } 466 | assert.Equal(t, []byte{0x3f, 0x20}, encoded[:2]) 467 | _, _, decoded, err := decodeInteger(encoded, 5, DefaultMaxIntegerValue, DefaultMaxIntegerEncodedLength) 468 | if err != nil { 469 | t.Fatal(err) 470 | } 471 | assert.Equal(t, 63, decoded) 472 | assert.Equal(t, byte(0xbe), encoded[2]) 473 | assert.Equal(t, []Header{{"b", "c", false}}, encoder.dynamicTable) 474 | } 475 | 476 | func TestDynamicTableResizing(t *testing.T) { 477 | decoder := NewDecoder(64 + 4) 478 | decoder.addNewDynamicEntry("a", "b") 479 | decoder.addNewDynamicEntry("b", "c") 480 | assert.Equal(t, []Header{{"b", "c", false}, {"a", "b", false}}, decoder.dynamicTable) 481 | _, err := decoder.Decode([]byte{63, 3}) 482 | if err != nil { 483 | t.Fatal(err) 484 | } 485 | assert.Equal(t, []Header{{"b", "c", false}}, decoder.dynamicTable) 486 | } 487 | 488 | func TestDynamicTableEntryBiggerThanTable(t *testing.T) { 489 | decoder := NewDecoder(32 + 12) 490 | decoder.addNewDynamicEntry("a", "b") 491 | decoder.addNewDynamicEntry("aafadslkjasfdkljasfkdjlajklsfdfajklsfdjkladsfjklasjklfdf", "adfsljasfdkjlsdalkfajklsdfjkalsfdjalsdfjalksdfjaldskfjlsjk") 492 | assert.Equal(t, []Header{}, decoder.dynamicTable) 493 | } 494 | -------------------------------------------------------------------------------- /huffman_tables.go: -------------------------------------------------------------------------------- 1 | package hpack 2 | 3 | type lookupTableEntry struct { 4 | symbol uint32 5 | bits uint8 6 | nextTable []*lookupTableEntry 7 | } 8 | 9 | var lookupTable = []*lookupTableEntry{ 10 | {48, 5, nil}, 11 | {48, 5, nil}, 12 | {48, 5, nil}, 13 | {48, 5, nil}, 14 | {48, 5, nil}, 15 | {48, 5, nil}, 16 | {48, 5, nil}, 17 | {48, 5, nil}, 18 | {49, 5, nil}, 19 | {49, 5, nil}, 20 | {49, 5, nil}, 21 | {49, 5, nil}, 22 | {49, 5, nil}, 23 | {49, 5, nil}, 24 | {49, 5, nil}, 25 | {49, 5, nil}, 26 | {50, 5, nil}, 27 | {50, 5, nil}, 28 | {50, 5, nil}, 29 | {50, 5, nil}, 30 | {50, 5, nil}, 31 | {50, 5, nil}, 32 | {50, 5, nil}, 33 | {50, 5, nil}, 34 | {97, 5, nil}, 35 | {97, 5, nil}, 36 | {97, 5, nil}, 37 | {97, 5, nil}, 38 | {97, 5, nil}, 39 | {97, 5, nil}, 40 | {97, 5, nil}, 41 | {97, 5, nil}, 42 | {99, 5, nil}, 43 | {99, 5, nil}, 44 | {99, 5, nil}, 45 | {99, 5, nil}, 46 | {99, 5, nil}, 47 | {99, 5, nil}, 48 | {99, 5, nil}, 49 | {99, 5, nil}, 50 | {101, 5, nil}, 51 | {101, 5, nil}, 52 | {101, 5, nil}, 53 | {101, 5, nil}, 54 | {101, 5, nil}, 55 | {101, 5, nil}, 56 | {101, 5, nil}, 57 | {101, 5, nil}, 58 | {105, 5, nil}, 59 | {105, 5, nil}, 60 | {105, 5, nil}, 61 | {105, 5, nil}, 62 | {105, 5, nil}, 63 | {105, 5, nil}, 64 | {105, 5, nil}, 65 | {105, 5, nil}, 66 | {111, 5, nil}, 67 | {111, 5, nil}, 68 | {111, 5, nil}, 69 | {111, 5, nil}, 70 | {111, 5, nil}, 71 | {111, 5, nil}, 72 | {111, 5, nil}, 73 | {111, 5, nil}, 74 | {115, 5, nil}, 75 | {115, 5, nil}, 76 | {115, 5, nil}, 77 | {115, 5, nil}, 78 | {115, 5, nil}, 79 | {115, 5, nil}, 80 | {115, 5, nil}, 81 | {115, 5, nil}, 82 | {116, 5, nil}, 83 | {116, 5, nil}, 84 | {116, 5, nil}, 85 | {116, 5, nil}, 86 | {116, 5, nil}, 87 | {116, 5, nil}, 88 | {116, 5, nil}, 89 | {116, 5, nil}, 90 | {32, 6, nil}, 91 | {32, 6, nil}, 92 | {32, 6, nil}, 93 | {32, 6, nil}, 94 | {37, 6, nil}, 95 | {37, 6, nil}, 96 | {37, 6, nil}, 97 | {37, 6, nil}, 98 | {45, 6, nil}, 99 | {45, 6, nil}, 100 | {45, 6, nil}, 101 | {45, 6, nil}, 102 | {46, 6, nil}, 103 | {46, 6, nil}, 104 | {46, 6, nil}, 105 | {46, 6, nil}, 106 | {47, 6, nil}, 107 | {47, 6, nil}, 108 | {47, 6, nil}, 109 | {47, 6, nil}, 110 | {51, 6, nil}, 111 | {51, 6, nil}, 112 | {51, 6, nil}, 113 | {51, 6, nil}, 114 | {52, 6, nil}, 115 | {52, 6, nil}, 116 | {52, 6, nil}, 117 | {52, 6, nil}, 118 | {53, 6, nil}, 119 | {53, 6, nil}, 120 | {53, 6, nil}, 121 | {53, 6, nil}, 122 | {54, 6, nil}, 123 | {54, 6, nil}, 124 | {54, 6, nil}, 125 | {54, 6, nil}, 126 | {55, 6, nil}, 127 | {55, 6, nil}, 128 | {55, 6, nil}, 129 | {55, 6, nil}, 130 | {56, 6, nil}, 131 | {56, 6, nil}, 132 | {56, 6, nil}, 133 | {56, 6, nil}, 134 | {57, 6, nil}, 135 | {57, 6, nil}, 136 | {57, 6, nil}, 137 | {57, 6, nil}, 138 | {61, 6, nil}, 139 | {61, 6, nil}, 140 | {61, 6, nil}, 141 | {61, 6, nil}, 142 | {65, 6, nil}, 143 | {65, 6, nil}, 144 | {65, 6, nil}, 145 | {65, 6, nil}, 146 | {95, 6, nil}, 147 | {95, 6, nil}, 148 | {95, 6, nil}, 149 | {95, 6, nil}, 150 | {98, 6, nil}, 151 | {98, 6, nil}, 152 | {98, 6, nil}, 153 | {98, 6, nil}, 154 | {100, 6, nil}, 155 | {100, 6, nil}, 156 | {100, 6, nil}, 157 | {100, 6, nil}, 158 | {102, 6, nil}, 159 | {102, 6, nil}, 160 | {102, 6, nil}, 161 | {102, 6, nil}, 162 | {103, 6, nil}, 163 | {103, 6, nil}, 164 | {103, 6, nil}, 165 | {103, 6, nil}, 166 | {104, 6, nil}, 167 | {104, 6, nil}, 168 | {104, 6, nil}, 169 | {104, 6, nil}, 170 | {108, 6, nil}, 171 | {108, 6, nil}, 172 | {108, 6, nil}, 173 | {108, 6, nil}, 174 | {109, 6, nil}, 175 | {109, 6, nil}, 176 | {109, 6, nil}, 177 | {109, 6, nil}, 178 | {110, 6, nil}, 179 | {110, 6, nil}, 180 | {110, 6, nil}, 181 | {110, 6, nil}, 182 | {112, 6, nil}, 183 | {112, 6, nil}, 184 | {112, 6, nil}, 185 | {112, 6, nil}, 186 | {114, 6, nil}, 187 | {114, 6, nil}, 188 | {114, 6, nil}, 189 | {114, 6, nil}, 190 | {117, 6, nil}, 191 | {117, 6, nil}, 192 | {117, 6, nil}, 193 | {117, 6, nil}, 194 | {58, 7, nil}, 195 | {58, 7, nil}, 196 | {66, 7, nil}, 197 | {66, 7, nil}, 198 | {67, 7, nil}, 199 | {67, 7, nil}, 200 | {68, 7, nil}, 201 | {68, 7, nil}, 202 | {69, 7, nil}, 203 | {69, 7, nil}, 204 | {70, 7, nil}, 205 | {70, 7, nil}, 206 | {71, 7, nil}, 207 | {71, 7, nil}, 208 | {72, 7, nil}, 209 | {72, 7, nil}, 210 | {73, 7, nil}, 211 | {73, 7, nil}, 212 | {74, 7, nil}, 213 | {74, 7, nil}, 214 | {75, 7, nil}, 215 | {75, 7, nil}, 216 | {76, 7, nil}, 217 | {76, 7, nil}, 218 | {77, 7, nil}, 219 | {77, 7, nil}, 220 | {78, 7, nil}, 221 | {78, 7, nil}, 222 | {79, 7, nil}, 223 | {79, 7, nil}, 224 | {80, 7, nil}, 225 | {80, 7, nil}, 226 | {81, 7, nil}, 227 | {81, 7, nil}, 228 | {82, 7, nil}, 229 | {82, 7, nil}, 230 | {83, 7, nil}, 231 | {83, 7, nil}, 232 | {84, 7, nil}, 233 | {84, 7, nil}, 234 | {85, 7, nil}, 235 | {85, 7, nil}, 236 | {86, 7, nil}, 237 | {86, 7, nil}, 238 | {87, 7, nil}, 239 | {87, 7, nil}, 240 | {89, 7, nil}, 241 | {89, 7, nil}, 242 | {106, 7, nil}, 243 | {106, 7, nil}, 244 | {107, 7, nil}, 245 | {107, 7, nil}, 246 | {113, 7, nil}, 247 | {113, 7, nil}, 248 | {118, 7, nil}, 249 | {118, 7, nil}, 250 | {119, 7, nil}, 251 | {119, 7, nil}, 252 | {120, 7, nil}, 253 | {120, 7, nil}, 254 | {121, 7, nil}, 255 | {121, 7, nil}, 256 | {122, 7, nil}, 257 | {122, 7, nil}, 258 | {38, 8, nil}, 259 | {42, 8, nil}, 260 | {44, 8, nil}, 261 | {59, 8, nil}, 262 | {88, 8, nil}, 263 | {90, 8, nil}, 264 | {0, 0, 265 | []*lookupTableEntry{ 266 | {33, 10, nil}, 267 | {33, 10, nil}, 268 | {33, 10, nil}, 269 | {33, 10, nil}, 270 | {33, 10, nil}, 271 | {33, 10, nil}, 272 | {33, 10, nil}, 273 | {33, 10, nil}, 274 | {33, 10, nil}, 275 | {33, 10, nil}, 276 | {33, 10, nil}, 277 | {33, 10, nil}, 278 | {33, 10, nil}, 279 | {33, 10, nil}, 280 | {33, 10, nil}, 281 | {33, 10, nil}, 282 | {33, 10, nil}, 283 | {33, 10, nil}, 284 | {33, 10, nil}, 285 | {33, 10, nil}, 286 | {33, 10, nil}, 287 | {33, 10, nil}, 288 | {33, 10, nil}, 289 | {33, 10, nil}, 290 | {33, 10, nil}, 291 | {33, 10, nil}, 292 | {33, 10, nil}, 293 | {33, 10, nil}, 294 | {33, 10, nil}, 295 | {33, 10, nil}, 296 | {33, 10, nil}, 297 | {33, 10, nil}, 298 | {33, 10, nil}, 299 | {33, 10, nil}, 300 | {33, 10, nil}, 301 | {33, 10, nil}, 302 | {33, 10, nil}, 303 | {33, 10, nil}, 304 | {33, 10, nil}, 305 | {33, 10, nil}, 306 | {33, 10, nil}, 307 | {33, 10, nil}, 308 | {33, 10, nil}, 309 | {33, 10, nil}, 310 | {33, 10, nil}, 311 | {33, 10, nil}, 312 | {33, 10, nil}, 313 | {33, 10, nil}, 314 | {33, 10, nil}, 315 | {33, 10, nil}, 316 | {33, 10, nil}, 317 | {33, 10, nil}, 318 | {33, 10, nil}, 319 | {33, 10, nil}, 320 | {33, 10, nil}, 321 | {33, 10, nil}, 322 | {33, 10, nil}, 323 | {33, 10, nil}, 324 | {33, 10, nil}, 325 | {33, 10, nil}, 326 | {33, 10, nil}, 327 | {33, 10, nil}, 328 | {33, 10, nil}, 329 | {33, 10, nil}, 330 | {34, 10, nil}, 331 | {34, 10, nil}, 332 | {34, 10, nil}, 333 | {34, 10, nil}, 334 | {34, 10, nil}, 335 | {34, 10, nil}, 336 | {34, 10, nil}, 337 | {34, 10, nil}, 338 | {34, 10, nil}, 339 | {34, 10, nil}, 340 | {34, 10, nil}, 341 | {34, 10, nil}, 342 | {34, 10, nil}, 343 | {34, 10, nil}, 344 | {34, 10, nil}, 345 | {34, 10, nil}, 346 | {34, 10, nil}, 347 | {34, 10, nil}, 348 | {34, 10, nil}, 349 | {34, 10, nil}, 350 | {34, 10, nil}, 351 | {34, 10, nil}, 352 | {34, 10, nil}, 353 | {34, 10, nil}, 354 | {34, 10, nil}, 355 | {34, 10, nil}, 356 | {34, 10, nil}, 357 | {34, 10, nil}, 358 | {34, 10, nil}, 359 | {34, 10, nil}, 360 | {34, 10, nil}, 361 | {34, 10, nil}, 362 | {34, 10, nil}, 363 | {34, 10, nil}, 364 | {34, 10, nil}, 365 | {34, 10, nil}, 366 | {34, 10, nil}, 367 | {34, 10, nil}, 368 | {34, 10, nil}, 369 | {34, 10, nil}, 370 | {34, 10, nil}, 371 | {34, 10, nil}, 372 | {34, 10, nil}, 373 | {34, 10, nil}, 374 | {34, 10, nil}, 375 | {34, 10, nil}, 376 | {34, 10, nil}, 377 | {34, 10, nil}, 378 | {34, 10, nil}, 379 | {34, 10, nil}, 380 | {34, 10, nil}, 381 | {34, 10, nil}, 382 | {34, 10, nil}, 383 | {34, 10, nil}, 384 | {34, 10, nil}, 385 | {34, 10, nil}, 386 | {34, 10, nil}, 387 | {34, 10, nil}, 388 | {34, 10, nil}, 389 | {34, 10, nil}, 390 | {34, 10, nil}, 391 | {34, 10, nil}, 392 | {34, 10, nil}, 393 | {34, 10, nil}, 394 | {40, 10, nil}, 395 | {40, 10, nil}, 396 | {40, 10, nil}, 397 | {40, 10, nil}, 398 | {40, 10, nil}, 399 | {40, 10, nil}, 400 | {40, 10, nil}, 401 | {40, 10, nil}, 402 | {40, 10, nil}, 403 | {40, 10, nil}, 404 | {40, 10, nil}, 405 | {40, 10, nil}, 406 | {40, 10, nil}, 407 | {40, 10, nil}, 408 | {40, 10, nil}, 409 | {40, 10, nil}, 410 | {40, 10, nil}, 411 | {40, 10, nil}, 412 | {40, 10, nil}, 413 | {40, 10, nil}, 414 | {40, 10, nil}, 415 | {40, 10, nil}, 416 | {40, 10, nil}, 417 | {40, 10, nil}, 418 | {40, 10, nil}, 419 | {40, 10, nil}, 420 | {40, 10, nil}, 421 | {40, 10, nil}, 422 | {40, 10, nil}, 423 | {40, 10, nil}, 424 | {40, 10, nil}, 425 | {40, 10, nil}, 426 | {40, 10, nil}, 427 | {40, 10, nil}, 428 | {40, 10, nil}, 429 | {40, 10, nil}, 430 | {40, 10, nil}, 431 | {40, 10, nil}, 432 | {40, 10, nil}, 433 | {40, 10, nil}, 434 | {40, 10, nil}, 435 | {40, 10, nil}, 436 | {40, 10, nil}, 437 | {40, 10, nil}, 438 | {40, 10, nil}, 439 | {40, 10, nil}, 440 | {40, 10, nil}, 441 | {40, 10, nil}, 442 | {40, 10, nil}, 443 | {40, 10, nil}, 444 | {40, 10, nil}, 445 | {40, 10, nil}, 446 | {40, 10, nil}, 447 | {40, 10, nil}, 448 | {40, 10, nil}, 449 | {40, 10, nil}, 450 | {40, 10, nil}, 451 | {40, 10, nil}, 452 | {40, 10, nil}, 453 | {40, 10, nil}, 454 | {40, 10, nil}, 455 | {40, 10, nil}, 456 | {40, 10, nil}, 457 | {40, 10, nil}, 458 | {41, 10, nil}, 459 | {41, 10, nil}, 460 | {41, 10, nil}, 461 | {41, 10, nil}, 462 | {41, 10, nil}, 463 | {41, 10, nil}, 464 | {41, 10, nil}, 465 | {41, 10, nil}, 466 | {41, 10, nil}, 467 | {41, 10, nil}, 468 | {41, 10, nil}, 469 | {41, 10, nil}, 470 | {41, 10, nil}, 471 | {41, 10, nil}, 472 | {41, 10, nil}, 473 | {41, 10, nil}, 474 | {41, 10, nil}, 475 | {41, 10, nil}, 476 | {41, 10, nil}, 477 | {41, 10, nil}, 478 | {41, 10, nil}, 479 | {41, 10, nil}, 480 | {41, 10, nil}, 481 | {41, 10, nil}, 482 | {41, 10, nil}, 483 | {41, 10, nil}, 484 | {41, 10, nil}, 485 | {41, 10, nil}, 486 | {41, 10, nil}, 487 | {41, 10, nil}, 488 | {41, 10, nil}, 489 | {41, 10, nil}, 490 | {41, 10, nil}, 491 | {41, 10, nil}, 492 | {41, 10, nil}, 493 | {41, 10, nil}, 494 | {41, 10, nil}, 495 | {41, 10, nil}, 496 | {41, 10, nil}, 497 | {41, 10, nil}, 498 | {41, 10, nil}, 499 | {41, 10, nil}, 500 | {41, 10, nil}, 501 | {41, 10, nil}, 502 | {41, 10, nil}, 503 | {41, 10, nil}, 504 | {41, 10, nil}, 505 | {41, 10, nil}, 506 | {41, 10, nil}, 507 | {41, 10, nil}, 508 | {41, 10, nil}, 509 | {41, 10, nil}, 510 | {41, 10, nil}, 511 | {41, 10, nil}, 512 | {41, 10, nil}, 513 | {41, 10, nil}, 514 | {41, 10, nil}, 515 | {41, 10, nil}, 516 | {41, 10, nil}, 517 | {41, 10, nil}, 518 | {41, 10, nil}, 519 | {41, 10, nil}, 520 | {41, 10, nil}, 521 | {41, 10, nil}, 522 | }, 523 | }, 524 | {0, 0, 525 | []*lookupTableEntry{ 526 | {63, 10, nil}, 527 | {63, 10, nil}, 528 | {63, 10, nil}, 529 | {63, 10, nil}, 530 | {63, 10, nil}, 531 | {63, 10, nil}, 532 | {63, 10, nil}, 533 | {63, 10, nil}, 534 | {63, 10, nil}, 535 | {63, 10, nil}, 536 | {63, 10, nil}, 537 | {63, 10, nil}, 538 | {63, 10, nil}, 539 | {63, 10, nil}, 540 | {63, 10, nil}, 541 | {63, 10, nil}, 542 | {63, 10, nil}, 543 | {63, 10, nil}, 544 | {63, 10, nil}, 545 | {63, 10, nil}, 546 | {63, 10, nil}, 547 | {63, 10, nil}, 548 | {63, 10, nil}, 549 | {63, 10, nil}, 550 | {63, 10, nil}, 551 | {63, 10, nil}, 552 | {63, 10, nil}, 553 | {63, 10, nil}, 554 | {63, 10, nil}, 555 | {63, 10, nil}, 556 | {63, 10, nil}, 557 | {63, 10, nil}, 558 | {63, 10, nil}, 559 | {63, 10, nil}, 560 | {63, 10, nil}, 561 | {63, 10, nil}, 562 | {63, 10, nil}, 563 | {63, 10, nil}, 564 | {63, 10, nil}, 565 | {63, 10, nil}, 566 | {63, 10, nil}, 567 | {63, 10, nil}, 568 | {63, 10, nil}, 569 | {63, 10, nil}, 570 | {63, 10, nil}, 571 | {63, 10, nil}, 572 | {63, 10, nil}, 573 | {63, 10, nil}, 574 | {63, 10, nil}, 575 | {63, 10, nil}, 576 | {63, 10, nil}, 577 | {63, 10, nil}, 578 | {63, 10, nil}, 579 | {63, 10, nil}, 580 | {63, 10, nil}, 581 | {63, 10, nil}, 582 | {63, 10, nil}, 583 | {63, 10, nil}, 584 | {63, 10, nil}, 585 | {63, 10, nil}, 586 | {63, 10, nil}, 587 | {63, 10, nil}, 588 | {63, 10, nil}, 589 | {63, 10, nil}, 590 | {39, 11, nil}, 591 | {39, 11, nil}, 592 | {39, 11, nil}, 593 | {39, 11, nil}, 594 | {39, 11, nil}, 595 | {39, 11, nil}, 596 | {39, 11, nil}, 597 | {39, 11, nil}, 598 | {39, 11, nil}, 599 | {39, 11, nil}, 600 | {39, 11, nil}, 601 | {39, 11, nil}, 602 | {39, 11, nil}, 603 | {39, 11, nil}, 604 | {39, 11, nil}, 605 | {39, 11, nil}, 606 | {39, 11, nil}, 607 | {39, 11, nil}, 608 | {39, 11, nil}, 609 | {39, 11, nil}, 610 | {39, 11, nil}, 611 | {39, 11, nil}, 612 | {39, 11, nil}, 613 | {39, 11, nil}, 614 | {39, 11, nil}, 615 | {39, 11, nil}, 616 | {39, 11, nil}, 617 | {39, 11, nil}, 618 | {39, 11, nil}, 619 | {39, 11, nil}, 620 | {39, 11, nil}, 621 | {39, 11, nil}, 622 | {43, 11, nil}, 623 | {43, 11, nil}, 624 | {43, 11, nil}, 625 | {43, 11, nil}, 626 | {43, 11, nil}, 627 | {43, 11, nil}, 628 | {43, 11, nil}, 629 | {43, 11, nil}, 630 | {43, 11, nil}, 631 | {43, 11, nil}, 632 | {43, 11, nil}, 633 | {43, 11, nil}, 634 | {43, 11, nil}, 635 | {43, 11, nil}, 636 | {43, 11, nil}, 637 | {43, 11, nil}, 638 | {43, 11, nil}, 639 | {43, 11, nil}, 640 | {43, 11, nil}, 641 | {43, 11, nil}, 642 | {43, 11, nil}, 643 | {43, 11, nil}, 644 | {43, 11, nil}, 645 | {43, 11, nil}, 646 | {43, 11, nil}, 647 | {43, 11, nil}, 648 | {43, 11, nil}, 649 | {43, 11, nil}, 650 | {43, 11, nil}, 651 | {43, 11, nil}, 652 | {43, 11, nil}, 653 | {43, 11, nil}, 654 | {124, 11, nil}, 655 | {124, 11, nil}, 656 | {124, 11, nil}, 657 | {124, 11, nil}, 658 | {124, 11, nil}, 659 | {124, 11, nil}, 660 | {124, 11, nil}, 661 | {124, 11, nil}, 662 | {124, 11, nil}, 663 | {124, 11, nil}, 664 | {124, 11, nil}, 665 | {124, 11, nil}, 666 | {124, 11, nil}, 667 | {124, 11, nil}, 668 | {124, 11, nil}, 669 | {124, 11, nil}, 670 | {124, 11, nil}, 671 | {124, 11, nil}, 672 | {124, 11, nil}, 673 | {124, 11, nil}, 674 | {124, 11, nil}, 675 | {124, 11, nil}, 676 | {124, 11, nil}, 677 | {124, 11, nil}, 678 | {124, 11, nil}, 679 | {124, 11, nil}, 680 | {124, 11, nil}, 681 | {124, 11, nil}, 682 | {124, 11, nil}, 683 | {124, 11, nil}, 684 | {124, 11, nil}, 685 | {124, 11, nil}, 686 | {35, 12, nil}, 687 | {35, 12, nil}, 688 | {35, 12, nil}, 689 | {35, 12, nil}, 690 | {35, 12, nil}, 691 | {35, 12, nil}, 692 | {35, 12, nil}, 693 | {35, 12, nil}, 694 | {35, 12, nil}, 695 | {35, 12, nil}, 696 | {35, 12, nil}, 697 | {35, 12, nil}, 698 | {35, 12, nil}, 699 | {35, 12, nil}, 700 | {35, 12, nil}, 701 | {35, 12, nil}, 702 | {62, 12, nil}, 703 | {62, 12, nil}, 704 | {62, 12, nil}, 705 | {62, 12, nil}, 706 | {62, 12, nil}, 707 | {62, 12, nil}, 708 | {62, 12, nil}, 709 | {62, 12, nil}, 710 | {62, 12, nil}, 711 | {62, 12, nil}, 712 | {62, 12, nil}, 713 | {62, 12, nil}, 714 | {62, 12, nil}, 715 | {62, 12, nil}, 716 | {62, 12, nil}, 717 | {62, 12, nil}, 718 | {0, 13, nil}, 719 | {0, 13, nil}, 720 | {0, 13, nil}, 721 | {0, 13, nil}, 722 | {0, 13, nil}, 723 | {0, 13, nil}, 724 | {0, 13, nil}, 725 | {0, 13, nil}, 726 | {36, 13, nil}, 727 | {36, 13, nil}, 728 | {36, 13, nil}, 729 | {36, 13, nil}, 730 | {36, 13, nil}, 731 | {36, 13, nil}, 732 | {36, 13, nil}, 733 | {36, 13, nil}, 734 | {64, 13, nil}, 735 | {64, 13, nil}, 736 | {64, 13, nil}, 737 | {64, 13, nil}, 738 | {64, 13, nil}, 739 | {64, 13, nil}, 740 | {64, 13, nil}, 741 | {64, 13, nil}, 742 | {91, 13, nil}, 743 | {91, 13, nil}, 744 | {91, 13, nil}, 745 | {91, 13, nil}, 746 | {91, 13, nil}, 747 | {91, 13, nil}, 748 | {91, 13, nil}, 749 | {91, 13, nil}, 750 | {93, 13, nil}, 751 | {93, 13, nil}, 752 | {93, 13, nil}, 753 | {93, 13, nil}, 754 | {93, 13, nil}, 755 | {93, 13, nil}, 756 | {93, 13, nil}, 757 | {93, 13, nil}, 758 | {126, 13, nil}, 759 | {126, 13, nil}, 760 | {126, 13, nil}, 761 | {126, 13, nil}, 762 | {126, 13, nil}, 763 | {126, 13, nil}, 764 | {126, 13, nil}, 765 | {126, 13, nil}, 766 | {94, 14, nil}, 767 | {94, 14, nil}, 768 | {94, 14, nil}, 769 | {94, 14, nil}, 770 | {125, 14, nil}, 771 | {125, 14, nil}, 772 | {125, 14, nil}, 773 | {125, 14, nil}, 774 | {60, 15, nil}, 775 | {60, 15, nil}, 776 | {96, 15, nil}, 777 | {96, 15, nil}, 778 | {123, 15, nil}, 779 | {123, 15, nil}, 780 | {0, 0, 781 | []*lookupTableEntry{ 782 | {92, 19, nil}, 783 | {92, 19, nil}, 784 | {92, 19, nil}, 785 | {92, 19, nil}, 786 | {92, 19, nil}, 787 | {92, 19, nil}, 788 | {92, 19, nil}, 789 | {92, 19, nil}, 790 | {92, 19, nil}, 791 | {92, 19, nil}, 792 | {92, 19, nil}, 793 | {92, 19, nil}, 794 | {92, 19, nil}, 795 | {92, 19, nil}, 796 | {92, 19, nil}, 797 | {92, 19, nil}, 798 | {92, 19, nil}, 799 | {92, 19, nil}, 800 | {92, 19, nil}, 801 | {92, 19, nil}, 802 | {92, 19, nil}, 803 | {92, 19, nil}, 804 | {92, 19, nil}, 805 | {92, 19, nil}, 806 | {92, 19, nil}, 807 | {92, 19, nil}, 808 | {92, 19, nil}, 809 | {92, 19, nil}, 810 | {92, 19, nil}, 811 | {92, 19, nil}, 812 | {92, 19, nil}, 813 | {92, 19, nil}, 814 | {195, 19, nil}, 815 | {195, 19, nil}, 816 | {195, 19, nil}, 817 | {195, 19, nil}, 818 | {195, 19, nil}, 819 | {195, 19, nil}, 820 | {195, 19, nil}, 821 | {195, 19, nil}, 822 | {195, 19, nil}, 823 | {195, 19, nil}, 824 | {195, 19, nil}, 825 | {195, 19, nil}, 826 | {195, 19, nil}, 827 | {195, 19, nil}, 828 | {195, 19, nil}, 829 | {195, 19, nil}, 830 | {195, 19, nil}, 831 | {195, 19, nil}, 832 | {195, 19, nil}, 833 | {195, 19, nil}, 834 | {195, 19, nil}, 835 | {195, 19, nil}, 836 | {195, 19, nil}, 837 | {195, 19, nil}, 838 | {195, 19, nil}, 839 | {195, 19, nil}, 840 | {195, 19, nil}, 841 | {195, 19, nil}, 842 | {195, 19, nil}, 843 | {195, 19, nil}, 844 | {195, 19, nil}, 845 | {195, 19, nil}, 846 | {208, 19, nil}, 847 | {208, 19, nil}, 848 | {208, 19, nil}, 849 | {208, 19, nil}, 850 | {208, 19, nil}, 851 | {208, 19, nil}, 852 | {208, 19, nil}, 853 | {208, 19, nil}, 854 | {208, 19, nil}, 855 | {208, 19, nil}, 856 | {208, 19, nil}, 857 | {208, 19, nil}, 858 | {208, 19, nil}, 859 | {208, 19, nil}, 860 | {208, 19, nil}, 861 | {208, 19, nil}, 862 | {208, 19, nil}, 863 | {208, 19, nil}, 864 | {208, 19, nil}, 865 | {208, 19, nil}, 866 | {208, 19, nil}, 867 | {208, 19, nil}, 868 | {208, 19, nil}, 869 | {208, 19, nil}, 870 | {208, 19, nil}, 871 | {208, 19, nil}, 872 | {208, 19, nil}, 873 | {208, 19, nil}, 874 | {208, 19, nil}, 875 | {208, 19, nil}, 876 | {208, 19, nil}, 877 | {208, 19, nil}, 878 | {128, 20, nil}, 879 | {128, 20, nil}, 880 | {128, 20, nil}, 881 | {128, 20, nil}, 882 | {128, 20, nil}, 883 | {128, 20, nil}, 884 | {128, 20, nil}, 885 | {128, 20, nil}, 886 | {128, 20, nil}, 887 | {128, 20, nil}, 888 | {128, 20, nil}, 889 | {128, 20, nil}, 890 | {128, 20, nil}, 891 | {128, 20, nil}, 892 | {128, 20, nil}, 893 | {128, 20, nil}, 894 | {130, 20, nil}, 895 | {130, 20, nil}, 896 | {130, 20, nil}, 897 | {130, 20, nil}, 898 | {130, 20, nil}, 899 | {130, 20, nil}, 900 | {130, 20, nil}, 901 | {130, 20, nil}, 902 | {130, 20, nil}, 903 | {130, 20, nil}, 904 | {130, 20, nil}, 905 | {130, 20, nil}, 906 | {130, 20, nil}, 907 | {130, 20, nil}, 908 | {130, 20, nil}, 909 | {130, 20, nil}, 910 | {131, 20, nil}, 911 | {131, 20, nil}, 912 | {131, 20, nil}, 913 | {131, 20, nil}, 914 | {131, 20, nil}, 915 | {131, 20, nil}, 916 | {131, 20, nil}, 917 | {131, 20, nil}, 918 | {131, 20, nil}, 919 | {131, 20, nil}, 920 | {131, 20, nil}, 921 | {131, 20, nil}, 922 | {131, 20, nil}, 923 | {131, 20, nil}, 924 | {131, 20, nil}, 925 | {131, 20, nil}, 926 | {162, 20, nil}, 927 | {162, 20, nil}, 928 | {162, 20, nil}, 929 | {162, 20, nil}, 930 | {162, 20, nil}, 931 | {162, 20, nil}, 932 | {162, 20, nil}, 933 | {162, 20, nil}, 934 | {162, 20, nil}, 935 | {162, 20, nil}, 936 | {162, 20, nil}, 937 | {162, 20, nil}, 938 | {162, 20, nil}, 939 | {162, 20, nil}, 940 | {162, 20, nil}, 941 | {162, 20, nil}, 942 | {184, 20, nil}, 943 | {184, 20, nil}, 944 | {184, 20, nil}, 945 | {184, 20, nil}, 946 | {184, 20, nil}, 947 | {184, 20, nil}, 948 | {184, 20, nil}, 949 | {184, 20, nil}, 950 | {184, 20, nil}, 951 | {184, 20, nil}, 952 | {184, 20, nil}, 953 | {184, 20, nil}, 954 | {184, 20, nil}, 955 | {184, 20, nil}, 956 | {184, 20, nil}, 957 | {184, 20, nil}, 958 | {194, 20, nil}, 959 | {194, 20, nil}, 960 | {194, 20, nil}, 961 | {194, 20, nil}, 962 | {194, 20, nil}, 963 | {194, 20, nil}, 964 | {194, 20, nil}, 965 | {194, 20, nil}, 966 | {194, 20, nil}, 967 | {194, 20, nil}, 968 | {194, 20, nil}, 969 | {194, 20, nil}, 970 | {194, 20, nil}, 971 | {194, 20, nil}, 972 | {194, 20, nil}, 973 | {194, 20, nil}, 974 | {224, 20, nil}, 975 | {224, 20, nil}, 976 | {224, 20, nil}, 977 | {224, 20, nil}, 978 | {224, 20, nil}, 979 | {224, 20, nil}, 980 | {224, 20, nil}, 981 | {224, 20, nil}, 982 | {224, 20, nil}, 983 | {224, 20, nil}, 984 | {224, 20, nil}, 985 | {224, 20, nil}, 986 | {224, 20, nil}, 987 | {224, 20, nil}, 988 | {224, 20, nil}, 989 | {224, 20, nil}, 990 | {226, 20, nil}, 991 | {226, 20, nil}, 992 | {226, 20, nil}, 993 | {226, 20, nil}, 994 | {226, 20, nil}, 995 | {226, 20, nil}, 996 | {226, 20, nil}, 997 | {226, 20, nil}, 998 | {226, 20, nil}, 999 | {226, 20, nil}, 1000 | {226, 20, nil}, 1001 | {226, 20, nil}, 1002 | {226, 20, nil}, 1003 | {226, 20, nil}, 1004 | {226, 20, nil}, 1005 | {226, 20, nil}, 1006 | {153, 21, nil}, 1007 | {153, 21, nil}, 1008 | {153, 21, nil}, 1009 | {153, 21, nil}, 1010 | {153, 21, nil}, 1011 | {153, 21, nil}, 1012 | {153, 21, nil}, 1013 | {153, 21, nil}, 1014 | {161, 21, nil}, 1015 | {161, 21, nil}, 1016 | {161, 21, nil}, 1017 | {161, 21, nil}, 1018 | {161, 21, nil}, 1019 | {161, 21, nil}, 1020 | {161, 21, nil}, 1021 | {161, 21, nil}, 1022 | {167, 21, nil}, 1023 | {167, 21, nil}, 1024 | {167, 21, nil}, 1025 | {167, 21, nil}, 1026 | {167, 21, nil}, 1027 | {167, 21, nil}, 1028 | {167, 21, nil}, 1029 | {167, 21, nil}, 1030 | {172, 21, nil}, 1031 | {172, 21, nil}, 1032 | {172, 21, nil}, 1033 | {172, 21, nil}, 1034 | {172, 21, nil}, 1035 | {172, 21, nil}, 1036 | {172, 21, nil}, 1037 | {172, 21, nil}, 1038 | }, 1039 | }, 1040 | {0, 0, 1041 | []*lookupTableEntry{ 1042 | {176, 21, nil}, 1043 | {176, 21, nil}, 1044 | {176, 21, nil}, 1045 | {176, 21, nil}, 1046 | {176, 21, nil}, 1047 | {176, 21, nil}, 1048 | {176, 21, nil}, 1049 | {176, 21, nil}, 1050 | {177, 21, nil}, 1051 | {177, 21, nil}, 1052 | {177, 21, nil}, 1053 | {177, 21, nil}, 1054 | {177, 21, nil}, 1055 | {177, 21, nil}, 1056 | {177, 21, nil}, 1057 | {177, 21, nil}, 1058 | {179, 21, nil}, 1059 | {179, 21, nil}, 1060 | {179, 21, nil}, 1061 | {179, 21, nil}, 1062 | {179, 21, nil}, 1063 | {179, 21, nil}, 1064 | {179, 21, nil}, 1065 | {179, 21, nil}, 1066 | {209, 21, nil}, 1067 | {209, 21, nil}, 1068 | {209, 21, nil}, 1069 | {209, 21, nil}, 1070 | {209, 21, nil}, 1071 | {209, 21, nil}, 1072 | {209, 21, nil}, 1073 | {209, 21, nil}, 1074 | {216, 21, nil}, 1075 | {216, 21, nil}, 1076 | {216, 21, nil}, 1077 | {216, 21, nil}, 1078 | {216, 21, nil}, 1079 | {216, 21, nil}, 1080 | {216, 21, nil}, 1081 | {216, 21, nil}, 1082 | {217, 21, nil}, 1083 | {217, 21, nil}, 1084 | {217, 21, nil}, 1085 | {217, 21, nil}, 1086 | {217, 21, nil}, 1087 | {217, 21, nil}, 1088 | {217, 21, nil}, 1089 | {217, 21, nil}, 1090 | {227, 21, nil}, 1091 | {227, 21, nil}, 1092 | {227, 21, nil}, 1093 | {227, 21, nil}, 1094 | {227, 21, nil}, 1095 | {227, 21, nil}, 1096 | {227, 21, nil}, 1097 | {227, 21, nil}, 1098 | {229, 21, nil}, 1099 | {229, 21, nil}, 1100 | {229, 21, nil}, 1101 | {229, 21, nil}, 1102 | {229, 21, nil}, 1103 | {229, 21, nil}, 1104 | {229, 21, nil}, 1105 | {229, 21, nil}, 1106 | {230, 21, nil}, 1107 | {230, 21, nil}, 1108 | {230, 21, nil}, 1109 | {230, 21, nil}, 1110 | {230, 21, nil}, 1111 | {230, 21, nil}, 1112 | {230, 21, nil}, 1113 | {230, 21, nil}, 1114 | {129, 22, nil}, 1115 | {129, 22, nil}, 1116 | {129, 22, nil}, 1117 | {129, 22, nil}, 1118 | {132, 22, nil}, 1119 | {132, 22, nil}, 1120 | {132, 22, nil}, 1121 | {132, 22, nil}, 1122 | {133, 22, nil}, 1123 | {133, 22, nil}, 1124 | {133, 22, nil}, 1125 | {133, 22, nil}, 1126 | {134, 22, nil}, 1127 | {134, 22, nil}, 1128 | {134, 22, nil}, 1129 | {134, 22, nil}, 1130 | {136, 22, nil}, 1131 | {136, 22, nil}, 1132 | {136, 22, nil}, 1133 | {136, 22, nil}, 1134 | {146, 22, nil}, 1135 | {146, 22, nil}, 1136 | {146, 22, nil}, 1137 | {146, 22, nil}, 1138 | {154, 22, nil}, 1139 | {154, 22, nil}, 1140 | {154, 22, nil}, 1141 | {154, 22, nil}, 1142 | {156, 22, nil}, 1143 | {156, 22, nil}, 1144 | {156, 22, nil}, 1145 | {156, 22, nil}, 1146 | {160, 22, nil}, 1147 | {160, 22, nil}, 1148 | {160, 22, nil}, 1149 | {160, 22, nil}, 1150 | {163, 22, nil}, 1151 | {163, 22, nil}, 1152 | {163, 22, nil}, 1153 | {163, 22, nil}, 1154 | {164, 22, nil}, 1155 | {164, 22, nil}, 1156 | {164, 22, nil}, 1157 | {164, 22, nil}, 1158 | {169, 22, nil}, 1159 | {169, 22, nil}, 1160 | {169, 22, nil}, 1161 | {169, 22, nil}, 1162 | {170, 22, nil}, 1163 | {170, 22, nil}, 1164 | {170, 22, nil}, 1165 | {170, 22, nil}, 1166 | {173, 22, nil}, 1167 | {173, 22, nil}, 1168 | {173, 22, nil}, 1169 | {173, 22, nil}, 1170 | {178, 22, nil}, 1171 | {178, 22, nil}, 1172 | {178, 22, nil}, 1173 | {178, 22, nil}, 1174 | {181, 22, nil}, 1175 | {181, 22, nil}, 1176 | {181, 22, nil}, 1177 | {181, 22, nil}, 1178 | {185, 22, nil}, 1179 | {185, 22, nil}, 1180 | {185, 22, nil}, 1181 | {185, 22, nil}, 1182 | {186, 22, nil}, 1183 | {186, 22, nil}, 1184 | {186, 22, nil}, 1185 | {186, 22, nil}, 1186 | {187, 22, nil}, 1187 | {187, 22, nil}, 1188 | {187, 22, nil}, 1189 | {187, 22, nil}, 1190 | {189, 22, nil}, 1191 | {189, 22, nil}, 1192 | {189, 22, nil}, 1193 | {189, 22, nil}, 1194 | {190, 22, nil}, 1195 | {190, 22, nil}, 1196 | {190, 22, nil}, 1197 | {190, 22, nil}, 1198 | {196, 22, nil}, 1199 | {196, 22, nil}, 1200 | {196, 22, nil}, 1201 | {196, 22, nil}, 1202 | {198, 22, nil}, 1203 | {198, 22, nil}, 1204 | {198, 22, nil}, 1205 | {198, 22, nil}, 1206 | {228, 22, nil}, 1207 | {228, 22, nil}, 1208 | {228, 22, nil}, 1209 | {228, 22, nil}, 1210 | {232, 22, nil}, 1211 | {232, 22, nil}, 1212 | {232, 22, nil}, 1213 | {232, 22, nil}, 1214 | {233, 22, nil}, 1215 | {233, 22, nil}, 1216 | {233, 22, nil}, 1217 | {233, 22, nil}, 1218 | {1, 23, nil}, 1219 | {1, 23, nil}, 1220 | {135, 23, nil}, 1221 | {135, 23, nil}, 1222 | {137, 23, nil}, 1223 | {137, 23, nil}, 1224 | {138, 23, nil}, 1225 | {138, 23, nil}, 1226 | {139, 23, nil}, 1227 | {139, 23, nil}, 1228 | {140, 23, nil}, 1229 | {140, 23, nil}, 1230 | {141, 23, nil}, 1231 | {141, 23, nil}, 1232 | {143, 23, nil}, 1233 | {143, 23, nil}, 1234 | {147, 23, nil}, 1235 | {147, 23, nil}, 1236 | {149, 23, nil}, 1237 | {149, 23, nil}, 1238 | {150, 23, nil}, 1239 | {150, 23, nil}, 1240 | {151, 23, nil}, 1241 | {151, 23, nil}, 1242 | {152, 23, nil}, 1243 | {152, 23, nil}, 1244 | {155, 23, nil}, 1245 | {155, 23, nil}, 1246 | {157, 23, nil}, 1247 | {157, 23, nil}, 1248 | {158, 23, nil}, 1249 | {158, 23, nil}, 1250 | {165, 23, nil}, 1251 | {165, 23, nil}, 1252 | {166, 23, nil}, 1253 | {166, 23, nil}, 1254 | {168, 23, nil}, 1255 | {168, 23, nil}, 1256 | {174, 23, nil}, 1257 | {174, 23, nil}, 1258 | {175, 23, nil}, 1259 | {175, 23, nil}, 1260 | {180, 23, nil}, 1261 | {180, 23, nil}, 1262 | {182, 23, nil}, 1263 | {182, 23, nil}, 1264 | {183, 23, nil}, 1265 | {183, 23, nil}, 1266 | {188, 23, nil}, 1267 | {188, 23, nil}, 1268 | {191, 23, nil}, 1269 | {191, 23, nil}, 1270 | {197, 23, nil}, 1271 | {197, 23, nil}, 1272 | {231, 23, nil}, 1273 | {231, 23, nil}, 1274 | {239, 23, nil}, 1275 | {239, 23, nil}, 1276 | {9, 24, nil}, 1277 | {142, 24, nil}, 1278 | {144, 24, nil}, 1279 | {145, 24, nil}, 1280 | {148, 24, nil}, 1281 | {159, 24, nil}, 1282 | {171, 24, nil}, 1283 | {206, 24, nil}, 1284 | {215, 24, nil}, 1285 | {225, 24, nil}, 1286 | {236, 24, nil}, 1287 | {237, 24, nil}, 1288 | {0, 0, 1289 | []*lookupTableEntry{ 1290 | {199, 25, nil}, 1291 | {199, 25, nil}, 1292 | {199, 25, nil}, 1293 | {199, 25, nil}, 1294 | {199, 25, nil}, 1295 | {199, 25, nil}, 1296 | {199, 25, nil}, 1297 | {199, 25, nil}, 1298 | {199, 25, nil}, 1299 | {199, 25, nil}, 1300 | {199, 25, nil}, 1301 | {199, 25, nil}, 1302 | {199, 25, nil}, 1303 | {199, 25, nil}, 1304 | {199, 25, nil}, 1305 | {199, 25, nil}, 1306 | {199, 25, nil}, 1307 | {199, 25, nil}, 1308 | {199, 25, nil}, 1309 | {199, 25, nil}, 1310 | {199, 25, nil}, 1311 | {199, 25, nil}, 1312 | {199, 25, nil}, 1313 | {199, 25, nil}, 1314 | {199, 25, nil}, 1315 | {199, 25, nil}, 1316 | {199, 25, nil}, 1317 | {199, 25, nil}, 1318 | {199, 25, nil}, 1319 | {199, 25, nil}, 1320 | {199, 25, nil}, 1321 | {199, 25, nil}, 1322 | {199, 25, nil}, 1323 | {199, 25, nil}, 1324 | {199, 25, nil}, 1325 | {199, 25, nil}, 1326 | {199, 25, nil}, 1327 | {199, 25, nil}, 1328 | {199, 25, nil}, 1329 | {199, 25, nil}, 1330 | {199, 25, nil}, 1331 | {199, 25, nil}, 1332 | {199, 25, nil}, 1333 | {199, 25, nil}, 1334 | {199, 25, nil}, 1335 | {199, 25, nil}, 1336 | {199, 25, nil}, 1337 | {199, 25, nil}, 1338 | {199, 25, nil}, 1339 | {199, 25, nil}, 1340 | {199, 25, nil}, 1341 | {199, 25, nil}, 1342 | {199, 25, nil}, 1343 | {199, 25, nil}, 1344 | {199, 25, nil}, 1345 | {199, 25, nil}, 1346 | {199, 25, nil}, 1347 | {199, 25, nil}, 1348 | {199, 25, nil}, 1349 | {199, 25, nil}, 1350 | {199, 25, nil}, 1351 | {199, 25, nil}, 1352 | {199, 25, nil}, 1353 | {199, 25, nil}, 1354 | {199, 25, nil}, 1355 | {199, 25, nil}, 1356 | {199, 25, nil}, 1357 | {199, 25, nil}, 1358 | {199, 25, nil}, 1359 | {199, 25, nil}, 1360 | {199, 25, nil}, 1361 | {199, 25, nil}, 1362 | {199, 25, nil}, 1363 | {199, 25, nil}, 1364 | {199, 25, nil}, 1365 | {199, 25, nil}, 1366 | {199, 25, nil}, 1367 | {199, 25, nil}, 1368 | {199, 25, nil}, 1369 | {199, 25, nil}, 1370 | {199, 25, nil}, 1371 | {199, 25, nil}, 1372 | {199, 25, nil}, 1373 | {199, 25, nil}, 1374 | {199, 25, nil}, 1375 | {199, 25, nil}, 1376 | {199, 25, nil}, 1377 | {199, 25, nil}, 1378 | {199, 25, nil}, 1379 | {199, 25, nil}, 1380 | {199, 25, nil}, 1381 | {199, 25, nil}, 1382 | {199, 25, nil}, 1383 | {199, 25, nil}, 1384 | {199, 25, nil}, 1385 | {199, 25, nil}, 1386 | {199, 25, nil}, 1387 | {199, 25, nil}, 1388 | {199, 25, nil}, 1389 | {199, 25, nil}, 1390 | {199, 25, nil}, 1391 | {199, 25, nil}, 1392 | {199, 25, nil}, 1393 | {199, 25, nil}, 1394 | {199, 25, nil}, 1395 | {199, 25, nil}, 1396 | {199, 25, nil}, 1397 | {199, 25, nil}, 1398 | {199, 25, nil}, 1399 | {199, 25, nil}, 1400 | {199, 25, nil}, 1401 | {199, 25, nil}, 1402 | {199, 25, nil}, 1403 | {199, 25, nil}, 1404 | {199, 25, nil}, 1405 | {199, 25, nil}, 1406 | {199, 25, nil}, 1407 | {199, 25, nil}, 1408 | {199, 25, nil}, 1409 | {199, 25, nil}, 1410 | {199, 25, nil}, 1411 | {199, 25, nil}, 1412 | {199, 25, nil}, 1413 | {199, 25, nil}, 1414 | {199, 25, nil}, 1415 | {199, 25, nil}, 1416 | {199, 25, nil}, 1417 | {199, 25, nil}, 1418 | {207, 25, nil}, 1419 | {207, 25, nil}, 1420 | {207, 25, nil}, 1421 | {207, 25, nil}, 1422 | {207, 25, nil}, 1423 | {207, 25, nil}, 1424 | {207, 25, nil}, 1425 | {207, 25, nil}, 1426 | {207, 25, nil}, 1427 | {207, 25, nil}, 1428 | {207, 25, nil}, 1429 | {207, 25, nil}, 1430 | {207, 25, nil}, 1431 | {207, 25, nil}, 1432 | {207, 25, nil}, 1433 | {207, 25, nil}, 1434 | {207, 25, nil}, 1435 | {207, 25, nil}, 1436 | {207, 25, nil}, 1437 | {207, 25, nil}, 1438 | {207, 25, nil}, 1439 | {207, 25, nil}, 1440 | {207, 25, nil}, 1441 | {207, 25, nil}, 1442 | {207, 25, nil}, 1443 | {207, 25, nil}, 1444 | {207, 25, nil}, 1445 | {207, 25, nil}, 1446 | {207, 25, nil}, 1447 | {207, 25, nil}, 1448 | {207, 25, nil}, 1449 | {207, 25, nil}, 1450 | {207, 25, nil}, 1451 | {207, 25, nil}, 1452 | {207, 25, nil}, 1453 | {207, 25, nil}, 1454 | {207, 25, nil}, 1455 | {207, 25, nil}, 1456 | {207, 25, nil}, 1457 | {207, 25, nil}, 1458 | {207, 25, nil}, 1459 | {207, 25, nil}, 1460 | {207, 25, nil}, 1461 | {207, 25, nil}, 1462 | {207, 25, nil}, 1463 | {207, 25, nil}, 1464 | {207, 25, nil}, 1465 | {207, 25, nil}, 1466 | {207, 25, nil}, 1467 | {207, 25, nil}, 1468 | {207, 25, nil}, 1469 | {207, 25, nil}, 1470 | {207, 25, nil}, 1471 | {207, 25, nil}, 1472 | {207, 25, nil}, 1473 | {207, 25, nil}, 1474 | {207, 25, nil}, 1475 | {207, 25, nil}, 1476 | {207, 25, nil}, 1477 | {207, 25, nil}, 1478 | {207, 25, nil}, 1479 | {207, 25, nil}, 1480 | {207, 25, nil}, 1481 | {207, 25, nil}, 1482 | {207, 25, nil}, 1483 | {207, 25, nil}, 1484 | {207, 25, nil}, 1485 | {207, 25, nil}, 1486 | {207, 25, nil}, 1487 | {207, 25, nil}, 1488 | {207, 25, nil}, 1489 | {207, 25, nil}, 1490 | {207, 25, nil}, 1491 | {207, 25, nil}, 1492 | {207, 25, nil}, 1493 | {207, 25, nil}, 1494 | {207, 25, nil}, 1495 | {207, 25, nil}, 1496 | {207, 25, nil}, 1497 | {207, 25, nil}, 1498 | {207, 25, nil}, 1499 | {207, 25, nil}, 1500 | {207, 25, nil}, 1501 | {207, 25, nil}, 1502 | {207, 25, nil}, 1503 | {207, 25, nil}, 1504 | {207, 25, nil}, 1505 | {207, 25, nil}, 1506 | {207, 25, nil}, 1507 | {207, 25, nil}, 1508 | {207, 25, nil}, 1509 | {207, 25, nil}, 1510 | {207, 25, nil}, 1511 | {207, 25, nil}, 1512 | {207, 25, nil}, 1513 | {207, 25, nil}, 1514 | {207, 25, nil}, 1515 | {207, 25, nil}, 1516 | {207, 25, nil}, 1517 | {207, 25, nil}, 1518 | {207, 25, nil}, 1519 | {207, 25, nil}, 1520 | {207, 25, nil}, 1521 | {207, 25, nil}, 1522 | {207, 25, nil}, 1523 | {207, 25, nil}, 1524 | {207, 25, nil}, 1525 | {207, 25, nil}, 1526 | {207, 25, nil}, 1527 | {207, 25, nil}, 1528 | {207, 25, nil}, 1529 | {207, 25, nil}, 1530 | {207, 25, nil}, 1531 | {207, 25, nil}, 1532 | {207, 25, nil}, 1533 | {207, 25, nil}, 1534 | {207, 25, nil}, 1535 | {207, 25, nil}, 1536 | {207, 25, nil}, 1537 | {207, 25, nil}, 1538 | {207, 25, nil}, 1539 | {207, 25, nil}, 1540 | {207, 25, nil}, 1541 | {207, 25, nil}, 1542 | {207, 25, nil}, 1543 | {207, 25, nil}, 1544 | {207, 25, nil}, 1545 | {207, 25, nil}, 1546 | }, 1547 | }, 1548 | {0, 0, 1549 | []*lookupTableEntry{ 1550 | {234, 25, nil}, 1551 | {234, 25, nil}, 1552 | {234, 25, nil}, 1553 | {234, 25, nil}, 1554 | {234, 25, nil}, 1555 | {234, 25, nil}, 1556 | {234, 25, nil}, 1557 | {234, 25, nil}, 1558 | {234, 25, nil}, 1559 | {234, 25, nil}, 1560 | {234, 25, nil}, 1561 | {234, 25, nil}, 1562 | {234, 25, nil}, 1563 | {234, 25, nil}, 1564 | {234, 25, nil}, 1565 | {234, 25, nil}, 1566 | {234, 25, nil}, 1567 | {234, 25, nil}, 1568 | {234, 25, nil}, 1569 | {234, 25, nil}, 1570 | {234, 25, nil}, 1571 | {234, 25, nil}, 1572 | {234, 25, nil}, 1573 | {234, 25, nil}, 1574 | {234, 25, nil}, 1575 | {234, 25, nil}, 1576 | {234, 25, nil}, 1577 | {234, 25, nil}, 1578 | {234, 25, nil}, 1579 | {234, 25, nil}, 1580 | {234, 25, nil}, 1581 | {234, 25, nil}, 1582 | {234, 25, nil}, 1583 | {234, 25, nil}, 1584 | {234, 25, nil}, 1585 | {234, 25, nil}, 1586 | {234, 25, nil}, 1587 | {234, 25, nil}, 1588 | {234, 25, nil}, 1589 | {234, 25, nil}, 1590 | {234, 25, nil}, 1591 | {234, 25, nil}, 1592 | {234, 25, nil}, 1593 | {234, 25, nil}, 1594 | {234, 25, nil}, 1595 | {234, 25, nil}, 1596 | {234, 25, nil}, 1597 | {234, 25, nil}, 1598 | {234, 25, nil}, 1599 | {234, 25, nil}, 1600 | {234, 25, nil}, 1601 | {234, 25, nil}, 1602 | {234, 25, nil}, 1603 | {234, 25, nil}, 1604 | {234, 25, nil}, 1605 | {234, 25, nil}, 1606 | {234, 25, nil}, 1607 | {234, 25, nil}, 1608 | {234, 25, nil}, 1609 | {234, 25, nil}, 1610 | {234, 25, nil}, 1611 | {234, 25, nil}, 1612 | {234, 25, nil}, 1613 | {234, 25, nil}, 1614 | {234, 25, nil}, 1615 | {234, 25, nil}, 1616 | {234, 25, nil}, 1617 | {234, 25, nil}, 1618 | {234, 25, nil}, 1619 | {234, 25, nil}, 1620 | {234, 25, nil}, 1621 | {234, 25, nil}, 1622 | {234, 25, nil}, 1623 | {234, 25, nil}, 1624 | {234, 25, nil}, 1625 | {234, 25, nil}, 1626 | {234, 25, nil}, 1627 | {234, 25, nil}, 1628 | {234, 25, nil}, 1629 | {234, 25, nil}, 1630 | {234, 25, nil}, 1631 | {234, 25, nil}, 1632 | {234, 25, nil}, 1633 | {234, 25, nil}, 1634 | {234, 25, nil}, 1635 | {234, 25, nil}, 1636 | {234, 25, nil}, 1637 | {234, 25, nil}, 1638 | {234, 25, nil}, 1639 | {234, 25, nil}, 1640 | {234, 25, nil}, 1641 | {234, 25, nil}, 1642 | {234, 25, nil}, 1643 | {234, 25, nil}, 1644 | {234, 25, nil}, 1645 | {234, 25, nil}, 1646 | {234, 25, nil}, 1647 | {234, 25, nil}, 1648 | {234, 25, nil}, 1649 | {234, 25, nil}, 1650 | {234, 25, nil}, 1651 | {234, 25, nil}, 1652 | {234, 25, nil}, 1653 | {234, 25, nil}, 1654 | {234, 25, nil}, 1655 | {234, 25, nil}, 1656 | {234, 25, nil}, 1657 | {234, 25, nil}, 1658 | {234, 25, nil}, 1659 | {234, 25, nil}, 1660 | {234, 25, nil}, 1661 | {234, 25, nil}, 1662 | {234, 25, nil}, 1663 | {234, 25, nil}, 1664 | {234, 25, nil}, 1665 | {234, 25, nil}, 1666 | {234, 25, nil}, 1667 | {234, 25, nil}, 1668 | {234, 25, nil}, 1669 | {234, 25, nil}, 1670 | {234, 25, nil}, 1671 | {234, 25, nil}, 1672 | {234, 25, nil}, 1673 | {234, 25, nil}, 1674 | {234, 25, nil}, 1675 | {234, 25, nil}, 1676 | {234, 25, nil}, 1677 | {234, 25, nil}, 1678 | {235, 25, nil}, 1679 | {235, 25, nil}, 1680 | {235, 25, nil}, 1681 | {235, 25, nil}, 1682 | {235, 25, nil}, 1683 | {235, 25, nil}, 1684 | {235, 25, nil}, 1685 | {235, 25, nil}, 1686 | {235, 25, nil}, 1687 | {235, 25, nil}, 1688 | {235, 25, nil}, 1689 | {235, 25, nil}, 1690 | {235, 25, nil}, 1691 | {235, 25, nil}, 1692 | {235, 25, nil}, 1693 | {235, 25, nil}, 1694 | {235, 25, nil}, 1695 | {235, 25, nil}, 1696 | {235, 25, nil}, 1697 | {235, 25, nil}, 1698 | {235, 25, nil}, 1699 | {235, 25, nil}, 1700 | {235, 25, nil}, 1701 | {235, 25, nil}, 1702 | {235, 25, nil}, 1703 | {235, 25, nil}, 1704 | {235, 25, nil}, 1705 | {235, 25, nil}, 1706 | {235, 25, nil}, 1707 | {235, 25, nil}, 1708 | {235, 25, nil}, 1709 | {235, 25, nil}, 1710 | {235, 25, nil}, 1711 | {235, 25, nil}, 1712 | {235, 25, nil}, 1713 | {235, 25, nil}, 1714 | {235, 25, nil}, 1715 | {235, 25, nil}, 1716 | {235, 25, nil}, 1717 | {235, 25, nil}, 1718 | {235, 25, nil}, 1719 | {235, 25, nil}, 1720 | {235, 25, nil}, 1721 | {235, 25, nil}, 1722 | {235, 25, nil}, 1723 | {235, 25, nil}, 1724 | {235, 25, nil}, 1725 | {235, 25, nil}, 1726 | {235, 25, nil}, 1727 | {235, 25, nil}, 1728 | {235, 25, nil}, 1729 | {235, 25, nil}, 1730 | {235, 25, nil}, 1731 | {235, 25, nil}, 1732 | {235, 25, nil}, 1733 | {235, 25, nil}, 1734 | {235, 25, nil}, 1735 | {235, 25, nil}, 1736 | {235, 25, nil}, 1737 | {235, 25, nil}, 1738 | {235, 25, nil}, 1739 | {235, 25, nil}, 1740 | {235, 25, nil}, 1741 | {235, 25, nil}, 1742 | {235, 25, nil}, 1743 | {235, 25, nil}, 1744 | {235, 25, nil}, 1745 | {235, 25, nil}, 1746 | {235, 25, nil}, 1747 | {235, 25, nil}, 1748 | {235, 25, nil}, 1749 | {235, 25, nil}, 1750 | {235, 25, nil}, 1751 | {235, 25, nil}, 1752 | {235, 25, nil}, 1753 | {235, 25, nil}, 1754 | {235, 25, nil}, 1755 | {235, 25, nil}, 1756 | {235, 25, nil}, 1757 | {235, 25, nil}, 1758 | {235, 25, nil}, 1759 | {235, 25, nil}, 1760 | {235, 25, nil}, 1761 | {235, 25, nil}, 1762 | {235, 25, nil}, 1763 | {235, 25, nil}, 1764 | {235, 25, nil}, 1765 | {235, 25, nil}, 1766 | {235, 25, nil}, 1767 | {235, 25, nil}, 1768 | {235, 25, nil}, 1769 | {235, 25, nil}, 1770 | {235, 25, nil}, 1771 | {235, 25, nil}, 1772 | {235, 25, nil}, 1773 | {235, 25, nil}, 1774 | {235, 25, nil}, 1775 | {235, 25, nil}, 1776 | {235, 25, nil}, 1777 | {235, 25, nil}, 1778 | {235, 25, nil}, 1779 | {235, 25, nil}, 1780 | {235, 25, nil}, 1781 | {235, 25, nil}, 1782 | {235, 25, nil}, 1783 | {235, 25, nil}, 1784 | {235, 25, nil}, 1785 | {235, 25, nil}, 1786 | {235, 25, nil}, 1787 | {235, 25, nil}, 1788 | {235, 25, nil}, 1789 | {235, 25, nil}, 1790 | {235, 25, nil}, 1791 | {235, 25, nil}, 1792 | {235, 25, nil}, 1793 | {235, 25, nil}, 1794 | {235, 25, nil}, 1795 | {235, 25, nil}, 1796 | {235, 25, nil}, 1797 | {235, 25, nil}, 1798 | {235, 25, nil}, 1799 | {235, 25, nil}, 1800 | {235, 25, nil}, 1801 | {235, 25, nil}, 1802 | {235, 25, nil}, 1803 | {235, 25, nil}, 1804 | {235, 25, nil}, 1805 | {235, 25, nil}, 1806 | }, 1807 | }, 1808 | {0, 0, 1809 | []*lookupTableEntry{ 1810 | {192, 26, nil}, 1811 | {192, 26, nil}, 1812 | {192, 26, nil}, 1813 | {192, 26, nil}, 1814 | {192, 26, nil}, 1815 | {192, 26, nil}, 1816 | {192, 26, nil}, 1817 | {192, 26, nil}, 1818 | {192, 26, nil}, 1819 | {192, 26, nil}, 1820 | {192, 26, nil}, 1821 | {192, 26, nil}, 1822 | {192, 26, nil}, 1823 | {192, 26, nil}, 1824 | {192, 26, nil}, 1825 | {192, 26, nil}, 1826 | {192, 26, nil}, 1827 | {192, 26, nil}, 1828 | {192, 26, nil}, 1829 | {192, 26, nil}, 1830 | {192, 26, nil}, 1831 | {192, 26, nil}, 1832 | {192, 26, nil}, 1833 | {192, 26, nil}, 1834 | {192, 26, nil}, 1835 | {192, 26, nil}, 1836 | {192, 26, nil}, 1837 | {192, 26, nil}, 1838 | {192, 26, nil}, 1839 | {192, 26, nil}, 1840 | {192, 26, nil}, 1841 | {192, 26, nil}, 1842 | {192, 26, nil}, 1843 | {192, 26, nil}, 1844 | {192, 26, nil}, 1845 | {192, 26, nil}, 1846 | {192, 26, nil}, 1847 | {192, 26, nil}, 1848 | {192, 26, nil}, 1849 | {192, 26, nil}, 1850 | {192, 26, nil}, 1851 | {192, 26, nil}, 1852 | {192, 26, nil}, 1853 | {192, 26, nil}, 1854 | {192, 26, nil}, 1855 | {192, 26, nil}, 1856 | {192, 26, nil}, 1857 | {192, 26, nil}, 1858 | {192, 26, nil}, 1859 | {192, 26, nil}, 1860 | {192, 26, nil}, 1861 | {192, 26, nil}, 1862 | {192, 26, nil}, 1863 | {192, 26, nil}, 1864 | {192, 26, nil}, 1865 | {192, 26, nil}, 1866 | {192, 26, nil}, 1867 | {192, 26, nil}, 1868 | {192, 26, nil}, 1869 | {192, 26, nil}, 1870 | {192, 26, nil}, 1871 | {192, 26, nil}, 1872 | {192, 26, nil}, 1873 | {192, 26, nil}, 1874 | {193, 26, nil}, 1875 | {193, 26, nil}, 1876 | {193, 26, nil}, 1877 | {193, 26, nil}, 1878 | {193, 26, nil}, 1879 | {193, 26, nil}, 1880 | {193, 26, nil}, 1881 | {193, 26, nil}, 1882 | {193, 26, nil}, 1883 | {193, 26, nil}, 1884 | {193, 26, nil}, 1885 | {193, 26, nil}, 1886 | {193, 26, nil}, 1887 | {193, 26, nil}, 1888 | {193, 26, nil}, 1889 | {193, 26, nil}, 1890 | {193, 26, nil}, 1891 | {193, 26, nil}, 1892 | {193, 26, nil}, 1893 | {193, 26, nil}, 1894 | {193, 26, nil}, 1895 | {193, 26, nil}, 1896 | {193, 26, nil}, 1897 | {193, 26, nil}, 1898 | {193, 26, nil}, 1899 | {193, 26, nil}, 1900 | {193, 26, nil}, 1901 | {193, 26, nil}, 1902 | {193, 26, nil}, 1903 | {193, 26, nil}, 1904 | {193, 26, nil}, 1905 | {193, 26, nil}, 1906 | {193, 26, nil}, 1907 | {193, 26, nil}, 1908 | {193, 26, nil}, 1909 | {193, 26, nil}, 1910 | {193, 26, nil}, 1911 | {193, 26, nil}, 1912 | {193, 26, nil}, 1913 | {193, 26, nil}, 1914 | {193, 26, nil}, 1915 | {193, 26, nil}, 1916 | {193, 26, nil}, 1917 | {193, 26, nil}, 1918 | {193, 26, nil}, 1919 | {193, 26, nil}, 1920 | {193, 26, nil}, 1921 | {193, 26, nil}, 1922 | {193, 26, nil}, 1923 | {193, 26, nil}, 1924 | {193, 26, nil}, 1925 | {193, 26, nil}, 1926 | {193, 26, nil}, 1927 | {193, 26, nil}, 1928 | {193, 26, nil}, 1929 | {193, 26, nil}, 1930 | {193, 26, nil}, 1931 | {193, 26, nil}, 1932 | {193, 26, nil}, 1933 | {193, 26, nil}, 1934 | {193, 26, nil}, 1935 | {193, 26, nil}, 1936 | {193, 26, nil}, 1937 | {193, 26, nil}, 1938 | {200, 26, nil}, 1939 | {200, 26, nil}, 1940 | {200, 26, nil}, 1941 | {200, 26, nil}, 1942 | {200, 26, nil}, 1943 | {200, 26, nil}, 1944 | {200, 26, nil}, 1945 | {200, 26, nil}, 1946 | {200, 26, nil}, 1947 | {200, 26, nil}, 1948 | {200, 26, nil}, 1949 | {200, 26, nil}, 1950 | {200, 26, nil}, 1951 | {200, 26, nil}, 1952 | {200, 26, nil}, 1953 | {200, 26, nil}, 1954 | {200, 26, nil}, 1955 | {200, 26, nil}, 1956 | {200, 26, nil}, 1957 | {200, 26, nil}, 1958 | {200, 26, nil}, 1959 | {200, 26, nil}, 1960 | {200, 26, nil}, 1961 | {200, 26, nil}, 1962 | {200, 26, nil}, 1963 | {200, 26, nil}, 1964 | {200, 26, nil}, 1965 | {200, 26, nil}, 1966 | {200, 26, nil}, 1967 | {200, 26, nil}, 1968 | {200, 26, nil}, 1969 | {200, 26, nil}, 1970 | {200, 26, nil}, 1971 | {200, 26, nil}, 1972 | {200, 26, nil}, 1973 | {200, 26, nil}, 1974 | {200, 26, nil}, 1975 | {200, 26, nil}, 1976 | {200, 26, nil}, 1977 | {200, 26, nil}, 1978 | {200, 26, nil}, 1979 | {200, 26, nil}, 1980 | {200, 26, nil}, 1981 | {200, 26, nil}, 1982 | {200, 26, nil}, 1983 | {200, 26, nil}, 1984 | {200, 26, nil}, 1985 | {200, 26, nil}, 1986 | {200, 26, nil}, 1987 | {200, 26, nil}, 1988 | {200, 26, nil}, 1989 | {200, 26, nil}, 1990 | {200, 26, nil}, 1991 | {200, 26, nil}, 1992 | {200, 26, nil}, 1993 | {200, 26, nil}, 1994 | {200, 26, nil}, 1995 | {200, 26, nil}, 1996 | {200, 26, nil}, 1997 | {200, 26, nil}, 1998 | {200, 26, nil}, 1999 | {200, 26, nil}, 2000 | {200, 26, nil}, 2001 | {200, 26, nil}, 2002 | {201, 26, nil}, 2003 | {201, 26, nil}, 2004 | {201, 26, nil}, 2005 | {201, 26, nil}, 2006 | {201, 26, nil}, 2007 | {201, 26, nil}, 2008 | {201, 26, nil}, 2009 | {201, 26, nil}, 2010 | {201, 26, nil}, 2011 | {201, 26, nil}, 2012 | {201, 26, nil}, 2013 | {201, 26, nil}, 2014 | {201, 26, nil}, 2015 | {201, 26, nil}, 2016 | {201, 26, nil}, 2017 | {201, 26, nil}, 2018 | {201, 26, nil}, 2019 | {201, 26, nil}, 2020 | {201, 26, nil}, 2021 | {201, 26, nil}, 2022 | {201, 26, nil}, 2023 | {201, 26, nil}, 2024 | {201, 26, nil}, 2025 | {201, 26, nil}, 2026 | {201, 26, nil}, 2027 | {201, 26, nil}, 2028 | {201, 26, nil}, 2029 | {201, 26, nil}, 2030 | {201, 26, nil}, 2031 | {201, 26, nil}, 2032 | {201, 26, nil}, 2033 | {201, 26, nil}, 2034 | {201, 26, nil}, 2035 | {201, 26, nil}, 2036 | {201, 26, nil}, 2037 | {201, 26, nil}, 2038 | {201, 26, nil}, 2039 | {201, 26, nil}, 2040 | {201, 26, nil}, 2041 | {201, 26, nil}, 2042 | {201, 26, nil}, 2043 | {201, 26, nil}, 2044 | {201, 26, nil}, 2045 | {201, 26, nil}, 2046 | {201, 26, nil}, 2047 | {201, 26, nil}, 2048 | {201, 26, nil}, 2049 | {201, 26, nil}, 2050 | {201, 26, nil}, 2051 | {201, 26, nil}, 2052 | {201, 26, nil}, 2053 | {201, 26, nil}, 2054 | {201, 26, nil}, 2055 | {201, 26, nil}, 2056 | {201, 26, nil}, 2057 | {201, 26, nil}, 2058 | {201, 26, nil}, 2059 | {201, 26, nil}, 2060 | {201, 26, nil}, 2061 | {201, 26, nil}, 2062 | {201, 26, nil}, 2063 | {201, 26, nil}, 2064 | {201, 26, nil}, 2065 | {201, 26, nil}, 2066 | }, 2067 | }, 2068 | {0, 0, 2069 | []*lookupTableEntry{ 2070 | {202, 26, nil}, 2071 | {202, 26, nil}, 2072 | {202, 26, nil}, 2073 | {202, 26, nil}, 2074 | {202, 26, nil}, 2075 | {202, 26, nil}, 2076 | {202, 26, nil}, 2077 | {202, 26, nil}, 2078 | {202, 26, nil}, 2079 | {202, 26, nil}, 2080 | {202, 26, nil}, 2081 | {202, 26, nil}, 2082 | {202, 26, nil}, 2083 | {202, 26, nil}, 2084 | {202, 26, nil}, 2085 | {202, 26, nil}, 2086 | {202, 26, nil}, 2087 | {202, 26, nil}, 2088 | {202, 26, nil}, 2089 | {202, 26, nil}, 2090 | {202, 26, nil}, 2091 | {202, 26, nil}, 2092 | {202, 26, nil}, 2093 | {202, 26, nil}, 2094 | {202, 26, nil}, 2095 | {202, 26, nil}, 2096 | {202, 26, nil}, 2097 | {202, 26, nil}, 2098 | {202, 26, nil}, 2099 | {202, 26, nil}, 2100 | {202, 26, nil}, 2101 | {202, 26, nil}, 2102 | {202, 26, nil}, 2103 | {202, 26, nil}, 2104 | {202, 26, nil}, 2105 | {202, 26, nil}, 2106 | {202, 26, nil}, 2107 | {202, 26, nil}, 2108 | {202, 26, nil}, 2109 | {202, 26, nil}, 2110 | {202, 26, nil}, 2111 | {202, 26, nil}, 2112 | {202, 26, nil}, 2113 | {202, 26, nil}, 2114 | {202, 26, nil}, 2115 | {202, 26, nil}, 2116 | {202, 26, nil}, 2117 | {202, 26, nil}, 2118 | {202, 26, nil}, 2119 | {202, 26, nil}, 2120 | {202, 26, nil}, 2121 | {202, 26, nil}, 2122 | {202, 26, nil}, 2123 | {202, 26, nil}, 2124 | {202, 26, nil}, 2125 | {202, 26, nil}, 2126 | {202, 26, nil}, 2127 | {202, 26, nil}, 2128 | {202, 26, nil}, 2129 | {202, 26, nil}, 2130 | {202, 26, nil}, 2131 | {202, 26, nil}, 2132 | {202, 26, nil}, 2133 | {202, 26, nil}, 2134 | {205, 26, nil}, 2135 | {205, 26, nil}, 2136 | {205, 26, nil}, 2137 | {205, 26, nil}, 2138 | {205, 26, nil}, 2139 | {205, 26, nil}, 2140 | {205, 26, nil}, 2141 | {205, 26, nil}, 2142 | {205, 26, nil}, 2143 | {205, 26, nil}, 2144 | {205, 26, nil}, 2145 | {205, 26, nil}, 2146 | {205, 26, nil}, 2147 | {205, 26, nil}, 2148 | {205, 26, nil}, 2149 | {205, 26, nil}, 2150 | {205, 26, nil}, 2151 | {205, 26, nil}, 2152 | {205, 26, nil}, 2153 | {205, 26, nil}, 2154 | {205, 26, nil}, 2155 | {205, 26, nil}, 2156 | {205, 26, nil}, 2157 | {205, 26, nil}, 2158 | {205, 26, nil}, 2159 | {205, 26, nil}, 2160 | {205, 26, nil}, 2161 | {205, 26, nil}, 2162 | {205, 26, nil}, 2163 | {205, 26, nil}, 2164 | {205, 26, nil}, 2165 | {205, 26, nil}, 2166 | {205, 26, nil}, 2167 | {205, 26, nil}, 2168 | {205, 26, nil}, 2169 | {205, 26, nil}, 2170 | {205, 26, nil}, 2171 | {205, 26, nil}, 2172 | {205, 26, nil}, 2173 | {205, 26, nil}, 2174 | {205, 26, nil}, 2175 | {205, 26, nil}, 2176 | {205, 26, nil}, 2177 | {205, 26, nil}, 2178 | {205, 26, nil}, 2179 | {205, 26, nil}, 2180 | {205, 26, nil}, 2181 | {205, 26, nil}, 2182 | {205, 26, nil}, 2183 | {205, 26, nil}, 2184 | {205, 26, nil}, 2185 | {205, 26, nil}, 2186 | {205, 26, nil}, 2187 | {205, 26, nil}, 2188 | {205, 26, nil}, 2189 | {205, 26, nil}, 2190 | {205, 26, nil}, 2191 | {205, 26, nil}, 2192 | {205, 26, nil}, 2193 | {205, 26, nil}, 2194 | {205, 26, nil}, 2195 | {205, 26, nil}, 2196 | {205, 26, nil}, 2197 | {205, 26, nil}, 2198 | {210, 26, nil}, 2199 | {210, 26, nil}, 2200 | {210, 26, nil}, 2201 | {210, 26, nil}, 2202 | {210, 26, nil}, 2203 | {210, 26, nil}, 2204 | {210, 26, nil}, 2205 | {210, 26, nil}, 2206 | {210, 26, nil}, 2207 | {210, 26, nil}, 2208 | {210, 26, nil}, 2209 | {210, 26, nil}, 2210 | {210, 26, nil}, 2211 | {210, 26, nil}, 2212 | {210, 26, nil}, 2213 | {210, 26, nil}, 2214 | {210, 26, nil}, 2215 | {210, 26, nil}, 2216 | {210, 26, nil}, 2217 | {210, 26, nil}, 2218 | {210, 26, nil}, 2219 | {210, 26, nil}, 2220 | {210, 26, nil}, 2221 | {210, 26, nil}, 2222 | {210, 26, nil}, 2223 | {210, 26, nil}, 2224 | {210, 26, nil}, 2225 | {210, 26, nil}, 2226 | {210, 26, nil}, 2227 | {210, 26, nil}, 2228 | {210, 26, nil}, 2229 | {210, 26, nil}, 2230 | {210, 26, nil}, 2231 | {210, 26, nil}, 2232 | {210, 26, nil}, 2233 | {210, 26, nil}, 2234 | {210, 26, nil}, 2235 | {210, 26, nil}, 2236 | {210, 26, nil}, 2237 | {210, 26, nil}, 2238 | {210, 26, nil}, 2239 | {210, 26, nil}, 2240 | {210, 26, nil}, 2241 | {210, 26, nil}, 2242 | {210, 26, nil}, 2243 | {210, 26, nil}, 2244 | {210, 26, nil}, 2245 | {210, 26, nil}, 2246 | {210, 26, nil}, 2247 | {210, 26, nil}, 2248 | {210, 26, nil}, 2249 | {210, 26, nil}, 2250 | {210, 26, nil}, 2251 | {210, 26, nil}, 2252 | {210, 26, nil}, 2253 | {210, 26, nil}, 2254 | {210, 26, nil}, 2255 | {210, 26, nil}, 2256 | {210, 26, nil}, 2257 | {210, 26, nil}, 2258 | {210, 26, nil}, 2259 | {210, 26, nil}, 2260 | {210, 26, nil}, 2261 | {210, 26, nil}, 2262 | {213, 26, nil}, 2263 | {213, 26, nil}, 2264 | {213, 26, nil}, 2265 | {213, 26, nil}, 2266 | {213, 26, nil}, 2267 | {213, 26, nil}, 2268 | {213, 26, nil}, 2269 | {213, 26, nil}, 2270 | {213, 26, nil}, 2271 | {213, 26, nil}, 2272 | {213, 26, nil}, 2273 | {213, 26, nil}, 2274 | {213, 26, nil}, 2275 | {213, 26, nil}, 2276 | {213, 26, nil}, 2277 | {213, 26, nil}, 2278 | {213, 26, nil}, 2279 | {213, 26, nil}, 2280 | {213, 26, nil}, 2281 | {213, 26, nil}, 2282 | {213, 26, nil}, 2283 | {213, 26, nil}, 2284 | {213, 26, nil}, 2285 | {213, 26, nil}, 2286 | {213, 26, nil}, 2287 | {213, 26, nil}, 2288 | {213, 26, nil}, 2289 | {213, 26, nil}, 2290 | {213, 26, nil}, 2291 | {213, 26, nil}, 2292 | {213, 26, nil}, 2293 | {213, 26, nil}, 2294 | {213, 26, nil}, 2295 | {213, 26, nil}, 2296 | {213, 26, nil}, 2297 | {213, 26, nil}, 2298 | {213, 26, nil}, 2299 | {213, 26, nil}, 2300 | {213, 26, nil}, 2301 | {213, 26, nil}, 2302 | {213, 26, nil}, 2303 | {213, 26, nil}, 2304 | {213, 26, nil}, 2305 | {213, 26, nil}, 2306 | {213, 26, nil}, 2307 | {213, 26, nil}, 2308 | {213, 26, nil}, 2309 | {213, 26, nil}, 2310 | {213, 26, nil}, 2311 | {213, 26, nil}, 2312 | {213, 26, nil}, 2313 | {213, 26, nil}, 2314 | {213, 26, nil}, 2315 | {213, 26, nil}, 2316 | {213, 26, nil}, 2317 | {213, 26, nil}, 2318 | {213, 26, nil}, 2319 | {213, 26, nil}, 2320 | {213, 26, nil}, 2321 | {213, 26, nil}, 2322 | {213, 26, nil}, 2323 | {213, 26, nil}, 2324 | {213, 26, nil}, 2325 | {213, 26, nil}, 2326 | }, 2327 | }, 2328 | {0, 0, 2329 | []*lookupTableEntry{ 2330 | {218, 26, nil}, 2331 | {218, 26, nil}, 2332 | {218, 26, nil}, 2333 | {218, 26, nil}, 2334 | {218, 26, nil}, 2335 | {218, 26, nil}, 2336 | {218, 26, nil}, 2337 | {218, 26, nil}, 2338 | {218, 26, nil}, 2339 | {218, 26, nil}, 2340 | {218, 26, nil}, 2341 | {218, 26, nil}, 2342 | {218, 26, nil}, 2343 | {218, 26, nil}, 2344 | {218, 26, nil}, 2345 | {218, 26, nil}, 2346 | {218, 26, nil}, 2347 | {218, 26, nil}, 2348 | {218, 26, nil}, 2349 | {218, 26, nil}, 2350 | {218, 26, nil}, 2351 | {218, 26, nil}, 2352 | {218, 26, nil}, 2353 | {218, 26, nil}, 2354 | {218, 26, nil}, 2355 | {218, 26, nil}, 2356 | {218, 26, nil}, 2357 | {218, 26, nil}, 2358 | {218, 26, nil}, 2359 | {218, 26, nil}, 2360 | {218, 26, nil}, 2361 | {218, 26, nil}, 2362 | {218, 26, nil}, 2363 | {218, 26, nil}, 2364 | {218, 26, nil}, 2365 | {218, 26, nil}, 2366 | {218, 26, nil}, 2367 | {218, 26, nil}, 2368 | {218, 26, nil}, 2369 | {218, 26, nil}, 2370 | {218, 26, nil}, 2371 | {218, 26, nil}, 2372 | {218, 26, nil}, 2373 | {218, 26, nil}, 2374 | {218, 26, nil}, 2375 | {218, 26, nil}, 2376 | {218, 26, nil}, 2377 | {218, 26, nil}, 2378 | {218, 26, nil}, 2379 | {218, 26, nil}, 2380 | {218, 26, nil}, 2381 | {218, 26, nil}, 2382 | {218, 26, nil}, 2383 | {218, 26, nil}, 2384 | {218, 26, nil}, 2385 | {218, 26, nil}, 2386 | {218, 26, nil}, 2387 | {218, 26, nil}, 2388 | {218, 26, nil}, 2389 | {218, 26, nil}, 2390 | {218, 26, nil}, 2391 | {218, 26, nil}, 2392 | {218, 26, nil}, 2393 | {218, 26, nil}, 2394 | {219, 26, nil}, 2395 | {219, 26, nil}, 2396 | {219, 26, nil}, 2397 | {219, 26, nil}, 2398 | {219, 26, nil}, 2399 | {219, 26, nil}, 2400 | {219, 26, nil}, 2401 | {219, 26, nil}, 2402 | {219, 26, nil}, 2403 | {219, 26, nil}, 2404 | {219, 26, nil}, 2405 | {219, 26, nil}, 2406 | {219, 26, nil}, 2407 | {219, 26, nil}, 2408 | {219, 26, nil}, 2409 | {219, 26, nil}, 2410 | {219, 26, nil}, 2411 | {219, 26, nil}, 2412 | {219, 26, nil}, 2413 | {219, 26, nil}, 2414 | {219, 26, nil}, 2415 | {219, 26, nil}, 2416 | {219, 26, nil}, 2417 | {219, 26, nil}, 2418 | {219, 26, nil}, 2419 | {219, 26, nil}, 2420 | {219, 26, nil}, 2421 | {219, 26, nil}, 2422 | {219, 26, nil}, 2423 | {219, 26, nil}, 2424 | {219, 26, nil}, 2425 | {219, 26, nil}, 2426 | {219, 26, nil}, 2427 | {219, 26, nil}, 2428 | {219, 26, nil}, 2429 | {219, 26, nil}, 2430 | {219, 26, nil}, 2431 | {219, 26, nil}, 2432 | {219, 26, nil}, 2433 | {219, 26, nil}, 2434 | {219, 26, nil}, 2435 | {219, 26, nil}, 2436 | {219, 26, nil}, 2437 | {219, 26, nil}, 2438 | {219, 26, nil}, 2439 | {219, 26, nil}, 2440 | {219, 26, nil}, 2441 | {219, 26, nil}, 2442 | {219, 26, nil}, 2443 | {219, 26, nil}, 2444 | {219, 26, nil}, 2445 | {219, 26, nil}, 2446 | {219, 26, nil}, 2447 | {219, 26, nil}, 2448 | {219, 26, nil}, 2449 | {219, 26, nil}, 2450 | {219, 26, nil}, 2451 | {219, 26, nil}, 2452 | {219, 26, nil}, 2453 | {219, 26, nil}, 2454 | {219, 26, nil}, 2455 | {219, 26, nil}, 2456 | {219, 26, nil}, 2457 | {219, 26, nil}, 2458 | {238, 26, nil}, 2459 | {238, 26, nil}, 2460 | {238, 26, nil}, 2461 | {238, 26, nil}, 2462 | {238, 26, nil}, 2463 | {238, 26, nil}, 2464 | {238, 26, nil}, 2465 | {238, 26, nil}, 2466 | {238, 26, nil}, 2467 | {238, 26, nil}, 2468 | {238, 26, nil}, 2469 | {238, 26, nil}, 2470 | {238, 26, nil}, 2471 | {238, 26, nil}, 2472 | {238, 26, nil}, 2473 | {238, 26, nil}, 2474 | {238, 26, nil}, 2475 | {238, 26, nil}, 2476 | {238, 26, nil}, 2477 | {238, 26, nil}, 2478 | {238, 26, nil}, 2479 | {238, 26, nil}, 2480 | {238, 26, nil}, 2481 | {238, 26, nil}, 2482 | {238, 26, nil}, 2483 | {238, 26, nil}, 2484 | {238, 26, nil}, 2485 | {238, 26, nil}, 2486 | {238, 26, nil}, 2487 | {238, 26, nil}, 2488 | {238, 26, nil}, 2489 | {238, 26, nil}, 2490 | {238, 26, nil}, 2491 | {238, 26, nil}, 2492 | {238, 26, nil}, 2493 | {238, 26, nil}, 2494 | {238, 26, nil}, 2495 | {238, 26, nil}, 2496 | {238, 26, nil}, 2497 | {238, 26, nil}, 2498 | {238, 26, nil}, 2499 | {238, 26, nil}, 2500 | {238, 26, nil}, 2501 | {238, 26, nil}, 2502 | {238, 26, nil}, 2503 | {238, 26, nil}, 2504 | {238, 26, nil}, 2505 | {238, 26, nil}, 2506 | {238, 26, nil}, 2507 | {238, 26, nil}, 2508 | {238, 26, nil}, 2509 | {238, 26, nil}, 2510 | {238, 26, nil}, 2511 | {238, 26, nil}, 2512 | {238, 26, nil}, 2513 | {238, 26, nil}, 2514 | {238, 26, nil}, 2515 | {238, 26, nil}, 2516 | {238, 26, nil}, 2517 | {238, 26, nil}, 2518 | {238, 26, nil}, 2519 | {238, 26, nil}, 2520 | {238, 26, nil}, 2521 | {238, 26, nil}, 2522 | {240, 26, nil}, 2523 | {240, 26, nil}, 2524 | {240, 26, nil}, 2525 | {240, 26, nil}, 2526 | {240, 26, nil}, 2527 | {240, 26, nil}, 2528 | {240, 26, nil}, 2529 | {240, 26, nil}, 2530 | {240, 26, nil}, 2531 | {240, 26, nil}, 2532 | {240, 26, nil}, 2533 | {240, 26, nil}, 2534 | {240, 26, nil}, 2535 | {240, 26, nil}, 2536 | {240, 26, nil}, 2537 | {240, 26, nil}, 2538 | {240, 26, nil}, 2539 | {240, 26, nil}, 2540 | {240, 26, nil}, 2541 | {240, 26, nil}, 2542 | {240, 26, nil}, 2543 | {240, 26, nil}, 2544 | {240, 26, nil}, 2545 | {240, 26, nil}, 2546 | {240, 26, nil}, 2547 | {240, 26, nil}, 2548 | {240, 26, nil}, 2549 | {240, 26, nil}, 2550 | {240, 26, nil}, 2551 | {240, 26, nil}, 2552 | {240, 26, nil}, 2553 | {240, 26, nil}, 2554 | {240, 26, nil}, 2555 | {240, 26, nil}, 2556 | {240, 26, nil}, 2557 | {240, 26, nil}, 2558 | {240, 26, nil}, 2559 | {240, 26, nil}, 2560 | {240, 26, nil}, 2561 | {240, 26, nil}, 2562 | {240, 26, nil}, 2563 | {240, 26, nil}, 2564 | {240, 26, nil}, 2565 | {240, 26, nil}, 2566 | {240, 26, nil}, 2567 | {240, 26, nil}, 2568 | {240, 26, nil}, 2569 | {240, 26, nil}, 2570 | {240, 26, nil}, 2571 | {240, 26, nil}, 2572 | {240, 26, nil}, 2573 | {240, 26, nil}, 2574 | {240, 26, nil}, 2575 | {240, 26, nil}, 2576 | {240, 26, nil}, 2577 | {240, 26, nil}, 2578 | {240, 26, nil}, 2579 | {240, 26, nil}, 2580 | {240, 26, nil}, 2581 | {240, 26, nil}, 2582 | {240, 26, nil}, 2583 | {240, 26, nil}, 2584 | {240, 26, nil}, 2585 | {240, 26, nil}, 2586 | }, 2587 | }, 2588 | {0, 0, 2589 | []*lookupTableEntry{ 2590 | {242, 26, nil}, 2591 | {242, 26, nil}, 2592 | {242, 26, nil}, 2593 | {242, 26, nil}, 2594 | {242, 26, nil}, 2595 | {242, 26, nil}, 2596 | {242, 26, nil}, 2597 | {242, 26, nil}, 2598 | {242, 26, nil}, 2599 | {242, 26, nil}, 2600 | {242, 26, nil}, 2601 | {242, 26, nil}, 2602 | {242, 26, nil}, 2603 | {242, 26, nil}, 2604 | {242, 26, nil}, 2605 | {242, 26, nil}, 2606 | {242, 26, nil}, 2607 | {242, 26, nil}, 2608 | {242, 26, nil}, 2609 | {242, 26, nil}, 2610 | {242, 26, nil}, 2611 | {242, 26, nil}, 2612 | {242, 26, nil}, 2613 | {242, 26, nil}, 2614 | {242, 26, nil}, 2615 | {242, 26, nil}, 2616 | {242, 26, nil}, 2617 | {242, 26, nil}, 2618 | {242, 26, nil}, 2619 | {242, 26, nil}, 2620 | {242, 26, nil}, 2621 | {242, 26, nil}, 2622 | {242, 26, nil}, 2623 | {242, 26, nil}, 2624 | {242, 26, nil}, 2625 | {242, 26, nil}, 2626 | {242, 26, nil}, 2627 | {242, 26, nil}, 2628 | {242, 26, nil}, 2629 | {242, 26, nil}, 2630 | {242, 26, nil}, 2631 | {242, 26, nil}, 2632 | {242, 26, nil}, 2633 | {242, 26, nil}, 2634 | {242, 26, nil}, 2635 | {242, 26, nil}, 2636 | {242, 26, nil}, 2637 | {242, 26, nil}, 2638 | {242, 26, nil}, 2639 | {242, 26, nil}, 2640 | {242, 26, nil}, 2641 | {242, 26, nil}, 2642 | {242, 26, nil}, 2643 | {242, 26, nil}, 2644 | {242, 26, nil}, 2645 | {242, 26, nil}, 2646 | {242, 26, nil}, 2647 | {242, 26, nil}, 2648 | {242, 26, nil}, 2649 | {242, 26, nil}, 2650 | {242, 26, nil}, 2651 | {242, 26, nil}, 2652 | {242, 26, nil}, 2653 | {242, 26, nil}, 2654 | {243, 26, nil}, 2655 | {243, 26, nil}, 2656 | {243, 26, nil}, 2657 | {243, 26, nil}, 2658 | {243, 26, nil}, 2659 | {243, 26, nil}, 2660 | {243, 26, nil}, 2661 | {243, 26, nil}, 2662 | {243, 26, nil}, 2663 | {243, 26, nil}, 2664 | {243, 26, nil}, 2665 | {243, 26, nil}, 2666 | {243, 26, nil}, 2667 | {243, 26, nil}, 2668 | {243, 26, nil}, 2669 | {243, 26, nil}, 2670 | {243, 26, nil}, 2671 | {243, 26, nil}, 2672 | {243, 26, nil}, 2673 | {243, 26, nil}, 2674 | {243, 26, nil}, 2675 | {243, 26, nil}, 2676 | {243, 26, nil}, 2677 | {243, 26, nil}, 2678 | {243, 26, nil}, 2679 | {243, 26, nil}, 2680 | {243, 26, nil}, 2681 | {243, 26, nil}, 2682 | {243, 26, nil}, 2683 | {243, 26, nil}, 2684 | {243, 26, nil}, 2685 | {243, 26, nil}, 2686 | {243, 26, nil}, 2687 | {243, 26, nil}, 2688 | {243, 26, nil}, 2689 | {243, 26, nil}, 2690 | {243, 26, nil}, 2691 | {243, 26, nil}, 2692 | {243, 26, nil}, 2693 | {243, 26, nil}, 2694 | {243, 26, nil}, 2695 | {243, 26, nil}, 2696 | {243, 26, nil}, 2697 | {243, 26, nil}, 2698 | {243, 26, nil}, 2699 | {243, 26, nil}, 2700 | {243, 26, nil}, 2701 | {243, 26, nil}, 2702 | {243, 26, nil}, 2703 | {243, 26, nil}, 2704 | {243, 26, nil}, 2705 | {243, 26, nil}, 2706 | {243, 26, nil}, 2707 | {243, 26, nil}, 2708 | {243, 26, nil}, 2709 | {243, 26, nil}, 2710 | {243, 26, nil}, 2711 | {243, 26, nil}, 2712 | {243, 26, nil}, 2713 | {243, 26, nil}, 2714 | {243, 26, nil}, 2715 | {243, 26, nil}, 2716 | {243, 26, nil}, 2717 | {243, 26, nil}, 2718 | {255, 26, nil}, 2719 | {255, 26, nil}, 2720 | {255, 26, nil}, 2721 | {255, 26, nil}, 2722 | {255, 26, nil}, 2723 | {255, 26, nil}, 2724 | {255, 26, nil}, 2725 | {255, 26, nil}, 2726 | {255, 26, nil}, 2727 | {255, 26, nil}, 2728 | {255, 26, nil}, 2729 | {255, 26, nil}, 2730 | {255, 26, nil}, 2731 | {255, 26, nil}, 2732 | {255, 26, nil}, 2733 | {255, 26, nil}, 2734 | {255, 26, nil}, 2735 | {255, 26, nil}, 2736 | {255, 26, nil}, 2737 | {255, 26, nil}, 2738 | {255, 26, nil}, 2739 | {255, 26, nil}, 2740 | {255, 26, nil}, 2741 | {255, 26, nil}, 2742 | {255, 26, nil}, 2743 | {255, 26, nil}, 2744 | {255, 26, nil}, 2745 | {255, 26, nil}, 2746 | {255, 26, nil}, 2747 | {255, 26, nil}, 2748 | {255, 26, nil}, 2749 | {255, 26, nil}, 2750 | {255, 26, nil}, 2751 | {255, 26, nil}, 2752 | {255, 26, nil}, 2753 | {255, 26, nil}, 2754 | {255, 26, nil}, 2755 | {255, 26, nil}, 2756 | {255, 26, nil}, 2757 | {255, 26, nil}, 2758 | {255, 26, nil}, 2759 | {255, 26, nil}, 2760 | {255, 26, nil}, 2761 | {255, 26, nil}, 2762 | {255, 26, nil}, 2763 | {255, 26, nil}, 2764 | {255, 26, nil}, 2765 | {255, 26, nil}, 2766 | {255, 26, nil}, 2767 | {255, 26, nil}, 2768 | {255, 26, nil}, 2769 | {255, 26, nil}, 2770 | {255, 26, nil}, 2771 | {255, 26, nil}, 2772 | {255, 26, nil}, 2773 | {255, 26, nil}, 2774 | {255, 26, nil}, 2775 | {255, 26, nil}, 2776 | {255, 26, nil}, 2777 | {255, 26, nil}, 2778 | {255, 26, nil}, 2779 | {255, 26, nil}, 2780 | {255, 26, nil}, 2781 | {255, 26, nil}, 2782 | {203, 27, nil}, 2783 | {203, 27, nil}, 2784 | {203, 27, nil}, 2785 | {203, 27, nil}, 2786 | {203, 27, nil}, 2787 | {203, 27, nil}, 2788 | {203, 27, nil}, 2789 | {203, 27, nil}, 2790 | {203, 27, nil}, 2791 | {203, 27, nil}, 2792 | {203, 27, nil}, 2793 | {203, 27, nil}, 2794 | {203, 27, nil}, 2795 | {203, 27, nil}, 2796 | {203, 27, nil}, 2797 | {203, 27, nil}, 2798 | {203, 27, nil}, 2799 | {203, 27, nil}, 2800 | {203, 27, nil}, 2801 | {203, 27, nil}, 2802 | {203, 27, nil}, 2803 | {203, 27, nil}, 2804 | {203, 27, nil}, 2805 | {203, 27, nil}, 2806 | {203, 27, nil}, 2807 | {203, 27, nil}, 2808 | {203, 27, nil}, 2809 | {203, 27, nil}, 2810 | {203, 27, nil}, 2811 | {203, 27, nil}, 2812 | {203, 27, nil}, 2813 | {203, 27, nil}, 2814 | {204, 27, nil}, 2815 | {204, 27, nil}, 2816 | {204, 27, nil}, 2817 | {204, 27, nil}, 2818 | {204, 27, nil}, 2819 | {204, 27, nil}, 2820 | {204, 27, nil}, 2821 | {204, 27, nil}, 2822 | {204, 27, nil}, 2823 | {204, 27, nil}, 2824 | {204, 27, nil}, 2825 | {204, 27, nil}, 2826 | {204, 27, nil}, 2827 | {204, 27, nil}, 2828 | {204, 27, nil}, 2829 | {204, 27, nil}, 2830 | {204, 27, nil}, 2831 | {204, 27, nil}, 2832 | {204, 27, nil}, 2833 | {204, 27, nil}, 2834 | {204, 27, nil}, 2835 | {204, 27, nil}, 2836 | {204, 27, nil}, 2837 | {204, 27, nil}, 2838 | {204, 27, nil}, 2839 | {204, 27, nil}, 2840 | {204, 27, nil}, 2841 | {204, 27, nil}, 2842 | {204, 27, nil}, 2843 | {204, 27, nil}, 2844 | {204, 27, nil}, 2845 | {204, 27, nil}, 2846 | }, 2847 | }, 2848 | {0, 0, 2849 | []*lookupTableEntry{ 2850 | {211, 27, nil}, 2851 | {211, 27, nil}, 2852 | {211, 27, nil}, 2853 | {211, 27, nil}, 2854 | {211, 27, nil}, 2855 | {211, 27, nil}, 2856 | {211, 27, nil}, 2857 | {211, 27, nil}, 2858 | {211, 27, nil}, 2859 | {211, 27, nil}, 2860 | {211, 27, nil}, 2861 | {211, 27, nil}, 2862 | {211, 27, nil}, 2863 | {211, 27, nil}, 2864 | {211, 27, nil}, 2865 | {211, 27, nil}, 2866 | {211, 27, nil}, 2867 | {211, 27, nil}, 2868 | {211, 27, nil}, 2869 | {211, 27, nil}, 2870 | {211, 27, nil}, 2871 | {211, 27, nil}, 2872 | {211, 27, nil}, 2873 | {211, 27, nil}, 2874 | {211, 27, nil}, 2875 | {211, 27, nil}, 2876 | {211, 27, nil}, 2877 | {211, 27, nil}, 2878 | {211, 27, nil}, 2879 | {211, 27, nil}, 2880 | {211, 27, nil}, 2881 | {211, 27, nil}, 2882 | {212, 27, nil}, 2883 | {212, 27, nil}, 2884 | {212, 27, nil}, 2885 | {212, 27, nil}, 2886 | {212, 27, nil}, 2887 | {212, 27, nil}, 2888 | {212, 27, nil}, 2889 | {212, 27, nil}, 2890 | {212, 27, nil}, 2891 | {212, 27, nil}, 2892 | {212, 27, nil}, 2893 | {212, 27, nil}, 2894 | {212, 27, nil}, 2895 | {212, 27, nil}, 2896 | {212, 27, nil}, 2897 | {212, 27, nil}, 2898 | {212, 27, nil}, 2899 | {212, 27, nil}, 2900 | {212, 27, nil}, 2901 | {212, 27, nil}, 2902 | {212, 27, nil}, 2903 | {212, 27, nil}, 2904 | {212, 27, nil}, 2905 | {212, 27, nil}, 2906 | {212, 27, nil}, 2907 | {212, 27, nil}, 2908 | {212, 27, nil}, 2909 | {212, 27, nil}, 2910 | {212, 27, nil}, 2911 | {212, 27, nil}, 2912 | {212, 27, nil}, 2913 | {212, 27, nil}, 2914 | {214, 27, nil}, 2915 | {214, 27, nil}, 2916 | {214, 27, nil}, 2917 | {214, 27, nil}, 2918 | {214, 27, nil}, 2919 | {214, 27, nil}, 2920 | {214, 27, nil}, 2921 | {214, 27, nil}, 2922 | {214, 27, nil}, 2923 | {214, 27, nil}, 2924 | {214, 27, nil}, 2925 | {214, 27, nil}, 2926 | {214, 27, nil}, 2927 | {214, 27, nil}, 2928 | {214, 27, nil}, 2929 | {214, 27, nil}, 2930 | {214, 27, nil}, 2931 | {214, 27, nil}, 2932 | {214, 27, nil}, 2933 | {214, 27, nil}, 2934 | {214, 27, nil}, 2935 | {214, 27, nil}, 2936 | {214, 27, nil}, 2937 | {214, 27, nil}, 2938 | {214, 27, nil}, 2939 | {214, 27, nil}, 2940 | {214, 27, nil}, 2941 | {214, 27, nil}, 2942 | {214, 27, nil}, 2943 | {214, 27, nil}, 2944 | {214, 27, nil}, 2945 | {214, 27, nil}, 2946 | {221, 27, nil}, 2947 | {221, 27, nil}, 2948 | {221, 27, nil}, 2949 | {221, 27, nil}, 2950 | {221, 27, nil}, 2951 | {221, 27, nil}, 2952 | {221, 27, nil}, 2953 | {221, 27, nil}, 2954 | {221, 27, nil}, 2955 | {221, 27, nil}, 2956 | {221, 27, nil}, 2957 | {221, 27, nil}, 2958 | {221, 27, nil}, 2959 | {221, 27, nil}, 2960 | {221, 27, nil}, 2961 | {221, 27, nil}, 2962 | {221, 27, nil}, 2963 | {221, 27, nil}, 2964 | {221, 27, nil}, 2965 | {221, 27, nil}, 2966 | {221, 27, nil}, 2967 | {221, 27, nil}, 2968 | {221, 27, nil}, 2969 | {221, 27, nil}, 2970 | {221, 27, nil}, 2971 | {221, 27, nil}, 2972 | {221, 27, nil}, 2973 | {221, 27, nil}, 2974 | {221, 27, nil}, 2975 | {221, 27, nil}, 2976 | {221, 27, nil}, 2977 | {221, 27, nil}, 2978 | {222, 27, nil}, 2979 | {222, 27, nil}, 2980 | {222, 27, nil}, 2981 | {222, 27, nil}, 2982 | {222, 27, nil}, 2983 | {222, 27, nil}, 2984 | {222, 27, nil}, 2985 | {222, 27, nil}, 2986 | {222, 27, nil}, 2987 | {222, 27, nil}, 2988 | {222, 27, nil}, 2989 | {222, 27, nil}, 2990 | {222, 27, nil}, 2991 | {222, 27, nil}, 2992 | {222, 27, nil}, 2993 | {222, 27, nil}, 2994 | {222, 27, nil}, 2995 | {222, 27, nil}, 2996 | {222, 27, nil}, 2997 | {222, 27, nil}, 2998 | {222, 27, nil}, 2999 | {222, 27, nil}, 3000 | {222, 27, nil}, 3001 | {222, 27, nil}, 3002 | {222, 27, nil}, 3003 | {222, 27, nil}, 3004 | {222, 27, nil}, 3005 | {222, 27, nil}, 3006 | {222, 27, nil}, 3007 | {222, 27, nil}, 3008 | {222, 27, nil}, 3009 | {222, 27, nil}, 3010 | {223, 27, nil}, 3011 | {223, 27, nil}, 3012 | {223, 27, nil}, 3013 | {223, 27, nil}, 3014 | {223, 27, nil}, 3015 | {223, 27, nil}, 3016 | {223, 27, nil}, 3017 | {223, 27, nil}, 3018 | {223, 27, nil}, 3019 | {223, 27, nil}, 3020 | {223, 27, nil}, 3021 | {223, 27, nil}, 3022 | {223, 27, nil}, 3023 | {223, 27, nil}, 3024 | {223, 27, nil}, 3025 | {223, 27, nil}, 3026 | {223, 27, nil}, 3027 | {223, 27, nil}, 3028 | {223, 27, nil}, 3029 | {223, 27, nil}, 3030 | {223, 27, nil}, 3031 | {223, 27, nil}, 3032 | {223, 27, nil}, 3033 | {223, 27, nil}, 3034 | {223, 27, nil}, 3035 | {223, 27, nil}, 3036 | {223, 27, nil}, 3037 | {223, 27, nil}, 3038 | {223, 27, nil}, 3039 | {223, 27, nil}, 3040 | {223, 27, nil}, 3041 | {223, 27, nil}, 3042 | {241, 27, nil}, 3043 | {241, 27, nil}, 3044 | {241, 27, nil}, 3045 | {241, 27, nil}, 3046 | {241, 27, nil}, 3047 | {241, 27, nil}, 3048 | {241, 27, nil}, 3049 | {241, 27, nil}, 3050 | {241, 27, nil}, 3051 | {241, 27, nil}, 3052 | {241, 27, nil}, 3053 | {241, 27, nil}, 3054 | {241, 27, nil}, 3055 | {241, 27, nil}, 3056 | {241, 27, nil}, 3057 | {241, 27, nil}, 3058 | {241, 27, nil}, 3059 | {241, 27, nil}, 3060 | {241, 27, nil}, 3061 | {241, 27, nil}, 3062 | {241, 27, nil}, 3063 | {241, 27, nil}, 3064 | {241, 27, nil}, 3065 | {241, 27, nil}, 3066 | {241, 27, nil}, 3067 | {241, 27, nil}, 3068 | {241, 27, nil}, 3069 | {241, 27, nil}, 3070 | {241, 27, nil}, 3071 | {241, 27, nil}, 3072 | {241, 27, nil}, 3073 | {241, 27, nil}, 3074 | {244, 27, nil}, 3075 | {244, 27, nil}, 3076 | {244, 27, nil}, 3077 | {244, 27, nil}, 3078 | {244, 27, nil}, 3079 | {244, 27, nil}, 3080 | {244, 27, nil}, 3081 | {244, 27, nil}, 3082 | {244, 27, nil}, 3083 | {244, 27, nil}, 3084 | {244, 27, nil}, 3085 | {244, 27, nil}, 3086 | {244, 27, nil}, 3087 | {244, 27, nil}, 3088 | {244, 27, nil}, 3089 | {244, 27, nil}, 3090 | {244, 27, nil}, 3091 | {244, 27, nil}, 3092 | {244, 27, nil}, 3093 | {244, 27, nil}, 3094 | {244, 27, nil}, 3095 | {244, 27, nil}, 3096 | {244, 27, nil}, 3097 | {244, 27, nil}, 3098 | {244, 27, nil}, 3099 | {244, 27, nil}, 3100 | {244, 27, nil}, 3101 | {244, 27, nil}, 3102 | {244, 27, nil}, 3103 | {244, 27, nil}, 3104 | {244, 27, nil}, 3105 | {244, 27, nil}, 3106 | }, 3107 | }, 3108 | {0, 0, 3109 | []*lookupTableEntry{ 3110 | {245, 27, nil}, 3111 | {245, 27, nil}, 3112 | {245, 27, nil}, 3113 | {245, 27, nil}, 3114 | {245, 27, nil}, 3115 | {245, 27, nil}, 3116 | {245, 27, nil}, 3117 | {245, 27, nil}, 3118 | {245, 27, nil}, 3119 | {245, 27, nil}, 3120 | {245, 27, nil}, 3121 | {245, 27, nil}, 3122 | {245, 27, nil}, 3123 | {245, 27, nil}, 3124 | {245, 27, nil}, 3125 | {245, 27, nil}, 3126 | {245, 27, nil}, 3127 | {245, 27, nil}, 3128 | {245, 27, nil}, 3129 | {245, 27, nil}, 3130 | {245, 27, nil}, 3131 | {245, 27, nil}, 3132 | {245, 27, nil}, 3133 | {245, 27, nil}, 3134 | {245, 27, nil}, 3135 | {245, 27, nil}, 3136 | {245, 27, nil}, 3137 | {245, 27, nil}, 3138 | {245, 27, nil}, 3139 | {245, 27, nil}, 3140 | {245, 27, nil}, 3141 | {245, 27, nil}, 3142 | {246, 27, nil}, 3143 | {246, 27, nil}, 3144 | {246, 27, nil}, 3145 | {246, 27, nil}, 3146 | {246, 27, nil}, 3147 | {246, 27, nil}, 3148 | {246, 27, nil}, 3149 | {246, 27, nil}, 3150 | {246, 27, nil}, 3151 | {246, 27, nil}, 3152 | {246, 27, nil}, 3153 | {246, 27, nil}, 3154 | {246, 27, nil}, 3155 | {246, 27, nil}, 3156 | {246, 27, nil}, 3157 | {246, 27, nil}, 3158 | {246, 27, nil}, 3159 | {246, 27, nil}, 3160 | {246, 27, nil}, 3161 | {246, 27, nil}, 3162 | {246, 27, nil}, 3163 | {246, 27, nil}, 3164 | {246, 27, nil}, 3165 | {246, 27, nil}, 3166 | {246, 27, nil}, 3167 | {246, 27, nil}, 3168 | {246, 27, nil}, 3169 | {246, 27, nil}, 3170 | {246, 27, nil}, 3171 | {246, 27, nil}, 3172 | {246, 27, nil}, 3173 | {246, 27, nil}, 3174 | {247, 27, nil}, 3175 | {247, 27, nil}, 3176 | {247, 27, nil}, 3177 | {247, 27, nil}, 3178 | {247, 27, nil}, 3179 | {247, 27, nil}, 3180 | {247, 27, nil}, 3181 | {247, 27, nil}, 3182 | {247, 27, nil}, 3183 | {247, 27, nil}, 3184 | {247, 27, nil}, 3185 | {247, 27, nil}, 3186 | {247, 27, nil}, 3187 | {247, 27, nil}, 3188 | {247, 27, nil}, 3189 | {247, 27, nil}, 3190 | {247, 27, nil}, 3191 | {247, 27, nil}, 3192 | {247, 27, nil}, 3193 | {247, 27, nil}, 3194 | {247, 27, nil}, 3195 | {247, 27, nil}, 3196 | {247, 27, nil}, 3197 | {247, 27, nil}, 3198 | {247, 27, nil}, 3199 | {247, 27, nil}, 3200 | {247, 27, nil}, 3201 | {247, 27, nil}, 3202 | {247, 27, nil}, 3203 | {247, 27, nil}, 3204 | {247, 27, nil}, 3205 | {247, 27, nil}, 3206 | {248, 27, nil}, 3207 | {248, 27, nil}, 3208 | {248, 27, nil}, 3209 | {248, 27, nil}, 3210 | {248, 27, nil}, 3211 | {248, 27, nil}, 3212 | {248, 27, nil}, 3213 | {248, 27, nil}, 3214 | {248, 27, nil}, 3215 | {248, 27, nil}, 3216 | {248, 27, nil}, 3217 | {248, 27, nil}, 3218 | {248, 27, nil}, 3219 | {248, 27, nil}, 3220 | {248, 27, nil}, 3221 | {248, 27, nil}, 3222 | {248, 27, nil}, 3223 | {248, 27, nil}, 3224 | {248, 27, nil}, 3225 | {248, 27, nil}, 3226 | {248, 27, nil}, 3227 | {248, 27, nil}, 3228 | {248, 27, nil}, 3229 | {248, 27, nil}, 3230 | {248, 27, nil}, 3231 | {248, 27, nil}, 3232 | {248, 27, nil}, 3233 | {248, 27, nil}, 3234 | {248, 27, nil}, 3235 | {248, 27, nil}, 3236 | {248, 27, nil}, 3237 | {248, 27, nil}, 3238 | {250, 27, nil}, 3239 | {250, 27, nil}, 3240 | {250, 27, nil}, 3241 | {250, 27, nil}, 3242 | {250, 27, nil}, 3243 | {250, 27, nil}, 3244 | {250, 27, nil}, 3245 | {250, 27, nil}, 3246 | {250, 27, nil}, 3247 | {250, 27, nil}, 3248 | {250, 27, nil}, 3249 | {250, 27, nil}, 3250 | {250, 27, nil}, 3251 | {250, 27, nil}, 3252 | {250, 27, nil}, 3253 | {250, 27, nil}, 3254 | {250, 27, nil}, 3255 | {250, 27, nil}, 3256 | {250, 27, nil}, 3257 | {250, 27, nil}, 3258 | {250, 27, nil}, 3259 | {250, 27, nil}, 3260 | {250, 27, nil}, 3261 | {250, 27, nil}, 3262 | {250, 27, nil}, 3263 | {250, 27, nil}, 3264 | {250, 27, nil}, 3265 | {250, 27, nil}, 3266 | {250, 27, nil}, 3267 | {250, 27, nil}, 3268 | {250, 27, nil}, 3269 | {250, 27, nil}, 3270 | {251, 27, nil}, 3271 | {251, 27, nil}, 3272 | {251, 27, nil}, 3273 | {251, 27, nil}, 3274 | {251, 27, nil}, 3275 | {251, 27, nil}, 3276 | {251, 27, nil}, 3277 | {251, 27, nil}, 3278 | {251, 27, nil}, 3279 | {251, 27, nil}, 3280 | {251, 27, nil}, 3281 | {251, 27, nil}, 3282 | {251, 27, nil}, 3283 | {251, 27, nil}, 3284 | {251, 27, nil}, 3285 | {251, 27, nil}, 3286 | {251, 27, nil}, 3287 | {251, 27, nil}, 3288 | {251, 27, nil}, 3289 | {251, 27, nil}, 3290 | {251, 27, nil}, 3291 | {251, 27, nil}, 3292 | {251, 27, nil}, 3293 | {251, 27, nil}, 3294 | {251, 27, nil}, 3295 | {251, 27, nil}, 3296 | {251, 27, nil}, 3297 | {251, 27, nil}, 3298 | {251, 27, nil}, 3299 | {251, 27, nil}, 3300 | {251, 27, nil}, 3301 | {251, 27, nil}, 3302 | {252, 27, nil}, 3303 | {252, 27, nil}, 3304 | {252, 27, nil}, 3305 | {252, 27, nil}, 3306 | {252, 27, nil}, 3307 | {252, 27, nil}, 3308 | {252, 27, nil}, 3309 | {252, 27, nil}, 3310 | {252, 27, nil}, 3311 | {252, 27, nil}, 3312 | {252, 27, nil}, 3313 | {252, 27, nil}, 3314 | {252, 27, nil}, 3315 | {252, 27, nil}, 3316 | {252, 27, nil}, 3317 | {252, 27, nil}, 3318 | {252, 27, nil}, 3319 | {252, 27, nil}, 3320 | {252, 27, nil}, 3321 | {252, 27, nil}, 3322 | {252, 27, nil}, 3323 | {252, 27, nil}, 3324 | {252, 27, nil}, 3325 | {252, 27, nil}, 3326 | {252, 27, nil}, 3327 | {252, 27, nil}, 3328 | {252, 27, nil}, 3329 | {252, 27, nil}, 3330 | {252, 27, nil}, 3331 | {252, 27, nil}, 3332 | {252, 27, nil}, 3333 | {252, 27, nil}, 3334 | {253, 27, nil}, 3335 | {253, 27, nil}, 3336 | {253, 27, nil}, 3337 | {253, 27, nil}, 3338 | {253, 27, nil}, 3339 | {253, 27, nil}, 3340 | {253, 27, nil}, 3341 | {253, 27, nil}, 3342 | {253, 27, nil}, 3343 | {253, 27, nil}, 3344 | {253, 27, nil}, 3345 | {253, 27, nil}, 3346 | {253, 27, nil}, 3347 | {253, 27, nil}, 3348 | {253, 27, nil}, 3349 | {253, 27, nil}, 3350 | {253, 27, nil}, 3351 | {253, 27, nil}, 3352 | {253, 27, nil}, 3353 | {253, 27, nil}, 3354 | {253, 27, nil}, 3355 | {253, 27, nil}, 3356 | {253, 27, nil}, 3357 | {253, 27, nil}, 3358 | {253, 27, nil}, 3359 | {253, 27, nil}, 3360 | {253, 27, nil}, 3361 | {253, 27, nil}, 3362 | {253, 27, nil}, 3363 | {253, 27, nil}, 3364 | {253, 27, nil}, 3365 | {253, 27, nil}, 3366 | }, 3367 | }, 3368 | {0, 0, 3369 | []*lookupTableEntry{ 3370 | {254, 27, nil}, 3371 | {254, 27, nil}, 3372 | {254, 27, nil}, 3373 | {254, 27, nil}, 3374 | {254, 27, nil}, 3375 | {254, 27, nil}, 3376 | {254, 27, nil}, 3377 | {254, 27, nil}, 3378 | {254, 27, nil}, 3379 | {254, 27, nil}, 3380 | {254, 27, nil}, 3381 | {254, 27, nil}, 3382 | {254, 27, nil}, 3383 | {254, 27, nil}, 3384 | {254, 27, nil}, 3385 | {254, 27, nil}, 3386 | {254, 27, nil}, 3387 | {254, 27, nil}, 3388 | {254, 27, nil}, 3389 | {254, 27, nil}, 3390 | {254, 27, nil}, 3391 | {254, 27, nil}, 3392 | {254, 27, nil}, 3393 | {254, 27, nil}, 3394 | {254, 27, nil}, 3395 | {254, 27, nil}, 3396 | {254, 27, nil}, 3397 | {254, 27, nil}, 3398 | {254, 27, nil}, 3399 | {254, 27, nil}, 3400 | {254, 27, nil}, 3401 | {254, 27, nil}, 3402 | {2, 28, nil}, 3403 | {2, 28, nil}, 3404 | {2, 28, nil}, 3405 | {2, 28, nil}, 3406 | {2, 28, nil}, 3407 | {2, 28, nil}, 3408 | {2, 28, nil}, 3409 | {2, 28, nil}, 3410 | {2, 28, nil}, 3411 | {2, 28, nil}, 3412 | {2, 28, nil}, 3413 | {2, 28, nil}, 3414 | {2, 28, nil}, 3415 | {2, 28, nil}, 3416 | {2, 28, nil}, 3417 | {2, 28, nil}, 3418 | {3, 28, nil}, 3419 | {3, 28, nil}, 3420 | {3, 28, nil}, 3421 | {3, 28, nil}, 3422 | {3, 28, nil}, 3423 | {3, 28, nil}, 3424 | {3, 28, nil}, 3425 | {3, 28, nil}, 3426 | {3, 28, nil}, 3427 | {3, 28, nil}, 3428 | {3, 28, nil}, 3429 | {3, 28, nil}, 3430 | {3, 28, nil}, 3431 | {3, 28, nil}, 3432 | {3, 28, nil}, 3433 | {3, 28, nil}, 3434 | {4, 28, nil}, 3435 | {4, 28, nil}, 3436 | {4, 28, nil}, 3437 | {4, 28, nil}, 3438 | {4, 28, nil}, 3439 | {4, 28, nil}, 3440 | {4, 28, nil}, 3441 | {4, 28, nil}, 3442 | {4, 28, nil}, 3443 | {4, 28, nil}, 3444 | {4, 28, nil}, 3445 | {4, 28, nil}, 3446 | {4, 28, nil}, 3447 | {4, 28, nil}, 3448 | {4, 28, nil}, 3449 | {4, 28, nil}, 3450 | {5, 28, nil}, 3451 | {5, 28, nil}, 3452 | {5, 28, nil}, 3453 | {5, 28, nil}, 3454 | {5, 28, nil}, 3455 | {5, 28, nil}, 3456 | {5, 28, nil}, 3457 | {5, 28, nil}, 3458 | {5, 28, nil}, 3459 | {5, 28, nil}, 3460 | {5, 28, nil}, 3461 | {5, 28, nil}, 3462 | {5, 28, nil}, 3463 | {5, 28, nil}, 3464 | {5, 28, nil}, 3465 | {5, 28, nil}, 3466 | {6, 28, nil}, 3467 | {6, 28, nil}, 3468 | {6, 28, nil}, 3469 | {6, 28, nil}, 3470 | {6, 28, nil}, 3471 | {6, 28, nil}, 3472 | {6, 28, nil}, 3473 | {6, 28, nil}, 3474 | {6, 28, nil}, 3475 | {6, 28, nil}, 3476 | {6, 28, nil}, 3477 | {6, 28, nil}, 3478 | {6, 28, nil}, 3479 | {6, 28, nil}, 3480 | {6, 28, nil}, 3481 | {6, 28, nil}, 3482 | {7, 28, nil}, 3483 | {7, 28, nil}, 3484 | {7, 28, nil}, 3485 | {7, 28, nil}, 3486 | {7, 28, nil}, 3487 | {7, 28, nil}, 3488 | {7, 28, nil}, 3489 | {7, 28, nil}, 3490 | {7, 28, nil}, 3491 | {7, 28, nil}, 3492 | {7, 28, nil}, 3493 | {7, 28, nil}, 3494 | {7, 28, nil}, 3495 | {7, 28, nil}, 3496 | {7, 28, nil}, 3497 | {7, 28, nil}, 3498 | {8, 28, nil}, 3499 | {8, 28, nil}, 3500 | {8, 28, nil}, 3501 | {8, 28, nil}, 3502 | {8, 28, nil}, 3503 | {8, 28, nil}, 3504 | {8, 28, nil}, 3505 | {8, 28, nil}, 3506 | {8, 28, nil}, 3507 | {8, 28, nil}, 3508 | {8, 28, nil}, 3509 | {8, 28, nil}, 3510 | {8, 28, nil}, 3511 | {8, 28, nil}, 3512 | {8, 28, nil}, 3513 | {8, 28, nil}, 3514 | {11, 28, nil}, 3515 | {11, 28, nil}, 3516 | {11, 28, nil}, 3517 | {11, 28, nil}, 3518 | {11, 28, nil}, 3519 | {11, 28, nil}, 3520 | {11, 28, nil}, 3521 | {11, 28, nil}, 3522 | {11, 28, nil}, 3523 | {11, 28, nil}, 3524 | {11, 28, nil}, 3525 | {11, 28, nil}, 3526 | {11, 28, nil}, 3527 | {11, 28, nil}, 3528 | {11, 28, nil}, 3529 | {11, 28, nil}, 3530 | {12, 28, nil}, 3531 | {12, 28, nil}, 3532 | {12, 28, nil}, 3533 | {12, 28, nil}, 3534 | {12, 28, nil}, 3535 | {12, 28, nil}, 3536 | {12, 28, nil}, 3537 | {12, 28, nil}, 3538 | {12, 28, nil}, 3539 | {12, 28, nil}, 3540 | {12, 28, nil}, 3541 | {12, 28, nil}, 3542 | {12, 28, nil}, 3543 | {12, 28, nil}, 3544 | {12, 28, nil}, 3545 | {12, 28, nil}, 3546 | {14, 28, nil}, 3547 | {14, 28, nil}, 3548 | {14, 28, nil}, 3549 | {14, 28, nil}, 3550 | {14, 28, nil}, 3551 | {14, 28, nil}, 3552 | {14, 28, nil}, 3553 | {14, 28, nil}, 3554 | {14, 28, nil}, 3555 | {14, 28, nil}, 3556 | {14, 28, nil}, 3557 | {14, 28, nil}, 3558 | {14, 28, nil}, 3559 | {14, 28, nil}, 3560 | {14, 28, nil}, 3561 | {14, 28, nil}, 3562 | {15, 28, nil}, 3563 | {15, 28, nil}, 3564 | {15, 28, nil}, 3565 | {15, 28, nil}, 3566 | {15, 28, nil}, 3567 | {15, 28, nil}, 3568 | {15, 28, nil}, 3569 | {15, 28, nil}, 3570 | {15, 28, nil}, 3571 | {15, 28, nil}, 3572 | {15, 28, nil}, 3573 | {15, 28, nil}, 3574 | {15, 28, nil}, 3575 | {15, 28, nil}, 3576 | {15, 28, nil}, 3577 | {15, 28, nil}, 3578 | {16, 28, nil}, 3579 | {16, 28, nil}, 3580 | {16, 28, nil}, 3581 | {16, 28, nil}, 3582 | {16, 28, nil}, 3583 | {16, 28, nil}, 3584 | {16, 28, nil}, 3585 | {16, 28, nil}, 3586 | {16, 28, nil}, 3587 | {16, 28, nil}, 3588 | {16, 28, nil}, 3589 | {16, 28, nil}, 3590 | {16, 28, nil}, 3591 | {16, 28, nil}, 3592 | {16, 28, nil}, 3593 | {16, 28, nil}, 3594 | {17, 28, nil}, 3595 | {17, 28, nil}, 3596 | {17, 28, nil}, 3597 | {17, 28, nil}, 3598 | {17, 28, nil}, 3599 | {17, 28, nil}, 3600 | {17, 28, nil}, 3601 | {17, 28, nil}, 3602 | {17, 28, nil}, 3603 | {17, 28, nil}, 3604 | {17, 28, nil}, 3605 | {17, 28, nil}, 3606 | {17, 28, nil}, 3607 | {17, 28, nil}, 3608 | {17, 28, nil}, 3609 | {17, 28, nil}, 3610 | {18, 28, nil}, 3611 | {18, 28, nil}, 3612 | {18, 28, nil}, 3613 | {18, 28, nil}, 3614 | {18, 28, nil}, 3615 | {18, 28, nil}, 3616 | {18, 28, nil}, 3617 | {18, 28, nil}, 3618 | {18, 28, nil}, 3619 | {18, 28, nil}, 3620 | {18, 28, nil}, 3621 | {18, 28, nil}, 3622 | {18, 28, nil}, 3623 | {18, 28, nil}, 3624 | {18, 28, nil}, 3625 | {18, 28, nil}, 3626 | }, 3627 | }, 3628 | {0, 0, 3629 | []*lookupTableEntry{ 3630 | {19, 28, nil}, 3631 | {19, 28, nil}, 3632 | {19, 28, nil}, 3633 | {19, 28, nil}, 3634 | {19, 28, nil}, 3635 | {19, 28, nil}, 3636 | {19, 28, nil}, 3637 | {19, 28, nil}, 3638 | {19, 28, nil}, 3639 | {19, 28, nil}, 3640 | {19, 28, nil}, 3641 | {19, 28, nil}, 3642 | {19, 28, nil}, 3643 | {19, 28, nil}, 3644 | {19, 28, nil}, 3645 | {19, 28, nil}, 3646 | {20, 28, nil}, 3647 | {20, 28, nil}, 3648 | {20, 28, nil}, 3649 | {20, 28, nil}, 3650 | {20, 28, nil}, 3651 | {20, 28, nil}, 3652 | {20, 28, nil}, 3653 | {20, 28, nil}, 3654 | {20, 28, nil}, 3655 | {20, 28, nil}, 3656 | {20, 28, nil}, 3657 | {20, 28, nil}, 3658 | {20, 28, nil}, 3659 | {20, 28, nil}, 3660 | {20, 28, nil}, 3661 | {20, 28, nil}, 3662 | {21, 28, nil}, 3663 | {21, 28, nil}, 3664 | {21, 28, nil}, 3665 | {21, 28, nil}, 3666 | {21, 28, nil}, 3667 | {21, 28, nil}, 3668 | {21, 28, nil}, 3669 | {21, 28, nil}, 3670 | {21, 28, nil}, 3671 | {21, 28, nil}, 3672 | {21, 28, nil}, 3673 | {21, 28, nil}, 3674 | {21, 28, nil}, 3675 | {21, 28, nil}, 3676 | {21, 28, nil}, 3677 | {21, 28, nil}, 3678 | {23, 28, nil}, 3679 | {23, 28, nil}, 3680 | {23, 28, nil}, 3681 | {23, 28, nil}, 3682 | {23, 28, nil}, 3683 | {23, 28, nil}, 3684 | {23, 28, nil}, 3685 | {23, 28, nil}, 3686 | {23, 28, nil}, 3687 | {23, 28, nil}, 3688 | {23, 28, nil}, 3689 | {23, 28, nil}, 3690 | {23, 28, nil}, 3691 | {23, 28, nil}, 3692 | {23, 28, nil}, 3693 | {23, 28, nil}, 3694 | {24, 28, nil}, 3695 | {24, 28, nil}, 3696 | {24, 28, nil}, 3697 | {24, 28, nil}, 3698 | {24, 28, nil}, 3699 | {24, 28, nil}, 3700 | {24, 28, nil}, 3701 | {24, 28, nil}, 3702 | {24, 28, nil}, 3703 | {24, 28, nil}, 3704 | {24, 28, nil}, 3705 | {24, 28, nil}, 3706 | {24, 28, nil}, 3707 | {24, 28, nil}, 3708 | {24, 28, nil}, 3709 | {24, 28, nil}, 3710 | {25, 28, nil}, 3711 | {25, 28, nil}, 3712 | {25, 28, nil}, 3713 | {25, 28, nil}, 3714 | {25, 28, nil}, 3715 | {25, 28, nil}, 3716 | {25, 28, nil}, 3717 | {25, 28, nil}, 3718 | {25, 28, nil}, 3719 | {25, 28, nil}, 3720 | {25, 28, nil}, 3721 | {25, 28, nil}, 3722 | {25, 28, nil}, 3723 | {25, 28, nil}, 3724 | {25, 28, nil}, 3725 | {25, 28, nil}, 3726 | {26, 28, nil}, 3727 | {26, 28, nil}, 3728 | {26, 28, nil}, 3729 | {26, 28, nil}, 3730 | {26, 28, nil}, 3731 | {26, 28, nil}, 3732 | {26, 28, nil}, 3733 | {26, 28, nil}, 3734 | {26, 28, nil}, 3735 | {26, 28, nil}, 3736 | {26, 28, nil}, 3737 | {26, 28, nil}, 3738 | {26, 28, nil}, 3739 | {26, 28, nil}, 3740 | {26, 28, nil}, 3741 | {26, 28, nil}, 3742 | {27, 28, nil}, 3743 | {27, 28, nil}, 3744 | {27, 28, nil}, 3745 | {27, 28, nil}, 3746 | {27, 28, nil}, 3747 | {27, 28, nil}, 3748 | {27, 28, nil}, 3749 | {27, 28, nil}, 3750 | {27, 28, nil}, 3751 | {27, 28, nil}, 3752 | {27, 28, nil}, 3753 | {27, 28, nil}, 3754 | {27, 28, nil}, 3755 | {27, 28, nil}, 3756 | {27, 28, nil}, 3757 | {27, 28, nil}, 3758 | {28, 28, nil}, 3759 | {28, 28, nil}, 3760 | {28, 28, nil}, 3761 | {28, 28, nil}, 3762 | {28, 28, nil}, 3763 | {28, 28, nil}, 3764 | {28, 28, nil}, 3765 | {28, 28, nil}, 3766 | {28, 28, nil}, 3767 | {28, 28, nil}, 3768 | {28, 28, nil}, 3769 | {28, 28, nil}, 3770 | {28, 28, nil}, 3771 | {28, 28, nil}, 3772 | {28, 28, nil}, 3773 | {28, 28, nil}, 3774 | {29, 28, nil}, 3775 | {29, 28, nil}, 3776 | {29, 28, nil}, 3777 | {29, 28, nil}, 3778 | {29, 28, nil}, 3779 | {29, 28, nil}, 3780 | {29, 28, nil}, 3781 | {29, 28, nil}, 3782 | {29, 28, nil}, 3783 | {29, 28, nil}, 3784 | {29, 28, nil}, 3785 | {29, 28, nil}, 3786 | {29, 28, nil}, 3787 | {29, 28, nil}, 3788 | {29, 28, nil}, 3789 | {29, 28, nil}, 3790 | {30, 28, nil}, 3791 | {30, 28, nil}, 3792 | {30, 28, nil}, 3793 | {30, 28, nil}, 3794 | {30, 28, nil}, 3795 | {30, 28, nil}, 3796 | {30, 28, nil}, 3797 | {30, 28, nil}, 3798 | {30, 28, nil}, 3799 | {30, 28, nil}, 3800 | {30, 28, nil}, 3801 | {30, 28, nil}, 3802 | {30, 28, nil}, 3803 | {30, 28, nil}, 3804 | {30, 28, nil}, 3805 | {30, 28, nil}, 3806 | {31, 28, nil}, 3807 | {31, 28, nil}, 3808 | {31, 28, nil}, 3809 | {31, 28, nil}, 3810 | {31, 28, nil}, 3811 | {31, 28, nil}, 3812 | {31, 28, nil}, 3813 | {31, 28, nil}, 3814 | {31, 28, nil}, 3815 | {31, 28, nil}, 3816 | {31, 28, nil}, 3817 | {31, 28, nil}, 3818 | {31, 28, nil}, 3819 | {31, 28, nil}, 3820 | {31, 28, nil}, 3821 | {31, 28, nil}, 3822 | {127, 28, nil}, 3823 | {127, 28, nil}, 3824 | {127, 28, nil}, 3825 | {127, 28, nil}, 3826 | {127, 28, nil}, 3827 | {127, 28, nil}, 3828 | {127, 28, nil}, 3829 | {127, 28, nil}, 3830 | {127, 28, nil}, 3831 | {127, 28, nil}, 3832 | {127, 28, nil}, 3833 | {127, 28, nil}, 3834 | {127, 28, nil}, 3835 | {127, 28, nil}, 3836 | {127, 28, nil}, 3837 | {127, 28, nil}, 3838 | {220, 28, nil}, 3839 | {220, 28, nil}, 3840 | {220, 28, nil}, 3841 | {220, 28, nil}, 3842 | {220, 28, nil}, 3843 | {220, 28, nil}, 3844 | {220, 28, nil}, 3845 | {220, 28, nil}, 3846 | {220, 28, nil}, 3847 | {220, 28, nil}, 3848 | {220, 28, nil}, 3849 | {220, 28, nil}, 3850 | {220, 28, nil}, 3851 | {220, 28, nil}, 3852 | {220, 28, nil}, 3853 | {220, 28, nil}, 3854 | {249, 28, nil}, 3855 | {249, 28, nil}, 3856 | {249, 28, nil}, 3857 | {249, 28, nil}, 3858 | {249, 28, nil}, 3859 | {249, 28, nil}, 3860 | {249, 28, nil}, 3861 | {249, 28, nil}, 3862 | {249, 28, nil}, 3863 | {249, 28, nil}, 3864 | {249, 28, nil}, 3865 | {249, 28, nil}, 3866 | {249, 28, nil}, 3867 | {249, 28, nil}, 3868 | {249, 28, nil}, 3869 | {249, 28, nil}, 3870 | {10, 30, nil}, 3871 | {10, 30, nil}, 3872 | {10, 30, nil}, 3873 | {10, 30, nil}, 3874 | {13, 30, nil}, 3875 | {13, 30, nil}, 3876 | {13, 30, nil}, 3877 | {13, 30, nil}, 3878 | {22, 30, nil}, 3879 | {22, 30, nil}, 3880 | {22, 30, nil}, 3881 | {22, 30, nil}, 3882 | {256, 30, nil}, 3883 | {256, 30, nil}, 3884 | {256, 30, nil}, 3885 | {256, 30, nil}, 3886 | }, 3887 | }, 3888 | }, 3889 | }, 3890 | }, 3891 | }, 3892 | } 3893 | --------------------------------------------------------------------------------