1<!DOCTYPE HTML>
2<html>
3
4<!--
5  pgn4web javascript chessboard
6  copyright (C) 2009-2014 Paolo Casaschi
7  see README file and http://pgn4web.casaschi.net
8  for credits, license and more details
9
10  Huffman encoding/decoding derived from code at http://rumkin.com/tools/compression/compress_huff.php
11
12  PLEASE NOTE THIS FILE IS USED ONLY TO FINE TUNE HUFFMANN ENCODING:
13  actual functions for PGN encoding/decoding are contained in pgn-decoder.js and pgn-encoder.js
14-->
15
16<head>
17
18<title>pgn4web PGN encoder/decoder test</title>
19
20<link rel="icon" sizes="16x16" href="pawn.ico" />
21
22<script type="text/javascript">
23"use strict";
24
25// fix this to use customized letter distribution
26var USE_PRESET_LETTER_DISTRIBUTION = true;
27// fix this once you have the letter codes corresponding to the letter distribution above
28var USE_PRESET_LETTER_CODES = true;
29// fix this once you have the decoding values l[] corresponding to the letter codes above
30var USE_PRESET_DECODING_SET = true;
31
32var encodingCharSet = "$0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
33var encodingVersion = 1;
34// version 1 of PGN encoding:
35//   encodedPGN = nnn$xxx0
36//   nnn = number representing bytes length of the decoded message
37//   $ = dollar char (delimiter for length info)
38//   xxx = encoded text (using LetterCodes below)
39//   0 = zero char (version marker)
40
41function BitsToBytes(i) {
42  var o = 0;
43  if (i.charAt(0) == '1') { o += 32; }
44  if (i.charAt(1) == '1') { o += 16; }
45  if (i.charAt(2) == '1') { o +=  8; }
46  if (i.charAt(3) == '1') { o +=  4; }
47  if (i.charAt(4) == '1') { o +=  2; }
48  if (i.charAt(5) == '1') { o +=  1; }
49  return encodingCharSet.charAt(o);
50}
51
52
53function EncodePGN(ov) {
54  var i, idx, c;
55
56  var Letters = new Array(256);
57  var LetterCodes = new Array(256);
58
59  for (i = 0; i < 256; i ++) { Letters[i] = 0; }
60  for (i = 0; i < ov.length; i ++) { Letters[ov.charCodeAt(i)]++; }
61
62  if (USE_PRESET_LETTER_DISTRIBUTION) {
63  Letters[0] = 1;
64  Letters[1] = 1;
65  Letters[2] = 1;
66  Letters[3] = 1;
67  Letters[4] = 1;
68  Letters[5] = 1;
69  Letters[6] = 1;
70  Letters[7] = 1;
71  Letters[8] = 1;
72  Letters[9] = 1;
73  Letters[10] = 25000;
74  Letters[11] = 1;
75  Letters[12] = 1;
76  Letters[13] = 25000;
77  Letters[14] = 1;
78  Letters[15] = 1;
79  Letters[16] = 1;
80  Letters[17] = 1;
81  Letters[18] = 1;
82  Letters[19] = 1;
83  Letters[20] = 1;
84  Letters[21] = 1;
85  Letters[22] = 1;
86  Letters[23] = 1;
87  Letters[24] = 1;
88  Letters[25] = 1;
89  Letters[26] = 1;
90  Letters[27] = 1;
91  Letters[28] = 1;
92  Letters[29] = 1;
93  Letters[30] = 1;
94  Letters[31] = 1;
95  Letters[32] = 273240;
96  Letters[33] = 200;    // !
97  Letters[34] = 64928;    // "
98  Letters[35] = 326;    // #
99  Letters[36] = 163;    // $
100  Letters[37] = 25;    // %
101  Letters[38] = 25;    // &
102  Letters[39] = 500;    // '
103  Letters[40] = 1607;    // (
104  Letters[41] = 1592;    // )
105  Letters[42] = 10;    // *
106  Letters[43] = 9086;    // +
107  Letters[44] = 4231;    // ,
108  Letters[45] = 11848;    // -
109  Letters[46] = 91283;    // .
110  Letters[47] = 9685;    // /
111  Letters[48] = 27308;    // 0
112  Letters[49] = 57229;    // 1
113  Letters[50] = 57065;    // 2
114  Letters[51] = 49049;    // 3
115  Letters[52] = 46441;    // 4
116  Letters[53] = 42430;    // 5
117  Letters[54] = 38872;    // 6
118  Letters[55] = 27853;    // 7
119  Letters[56] = 21292;    // 8
120  Letters[57] = 14627;    // 9
121  Letters[58] = 270;    // :
122  Letters[59] = 136;    // ;
123  Letters[60] = 290;    // <
124  Letters[61] = 1015;    // =
125  Letters[62] = 290;    // >
126  Letters[63] = 7511;    // ?
127  Letters[64] = 100;    // @
128  Letters[65] = 3580;    // A
129  Letters[66] = 31461;    // B
130  Letters[67] = 4369;    // C
131  Letters[68] = 6993;    // D
132  Letters[69] = 13777;    // E
133  Letters[70] = 1719;    // F
134  Letters[71] = 1902;    // G
135  Letters[72] = 639;    // H
136  Letters[73] = 1054;    // I
137  Letters[74] = 420;    // J
138  Letters[75] = 16962;    // K
139  Letters[76] = 961;    // L
140  Letters[77] = 1378;    // M
141  Letters[78] = 29494;    // N
142  Letters[79] = 10671;    // O
143  Letters[80] = 7817;    // P
144  Letters[81] = 19645;    // Q
145  Letters[82] = 34436;    // R
146  Letters[83] = 5795;    // S
147  Letters[84] = 2037;    // T
148  Letters[85] = 1364;    // U
149  Letters[86] = 621;    // V
150  Letters[87] = 5270;    // W
151  Letters[88] = 249;    // X
152  Letters[89] = 185;    // Y
153  Letters[90] = 620;    // Z
154  Letters[91] = 31633;    // [
155  Letters[92] = 15;    // \
156  Letters[93] = 31628;    // ]
157  Letters[94] = 10;    // ^
158  Letters[95] = 15;    // _
159  Letters[96] = 10;    // `
160  Letters[97] = 35573;    // a
161  Letters[98] = 19456;    // b
162  Letters[99] = 33228;    // c
163  Letters[100] = 36380;    // d
164  Letters[101] = 64738;    // e
165  Letters[102] = 25736;    // f
166  Letters[103] = 19801;    // g
167  Letters[104] = 20415;    // h
168  Letters[105] = 16706;    // i
169  Letters[106] = 530;    // j
170  Letters[107] = 7806;    // k
171  Letters[108] = 18510;    // l
172  Letters[109] = 3044;    // m
173  Letters[110] = 20680;    // n
174  Letters[111] = 17771;    // o
175  Letters[112] = 9101;    // p
176  Letters[113] = 903;    // q
177  Letters[114] = 10153;    // r
178  Letters[115] = 9963;    // s
179  Letters[116] = 32763;    // t
180  Letters[117] = 10268;    // u
181  Letters[118] = 7508;    // v
182  Letters[119] = 2173;    // w
183  Letters[120] = 32913;    // x
184  Letters[121] = 2135;    // y
185  Letters[122] = 722;    // z
186  Letters[123] = 1000;   // {
187  Letters[124] = 10;   // |
188  Letters[125] = 1000;   // }
189  Letters[126] = 10;   // ~
190  Letters[127] = 1;
191  Letters[128] = 1;
192  Letters[129] = 1;
193  Letters[130] = 1;
194  Letters[131] = 1;
195  Letters[132] = 1;
196  Letters[133] = 1;
197  Letters[134] = 1;
198  Letters[135] = 1;
199  Letters[136] = 1;
200  Letters[137] = 1;
201  Letters[138] = 1;
202  Letters[139] = 1;
203  Letters[140] = 1;
204  Letters[141] = 1;
205  Letters[142] = 1;
206  Letters[143] = 1;
207  Letters[144] = 1;
208  Letters[145] = 1;
209  Letters[146] = 1;
210  Letters[147] = 1;
211  Letters[148] = 1;
212  Letters[149] = 1;
213  Letters[150] = 1;
214  Letters[151] = 1;
215  Letters[152] = 1;
216  Letters[153] = 1;
217  Letters[154] = 1;
218  Letters[155] = 1;
219  Letters[156] = 1;
220  Letters[157] = 1;
221  Letters[158] = 1;
222  Letters[159] = 1;
223  Letters[160] = 1;
224  Letters[161] = 1;
225  Letters[162] = 1;
226  Letters[163] = 1;
227  Letters[164] = 1;
228  Letters[165] = 1;
229  Letters[166] = 1;
230  Letters[167] = 1;
231  Letters[168] = 1;
232  Letters[169] = 1;
233  Letters[170] = 1;
234  Letters[171] = 1;
235  Letters[172] = 1;
236  Letters[173] = 1;
237  Letters[174] = 1;
238  Letters[175] = 1;
239  Letters[176] = 1;
240  Letters[177] = 1;
241  Letters[178] = 1;
242  Letters[179] = 1;
243  Letters[180] = 1;
244  Letters[181] = 1;
245  Letters[182] = 1;
246  Letters[183] = 1;
247  Letters[184] = 1;
248  Letters[185] = 1;
249  Letters[186] = 1;
250  Letters[187] = 1;
251  Letters[188] = 1;
252  Letters[189] = 1;
253  Letters[190] = 1;
254  Letters[191] = 1;
255  Letters[192] = 1;
256  Letters[193] = 1;
257  Letters[194] = 1;
258  Letters[195] = 1;
259  Letters[196] = 1;
260  Letters[197] = 1;
261  Letters[198] = 1;
262  Letters[199] = 1;
263  Letters[200] = 1;
264  Letters[201] = 1;
265  Letters[202] = 1;
266  Letters[203] = 1;
267  Letters[204] = 1;
268  Letters[205] = 1;
269  Letters[206] = 1;
270  Letters[207] = 1;
271  Letters[208] = 1;
272  Letters[209] = 1;
273  Letters[210] = 1;
274  Letters[211] = 1;
275  Letters[212] = 1;
276  Letters[213] = 1;
277  Letters[214] = 1;
278  Letters[215] = 1;
279  Letters[216] = 1;
280  Letters[217] = 1;
281  Letters[218] = 1;
282  Letters[219] = 1;
283  Letters[220] = 1;
284  Letters[221] = 1;
285  Letters[222] = 1;
286  Letters[223] = 1;
287  Letters[224] = 1;
288  Letters[225] = 1;
289  Letters[226] = 1;
290  Letters[227] = 1;
291  Letters[228] = 1;
292  Letters[229] = 1;
293  Letters[230] = 1;
294  Letters[231] = 1;
295  Letters[232] = 1;
296  Letters[233] = 1;
297  Letters[234] = 1;
298  Letters[235] = 1;
299  Letters[236] = 1;
300  Letters[237] = 1;
301  Letters[238] = 1;
302  Letters[239] = 1;
303  Letters[240] = 1;
304  Letters[241] = 1;
305  Letters[242] = 1;
306  Letters[243] = 1;
307  Letters[244] = 1;
308  Letters[245] = 1;
309  Letters[246] = 1;
310  Letters[247] = 1;
311  Letters[248] = 1;
312  Letters[249] = 1;
313  Letters[250] = 1;
314  Letters[251] = 1;
315  Letters[252] = 1;
316  Letters[253] = 1;
317  Letters[254] = 1;
318  Letters[255] = 1;
319  }
320
321  // Build a Huffman tree from the letter count frequencies
322  var NodeLetter = new Array(512);
323  var NodeCount = new Array(512);
324  var NodeChild1 = new Array(512);
325  var NodeChild2 = new Array(512);
326  var NextParent = 0;
327
328  for (i = 0; i < 256; i ++) {
329    if (Letters[i] > 0) {
330      NodeLetter[NextParent] = i;
331      NodeCount[NextParent] = Letters[i];
332      NodeChild1[NextParent] = -1;
333      NodeChild2[NextParent] = -1;
334      NextParent ++;
335    }
336  }
337
338  // Built node list.  Now combine nodes to make a tree
339  var SmallestNode1;
340  var SmallestNode2 = 1;
341  while (SmallestNode2 != -1) {
342    SmallestNode1 = -1;
343    SmallestNode2 = -1;
344
345    for (i = 0; i < NextParent; i ++) {
346      if (NodeCount[i] > 0) {
347        if (SmallestNode1 == -1) {
348          SmallestNode1 = i;
349        } else if (SmallestNode2 == -1) {
350          if (NodeCount[i] < NodeCount[SmallestNode1]) {
351            SmallestNode2 = SmallestNode1;
352            SmallestNode1 = i;
353          } else {
354            SmallestNode2 = i;
355          }
356        } else if (NodeCount[i] <= NodeCount[SmallestNode1]) {
357          SmallestNode2 = SmallestNode1;
358          SmallestNode1 = i;
359        }
360      }
361    }
362
363    if (SmallestNode2 != -1) {
364      NodeCount[NextParent] = NodeCount[SmallestNode1] + NodeCount[SmallestNode2];
365      NodeCount[SmallestNode1] = 0;
366      NodeCount[SmallestNode2] = 0;
367      // Reversed SmallestNode numbers here for ordering in the tree
368      NodeChild1[NextParent] = SmallestNode2;
369      NodeChild2[NextParent] = SmallestNode1;
370      NextParent ++;
371    }
372  }
373
374  // We have constructed the nodes. Now rewrite the list into a single array.
375  // The value of an array element will be positive if it is the character
376  // code we want. Otherwise, it branches. The left branch will be the next
377  // array element. The value of the array will be (offset * -1), which is
378  // the right branch.
379  var FinalNodes = Array(NextParent);
380  var DepthIndex = Array(256);
381  var Depth = 0;
382  var NextFinal = 0;
383  DepthIndex[Depth] = SmallestNode1;
384  while (Depth >= 0) {
385    if (NodeChild1[DepthIndex[Depth]] > -1 && NodeChild2[DepthIndex[Depth]] > -1) {
386      // If there is a left and right, push them on the stack
387      idx = NodeChild1[DepthIndex[Depth]];
388      NodeChild1[DepthIndex[Depth]] = -2 - NextFinal;
389      Depth ++;
390      DepthIndex[Depth] = idx;
391      NextFinal ++;
392    } else if (NodeChild1[DepthIndex[Depth]] < 0 && NodeChild2[DepthIndex[Depth]] > -1) {
393      // If there is a left and a right, but the left was taken,
394      // push the right on the stack.
395      // Update the FinalNodes[] with the location for the right branch.
396      idx = NodeChild1[DepthIndex[Depth]];
397      idx = 0 - idx;
398      idx -= 2;
399      FinalNodes[idx] = - NextFinal;
400
401      // Traverse right branch
402      idx = NodeChild2[DepthIndex[Depth]];
403      NodeChild2[DepthIndex[Depth]] = -2;
404      Depth ++;
405      DepthIndex[Depth] = idx;
406    } else if (NodeChild1[DepthIndex[Depth]] < -1 && NodeChild2[DepthIndex[Depth]] < -1) {
407      // If there was a left and a right, but they were both taken, pop up a level
408      Depth --;
409    } else if (NodeChild1[DepthIndex[Depth]] == -1 && NodeChild2[DepthIndex[Depth]] == -1) {
410      // If we have a child here, add it to the final nodes, pop up
411      FinalNodes[NextFinal] = NodeLetter[DepthIndex[Depth]];
412      NextFinal ++;
413      Depth --;
414    } else {
415      // This shouldn't ever happen
416      alert('Bad algorithm!');
417      return new Array ("", "", "");
418    }
419  }
420
421  // We have the tree. Associate codes with the letters.
422  var CodeIndex = new Array(256);
423  DepthIndex[0] = 0;
424  CodeIndex[0] = "";
425  Depth = 0;
426  while (Depth >= 0) {
427    if (FinalNodes[DepthIndex[Depth]] < 0) {
428      c = CodeIndex[Depth];
429      idx = DepthIndex[Depth];
430      DepthIndex[Depth + 1] = DepthIndex[Depth] + 1;
431      CodeIndex[Depth + 1] = c + '0';
432      DepthIndex[Depth] = 0 - FinalNodes[idx];
433      CodeIndex[Depth] = c + '1';
434      Depth ++;
435    } else {
436      LetterCodes[FinalNodes[DepthIndex[Depth]]] = CodeIndex[Depth];
437      Depth --;
438    }
439  }
440
441
442  if (USE_PRESET_LETTER_CODES) {
443  LetterCodes[0]   = '00111111111111110';
444  LetterCodes[1]   = '0101101';
445  LetterCodes[2]   = '00111111111111111';
446  LetterCodes[3]   = '00111111111111100';
447  LetterCodes[4]   = '00111111111111101';
448  LetterCodes[5]   = '000011111111111010';
449  LetterCodes[6]   = '000011111111111011';
450  LetterCodes[7]   = '000011111111111000';
451  LetterCodes[8]   = '000011111111111001';
452  LetterCodes[9]   = '000011111111111110';
453  LetterCodes[10]  = '0101100';
454  LetterCodes[11]  = '000011111111111111';
455  LetterCodes[12]  = '000011111111111100';
456  LetterCodes[13]  = '0011100';
457  LetterCodes[14]  = '000011111111111101';
458  LetterCodes[15]  = '000011111111110010';
459  LetterCodes[16]  = '000011111111110011';
460  LetterCodes[17]  = '000011111111110000';
461  LetterCodes[18]  = '000011111111110001';
462  LetterCodes[19]  = '000011111111110110';
463  LetterCodes[20]  = '000011111111110111';
464  LetterCodes[21]  = '000011111111110100';
465  LetterCodes[22]  = '000011111111110101';
466  LetterCodes[23]  = '1111111111110101010';
467  LetterCodes[24]  = '1111111111110101011';
468  LetterCodes[25]  = '1111111111110101000';
469  LetterCodes[26]  = '1111111111110101001';
470  LetterCodes[27]  = '1111111111110101110';
471  LetterCodes[28]  = '1111111111110101111';
472  LetterCodes[29]  = '1111111111110101100';
473  LetterCodes[30]  = '1111111111110101101';
474  LetterCodes[31]  = '1111111111110100010';
475  LetterCodes[32]  = '1000';
476  LetterCodes[33]  = '101111111110';
477  LetterCodes[34]  = '00010';
478  LetterCodes[35]  = '11111111110';
479  LetterCodes[36]  = '0011111111110';
480  LetterCodes[37]  = '1011111111110';
481  LetterCodes[38]  = '00001111111110';
482  LetterCodes[39]  = '00111111110';
483  LetterCodes[40]  = '0011101';
484  LetterCodes[41]  = '111111110';
485  LetterCodes[42]  = '11001111111110';
486  LetterCodes[43]  = '1111110';
487  LetterCodes[44]  = '000011110';
488  LetterCodes[45]  = '0011110';
489  LetterCodes[46]  = '00000';
490  LetterCodes[47]  = '0110110';
491  LetterCodes[48]  = '010100';
492  LetterCodes[49]  = '00110';
493  LetterCodes[50]  = '01000';
494  LetterCodes[51]  = '01100';
495  LetterCodes[52]  = '11000';
496  LetterCodes[53]  = '11010';
497  LetterCodes[54]  = '11100';
498  LetterCodes[55]  = '001010';
499  LetterCodes[56]  = '011100';
500  LetterCodes[57]  = '0001110';
501  LetterCodes[58]  = '001111111110';
502  LetterCodes[59]  = '1111111111100';
503  LetterCodes[60]  = '10111111110';
504  LetterCodes[61]  = '1100110100';
505  LetterCodes[62]  = '000011111110';
506  LetterCodes[63]  = '00011110';
507  LetterCodes[64]  = '1100111111110';
508  LetterCodes[65]  = '110011100';
509  LetterCodes[66]  = '000010';
510  LetterCodes[67]  = '10111110';
511  LetterCodes[68]  = '00111110';
512  LetterCodes[69]  = '0010110';
513  LetterCodes[70]  = '110011101';
514  LetterCodes[71]  = '110011110';
515  LetterCodes[72]  = '1100110101';
516  LetterCodes[73]  = '0010111110';
517  LetterCodes[74]  = '11001111110';
518  LetterCodes[75]  = '101110';
519  LetterCodes[76]  = '1100111110';
520  LetterCodes[77]  = '101111110';
521  LetterCodes[78]  = '000110';
522  LetterCodes[79]  = '0101110';
523  LetterCodes[80]  = '1011110';
524  LetterCodes[81]  = '011101';
525  LetterCodes[82]  = '11101';
526  LetterCodes[83]  = '11001100';
527  LetterCodes[84]  = '001111110';
528  LetterCodes[85]  = '0000111110';
529  LetterCodes[86]  = '1111111110';
530  LetterCodes[87]  = '11111110';
531  LetterCodes[88]  = '110011111110';
532  LetterCodes[89]  = '0000111111110';
533  LetterCodes[90]  = '1011111110';
534  LetterCodes[91]  = '10010';
535  LetterCodes[92]  = '00111111111110';
536  LetterCodes[93]  = '10011';
537  LetterCodes[94]  = '11001111111111';
538  LetterCodes[95]  = '11111111111010';
539  LetterCodes[96]  = '10111111111110';
540  LetterCodes[97]  = '11110';
541  LetterCodes[98]  = '011010';
542  LetterCodes[99]  = '10100';
543  LetterCodes[100] = '11011';
544  LetterCodes[101] = '00100';
545  LetterCodes[102] = '010010';
546  LetterCodes[103] = '010011';
547  LetterCodes[104] = '011110';
548  LetterCodes[105] = '0000110';
549  LetterCodes[106] = '00001111110';
550  LetterCodes[107] = '00001110';
551  LetterCodes[108] = '110010';
552  LetterCodes[109] = '000111110';
553  LetterCodes[110] = '010101';
554  LetterCodes[111] = '111110';
555  LetterCodes[112] = '0110111';
556  LetterCodes[113] = '1100110110';
557  LetterCodes[114] = '0111110';
558  LetterCodes[115] = '0111111';
559  LetterCodes[116] = '10110';
560  LetterCodes[117] = '0101111';
561  LetterCodes[118] = '00101110';
562  LetterCodes[119] = '000111111';
563  LetterCodes[120] = '10101';
564  LetterCodes[121] = '001011110';
565  LetterCodes[122] = '1100110111';
566  LetterCodes[123] = '0010111111';
567  LetterCodes[124] = '001111111111110';
568  LetterCodes[125] = '0011111110';
569  LetterCodes[126] = '111111111110110';
570  LetterCodes[127] = '1111111111110100011';
571  LetterCodes[128] = '1111111111110100000';
572  LetterCodes[129] = '1111111111110100001';
573  LetterCodes[130] = '1111111111110100110';
574  LetterCodes[131] = '1111111111110100111';
575  LetterCodes[132] = '1111111111110100100';
576  LetterCodes[133] = '1111111111110100101';
577  LetterCodes[134] = '1111111111110111010';
578  LetterCodes[135] = '1111111111110111011';
579  LetterCodes[136] = '1111111111110111000';
580  LetterCodes[137] = '1111111111110111001';
581  LetterCodes[138] = '1111111111110111110';
582  LetterCodes[139] = '1111111111110111111';
583  LetterCodes[140] = '1111111111110111100';
584  LetterCodes[141] = '1111111111110111101';
585  LetterCodes[142] = '1111111111110110010';
586  LetterCodes[143] = '1111111111110110011';
587  LetterCodes[144] = '1111111111110110000';
588  LetterCodes[145] = '1111111111110110001';
589  LetterCodes[146] = '1111111111110110110';
590  LetterCodes[147] = '1111111111110110111';
591  LetterCodes[148] = '1111111111110110100';
592  LetterCodes[149] = '1111111111110110101';
593  LetterCodes[150] = '1111111111110001010';
594  LetterCodes[151] = '1111111111110001011';
595  LetterCodes[152] = '1111111111110001000';
596  LetterCodes[153] = '1111111111110001001';
597  LetterCodes[154] = '1111111111110001110';
598  LetterCodes[155] = '1111111111110001111';
599  LetterCodes[156] = '1111111111110001100';
600  LetterCodes[157] = '1111111111110001101';
601  LetterCodes[158] = '1111111111110000010';
602  LetterCodes[159] = '1111111111110000011';
603  LetterCodes[160] = '1111111111110000000';
604  LetterCodes[161] = '1111111111110000001';
605  LetterCodes[162] = '1111111111110000110';
606  LetterCodes[163] = '1111111111110000111';
607  LetterCodes[164] = '1111111111110000100';
608  LetterCodes[165] = '1111111111110000101';
609  LetterCodes[166] = '1111111111110011010';
610  LetterCodes[167] = '1111111111110011011';
611  LetterCodes[168] = '1111111111110011000';
612  LetterCodes[169] = '1111111111110011001';
613  LetterCodes[170] = '1111111111110011110';
614  LetterCodes[171] = '1111111111110011111';
615  LetterCodes[172] = '1111111111110011100';
616  LetterCodes[173] = '1111111111110011101';
617  LetterCodes[174] = '1111111111110010010';
618  LetterCodes[175] = '1111111111110010011';
619  LetterCodes[176] = '1111111111110010000';
620  LetterCodes[177] = '1111111111110010001';
621  LetterCodes[178] = '1111111111110010110';
622  LetterCodes[179] = '1111111111110010111';
623  LetterCodes[180] = '1111111111110010100';
624  LetterCodes[181] = '1111111111110010101';
625  LetterCodes[182] = '1111111111111101010';
626  LetterCodes[183] = '1111111111111101011';
627  LetterCodes[184] = '1111111111111101000';
628  LetterCodes[185] = '1111111111111101001';
629  LetterCodes[186] = '1111111111111101110';
630  LetterCodes[187] = '1111111111111101111';
631  LetterCodes[188] = '1111111111111101100';
632  LetterCodes[189] = '1111111111111101101';
633  LetterCodes[190] = '1111111111111100010';
634  LetterCodes[191] = '1111111111111100011';
635  LetterCodes[192] = '1111111111111100000';
636  LetterCodes[193] = '1111111111111100001';
637  LetterCodes[194] = '1111111111111100110';
638  LetterCodes[195] = '1111111111111100111';
639  LetterCodes[196] = '1111111111111100100';
640  LetterCodes[197] = '1111111111111100101';
641  LetterCodes[198] = '1111111111111111010';
642  LetterCodes[199] = '1111111111111111011';
643  LetterCodes[200] = '1111111111111111000';
644  LetterCodes[201] = '1111111111111111001';
645  LetterCodes[202] = '1111111111111111110';
646  LetterCodes[203] = '1111111111111111111';
647  LetterCodes[204] = '1111111111111111100';
648  LetterCodes[205] = '1111111111111111101';
649  LetterCodes[206] = '1111111111111110010';
650  LetterCodes[207] = '1111111111111110011';
651  LetterCodes[208] = '1111111111111110000';
652  LetterCodes[209] = '1111111111111110001';
653  LetterCodes[210] = '1111111111111110110';
654  LetterCodes[211] = '1111111111111110111';
655  LetterCodes[212] = '1111111111111110100';
656  LetterCodes[213] = '1111111111111110101';
657  LetterCodes[214] = '1111111111111001010';
658  LetterCodes[215] = '1111111111111001011';
659  LetterCodes[216] = '1111111111111001000';
660  LetterCodes[217] = '1111111111111001001';
661  LetterCodes[218] = '1111111111111001110';
662  LetterCodes[219] = '1111111111111001111';
663  LetterCodes[220] = '1111111111111001100';
664  LetterCodes[221] = '1111111111111001101';
665  LetterCodes[222] = '1111111111111000010';
666  LetterCodes[223] = '1111111111111000011';
667  LetterCodes[224] = '1111111111111000000';
668  LetterCodes[225] = '1111111111111000001';
669  LetterCodes[226] = '1111111111111000110';
670  LetterCodes[227] = '1111111111111000111';
671  LetterCodes[228] = '1111111111111000100';
672  LetterCodes[229] = '1111111111111000101';
673  LetterCodes[230] = '1111111111111011010';
674  LetterCodes[231] = '1111111111111011011';
675  LetterCodes[232] = '1111111111111011000';
676  LetterCodes[233] = '1111111111111011001';
677  LetterCodes[234] = '1111111111111011110';
678  LetterCodes[235] = '1111111111111011111';
679  LetterCodes[236] = '1111111111111011100';
680  LetterCodes[237] = '1111111111111011101';
681  LetterCodes[238] = '1111111111111010010';
682  LetterCodes[239] = '1111111111111010011';
683  LetterCodes[240] = '1111111111111010000';
684  LetterCodes[241] = '1111111111111010001';
685  LetterCodes[242] = '1111111111111010110';
686  LetterCodes[243] = '1111111111111010111';
687  LetterCodes[244] = '1111111111111010100';
688  LetterCodes[245] = '1111111111111010101';
689  LetterCodes[246] = '10111111111111010';
690  LetterCodes[247] = '10111111111111011';
691  LetterCodes[248] = '10111111111111000';
692  LetterCodes[249] = '10111111111111001';
693  LetterCodes[250] = '10111111111111110';
694  LetterCodes[251] = '10111111111111111';
695  LetterCodes[252] = '10111111111111100';
696  LetterCodes[253] = '10111111111111101';
697  LetterCodes[254] = '1111111111101110';
698  LetterCodes[255] = '1111111111101111';
699  }
700
701  // Build resulting data stream
702  // The bits string could get very large
703  var bits = "";
704  var bytes = ov.length + "$";
705  for (i = 0; i < ov.length; i ++) {
706    // converts ASCII chars above 255 to a star (code 42) avoiding decoding failure
707    if (ov.charCodeAt(i) > 255) { bits += LetterCodes[42]; }
708    else { bits += LetterCodes[ov.charCodeAt(i)]; }
709    while (bits.length > 5) {
710      bytes += BitsToBytes(bits);
711      bits = bits.slice(6, bits.length);
712    }
713  }
714  bytes += BitsToBytes(bits);
715
716  var encodedNodes = "";
717  for (i = 0; i < FinalNodes.length; i ++) {
718    var x, y;
719    x = FinalNodes[i] + 512;
720    y = x & 0x3F;
721    x >>= 6;
722    x &= 0x3F;
723    encodedNodes += encodingCharSet.charAt(x) + encodingCharSet.charAt(y);
724  }
725
726  bytes += encodingCharSet.charAt(encodingVersion);
727
728  return new Array (bytes, encodedNodes, LetterCodes);
729}
730
731
732function DecodePGN(bytes, encodedNodes) {
733
734  if (bytes.charAt(bytes.length - 1) != encodingCharSet.charAt(encodingVersion)) {
735    alert("ERROR: PGN encoding version mismatch (e:" +
736           bytes.charAt(bytes.length - 1) + " d:" + encodingCharSet.charAt(encodingVersion) + ")");
737  }
738
739  var originalLength = parseInt(bytes.match(/^[0-9]*/), 10);
740  bytes = bytes.replace(/^[0-9]*\$/,"");
741
742  var l = new Array();
743  while(encodedNodes.length) {
744    l.push((encodingCharSet.indexOf(encodedNodes.charAt(0))<<6)+encodingCharSet.indexOf(encodedNodes.charAt(1))-512);
745    encodedNodes = encodedNodes.slice(2,encodedNodes.length);
746  }
747
748  if (USE_PRESET_DECODING_SET) {
749  l[0] = -146;
750  l[1] = -111;
751  l[2] = -66;
752  l[3] = -55;
753  l[4] = -6;
754  l[5] = 46;
755  l[6] = -8;
756  l[7] = 66;
757  l[8] = -10;
758  l[9] = 105;
759  l[10] = -12;
760  l[11] = 107;
761  l[12] = -14;
762  l[13] = 44;
763  l[14] = -16;
764  l[15] = 85;
765  l[16] = -18;
766  l[17] = 106;
767  l[18] = -20;
768  l[19] = 62;
769  l[20] = -22;
770  l[21] = 89;
771  l[22] = -24;
772  l[23] = 38;
773  l[24] = -40;
774  l[25] = -33;
775  l[26] = -30;
776  l[27] = -29;
777  l[28] = 17;
778  l[29] = 18;
779  l[30] = -32;
780  l[31] = 15;
781  l[32] = 16;
782  l[33] = -37;
783  l[34] = -36;
784  l[35] = 21;
785  l[36] = 22;
786  l[37] = -39;
787  l[38] = 19;
788  l[39] = 20;
789  l[40] = -48;
790  l[41] = -45;
791  l[42] = -44;
792  l[43] = 7;
793  l[44] = 8;
794  l[45] = -47;
795  l[46] = 5;
796  l[47] = 6;
797  l[48] = -52;
798  l[49] = -51;
799  l[50] = 12;
800  l[51] = 14;
801  l[52] = -54;
802  l[53] = 9;
803  l[54] = 11;
804  l[55] = -57;
805  l[56] = 34;
806  l[57] = -59;
807  l[58] = 78;
808  l[59] = -61;
809  l[60] = 57;
810  l[61] = -63;
811  l[62] = 63;
812  l[63] = -65;
813  l[64] = 109;
814  l[65] = 119;
815  l[66] = -80;
816  l[67] = -69;
817  l[68] = 101;
818  l[69] = -71;
819  l[70] = 55;
820  l[71] = -73;
821  l[72] = 69;
822  l[73] = -75;
823  l[74] = 118;
824  l[75] = -77;
825  l[76] = 121;
826  l[77] = -79;
827  l[78] = 73;
828  l[79] = 123;
829  l[80] = -82;
830  l[81] = 49;
831  l[82] = -86;
832  l[83] = -85;
833  l[84] = 13;
834  l[85] = 40;
835  l[86] = -88;
836  l[87] = 45;
837  l[88] = -90;
838  l[89] = 68;
839  l[90] = -92;
840  l[91] = 84;
841  l[92] = -94;
842  l[93] = 125;
843  l[94] = -96;
844  l[95] = 39;
845  l[96] = -98;
846  l[97] = 58;
847  l[98] = -100;
848  l[99] = 36;
849  l[100] = -102;
850  l[101] = 92;
851  l[102] = -104;
852  l[103] = 124;
853  l[104] = -108;
854  l[105] = -107;
855  l[106] = 3;
856  l[107] = 4;
857  l[108] = -110;
858  l[109] = 0;
859  l[110] = 2;
860  l[111] = -129;
861  l[112] = -118;
862  l[113] = -115;
863  l[114] = 50;
864  l[115] = -117;
865  l[116] = 102;
866  l[117] = 103;
867  l[118] = -122;
868  l[119] = -121;
869  l[120] = 48;
870  l[121] = 110;
871  l[122] = -126;
872  l[123] = -125;
873  l[124] = 10;
874  l[125] = 1;
875  l[126] = -128;
876  l[127] = 79;
877  l[128] = 117;
878  l[129] = -137;
879  l[130] = -132;
880  l[131] = 51;
881  l[132] = -134;
882  l[133] = 98;
883  l[134] = -136;
884  l[135] = 47;
885  l[136] = 112;
886  l[137] = -141;
887  l[138] = -140;
888  l[139] = 56;
889  l[140] = 81;
890  l[141] = -143;
891  l[142] = 104;
892  l[143] = -145;
893  l[144] = 114;
894  l[145] = 115;
895  l[146] = -192;
896  l[147] = -153;
897  l[148] = -150;
898  l[149] = 32;
899  l[150] = -152;
900  l[151] = 91;
901  l[152] = 93;
902  l[153] = -157;
903  l[154] = -156;
904  l[155] = 99;
905  l[156] = 120;
906  l[157] = -159;
907  l[158] = 116;
908  l[159] = -161;
909  l[160] = 75;
910  l[161] = -163;
911  l[162] = 80;
912  l[163] = -165;
913  l[164] = 67;
914  l[165] = -167;
915  l[166] = 77;
916  l[167] = -169;
917  l[168] = 90;
918  l[169] = -171;
919  l[170] = 60;
920  l[171] = -173;
921  l[172] = 33;
922  l[173] = -175;
923  l[174] = 37;
924  l[175] = -177;
925  l[176] = 96;
926  l[177] = -185;
927  l[178] = -182;
928  l[179] = -181;
929  l[180] = 248;
930  l[181] = 249;
931  l[182] = -184;
932  l[183] = 246;
933  l[184] = 247;
934  l[185] = -189;
935  l[186] = -188;
936  l[187] = 252;
937  l[188] = 253;
938  l[189] = -191;
939  l[190] = 250;
940  l[191] = 251;
941  l[192] = -228;
942  l[193] = -225;
943  l[194] = -196;
944  l[195] = 52;
945  l[196] = -198;
946  l[197] = 108;
947  l[198] = -208;
948  l[199] = -201;
949  l[200] = 83;
950  l[201] = -205;
951  l[202] = -204;
952  l[203] = 61;
953  l[204] = 72;
954  l[205] = -207;
955  l[206] = 113;
956  l[207] = 122;
957  l[208] = -212;
958  l[209] = -211;
959  l[210] = 65;
960  l[211] = 70;
961  l[212] = -214;
962  l[213] = 71;
963  l[214] = -216;
964  l[215] = 76;
965  l[216] = -218;
966  l[217] = 74;
967  l[218] = -220;
968  l[219] = 88;
969  l[220] = -222;
970  l[221] = 64;
971  l[222] = -224;
972  l[223] = 42;
973  l[224] = 94;
974  l[225] = -227;
975  l[226] = 53;
976  l[227] = 100;
977  l[228] = -232;
978  l[229] = -231;
979  l[230] = 54;
980  l[231] = 82;
981  l[232] = -234;
982  l[233] = 97;
983  l[234] = -236;
984  l[235] = 111;
985  l[236] = -238;
986  l[237] = 43;
987  l[238] = -240;
988  l[239] = 87;
989  l[240] = -242;
990  l[241] = 41;
991  l[242] = -244;
992  l[243] = 86;
993  l[244] = -246;
994  l[245] = 35;
995  l[246] = -256;
996  l[247] = -249;
997  l[248] = 59;
998  l[249] = -251;
999  l[250] = 95;
1000  l[251] = -253;
1001  l[252] = 126;
1002  l[253] = -255;
1003  l[254] = 254;
1004  l[255] = 255;
1005  l[256] = -384;
1006  l[257] = -321;
1007  l[258] = -290;
1008  l[259] = -275;
1009  l[260] = -268;
1010  l[261] = -265;
1011  l[262] = -264;
1012  l[263] = 160;
1013  l[264] = 161;
1014  l[265] = -267;
1015  l[266] = 158;
1016  l[267] = 159;
1017  l[268] = -272;
1018  l[269] = -271;
1019  l[270] = 164;
1020  l[271] = 165;
1021  l[272] = -274;
1022  l[273] = 162;
1023  l[274] = 163;
1024  l[275] = -283;
1025  l[276] = -280;
1026  l[277] = -279;
1027  l[278] = 152;
1028  l[279] = 153;
1029  l[280] = -282;
1030  l[281] = 150;
1031  l[282] = 151;
1032  l[283] = -287;
1033  l[284] = -286;
1034  l[285] = 156;
1035  l[286] = 157;
1036  l[287] = -289;
1037  l[288] = 154;
1038  l[289] = 155;
1039  l[290] = -306;
1040  l[291] = -299;
1041  l[292] = -296;
1042  l[293] = -295;
1043  l[294] = 176;
1044  l[295] = 177;
1045  l[296] = -298;
1046  l[297] = 174;
1047  l[298] = 175;
1048  l[299] = -303;
1049  l[300] = -302;
1050  l[301] = 180;
1051  l[302] = 181;
1052  l[303] = -305;
1053  l[304] = 178;
1054  l[305] = 179;
1055  l[306] = -314;
1056  l[307] = -311;
1057  l[308] = -310;
1058  l[309] = 168;
1059  l[310] = 169;
1060  l[311] = -313;
1061  l[312] = 166;
1062  l[313] = 167;
1063  l[314] = -318;
1064  l[315] = -317;
1065  l[316] = 172;
1066  l[317] = 173;
1067  l[318] = -320;
1068  l[319] = 170;
1069  l[320] = 171;
1070  l[321] = -353;
1071  l[322] = -338;
1072  l[323] = -331;
1073  l[324] = -328;
1074  l[325] = -327;
1075  l[326] = 128;
1076  l[327] = 129;
1077  l[328] = -330;
1078  l[329] = 31;
1079  l[330] = 127;
1080  l[331] = -335;
1081  l[332] = -334;
1082  l[333] = 132;
1083  l[334] = 133;
1084  l[335] = -337;
1085  l[336] = 130;
1086  l[337] = 131;
1087  l[338] = -346;
1088  l[339] = -343;
1089  l[340] = -342;
1090  l[341] = 25;
1091  l[342] = 26;
1092  l[343] = -345;
1093  l[344] = 23;
1094  l[345] = 24;
1095  l[346] = -350;
1096  l[347] = -349;
1097  l[348] = 29;
1098  l[349] = 30;
1099  l[350] = -352;
1100  l[351] = 27;
1101  l[352] = 28;
1102  l[353] = -369;
1103  l[354] = -362;
1104  l[355] = -359;
1105  l[356] = -358;
1106  l[357] = 144;
1107  l[358] = 145;
1108  l[359] = -361;
1109  l[360] = 142;
1110  l[361] = 143;
1111  l[362] = -366;
1112  l[363] = -365;
1113  l[364] = 148;
1114  l[365] = 149;
1115  l[366] = -368;
1116  l[367] = 146;
1117  l[368] = 147;
1118  l[369] = -377;
1119  l[370] = -374;
1120  l[371] = -373;
1121  l[372] = 136;
1122  l[373] = 137;
1123  l[374] = -376;
1124  l[375] = 134;
1125  l[376] = 135;
1126  l[377] = -381;
1127  l[378] = -380;
1128  l[379] = 140;
1129  l[380] = 141;
1130  l[381] = -383;
1131  l[382] = 138;
1132  l[383] = 139;
1133  l[384] = -448;
1134  l[385] = -417;
1135  l[386] = -402;
1136  l[387] = -395;
1137  l[388] = -392;
1138  l[389] = -391;
1139  l[390] = 224;
1140  l[391] = 225;
1141  l[392] = -394;
1142  l[393] = 222;
1143  l[394] = 223;
1144  l[395] = -399;
1145  l[396] = -398;
1146  l[397] = 228;
1147  l[398] = 229;
1148  l[399] = -401;
1149  l[400] = 226;
1150  l[401] = 227;
1151  l[402] = -410;
1152  l[403] = -407;
1153  l[404] = -406;
1154  l[405] = 216;
1155  l[406] = 217;
1156  l[407] = -409;
1157  l[408] = 214;
1158  l[409] = 215;
1159  l[410] = -414;
1160  l[411] = -413;
1161  l[412] = 220;
1162  l[413] = 221;
1163  l[414] = -416;
1164  l[415] = 218;
1165  l[416] = 219;
1166  l[417] = -433;
1167  l[418] = -426;
1168  l[419] = -423;
1169  l[420] = -422;
1170  l[421] = 240;
1171  l[422] = 241;
1172  l[423] = -425;
1173  l[424] = 238;
1174  l[425] = 239;
1175  l[426] = -430;
1176  l[427] = -429;
1177  l[428] = 244;
1178  l[429] = 245;
1179  l[430] = -432;
1180  l[431] = 242;
1181  l[432] = 243;
1182  l[433] = -441;
1183  l[434] = -438;
1184  l[435] = -437;
1185  l[436] = 232;
1186  l[437] = 233;
1187  l[438] = -440;
1188  l[439] = 230;
1189  l[440] = 231;
1190  l[441] = -445;
1191  l[442] = -444;
1192  l[443] = 236;
1193  l[444] = 237;
1194  l[445] = -447;
1195  l[446] = 234;
1196  l[447] = 235;
1197  l[448] = -480;
1198  l[449] = -465;
1199  l[450] = -458;
1200  l[451] = -455;
1201  l[452] = -454;
1202  l[453] = 192;
1203  l[454] = 193;
1204  l[455] = -457;
1205  l[456] = 190;
1206  l[457] = 191;
1207  l[458] = -462;
1208  l[459] = -461;
1209  l[460] = 196;
1210  l[461] = 197;
1211  l[462] = -464;
1212  l[463] = 194;
1213  l[464] = 195;
1214  l[465] = -473;
1215  l[466] = -470;
1216  l[467] = -469;
1217  l[468] = 184;
1218  l[469] = 185;
1219  l[470] = -472;
1220  l[471] = 182;
1221  l[472] = 183;
1222  l[473] = -477;
1223  l[474] = -476;
1224  l[475] = 188;
1225  l[476] = 189;
1226  l[477] = -479;
1227  l[478] = 186;
1228  l[479] = 187;
1229  l[480] = -496;
1230  l[481] = -489;
1231  l[482] = -486;
1232  l[483] = -485;
1233  l[484] = 208;
1234  l[485] = 209;
1235  l[486] = -488;
1236  l[487] = 206;
1237  l[488] = 207;
1238  l[489] = -493;
1239  l[490] = -492;
1240  l[491] = 212;
1241  l[492] = 213;
1242  l[493] = -495;
1243  l[494] = 210;
1244  l[495] = 211;
1245  l[496] = -504;
1246  l[497] = -501;
1247  l[498] = -500;
1248  l[499] = 200;
1249  l[500] = 201;
1250  l[501] = -503;
1251  l[502] = 198;
1252  l[503] = 199;
1253  l[504] = -508;
1254  l[505] = -507;
1255  l[506] = 204;
1256  l[507] = 205;
1257  l[508] = -510;
1258  l[509] = 202;
1259  l[510] = 203;
1260  }
1261
1262  var a=0, b=0, e=0, i, o="";
1263
1264  function B() { if (a===0) { b=encodingCharSet.indexOf(bytes.charAt(e++)); a=6; } return ((b>>--a)&0x01); }
1265
1266  while(originalLength>0) { i=0;
1267    while(l[i]<0) {
1268      if (B()) { i=-l[i]; }
1269      else { i++; }
1270    }
1271    o+=String.fromCharCode(l[i]);
1272    originalLength--;
1273  }
1274
1275  return o;
1276}
1277
1278</script>
1279
1280</head>
1281
1282<body style="margin: 0px; padding: 1.75em; font-family: sans-serif;">
1283
1284<h1 style="margin-top:0px; padding-top:0px;">pgn4web PGN encoder/decoder test</h1>
1285
1286<center>
1287
1288<textarea id="textArea" style="height:300px; width:900px;"></textarea>
1289<form>
1290<input type="button" style="width:700px;" onClick="javascript: testPGNencode();" value="pgn4web PGN encoder/decoder test">
1291<input type="button" style="width:200px;" onClick="javascript: document.getElementById('textArea').value = '';" value="clear form">
1292</form>
1293<div style="width: 900px; text-align: left"><b>status: </b><span id="status">enter PGN data and press the test button</span></div>
1294<br>
1295<table cellspacing=2 cellpadding=0 border=1>
1296<tr style="font-weight: bold; text-align: center;">
1297<td>original</td>
1298<td>decoded</td>
1299</tr>
1300<tr>
1301<td>
1302<textarea id="original" readonly style="height:300px; width:447px;">
1303</textarea>
1304</td>
1305<td>
1306<textarea id="decoded" readonly style="height:300px; width:447px;">
1307</textarea>
1308</td>
1309</tr>
1310</table>
1311<br>
1312<table cellspacing=2 cellpadding=0 border=1>
1313<tr style="font-weight: bold; text-align: center;">
1314<td>encoded</td>
1315</tr>
1316<tr>
1317<td>
1318<textarea id="encoded" readonly style="height:80px; width:896px;">
1319</textarea>
1320</td>
1321</tr>
1322<tr style="font-weight: bold; text-align: center;">
1323<td>decoding key</td>
1324</tr>
1325<tr>
1326<td>
1327<textarea id="decodingKey" readonly style="height:80px; width:896px;">
1328</textarea>
1329</td>
1330</tr>
1331</table>
1332<br>
1333<table cellspacing=2 cellpadding=0 border=1>
1334<tr style="font-weight: bold; text-align: center;">
1335<td>original letters</td>
1336<td>letter codes</td>
1337<td>decoding values</td>
1338<td>encoded letters</td>
1339</tr>
1340<tr>
1341<td>
1342<textarea id="originalLetters" readonly style="height:300px; width:195px;">
1343</textarea>
1344</td>
1345<td>
1346<textarea id="LetterCodes" readonly style="height:300px; width:335px;">
1347</textarea>
1348</td>
1349<td>
1350<textarea id="decodingValues" readonly style="height:300px; width:165px;">
1351</textarea>
1352</td>
1353<td>
1354<textarea id="encodedLetters" readonly style="height:300px; width:195px;">
1355</textarea>
1356</td>
1357</tr>
1358</table>
1359<br>
1360
1361</center>
1362
1363<script type="text/javascript">
1364
1365function testPGNencode() {
1366
1367  document.getElementById("status").innerHTML = "...encoding data...";
1368
1369  if (document.getElementById("textArea").value === "") {
1370    document.getElementById("original").value = document.getElementById("originalInput").innerHTML;
1371  } else {
1372    document.getElementById("original").value = document.getElementById("textArea").value;
1373  }
1374  original_var = document.getElementById("original").value;
1375  ret = new Array(3);
1376  ret = EncodePGN(original_var);
1377  test_bytes = ret[0];
1378  test_encodedNodes = ret[1];
1379  test_LetterCodes = ret[2];
1380
1381  document.getElementById("status").innerHTML = "...decoding data...";
1382
1383  document.getElementById("encoded").value = test_bytes;
1384
1385  document.getElementById("decoded").value = DecodePGN(test_bytes, test_encodedNodes);
1386
1387  compressPerc = Math.floor(100 * (document.getElementById("original").value.length - document.getElementById("encoded").value.length) / document.getElementById("original").value.length);
1388
1389  document.getElementById("status").innerHTML = "encoding/decoding test completed;" +
1390    " original: " + document.getElementById("original").value.length + ";" +
1391    " encoded: " + document.getElementById("encoded").value.length + ";" +
1392    " compression rate: " + compressPerc + "%";
1393
1394  if (document.getElementById("decoded").value != document.getElementById("original").value) {
1395    document.getElementById("status").innerHTML += "<br><span style='font-weight: bold; color: red;'>error: decoded different from original, please check for ASCII chars greater than 255 in the original input</span>";
1396  }
1397
1398  document.getElementById("originalLetters").value = letter_frequency(document.getElementById("original").value);
1399
1400  document.getElementById("encodedLetters").value = letter_frequency(document.getElementById("encoded").value);
1401
1402  document.getElementById("decodingKey").value = test_encodedNodes;
1403
1404  l = new Array();
1405  while(test_encodedNodes.length) {
1406    l.push((encodingCharSet.indexOf(test_encodedNodes.charAt(0))<<6)+encodingCharSet.indexOf(test_encodedNodes.charAt(1))-512);
1407    test_encodedNodes = test_encodedNodes.slice(2,test_encodedNodes.length);
1408  }
1409  o = "";
1410  for (i=0; i<l.length; i++) {
1411    o += "l[" + i + "]";
1412    if (i < 10) { o += "  "; }
1413    else { if (i < 100) { o += " "; } }
1414    o += " = " + l[i] + ";\n";
1415  }
1416  document.getElementById("decodingValues").value = o;
1417
1418  o = "";
1419  for (i=0; i<test_LetterCodes.length; i++) {
1420    o += "LetterCodes[" + i + "]";
1421    if (i < 10) { o += "  "; }
1422    else { if (i < 100) { o += " "; } }
1423    o += " = '" + test_LetterCodes[i] + "';\n";
1424  }
1425  document.getElementById("LetterCodes").innerHTML = o;
1426}
1427
1428function letter_frequency(s) {
1429  var thisLetters = new Array(256);
1430  for (i = 0; i < thisLetters.length; i ++) { thisLetters[i]=0; }
1431  var o = "";
1432  for (i = 0; i < s.length; i ++) { thisLetters[s.charCodeAt(i)]++; }
1433  for (i = 0; i < thisLetters.length; i ++) {
1434    o += "Letters[" + i + "]";
1435    if (i < 10) { o += "  "; }
1436    else { if (i < 100) { o += " "; } }
1437    o += " = " + thisLetters[i] + ";";
1438    if (i > 32) { o += "   // " + String.fromCharCode(i); }
1439    o += "\n";
1440  }
1441  return o;
1442}
1443
1444</script>
1445
1446<textarea id="originalInput" style="display:none;">
1447[White "Spassky, Boris"]
1448[Black "Fischer, Robert"]
1449[Result "0-1"]
1450[Date "1972"]
1451[Event "World Championship"]
1452[Site "Reykjavik"]
1453[Round "13"]
1454
14551. e4 Nf6 2. e5 Nd5 3. d4 d6 4. Nf3 g6
14565. Bc4 Nb6 6. Bb3 Bg7 7. Nbd2 O-O 8. h3 a5
14579. a4 dxe5 10. dxe5 Na6 11. O-O Nc5 12. Qe2 Qe8
145813. Ne4 Nbxa4 14. Bxa4 Nxa4 15. Re1 Nb6 16. Bd2 a4
145917. Bg5 h6 18. Bh4 Bf5 19. g4 Be6 20. Nd4 Bc4
146021. Qd2 Qd7 22. Rad1 Rfe8 23. f4 Bd5 24. Nc5 Qc8
146125. Qc3 e6 26. Kh2 Nd7 27. Nd3 c5 28. Nb5 Qc6
146229. Nd6 Qxd6 30. exd6 Bxc3 31. bxc3 f6 32. g5 hxg5
146333. fxg5 f5 34. Bg3 Kf7 35. Ne5 Nxe5 36. Bxe5 b5
146437. Rf1 Rh8 38. Bf6 a3 39. Rf4 a2 40. c4 Bxc4
146541. d7 Bd5 42. Kg3 Ra3 43. c3 Rha8 44. Rh4 e5
146645. Rh7 Ke6 46. Re7 Kd6 47. Rxe5 Rxc3 48. Kf2 Rc2
146749. Ke1 Kxd7 50. Rexd5 Kc6 51. Rd6 Kb7 52. Rd7 Ka6
146853. R7d2 Rxd2 54. Kxd2 b4 55. h4 Kb5 56. h5 c4
146957. Ra1 gxh5 58. g6 h4 59. g7 h3 60. Be7 Rg8
147061. Bf8 h2 62. Kc2 Kc6 63. Rd1 b3 64. Kc3 h1Q
147165. Rxh1 Kd5 66. Kb2 f4 67. Rd1 Ke4 68. Rc1 Kd3
147269. Rd1 Ke2 70. Rc1 f3 71. Bc5 Rxg7 72. Rxc4 Rd7
147373. Re4 Kf1 74. Bd4 f2 0-1
1474</textarea>
1475
1476</body>
1477</html>
1478
1479