if (typeof(initCharMap) != 'undefined') {
  initCharMap = selectMap;
  if (theTyper) theTyper.charmap = initCharMap();
  vumaps = 1;
}
function selectMap(id) {
  var map = id? id: charmapid; 
  return maps? maps.getMap(map): new CVietUniCodeMap();
}
function detectFormat (txt, alrt) {
  var enc= maps.detect(txt);
  var id= enc? enc[0]: 0;
  if (!alrt) return id;
  if (!id) alert("Xin loi, khong the nhan dang duoc ma , ban vui long thu lai ...");
  else alert("Bang ma duoc dung trong van ban tren la : "+ enc[1]);
  return id;
}
var maps = new CMaps();
maps.register("CVietUniCodeMap()");
maps.register("CVietCombUCMap()");
maps.register("CVietUTF8Map()");
maps.register("CVietEscUCMap()");
maps.register("CVietVniMap()");
maps.register("CVietTCVNMap()");
maps.register("CVietVISCIIMap()");
maps.register("CVietVPSMap()");
maps.register("CVietViqrMap()");
function CMaps() {                                               
this.length= 1;
this.names= ["_RESERVED_"];
this.constructors= ["_RESERVED_"];
this.patterns= ["_RESERVED_"];
this.register= function (constructor) {
  var map= eval(constructor);
  this.names[this.length] = map.vietchars[0];
  this.constructors[this.length] = constructor;
  var re= (map.pattern)? map.pattern: "\x5b\u1ea0\x2d\u1ef9\x5d";
  var reg= new RegExp();
  reg.compile(re, map.maxchrlen?'gi':'g');
  this.patterns[this.length++]= reg;
}
this.getMap= function(id) {
  var ind= this.length-1;
  if (typeof(id)=='number') { ind= id; }
  else {
    id= id.toUpperCase();
    while((ind>0) && (this.names[ind].toUpperCase()!=id)) { --ind; }
  }
  if(!ind || (ind>=this.length)) { return new CVietUniCodeMap(); }
  return eval(this.constructors[ind]);
}
this.detect= function(txt) {
  for (var i=this.length-1; i>0; --i) {
    if (this.patterns[i].test(txt)) break;
  }
  return i? [i, this.names[i]]: null;
}
return this;
}                    
CVietCharMap.prototype.lowerCaseOf = function (chr, ind) {
  var i = ind? ind: this.isVowel(chr);
  if(i) return ((i-1)%24 >= 12)? this.charAt(i-12): this.charAt(i);
  return 0;
}
CVietCharMap.prototype.indexOf = function (chr,isnumber) {
  var c = isnumber? String.fromcharCode(chr) : chr;
  var ind = this.length-1;
  while ((c != this.charAt(ind)) && (ind > 0)) --ind;
  return ind;
}
CVietCharMap.prototype.regExpAt = function (i) {
  var c=this.charAt(i);
  if(c) c = c.replace(/([\\\*\|\+\-\?\.\(\^\$])/g, "\\$1");
  return c? new RegExp(c,'g') : 0;
}
CVietCharMap.prototype.convertTxtTo = function (txt, newmap) {
  var i, c, regexp, res;
  if (newmap.isVIQR) txt= txt.replace(/([\.\?]+\s)/g, "\\$1");
  for (i= this.length-1; i>0; i--) {
    regexp= this.regExpAt(i);
    if(regexp) txt= txt.replace(regexp, "::"+i+"::");
  }
  for (i=this.length-1; i>0; i--) {
    c = newmap.charAt(i);
    if (!c) c= newmap.lowerCaseOf(0,i);
    txt= txt.replace(new RegExp("::"+i+"::",'g'), c);
  }
  return txt;
}
function CVietMultibyteMap(superior) { 
var map= superior? superior: new CVietCharMap();
map.maxchrlen = 3;
map.charAt = function (ind) { 
  return this.vietchars[ind];
}
map.lastCharsOf = function (str, num) {
  var vchar = null;
  var i= this.maxchrlen;
  var mystr = str;
  while (!vchar && (i > 1)) {
    var c = mystr.substring(mystr.length-i);
    if (this.indexOf(c)) vchar=[c, i]; 
    --i;
  }
  if (!vchar) vchar=[mystr.charAt(mystr.length-1), 1]; 
  if (!num) return vchar;
  var vchars = new Array(num);
  vchars[0]= vchar; 
  for ( i=1; i< num; i++) {
    mystr= mystr.substring(0,mystr.length-vchars[i-1][1]);  
    vchars[i]= this.lastCharsOf(mystr);
  }
  return vchars;
}
return map;
}
function CVietUTF8Map() { var map= new CVietMultibyteMap(new CVietUniCodeMap());
map.vietchars[0] = "UTF-8";
for (var i = 1; i < map.length; i++ ) {
  var c = map.vietchars[i], utf;
  if (c < 128) {
    utf = String.fromCharCode(c);
  }
  else if (c < 2048) {
    utf = String.fromCharCode(192 | c >> 6 );
    utf += String.fromCharCode(128 | c & 63);
  }
  else if (c < 65536) {
    utf = String.fromCharCode(224 | c >> 12);
    utf += String.fromCharCode(128 | c >> 6 & 63);
    utf += String.fromCharCode(128 | c & 63);
  }
  map.vietchars[i] = utf;
}
map.pattern=
"(\xe1\xba|\xe1\xbb)[\xa5\xa4\xa7\xa6\xac\xa9\xa8\xab\xaa\xaf"+
"\xae\xb1\xb0\xb7\xb6\xb3\xb2\xba\xbd\xbc\xbe\xbf\xa1\xa3\xa2]";

return map;
}
function CVietEscUCMap() { var map= new CVietMultibyteMap(new CVietUniCodeMap());
  map.vietchars[0] = "&#Unicode;";
  map.maxchrlen = 7;
  for (var i = 1; i < map.length; i++ ) {
    var c = map.vietchars[i];
    if (c < 256) map.vietchars[i] = String.fromCharCode(c);
    else map.vietchars[i] = "&#"+ c +';';
  }
  map.pattern="\x26\x23\x5c\x64\x5c\x64\x5c\x64\x5c\x64\x3b";
  return map;
}
function CVietCombUCMap() { var map = new CVietMultibyteMap(new CVietUniCodeMap());
  map.vietchars[0] = "Unicode to hop";
  map.maxchrlen = 2;
  var viettm = new Array("UNICODE-C", 769, 768, 803, 777, 771); // ('`.?~)
  for (var i = 1; i < map.length-4; i++ ) {
    var i_char = (i-1)%24;
    var i_tm = (i - i_char - 1)/24;
    var base_c = map.vietchars[i_char+1];
    if (i<25) base_c = String.fromCharCode(base_c);
    var tonmark = String.fromCharCode(viettm[i_tm]);
    map.vietchars[i] = i_tm? base_c + tonmark : base_c;
  }
  for (var i = map.length-4; i < map.length; i++ ) {
    map.vietchars[i] = String.fromCharCode(map.vietchars[i]);
  }
  map.pattern= "\x5b\u0301\u0300\u0323\u0309\u0303\x5d";
  return map;
}  
function CVietVniMap() { var map = new CVietMultibyteMap();
map.maxchrlen = 2;
map.vietchars = new Array(
"VNI-WIN",
"a","a\xe2","a\xea","e","e\xe2","i","o","o\xe2","\xf4","u","\xf6","y",
"A","A\xc2","A\xca","E","E\xc2","I","O","O\xc2","\xd4","U","\xd6","Y",
"a\xf9","a\xe1","a\xe9","e\xf9","e\xe1","\xed","o\xf9","o\xe1","\xf4\xf9","u\xf9","\xf6\xf9","y\xf9",
"A\xd9","A\xc1","A\xc9","E\xd9","E\xc1","\xcd","O\xd9","O\xc1","\xd4\xd9","U\xd9","\xd6\xd9","Y\xd9",
"a\xf8","a\xe0","a\xe8","e\xf8","e\xe0","\xec","o\xf8","o\xe0","\xf4\xf8","u\xf8","\xf6\xf8","y\xf8",
"A\xd8","A\xc0","A\xc8","E\xd8","E\xc0","\xcc","O\xd8","O\xc0","\xd4\xd8","U\xd8","\xd6\xd8","Y\xd8",
"a\xef","a\xe4","a\xeb","e\xef","e\xe4","\xf2","o\xef","o\xe4","\xf4\xef","u\xef","\xf6\xef","\xee",
"A\xcf","A\xc4","A\xcb","E\xcf","E\xc4","\xd2","O\xcf","O\xc4","\xd4\xcf","U\xcf","\xd6\xcf","\xce",
"a\xfb","a\xe5","a\xfa","e\xfb","e\xe5","\xe6","o\xfb","o\xe5","\xf4\xfb","u\xfb","\xf6\xfb","y\xfb",
"A\xdb","A\xc5","A\xda","E\xdb","E\xc5","\xc6","O\xdb","O\xc5","\xd4\xdb","U\xdb","\xd6\xdb","Y\xdb",
"a\xf5","a\xe3","a\xfc","e\xf5","e\xe3","\xf3","o\xf5","o\xe3","\xf4\xf5","u\xf5","\xf6\xf5","y\xf5",
"A\xd5","A\xc3","A\xdc","E\xd5","E\xc3","\xd3","O\xd5","O\xc3","\xd4\xd5","U\xd5","\xd6\xd5","Y\xd5",
"d","\xf1","D","\xd1");
map.pattern=
"\x5b\xf6\xf4\x5d\x5b\xf9\xf8\xef\xfb\xf5\x5d\x7c\x6f\x61\x5b\xeb"+
"\xf9\xf8\xef\xfb\xf5\x5d\x7c\xf1\x5b\x61\x6f\x65\x75\xf4\xf6\x5d"+
"\x5b\xe4\xe0\xe1\xe5\xe3\xf9\xf8\xef\xfb\xf5\x5d";
return map;
}
function CVietViqrMap() { var map = new CVietMultibyteMap();
map.vietchars = new Array(
 "VIQR",
 "a","a^","a(","e","e^","i","o","o^","o+","u","u+","y",
 "A","A^","A(","E","E^","I","O","O^","O+","U","U+", "Y",
 "a'","a^'","a('","e'","e^'","i'","o'","o^'","o+'","u'","u+'","y'", 
 "A'","A^'","A('","E'","E^'","I'","O'","O^'","O+'","U'","U+'","Y'", 
 "a`","a^`","a(`","e`","e^`","i`","o`","o^`","o+`","u`","u+`","y`", 
 "A`","A^`","A(`","E`","E^`","I`","O`","O^`","O+`","U`","U+`","Y`", 
 "a.","a^.","a(.","e.","e^.","i.","o.","o^.","o+.","u.","u+.","y.", 
 "A.","A^.","A(.","E.","E^.","I.","O.","O^.","O+.","U.","U+.","Y.", 
 "a?","a^?","a(?","e?","e^?","i?","o?","o^?","o+?","u?","u+?","y?", 
 "A?","A^?","A(?","E?","E^?","I?","O?","O^?","O+?","U?","U+?","Y?", 
 "a~","a^~","a(~","e~","e^~","i~","o~","o^~","o+~","u~","u+~","y~", 
 "A~","A^~","A(~","E~","E^~","I~","O~","O^~","O+~","U~","U+~","Y~",
 "d","dd","D","DD");
 map.pattern=
"\x75\x5b\x5c\x2b\x5c\x2a\x5d\x6f\x5b\x5c\x2b\x5c\x2a\x5d\x7c\x64\x64"+
"\x5b\x61\x6f\x65\x5d\x5b\x5c\x28\x5c\x5e\x7e\x27\x60\x5d\x7c\x5b\x61"+
"\x6f\x65\x5d\x5c\x5e\x5b\x7e\x60\x27\x5c\x2e\x5c\x3f\x5d\x7c\x5b\x75"+
"\x6f\x5d\x5c\x2b\x5b\x60\x27\x7e\x5c\x2e\x5c\x3f\x5d\x7c\x61\x5c\x28"+
"\x5b\x27\x60\x7e\x5c\x2e\x5c\x3f\x5d";
map.isVIQR= true;
map.regExpAt = function(ind) {
  var c=this.charAt(ind);
  if (!c) return null;
  c = c.replace(/\+/g, "[\\+\\*]");
  c = c.replace(/'/g, "['´]");
  c = c.replace(/([\-\?\.\(\^])/g, "\\$1");
  c = c.replace(/(d)d/gi, "$1$1|\\-$1|$1\\-");
  return new RegExp(c,'g');
}
map.convertTxtTo = function (txt, newmap) {
  var i, c, regexp, res, tmp;
  txt= txt.replace(/(\.\.+|\?\?+)/g, ";;;$1");
  while ((res=/(\.[\w\@\-\.\/\\][\w\@\-\.\/\\][\w\@\-\.\/\\]+\s*)/g.exec(txt))) {
    regexp= res[1].replace(/([\.\?\+\-\(\^\*\@\\)\]\}])/g,"\\$1");
    tmp= res[1].replace(/\./g,";;;.;;;");
    txt= txt.replace(new RegExp(regexp,'g'), tmp);
  }
  for (i=this.length-1; i>0; i--) {
    regexp= this.regExpAt(i);
    if(regexp) txt= txt.replace(regexp, "::"+i+"::");
  }
  for (i=this.length-1; i>0; i--) {
    c = newmap.charAt(i);
    if (!c) c= newmap.lowerCaseOf(0,i);
    txt= txt.replace(new RegExp("::"+i+"::",'g'), c);
  }
  txt= txt.replace(/;;;/g,"");
  txt= txt.replace(/\\([\.\?])/g,"$1");
  return txt;
}
return map;
}
function CVietTCVNMap() { var map = new CVietCharMap();
map.vietchars = new Array(
 "TCVN-3",
 97, 169, 168, 101, 170, 105, 111, 171, 172, 117, 173, 121, 
 65, 162, 161, 69, 163, 73, 79, 164, 165, 85, 166, 89,
 184, 202, 190, 208, 213, 221, 227, 232, 237, 243, 248, 253,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 181, 199, 187, 204, 210, 215, 223, 229, 234, 239, 245, 250,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 185, 203, 198, 209, 214, 222, 228, 233, 238, 244, 249, 254,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 182, 200, 188, 206, 211, 216, 225, 230, 235, 241, 246, 251,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 183, 201, 189, 207, 212, 220, 226, 231, 236, 242, 247, 252,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 100, 174, 68, 167);
map.pattern=
"\x5c\x77\xad[\xac\xed\xea\xee\xeb\xec]|\xae[\xb8\xb5\xb9\xb6\xb7"+
"\xca\xbe\xbb\xc6\xbc\xbd\xcc\xd1\xce\xcf\xaa\xd5\xd2\xd6\xd3\xd4"+
"\xdd\xd7\xde\xd8\xdc\xe3\xdf\xe4\xe1\xe2\xab\xe8\xe5\xe9\xe6\xe7"+
"\xac\xed\xea\xee\xeb\xec\xf3\xef\xf4\xf1\xf2\xf8\xf5\xf9\xf6\x5d";
return map;
}
function CVietVISCIIMap() { var map = new CVietCharMap();
map.vietchars = new Array(
"VISCII",
97, 226, 229, 101, 234, 105, 111, 244, 189, 117, 223, 121,
65, 194, 197, 69, 202, 73, 79, 212, 180, 85, 191, 89,
225, 164, 237, 233, 170, 237, 243, 175, 190, 250, 209, 253,
193, 8222, 129, 201, 352, 205, 211, 143, 8226, 218, 186, 221,
224, 165, 162, 232, 171, 236, 242, 176, 182, 249, 215, 207,
192, 8230, 8218, 200, 8249, 204, 210, 144, 8211, 217, 187, 376,
213, 167, 163, 169, 174, 184, 247, 181, 254, 248, 241, 220,
8364, 8225, 402, 8240, 381, 732, 353, 8220, 8221, 382, 185, 0,
228, 166, 198, 235, 172, 239, 246, 177, 183, 252, 216, 214,
196, 8224, 0, 203, 338, 8250, 8482, 8216, 8212, 339, 188, 0,
227, 231, 199, 168, 173, 238, 245, 178, 222, 251, 230, 219,
195, 0, 0, 710, 141, 206, 0, 8217, 179, 157, 255, 0,
100, 240, 68, 208);
map.pattern=
"\x5c\x77\xdf\x5b\xbd\xbe\xb6\xfe\xb7\xde\x5d\x7c\xf0\x5b\xe1\xe0\xd5"+
"\xe4\xe3\xa4\xed\xa2\xa3\xc6\xc7\xe8\xa9\xeb\xa8\xea\xaa\xab\xae\xac"+
"\xad\xed\xec\xb8\xef\xee\xf3\xf2\xf7\xf6\xf5\xf4\xaf\xb0\xb5\xb1\xb2"+
"\xbd\xbe\xb6\xfe\xb7\xde\xfa\xf9\xf8\xfc\xfb\xd1\xd7\xf1\xd8\x5d";
return map;
}
function CVietVPSMap() { var map = new CVietCharMap();
map.vietchars = new Array(
"VPS-Win",
97, 226, 230, 101, 234, 105, 111, 244, 214, 117, 220, 121,
65, 194, 710, 69, 202, 73, 79, 212, 247, 85, 208, 89,
225, 195, 161, 233, 8240, 237, 243, 211, 167, 250, 217, 353,
193, 402, 141, 201, 144, 180, 185, 8211, 157, 218, 173, 221,
224, 192, 162, 232, 352, 236, 242, 210, 169, 249, 216, 255,
0, 8222, 0, 215, 8220, 181, 188, 8212, 0, 168, 175, 178,
229, 198, 165, 203, 338, 206, 8224, 182, 174, 248, 191, 339,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
228, 196, 163, 200, 8249, 204, 213, 176, 170, 251, 186, 8250,
129, 8230, 0, 222, 8221, 183, 189, 732, 376, 209, 177, 0,
227, 197, 164, 235, 205, 239, 245, 8225, 171, 219, 187, 207,
8218, 0, 0, 254, 8226, 184, 0, 8482, 166, 172, 0, 0,
100, 199, 68, 241);
map.pattern=
"\x5c\x77\xdc\x5b\xd6\xa7\xa9\xae\xaa\xab\x5d\x7c\xc7\x5b\xe1\xe0\xe5"+
"\xe4\xe3\xc3\xed\xa2\xa5\xa3\xa4\xe8\xcb\xc8\xeb\xea\xcd\xed\xec\xce"+
"\xcc\xef\xf3\xf2\xd5\xf5\xf4\xd3\xd2\xb6\xb0\xd6\xa7\xa9\xae\xaa\xab"+
"\xfa\xf9\xf8\xfb\xdb\xd9\xd8\xbf\xba\x5d";
return map;
}