1/* 2 * pgn4web javascript chessboard 3 * copyright (C) 2009-2013 Paolo Casaschi 4 * see README file and http://pgn4web.casaschi.net 5 * for credits, license and more details 6 * 7 * Huffman encoding/decoding derived from code at http://rumkin.com/tools/compression/compress_huff.php 8 */ 9 10// version 1 of PGN encoding: 11// encodedPGN = nnn$xxx0 12// nnn = number representing bytes length of the decoded message 13// $ = dollar char (delimiter for length info) 14// xxx = encoded text (using LetterCodes below) 15// 0 = zero char (version marker) 16 17"use strict"; 18 19var encodingCharSet_dec; 20var encodingCharSet_enc; 21var encodingCharSet = encodingCharSet_enc = "$0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"; 22var encodingVersion_dec; 23var encodingVersion_enc; 24var encodingVersion = encodingVersion_enc = 1; 25var errorString; 26 27if (((encodingCharSet_dec != undefined) && (encodingCharSet_enc != encodingCharSet_dec)) || 28 ((encodingVersion_dec != undefined) && (encodingVersion_enc != encodingVersion_dec))) { 29 errorString = "error: PGN encoding/decoding version/charset mismatch"; 30 if (typeof myAlert == "function") { myAlert(errorString); } 31 else { alert(errorString); } 32} 33 34function EncodePGN(ov) { 35 36 function BitsToBytes(i) { 37 var o = 0; 38 if (i.charAt(0) == '1') { o += 32; } 39 if (i.charAt(1) == '1') { o += 16; } 40 if (i.charAt(2) == '1') { o += 8; } 41 if (i.charAt(3) == '1') { o += 4; } 42 if (i.charAt(4) == '1') { o += 2; } 43 if (i.charAt(5) == '1') { o += 1; } 44 return encodingCharSet.charAt(o); 45 } 46 47 var LetterCodes = new Array(256); 48 LetterCodes[0] = '00111111111111110'; 49 LetterCodes[1] = '0101101'; 50 LetterCodes[2] = '00111111111111111'; 51 LetterCodes[3] = '00111111111111100'; 52 LetterCodes[4] = '00111111111111101'; 53 LetterCodes[5] = '000011111111111010'; 54 LetterCodes[6] = '000011111111111011'; 55 LetterCodes[7] = '000011111111111000'; 56 LetterCodes[8] = '000011111111111001'; 57 LetterCodes[9] = '000011111111111110'; 58 LetterCodes[10] = '0101100'; 59 LetterCodes[11] = '000011111111111111'; 60 LetterCodes[12] = '000011111111111100'; 61 LetterCodes[13] = '0011100'; 62 LetterCodes[14] = '000011111111111101'; 63 LetterCodes[15] = '000011111111110010'; 64 LetterCodes[16] = '000011111111110011'; 65 LetterCodes[17] = '000011111111110000'; 66 LetterCodes[18] = '000011111111110001'; 67 LetterCodes[19] = '000011111111110110'; 68 LetterCodes[20] = '000011111111110111'; 69 LetterCodes[21] = '000011111111110100'; 70 LetterCodes[22] = '000011111111110101'; 71 LetterCodes[23] = '1111111111110101010'; 72 LetterCodes[24] = '1111111111110101011'; 73 LetterCodes[25] = '1111111111110101000'; 74 LetterCodes[26] = '1111111111110101001'; 75 LetterCodes[27] = '1111111111110101110'; 76 LetterCodes[28] = '1111111111110101111'; 77 LetterCodes[29] = '1111111111110101100'; 78 LetterCodes[30] = '1111111111110101101'; 79 LetterCodes[31] = '1111111111110100010'; 80 LetterCodes[32] = '1000'; 81 LetterCodes[33] = '101111111110'; 82 LetterCodes[34] = '00010'; 83 LetterCodes[35] = '11111111110'; 84 LetterCodes[36] = '0011111111110'; 85 LetterCodes[37] = '1011111111110'; 86 LetterCodes[38] = '00001111111110'; 87 LetterCodes[39] = '00111111110'; 88 LetterCodes[40] = '0011101'; 89 LetterCodes[41] = '111111110'; 90 LetterCodes[42] = '11001111111110'; 91 LetterCodes[43] = '1111110'; 92 LetterCodes[44] = '000011110'; 93 LetterCodes[45] = '0011110'; 94 LetterCodes[46] = '00000'; 95 LetterCodes[47] = '0110110'; 96 LetterCodes[48] = '010100'; 97 LetterCodes[49] = '00110'; 98 LetterCodes[50] = '01000'; 99 LetterCodes[51] = '01100'; 100 LetterCodes[52] = '11000'; 101 LetterCodes[53] = '11010'; 102 LetterCodes[54] = '11100'; 103 LetterCodes[55] = '001010'; 104 LetterCodes[56] = '011100'; 105 LetterCodes[57] = '0001110'; 106 LetterCodes[58] = '001111111110'; 107 LetterCodes[59] = '1111111111100'; 108 LetterCodes[60] = '10111111110'; 109 LetterCodes[61] = '1100110100'; 110 LetterCodes[62] = '000011111110'; 111 LetterCodes[63] = '00011110'; 112 LetterCodes[64] = '1100111111110'; 113 LetterCodes[65] = '110011100'; 114 LetterCodes[66] = '000010'; 115 LetterCodes[67] = '10111110'; 116 LetterCodes[68] = '00111110'; 117 LetterCodes[69] = '0010110'; 118 LetterCodes[70] = '110011101'; 119 LetterCodes[71] = '110011110'; 120 LetterCodes[72] = '1100110101'; 121 LetterCodes[73] = '0010111110'; 122 LetterCodes[74] = '11001111110'; 123 LetterCodes[75] = '101110'; 124 LetterCodes[76] = '1100111110'; 125 LetterCodes[77] = '101111110'; 126 LetterCodes[78] = '000110'; 127 LetterCodes[79] = '0101110'; 128 LetterCodes[80] = '1011110'; 129 LetterCodes[81] = '011101'; 130 LetterCodes[82] = '11101'; 131 LetterCodes[83] = '11001100'; 132 LetterCodes[84] = '001111110'; 133 LetterCodes[85] = '0000111110'; 134 LetterCodes[86] = '1111111110'; 135 LetterCodes[87] = '11111110'; 136 LetterCodes[88] = '110011111110'; 137 LetterCodes[89] = '0000111111110'; 138 LetterCodes[90] = '1011111110'; 139 LetterCodes[91] = '10010'; 140 LetterCodes[92] = '00111111111110'; 141 LetterCodes[93] = '10011'; 142 LetterCodes[94] = '11001111111111'; 143 LetterCodes[95] = '11111111111010'; 144 LetterCodes[96] = '10111111111110'; 145 LetterCodes[97] = '11110'; 146 LetterCodes[98] = '011010'; 147 LetterCodes[99] = '10100'; 148 LetterCodes[100] = '11011'; 149 LetterCodes[101] = '00100'; 150 LetterCodes[102] = '010010'; 151 LetterCodes[103] = '010011'; 152 LetterCodes[104] = '011110'; 153 LetterCodes[105] = '0000110'; 154 LetterCodes[106] = '00001111110'; 155 LetterCodes[107] = '00001110'; 156 LetterCodes[108] = '110010'; 157 LetterCodes[109] = '000111110'; 158 LetterCodes[110] = '010101'; 159 LetterCodes[111] = '111110'; 160 LetterCodes[112] = '0110111'; 161 LetterCodes[113] = '1100110110'; 162 LetterCodes[114] = '0111110'; 163 LetterCodes[115] = '0111111'; 164 LetterCodes[116] = '10110'; 165 LetterCodes[117] = '0101111'; 166 LetterCodes[118] = '00101110'; 167 LetterCodes[119] = '000111111'; 168 LetterCodes[120] = '10101'; 169 LetterCodes[121] = '001011110'; 170 LetterCodes[122] = '1100110111'; 171 LetterCodes[123] = '0010111111'; 172 LetterCodes[124] = '001111111111110'; 173 LetterCodes[125] = '0011111110'; 174 LetterCodes[126] = '111111111110110'; 175 LetterCodes[127] = '1111111111110100011'; 176 LetterCodes[128] = '1111111111110100000'; 177 LetterCodes[129] = '1111111111110100001'; 178 LetterCodes[130] = '1111111111110100110'; 179 LetterCodes[131] = '1111111111110100111'; 180 LetterCodes[132] = '1111111111110100100'; 181 LetterCodes[133] = '1111111111110100101'; 182 LetterCodes[134] = '1111111111110111010'; 183 LetterCodes[135] = '1111111111110111011'; 184 LetterCodes[136] = '1111111111110111000'; 185 LetterCodes[137] = '1111111111110111001'; 186 LetterCodes[138] = '1111111111110111110'; 187 LetterCodes[139] = '1111111111110111111'; 188 LetterCodes[140] = '1111111111110111100'; 189 LetterCodes[141] = '1111111111110111101'; 190 LetterCodes[142] = '1111111111110110010'; 191 LetterCodes[143] = '1111111111110110011'; 192 LetterCodes[144] = '1111111111110110000'; 193 LetterCodes[145] = '1111111111110110001'; 194 LetterCodes[146] = '1111111111110110110'; 195 LetterCodes[147] = '1111111111110110111'; 196 LetterCodes[148] = '1111111111110110100'; 197 LetterCodes[149] = '1111111111110110101'; 198 LetterCodes[150] = '1111111111110001010'; 199 LetterCodes[151] = '1111111111110001011'; 200 LetterCodes[152] = '1111111111110001000'; 201 LetterCodes[153] = '1111111111110001001'; 202 LetterCodes[154] = '1111111111110001110'; 203 LetterCodes[155] = '1111111111110001111'; 204 LetterCodes[156] = '1111111111110001100'; 205 LetterCodes[157] = '1111111111110001101'; 206 LetterCodes[158] = '1111111111110000010'; 207 LetterCodes[159] = '1111111111110000011'; 208 LetterCodes[160] = '1111111111110000000'; 209 LetterCodes[161] = '1111111111110000001'; 210 LetterCodes[162] = '1111111111110000110'; 211 LetterCodes[163] = '1111111111110000111'; 212 LetterCodes[164] = '1111111111110000100'; 213 LetterCodes[165] = '1111111111110000101'; 214 LetterCodes[166] = '1111111111110011010'; 215 LetterCodes[167] = '1111111111110011011'; 216 LetterCodes[168] = '1111111111110011000'; 217 LetterCodes[169] = '1111111111110011001'; 218 LetterCodes[170] = '1111111111110011110'; 219 LetterCodes[171] = '1111111111110011111'; 220 LetterCodes[172] = '1111111111110011100'; 221 LetterCodes[173] = '1111111111110011101'; 222 LetterCodes[174] = '1111111111110010010'; 223 LetterCodes[175] = '1111111111110010011'; 224 LetterCodes[176] = '1111111111110010000'; 225 LetterCodes[177] = '1111111111110010001'; 226 LetterCodes[178] = '1111111111110010110'; 227 LetterCodes[179] = '1111111111110010111'; 228 LetterCodes[180] = '1111111111110010100'; 229 LetterCodes[181] = '1111111111110010101'; 230 LetterCodes[182] = '1111111111111101010'; 231 LetterCodes[183] = '1111111111111101011'; 232 LetterCodes[184] = '1111111111111101000'; 233 LetterCodes[185] = '1111111111111101001'; 234 LetterCodes[186] = '1111111111111101110'; 235 LetterCodes[187] = '1111111111111101111'; 236 LetterCodes[188] = '1111111111111101100'; 237 LetterCodes[189] = '1111111111111101101'; 238 LetterCodes[190] = '1111111111111100010'; 239 LetterCodes[191] = '1111111111111100011'; 240 LetterCodes[192] = '1111111111111100000'; 241 LetterCodes[193] = '1111111111111100001'; 242 LetterCodes[194] = '1111111111111100110'; 243 LetterCodes[195] = '1111111111111100111'; 244 LetterCodes[196] = '1111111111111100100'; 245 LetterCodes[197] = '1111111111111100101'; 246 LetterCodes[198] = '1111111111111111010'; 247 LetterCodes[199] = '1111111111111111011'; 248 LetterCodes[200] = '1111111111111111000'; 249 LetterCodes[201] = '1111111111111111001'; 250 LetterCodes[202] = '1111111111111111110'; 251 LetterCodes[203] = '1111111111111111111'; 252 LetterCodes[204] = '1111111111111111100'; 253 LetterCodes[205] = '1111111111111111101'; 254 LetterCodes[206] = '1111111111111110010'; 255 LetterCodes[207] = '1111111111111110011'; 256 LetterCodes[208] = '1111111111111110000'; 257 LetterCodes[209] = '1111111111111110001'; 258 LetterCodes[210] = '1111111111111110110'; 259 LetterCodes[211] = '1111111111111110111'; 260 LetterCodes[212] = '1111111111111110100'; 261 LetterCodes[213] = '1111111111111110101'; 262 LetterCodes[214] = '1111111111111001010'; 263 LetterCodes[215] = '1111111111111001011'; 264 LetterCodes[216] = '1111111111111001000'; 265 LetterCodes[217] = '1111111111111001001'; 266 LetterCodes[218] = '1111111111111001110'; 267 LetterCodes[219] = '1111111111111001111'; 268 LetterCodes[220] = '1111111111111001100'; 269 LetterCodes[221] = '1111111111111001101'; 270 LetterCodes[222] = '1111111111111000010'; 271 LetterCodes[223] = '1111111111111000011'; 272 LetterCodes[224] = '1111111111111000000'; 273 LetterCodes[225] = '1111111111111000001'; 274 LetterCodes[226] = '1111111111111000110'; 275 LetterCodes[227] = '1111111111111000111'; 276 LetterCodes[228] = '1111111111111000100'; 277 LetterCodes[229] = '1111111111111000101'; 278 LetterCodes[230] = '1111111111111011010'; 279 LetterCodes[231] = '1111111111111011011'; 280 LetterCodes[232] = '1111111111111011000'; 281 LetterCodes[233] = '1111111111111011001'; 282 LetterCodes[234] = '1111111111111011110'; 283 LetterCodes[235] = '1111111111111011111'; 284 LetterCodes[236] = '1111111111111011100'; 285 LetterCodes[237] = '1111111111111011101'; 286 LetterCodes[238] = '1111111111111010010'; 287 LetterCodes[239] = '1111111111111010011'; 288 LetterCodes[240] = '1111111111111010000'; 289 LetterCodes[241] = '1111111111111010001'; 290 LetterCodes[242] = '1111111111111010110'; 291 LetterCodes[243] = '1111111111111010111'; 292 LetterCodes[244] = '1111111111111010100'; 293 LetterCodes[245] = '1111111111111010101'; 294 LetterCodes[246] = '10111111111111010'; 295 LetterCodes[247] = '10111111111111011'; 296 LetterCodes[248] = '10111111111111000'; 297 LetterCodes[249] = '10111111111111001'; 298 LetterCodes[250] = '10111111111111110'; 299 LetterCodes[251] = '10111111111111111'; 300 LetterCodes[252] = '10111111111111100'; 301 LetterCodes[253] = '10111111111111101'; 302 LetterCodes[254] = '1111111111101110'; 303 LetterCodes[255] = '1111111111101111'; 304 305 // Build resulting data stream 306 // The bits string could get very large 307 var bits = ""; 308 var bytes = ov.length + "$"; 309 for (var i = 0; i < ov.length; i ++) { 310 // converts ASCII chars above 255 to a star (code 42) avoiding decoding failure 311 if (ov.charCodeAt(i) > 255) { bits += LetterCodes[42]; } 312 else { bits += LetterCodes[ov.charCodeAt(i)]; } 313 while (bits.length > 5) { 314 bytes += BitsToBytes(bits); 315 bits = bits.slice(6, bits.length); 316 } 317 } 318 bytes += BitsToBytes(bits); 319 320 bytes += encodingCharSet.charAt(encodingVersion); 321 322 return bytes; 323} 324 325