/**
 * Compresses the given String using the 
 * The Lempel-Ziv-Welch (LZW) algorithm, which provides lossless data compression. 
 * You can read a complete description of it in the Wikipedia article on the subject. 
 * It was patented, but it fell in the public domain in 2004.
 * @see http://en.wikipedia.org/wiki/Lempel-Ziv-Welch
 * @param {String} s String data to compress
 * @return {String} compressed String data
 */
function lzwCompress(s) {
	var dict = {};
	var data = (s + "").split("");
	var out = [];
	var currChar;
	var phrase = data[0];
	var code = 256;
	for ( var i = 1; i < data.length; i++) {
		currChar = data[i];
		if (dict[phrase + currChar] != null) {
			phrase += currChar;
		} else {
			out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
			dict[phrase + currChar] = code;
			code++;
			phrase = currChar;
		}
	}
	out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
	for ( var i = 0; i < out.length; i++) {
		out[i] = String.fromCharCode(out[i]);
	}
	return out.join("");
}
/**
 * Decompresses the given String data, which was compressed using the Lempel-Ziv-Welch (LZW) algorithm.
 * If the given String data was not compressed using the Lempel-Ziv-Welch (LZW) algorithm, the original data will be returned.
 * The Lempel-Ziv-Welch (LZW) algorithm, which provides lossless data compression. 
 * You can read a complete description of it in the Wikipedia article on the subject. 
 * It was patented, but it fell in the public domain in 2004.
 * @see http://en.wikipedia.org/wiki/Lempel-Ziv-Welch
 * @param {String} s String data to decompress
 * @return {String} decompressed String data
 */
function lzwDecompress(s) {
	var dict = {};
	var data = (s + "").split("");
	var currChar = data[0];
	var oldPhrase = currChar;
	var out = [ currChar ];
	var code = 256;
	var phrase;
	for ( var i = 1; i < data.length; i++) {
		var currCode = data[i].charCodeAt(0);
		if (currCode < 256) {
			phrase = data[i];
		} else {
			phrase = dict[currCode] ? dict[currCode] : (oldPhrase + currChar);
		}
		out.push(phrase);
		currChar = phrase.charAt(0);
		dict[code] = oldPhrase + currChar;
		code++;
		oldPhrase = phrase;
	}
	return out.join("");
}

