11cb0ef41Sopenharmony_ci// set up a sparse array of all unicode codepoints listed in the index
21cb0ef41Sopenharmony_ci// this will be used for lookup in iso2022jpEncoded
31cb0ef41Sopenharmony_civar jis0208CPs = []; // index is unicode cp, value is pointer
41cb0ef41Sopenharmony_cifor (var p = 0; p < jis0208.length; p++) {
51cb0ef41Sopenharmony_ci    if (jis0208[p] != null && jis0208CPs[jis0208[p]] == null) {
61cb0ef41Sopenharmony_ci        jis0208CPs[jis0208[p]] = p;
71cb0ef41Sopenharmony_ci    }
81cb0ef41Sopenharmony_ci}
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci// set up mappings for half/full width katakana
111cb0ef41Sopenharmony_ci// index is a katakana index pointer, value is Unicode codepoint (dec)
121cb0ef41Sopenharmony_ci// this is copy-pasted from the json version of the index belonging to the Encoding spec
131cb0ef41Sopenharmony_civar iso2022jpkatakana = [
141cb0ef41Sopenharmony_ci    12290,
151cb0ef41Sopenharmony_ci    12300,
161cb0ef41Sopenharmony_ci    12301,
171cb0ef41Sopenharmony_ci    12289,
181cb0ef41Sopenharmony_ci    12539,
191cb0ef41Sopenharmony_ci    12530,
201cb0ef41Sopenharmony_ci    12449,
211cb0ef41Sopenharmony_ci    12451,
221cb0ef41Sopenharmony_ci    12453,
231cb0ef41Sopenharmony_ci    12455,
241cb0ef41Sopenharmony_ci    12457,
251cb0ef41Sopenharmony_ci    12515,
261cb0ef41Sopenharmony_ci    12517,
271cb0ef41Sopenharmony_ci    12519,
281cb0ef41Sopenharmony_ci    12483,
291cb0ef41Sopenharmony_ci    12540,
301cb0ef41Sopenharmony_ci    12450,
311cb0ef41Sopenharmony_ci    12452,
321cb0ef41Sopenharmony_ci    12454,
331cb0ef41Sopenharmony_ci    12456,
341cb0ef41Sopenharmony_ci    12458,
351cb0ef41Sopenharmony_ci    12459,
361cb0ef41Sopenharmony_ci    12461,
371cb0ef41Sopenharmony_ci    12463,
381cb0ef41Sopenharmony_ci    12465,
391cb0ef41Sopenharmony_ci    12467,
401cb0ef41Sopenharmony_ci    12469,
411cb0ef41Sopenharmony_ci    12471,
421cb0ef41Sopenharmony_ci    12473,
431cb0ef41Sopenharmony_ci    12475,
441cb0ef41Sopenharmony_ci    12477,
451cb0ef41Sopenharmony_ci    12479,
461cb0ef41Sopenharmony_ci    12481,
471cb0ef41Sopenharmony_ci    12484,
481cb0ef41Sopenharmony_ci    12486,
491cb0ef41Sopenharmony_ci    12488,
501cb0ef41Sopenharmony_ci    12490,
511cb0ef41Sopenharmony_ci    12491,
521cb0ef41Sopenharmony_ci    12492,
531cb0ef41Sopenharmony_ci    12493,
541cb0ef41Sopenharmony_ci    12494,
551cb0ef41Sopenharmony_ci    12495,
561cb0ef41Sopenharmony_ci    12498,
571cb0ef41Sopenharmony_ci    12501,
581cb0ef41Sopenharmony_ci    12504,
591cb0ef41Sopenharmony_ci    12507,
601cb0ef41Sopenharmony_ci    12510,
611cb0ef41Sopenharmony_ci    12511,
621cb0ef41Sopenharmony_ci    12512,
631cb0ef41Sopenharmony_ci    12513,
641cb0ef41Sopenharmony_ci    12514,
651cb0ef41Sopenharmony_ci    12516,
661cb0ef41Sopenharmony_ci    12518,
671cb0ef41Sopenharmony_ci    12520,
681cb0ef41Sopenharmony_ci    12521,
691cb0ef41Sopenharmony_ci    12522,
701cb0ef41Sopenharmony_ci    12523,
711cb0ef41Sopenharmony_ci    12524,
721cb0ef41Sopenharmony_ci    12525,
731cb0ef41Sopenharmony_ci    12527,
741cb0ef41Sopenharmony_ci    12531,
751cb0ef41Sopenharmony_ci    12443,
761cb0ef41Sopenharmony_ci    12444
771cb0ef41Sopenharmony_ci];
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_cifunction chars2cps(chars) {
801cb0ef41Sopenharmony_ci    // this is needed because of javascript's handling of supplementary characters
811cb0ef41Sopenharmony_ci    // char: a string of unicode characters
821cb0ef41Sopenharmony_ci    // returns an array of decimal code point values
831cb0ef41Sopenharmony_ci    var haut = 0;
841cb0ef41Sopenharmony_ci    var out = [];
851cb0ef41Sopenharmony_ci    for (var i = 0; i < chars.length; i++) {
861cb0ef41Sopenharmony_ci        var b = chars.charCodeAt(i);
871cb0ef41Sopenharmony_ci        if (b < 0 || b > 0xffff) {
881cb0ef41Sopenharmony_ci            alert(
891cb0ef41Sopenharmony_ci                "Error in chars2cps: byte out of range " + b.toString(16) + "!"
901cb0ef41Sopenharmony_ci            );
911cb0ef41Sopenharmony_ci        }
921cb0ef41Sopenharmony_ci        if (haut != 0) {
931cb0ef41Sopenharmony_ci            if (0xdc00 <= b && b <= 0xdfff) {
941cb0ef41Sopenharmony_ci                out.push(0x10000 + ((haut - 0xd800) << 10) + (b - 0xdc00));
951cb0ef41Sopenharmony_ci                haut = 0;
961cb0ef41Sopenharmony_ci                continue;
971cb0ef41Sopenharmony_ci            } else {
981cb0ef41Sopenharmony_ci                alert(
991cb0ef41Sopenharmony_ci                    "Error in chars2cps: surrogate out of range " +
1001cb0ef41Sopenharmony_ci                        haut.toString(16) +
1011cb0ef41Sopenharmony_ci                        "!"
1021cb0ef41Sopenharmony_ci                );
1031cb0ef41Sopenharmony_ci                haut = 0;
1041cb0ef41Sopenharmony_ci            }
1051cb0ef41Sopenharmony_ci        }
1061cb0ef41Sopenharmony_ci        if (0xd800 <= b && b <= 0xdbff) {
1071cb0ef41Sopenharmony_ci            haut = b;
1081cb0ef41Sopenharmony_ci        } else {
1091cb0ef41Sopenharmony_ci            out.push(b);
1101cb0ef41Sopenharmony_ci        }
1111cb0ef41Sopenharmony_ci    }
1121cb0ef41Sopenharmony_ci    return out;
1131cb0ef41Sopenharmony_ci}
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_cifunction iso2022jpEncoder(stream) {
1161cb0ef41Sopenharmony_ci    var cps = chars2cps(stream);
1171cb0ef41Sopenharmony_ci    var endofstream = 2000000;
1181cb0ef41Sopenharmony_ci    var out = "";
1191cb0ef41Sopenharmony_ci    var encState = "ascii";
1201cb0ef41Sopenharmony_ci    var finished = false;
1211cb0ef41Sopenharmony_ci    var cp, ptr;
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci    while (!finished) {
1241cb0ef41Sopenharmony_ci        if (cps.length == 0) cp = endofstream;
1251cb0ef41Sopenharmony_ci        else cp = cps.shift();
1261cb0ef41Sopenharmony_ci        if (cp == endofstream && encState != "ascii") {
1271cb0ef41Sopenharmony_ci            cps.unshift(cp);
1281cb0ef41Sopenharmony_ci            encState = "ascii";
1291cb0ef41Sopenharmony_ci            out += " 1B 28 42";
1301cb0ef41Sopenharmony_ci            continue;
1311cb0ef41Sopenharmony_ci        }
1321cb0ef41Sopenharmony_ci        if (cp == endofstream && encState == "ascii") {
1331cb0ef41Sopenharmony_ci            finished = true;
1341cb0ef41Sopenharmony_ci            continue;
1351cb0ef41Sopenharmony_ci        }
1361cb0ef41Sopenharmony_ci        if (
1371cb0ef41Sopenharmony_ci            (encState === "ascii" || encState === "roman") &&
1381cb0ef41Sopenharmony_ci            (cp === 0x0e || cp === 0x0f || cp === 0x1b)
1391cb0ef41Sopenharmony_ci        ) {
1401cb0ef41Sopenharmony_ci            //out += ' &#'+cp+';'
1411cb0ef41Sopenharmony_ci            // continue
1421cb0ef41Sopenharmony_ci            return null;
1431cb0ef41Sopenharmony_ci        }
1441cb0ef41Sopenharmony_ci        if (encState == "ascii" && cp >= 0x00 && cp <= 0x7f) {
1451cb0ef41Sopenharmony_ci            out += " " + cp.toString(16).toUpperCase();
1461cb0ef41Sopenharmony_ci            continue;
1471cb0ef41Sopenharmony_ci        }
1481cb0ef41Sopenharmony_ci        if (
1491cb0ef41Sopenharmony_ci            encState == "roman" &&
1501cb0ef41Sopenharmony_ci            ((cp >= 0x00 && cp <= 0x7f && cp !== 0x5c && cp !== 0x7e) ||
1511cb0ef41Sopenharmony_ci                cp == 0xa5 ||
1521cb0ef41Sopenharmony_ci                cp == 0x203e)
1531cb0ef41Sopenharmony_ci        ) {
1541cb0ef41Sopenharmony_ci            if (cp >= 0x00 && cp <= 0x7f) {
1551cb0ef41Sopenharmony_ci                // ASCII
1561cb0ef41Sopenharmony_ci                out += " " + cp.toString(16).toUpperCase();
1571cb0ef41Sopenharmony_ci                continue;
1581cb0ef41Sopenharmony_ci            }
1591cb0ef41Sopenharmony_ci            if (cp == 0xa5) {
1601cb0ef41Sopenharmony_ci                out += " 5C";
1611cb0ef41Sopenharmony_ci                continue;
1621cb0ef41Sopenharmony_ci            }
1631cb0ef41Sopenharmony_ci            if (cp == 0x203e) {
1641cb0ef41Sopenharmony_ci                out += " 7E";
1651cb0ef41Sopenharmony_ci                continue;
1661cb0ef41Sopenharmony_ci            }
1671cb0ef41Sopenharmony_ci        }
1681cb0ef41Sopenharmony_ci        if (encState != "ascii" && cp >= 0x00 && cp <= 0x7f) {
1691cb0ef41Sopenharmony_ci            cps.unshift(cp);
1701cb0ef41Sopenharmony_ci            encState = "ascii";
1711cb0ef41Sopenharmony_ci            out += " 1B 28 42";
1721cb0ef41Sopenharmony_ci            continue;
1731cb0ef41Sopenharmony_ci        }
1741cb0ef41Sopenharmony_ci        if ((cp == 0xa5 || cp == 0x203e) && encState != "roman") {
1751cb0ef41Sopenharmony_ci            cps.unshift(cp);
1761cb0ef41Sopenharmony_ci            encState = "roman";
1771cb0ef41Sopenharmony_ci            out += " 1B 28 4A";
1781cb0ef41Sopenharmony_ci            continue;
1791cb0ef41Sopenharmony_ci        }
1801cb0ef41Sopenharmony_ci        if (cp == 0x2212) cp = 0xff0d;
1811cb0ef41Sopenharmony_ci        if (cp >= 0xff61 && cp <= 0xff9f) {
1821cb0ef41Sopenharmony_ci            cp = iso2022jpkatakana[cp - 0xff61];
1831cb0ef41Sopenharmony_ci        }
1841cb0ef41Sopenharmony_ci        ptr = jis0208CPs[cp];
1851cb0ef41Sopenharmony_ci        if (ptr == null) {
1861cb0ef41Sopenharmony_ci            //out += ' &#'+cp+';'
1871cb0ef41Sopenharmony_ci            //continue
1881cb0ef41Sopenharmony_ci            return null;
1891cb0ef41Sopenharmony_ci        }
1901cb0ef41Sopenharmony_ci        if (encState != "jis0208") {
1911cb0ef41Sopenharmony_ci            cps.unshift(cp);
1921cb0ef41Sopenharmony_ci            encState = "jis0208";
1931cb0ef41Sopenharmony_ci            out += " 1B 24 42";
1941cb0ef41Sopenharmony_ci            continue;
1951cb0ef41Sopenharmony_ci        }
1961cb0ef41Sopenharmony_ci        var lead = Math.floor(ptr / 94) + 0x21;
1971cb0ef41Sopenharmony_ci        var trail = ptr % 94 + 0x21;
1981cb0ef41Sopenharmony_ci        out +=
1991cb0ef41Sopenharmony_ci            " " +
2001cb0ef41Sopenharmony_ci            lead.toString(16).toUpperCase() +
2011cb0ef41Sopenharmony_ci            " " +
2021cb0ef41Sopenharmony_ci            trail.toString(16).toUpperCase();
2031cb0ef41Sopenharmony_ci    }
2041cb0ef41Sopenharmony_ci    return out.trim();
2051cb0ef41Sopenharmony_ci}
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_cifunction convertToHex(str) {
2081cb0ef41Sopenharmony_ci    // converts a string of ASCII characters to hex byte codes
2091cb0ef41Sopenharmony_ci    var out = "";
2101cb0ef41Sopenharmony_ci    var result;
2111cb0ef41Sopenharmony_ci    for (var c = 0; c < str.length; c++) {
2121cb0ef41Sopenharmony_ci        result =
2131cb0ef41Sopenharmony_ci            str
2141cb0ef41Sopenharmony_ci                .charCodeAt(c)
2151cb0ef41Sopenharmony_ci                .toString(16)
2161cb0ef41Sopenharmony_ci                .toUpperCase() + " ";
2171cb0ef41Sopenharmony_ci        out += result;
2181cb0ef41Sopenharmony_ci    }
2191cb0ef41Sopenharmony_ci    return out;
2201cb0ef41Sopenharmony_ci}
2211cb0ef41Sopenharmony_ci
2221cb0ef41Sopenharmony_cifunction normalizeStr(str) {
2231cb0ef41Sopenharmony_ci    var out = "";
2241cb0ef41Sopenharmony_ci    for (var c = 0; c < str.length; c++) {
2251cb0ef41Sopenharmony_ci        if (
2261cb0ef41Sopenharmony_ci            str.charAt(c) == "%" &&
2271cb0ef41Sopenharmony_ci            str.charAt(c + 1) != "%" &&
2281cb0ef41Sopenharmony_ci            str.charAt(c + 2) != "%"
2291cb0ef41Sopenharmony_ci        ) {
2301cb0ef41Sopenharmony_ci            out += String.fromCodePoint(
2311cb0ef41Sopenharmony_ci                parseInt(str.charAt(c + 1) + str.charAt(c + 2), 16)
2321cb0ef41Sopenharmony_ci            );
2331cb0ef41Sopenharmony_ci            c += 2;
2341cb0ef41Sopenharmony_ci        } else out += str.charAt(c);
2351cb0ef41Sopenharmony_ci    }
2361cb0ef41Sopenharmony_ci    var result = "";
2371cb0ef41Sopenharmony_ci    for (var o = 0; o < out.length; o++) {
2381cb0ef41Sopenharmony_ci        result +=
2391cb0ef41Sopenharmony_ci            "%" +
2401cb0ef41Sopenharmony_ci            out
2411cb0ef41Sopenharmony_ci                .charCodeAt(o)
2421cb0ef41Sopenharmony_ci                .toString(16)
2431cb0ef41Sopenharmony_ci                .toUpperCase();
2441cb0ef41Sopenharmony_ci    }
2451cb0ef41Sopenharmony_ci    return result.replace(/%1B%28%42$/, "");
2461cb0ef41Sopenharmony_ci}
247