9e5386264f
* SimBrief integration #405 * Add briefing as API response; add acars_xml field #405
623 lines
18 KiB
JavaScript
Executable File
623 lines
18 KiB
JavaScript
Executable File
'use strict';
|
|
/*
|
|
* SimBrief APIv1 Javascript Functions
|
|
* For use with VA Dispatch systems
|
|
* By Derek Mayer - contact@simbrief.com
|
|
*
|
|
* Any individual wishing to make use of this class must first contact me
|
|
* to obtain a unique API key; without which it will be impossible to connect
|
|
* to the API.
|
|
*
|
|
* Any attempt to circumvent the API authorization, steal another
|
|
* developer's API key, hack, compromise, or gain unauthorized access to
|
|
* the SimBrief website or it's web systems, or bypass or allow others to bypass
|
|
* the SimBrief.com login screen will result in immediate revocation of the
|
|
* associated API key, and in serious situations, legal action at my discretion.
|
|
*/
|
|
|
|
/*
|
|
* Settings and initial variables
|
|
*/
|
|
|
|
let sbform = "sbapiform";
|
|
let sbworkerurl = "https://www.simbrief.com/ofp/ofp.loader.api.php";
|
|
let sbworkerid = 'SBworker';
|
|
let sbcallerid = 'SBcaller';
|
|
let sbworkerstyle = 'width=600,height=315';
|
|
let sbworker;
|
|
let SBloop;
|
|
|
|
let ofp_id;
|
|
let flight_id;
|
|
|
|
let outputpage_save;
|
|
let outputpage_calc;
|
|
let fe_result;
|
|
|
|
let timestamp;
|
|
let api_code;
|
|
|
|
|
|
function simbriefsubmit(_flight_id, outputpage) {
|
|
flight_id = _flight_id;
|
|
|
|
if (sbworker) {
|
|
sbworker.close();
|
|
}
|
|
|
|
if (SBloop) {
|
|
window.clearInterval(SBloop);
|
|
}
|
|
|
|
api_code = null;
|
|
ofp_id = null;
|
|
fe_result = null;
|
|
timestamp = null;
|
|
outputpage_save = null;
|
|
outputpage_calc = null;
|
|
|
|
do_simbriefsubmit(outputpage);
|
|
}
|
|
|
|
|
|
async function do_simbriefsubmit(outputpage) {
|
|
|
|
//CATCH UNDEFINED OUTPUT PAGE, SET IT TO THE CURRENT PAGE
|
|
|
|
if (!outputpage) {
|
|
outputpage = location.href;
|
|
}
|
|
|
|
if (!timestamp) {
|
|
timestamp = Math.round(+new Date() / 1000);
|
|
}
|
|
|
|
outputpage_save = outputpage;
|
|
outputpage_calc = outputpage.replace("http://", "");
|
|
|
|
if (!api_code) {
|
|
const api_req = document.getElementsByName('orig')[0].value + document.getElementsByName('dest')[0].value + document.getElementsByName('type')[0].value + timestamp + outputpage_calc;
|
|
|
|
let apiCodeResp;
|
|
|
|
try {
|
|
apiCodeResp = await phpvms.request({
|
|
method: 'POST',
|
|
url: '/simbrief/apicode',
|
|
data: {
|
|
api_req,
|
|
flight_id,
|
|
}
|
|
});
|
|
} catch (e) {
|
|
console.log('request error', e);
|
|
return;
|
|
}
|
|
|
|
api_code = apiCodeResp.data.api_code;
|
|
console.log('API code response: ', api_code);
|
|
}
|
|
|
|
//IF API_CODE IS SET, FINALIZE FORM
|
|
|
|
var apiform = document.getElementById(sbform);
|
|
apiform.setAttribute("method", "get");
|
|
apiform.setAttribute("action", sbworkerurl);
|
|
apiform.setAttribute("target", sbworkerid);
|
|
|
|
var input = document.createElement("input");
|
|
input.setAttribute("type", "hidden");
|
|
input.setAttribute("name", "apicode");
|
|
input.setAttribute("value", api_code);
|
|
apiform.appendChild(input);
|
|
|
|
|
|
var input = document.createElement("input");
|
|
input.setAttribute("type", "hidden");
|
|
input.setAttribute("name", "outputpage");
|
|
input.setAttribute("value", outputpage_calc);
|
|
apiform.appendChild(input);
|
|
|
|
|
|
var input = document.createElement("input");
|
|
input.setAttribute("type", "hidden");
|
|
input.setAttribute("name", "timestamp");
|
|
input.setAttribute("value", timestamp);
|
|
apiform.appendChild(input);
|
|
|
|
|
|
//LAUNCH FORM
|
|
|
|
window.name = sbcallerid;
|
|
LaunchSBworker();
|
|
apiform.submit();
|
|
|
|
//DETERMINE OFP_ID
|
|
|
|
ofp_id = timestamp + '_' + md5(document.getElementsByName('orig')[0].value + document.getElementsByName('dest')[0].value + document.getElementsByName('type')[0].value);
|
|
|
|
//LOOP TO DETECT WHEN THE WORKER PROCESS IS CLOSED
|
|
SBloop = window.setInterval(checkSBworker, 500);
|
|
}
|
|
|
|
/*
|
|
* Other related functions
|
|
*/
|
|
|
|
function LaunchSBworker() {
|
|
sbworker = window.open('about:blank', sbworkerid, sbworkerstyle)
|
|
|
|
//TEST FOR POPUP BLOCKERS
|
|
|
|
if (sbworker == null || typeof (sbworker) == 'undefined') {
|
|
alert('Please disable your pop-up blocker to generate a flight plan!');
|
|
} else {
|
|
if (window.focus) {
|
|
sbworker.focus();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
function checkSBworker() {
|
|
if (sbworker && sbworker.closed) {
|
|
window.clearInterval(SBloop);
|
|
Redirect_caller();
|
|
}
|
|
}
|
|
|
|
|
|
async function Redirect_caller() {
|
|
|
|
/*
|
|
* First check that the file actually exists.
|
|
* It might not if the window was closed before completion.
|
|
*
|
|
* An external PHP file is used so as to avoid any "Same
|
|
* Origin" errors.
|
|
*/
|
|
|
|
let apiCodeResp;
|
|
|
|
try {
|
|
apiCodeResp = await phpvms.request({
|
|
method: 'GET',
|
|
url: '/simbrief/check_ofp',
|
|
params: {
|
|
flight_id,
|
|
ofp_id,
|
|
}
|
|
});
|
|
} catch (e) {
|
|
console.log('request error', e);
|
|
setTimeout(function () {
|
|
Redirect_caller();
|
|
}, 500);
|
|
|
|
return;
|
|
}
|
|
|
|
api_code = apiCodeResp.data.id;
|
|
console.log('API code response: ', api_code);
|
|
|
|
/*
|
|
* If the file exists, redirect to the specified Output Page.
|
|
*/
|
|
outputpage_save += '/' + ofp_id;
|
|
|
|
let apiform = document.createElement("form");
|
|
apiform.setAttribute("method", "get");
|
|
apiform.setAttribute("action", outputpage_save);
|
|
|
|
/*
|
|
* Analyse link to see if there are any prior GET params.
|
|
* If so, append them to the form
|
|
*/
|
|
|
|
let urlinfo = urlObject({'url': outputpage_save});
|
|
for (let key in urlinfo['parameters']) {
|
|
let input = document.createElement("input");
|
|
input.setAttribute("type", "hidden");
|
|
input.setAttribute("name", key);
|
|
input.setAttribute("value", urlinfo['parameters'][key]);
|
|
apiform.appendChild(input);
|
|
}
|
|
|
|
let input = document.createElement("input");
|
|
input.setAttribute("type", "hidden");
|
|
input.setAttribute("name", "ofp_id");
|
|
input.setAttribute("value", ofp_id);
|
|
apiform.appendChild(input);
|
|
|
|
document.body.appendChild(apiform);
|
|
|
|
apiform.submit();
|
|
}
|
|
|
|
|
|
function sb_res_load(url) {
|
|
var fileref = document.createElement('script');
|
|
fileref.type = "text/javascript";
|
|
fileref.src = url + "&p=" + Math.floor(Math.random() * 10000000);
|
|
document.getElementsByTagName("head")[0].appendChild(fileref);
|
|
}
|
|
|
|
|
|
/*
|
|
* URLOBJECT function
|
|
* Courtesy Ayman Farhat
|
|
*/
|
|
|
|
function urlObject(options) {
|
|
"use strict";
|
|
/*global window, document*/
|
|
|
|
var url_search_arr,
|
|
option_key,
|
|
i,
|
|
urlObj,
|
|
get_param,
|
|
key,
|
|
val,
|
|
url_query,
|
|
url_get_params = {},
|
|
a = document.createElement('a'),
|
|
default_options = {
|
|
'url': window.location.href,
|
|
'unescape': true,
|
|
'convert_num': true
|
|
};
|
|
|
|
if (typeof options !== "object") {
|
|
options = default_options;
|
|
} else {
|
|
for (option_key in default_options) {
|
|
if (default_options.hasOwnProperty(option_key)) {
|
|
if (options[option_key] === undefined) {
|
|
options[option_key] = default_options[option_key];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
a.href = options.url;
|
|
url_query = a.search.substring(1);
|
|
url_search_arr = url_query.split('&');
|
|
|
|
if (url_search_arr[0].length > 1) {
|
|
for (i = 0; i < url_search_arr.length; i += 1) {
|
|
get_param = url_search_arr[i].split("=");
|
|
|
|
if (options.unescape) {
|
|
key = decodeURI(get_param[0]);
|
|
val = decodeURI(get_param[1]);
|
|
} else {
|
|
key = get_param[0];
|
|
val = get_param[1];
|
|
}
|
|
|
|
if (options.convert_num) {
|
|
if (val.match(/^\d+$/)) {
|
|
val = parseInt(val, 10);
|
|
} else if (val.match(/^\d+\.\d+$/)) {
|
|
val = parseFloat(val);
|
|
}
|
|
}
|
|
|
|
if (url_get_params[key] === undefined) {
|
|
url_get_params[key] = val;
|
|
} else if (typeof url_get_params[key] === "string") {
|
|
url_get_params[key] = [url_get_params[key], val];
|
|
} else {
|
|
url_get_params[key].push(val);
|
|
}
|
|
|
|
get_param = [];
|
|
}
|
|
}
|
|
|
|
urlObj = {
|
|
protocol: a.protocol,
|
|
hostname: a.hostname,
|
|
host: a.host,
|
|
port: a.port,
|
|
hash: a.hash.substr(1),
|
|
pathname: a.pathname,
|
|
search: a.search,
|
|
parameters: url_get_params
|
|
};
|
|
|
|
return urlObj;
|
|
}
|
|
|
|
|
|
/*
|
|
* MD5 and UTF8_ENCODE functions
|
|
* Courtesy of phpjs.org
|
|
*/
|
|
|
|
function md5(str) {
|
|
// discuss at: http://phpjs.org/functions/md5/
|
|
// original by: Webtoolkit.info (http://www.webtoolkit.info/)
|
|
// improved by: Michael White (http://getsprink.com)
|
|
// improved by: Jack
|
|
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
|
// input by: Brett Zamir (http://brett-zamir.me)
|
|
// bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
|
// depends on: utf8_encode
|
|
// example 1: md5('Kevin van Zonneveld');
|
|
// returns 1: '6e658d4bfcb59cc13f96c14450ac40b9'
|
|
|
|
var xl;
|
|
|
|
var rotateLeft = function (lValue, iShiftBits) {
|
|
return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
|
|
};
|
|
|
|
var addUnsigned = function (lX, lY) {
|
|
var lX4, lY4, lX8, lY8, lResult;
|
|
lX8 = (lX & 0x80000000);
|
|
lY8 = (lY & 0x80000000);
|
|
lX4 = (lX & 0x40000000);
|
|
lY4 = (lY & 0x40000000);
|
|
lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
|
|
if (lX4 & lY4) {
|
|
return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
|
|
}
|
|
if (lX4 | lY4) {
|
|
if (lResult & 0x40000000) {
|
|
return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
|
|
} else {
|
|
return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
|
|
}
|
|
} else {
|
|
return (lResult ^ lX8 ^ lY8);
|
|
}
|
|
};
|
|
|
|
var _F = function (x, y, z) {
|
|
return (x & y) | ((~x) & z);
|
|
};
|
|
var _G = function (x, y, z) {
|
|
return (x & z) | (y & (~z));
|
|
};
|
|
var _H = function (x, y, z) {
|
|
return (x ^ y ^ z);
|
|
};
|
|
var _I = function (x, y, z) {
|
|
return (y ^ (x | (~z)));
|
|
};
|
|
|
|
var _FF = function (a, b, c, d, x, s, ac) {
|
|
a = addUnsigned(a, addUnsigned(addUnsigned(_F(b, c, d), x), ac));
|
|
return addUnsigned(rotateLeft(a, s), b);
|
|
};
|
|
|
|
var _GG = function (a, b, c, d, x, s, ac) {
|
|
a = addUnsigned(a, addUnsigned(addUnsigned(_G(b, c, d), x), ac));
|
|
return addUnsigned(rotateLeft(a, s), b);
|
|
};
|
|
|
|
var _HH = function (a, b, c, d, x, s, ac) {
|
|
a = addUnsigned(a, addUnsigned(addUnsigned(_H(b, c, d), x), ac));
|
|
return addUnsigned(rotateLeft(a, s), b);
|
|
};
|
|
|
|
var _II = function (a, b, c, d, x, s, ac) {
|
|
a = addUnsigned(a, addUnsigned(addUnsigned(_I(b, c, d), x), ac));
|
|
return addUnsigned(rotateLeft(a, s), b);
|
|
};
|
|
|
|
var convertToWordArray = function (str) {
|
|
var lWordCount;
|
|
var lMessageLength = str.length;
|
|
var lNumberOfWords_temp1 = lMessageLength + 8;
|
|
var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
|
|
var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
|
|
var lWordArray = new Array(lNumberOfWords - 1);
|
|
var lBytePosition = 0;
|
|
var lByteCount = 0;
|
|
while (lByteCount < lMessageLength) {
|
|
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
|
|
lBytePosition = (lByteCount % 4) * 8;
|
|
lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount) << lBytePosition));
|
|
lByteCount++;
|
|
}
|
|
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
|
|
lBytePosition = (lByteCount % 4) * 8;
|
|
lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
|
|
lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
|
|
lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
|
|
return lWordArray;
|
|
};
|
|
|
|
var wordToHex = function (lValue) {
|
|
var wordToHexValue = '',
|
|
wordToHexValue_temp = '',
|
|
lByte, lCount;
|
|
for (lCount = 0; lCount <= 3; lCount++) {
|
|
lByte = (lValue >>> (lCount * 8)) & 255;
|
|
wordToHexValue_temp = '0' + lByte.toString(16);
|
|
wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2);
|
|
}
|
|
return wordToHexValue;
|
|
};
|
|
|
|
var x = [],
|
|
k, AA, BB, CC, DD, a, b, c, d, S11 = 7,
|
|
S12 = 12,
|
|
S13 = 17,
|
|
S14 = 22,
|
|
S21 = 5,
|
|
S22 = 9,
|
|
S23 = 14,
|
|
S24 = 20,
|
|
S31 = 4,
|
|
S32 = 11,
|
|
S33 = 16,
|
|
S34 = 23,
|
|
S41 = 6,
|
|
S42 = 10,
|
|
S43 = 15,
|
|
S44 = 21;
|
|
|
|
str = utf8_encode(str);
|
|
x = convertToWordArray(str);
|
|
a = 0x67452301;
|
|
b = 0xEFCDAB89;
|
|
c = 0x98BADCFE;
|
|
d = 0x10325476;
|
|
|
|
xl = x.length;
|
|
for (k = 0; k < xl; k += 16) {
|
|
AA = a;
|
|
BB = b;
|
|
CC = c;
|
|
DD = d;
|
|
a = _FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
|
|
d = _FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
|
|
c = _FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
|
|
b = _FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
|
|
a = _FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
|
|
d = _FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
|
|
c = _FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
|
|
b = _FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
|
|
a = _FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
|
|
d = _FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
|
|
c = _FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
|
|
b = _FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
|
|
a = _FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
|
|
d = _FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
|
|
c = _FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
|
|
b = _FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
|
|
a = _GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
|
|
d = _GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
|
|
c = _GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
|
|
b = _GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
|
|
a = _GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
|
|
d = _GG(d, a, b, c, x[k + 10], S22, 0x2441453);
|
|
c = _GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
|
|
b = _GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
|
|
a = _GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
|
|
d = _GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
|
|
c = _GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
|
|
b = _GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
|
|
a = _GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
|
|
d = _GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
|
|
c = _GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
|
|
b = _GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
|
|
a = _HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
|
|
d = _HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
|
|
c = _HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
|
|
b = _HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
|
|
a = _HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
|
|
d = _HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
|
|
c = _HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
|
|
b = _HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
|
|
a = _HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
|
|
d = _HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
|
|
c = _HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
|
|
b = _HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
|
|
a = _HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
|
|
d = _HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
|
|
c = _HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
|
|
b = _HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
|
|
a = _II(a, b, c, d, x[k + 0], S41, 0xF4292244);
|
|
d = _II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
|
|
c = _II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
|
|
b = _II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
|
|
a = _II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
|
|
d = _II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
|
|
c = _II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
|
|
b = _II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
|
|
a = _II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
|
|
d = _II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
|
|
c = _II(c, d, a, b, x[k + 6], S43, 0xA3014314);
|
|
b = _II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
|
|
a = _II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
|
|
d = _II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
|
|
c = _II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
|
|
b = _II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
|
|
a = addUnsigned(a, AA);
|
|
b = addUnsigned(b, BB);
|
|
c = addUnsigned(c, CC);
|
|
d = addUnsigned(d, DD);
|
|
}
|
|
|
|
var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
|
|
|
|
return temp.toUpperCase().substr(0, 10);
|
|
}
|
|
|
|
|
|
function utf8_encode(argString) {
|
|
// discuss at: http://phpjs.org/functions/utf8_encode/
|
|
// original by: Webtoolkit.info (http://www.webtoolkit.info/)
|
|
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
|
// improved by: sowberry
|
|
// improved by: Jack
|
|
// improved by: Yves Sucaet
|
|
// improved by: kirilloid
|
|
// bugfixed by: Onno Marsman
|
|
// bugfixed by: Onno Marsman
|
|
// bugfixed by: Ulrich
|
|
// bugfixed by: Rafal Kukawski
|
|
// bugfixed by: kirilloid
|
|
// example 1: utf8_encode('Kevin van Zonneveld');
|
|
// returns 1: 'Kevin van Zonneveld'
|
|
|
|
if (argString === null || typeof argString === 'undefined') {
|
|
return '';
|
|
}
|
|
|
|
// .replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
var string = (argString + '');
|
|
var utftext = '',
|
|
start, end, stringl = 0;
|
|
|
|
start = end = 0;
|
|
stringl = string.length;
|
|
for (var n = 0; n < stringl; n++) {
|
|
var c1 = string.charCodeAt(n);
|
|
var enc = null;
|
|
|
|
if (c1 < 128) {
|
|
end++;
|
|
} else if (c1 > 127 && c1 < 2048) {
|
|
enc = String.fromCharCode(
|
|
(c1 >> 6) | 192, (c1 & 63) | 128
|
|
);
|
|
} else if ((c1 & 0xF800) != 0xD800) {
|
|
enc = String.fromCharCode(
|
|
(c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128
|
|
);
|
|
} else {
|
|
// surrogate pairs
|
|
if ((c1 & 0xFC00) != 0xD800) {
|
|
throw new RangeError('Unmatched trail surrogate at ' + n);
|
|
}
|
|
var c2 = string.charCodeAt(++n);
|
|
if ((c2 & 0xFC00) != 0xDC00) {
|
|
throw new RangeError('Unmatched lead surrogate at ' + (n - 1));
|
|
}
|
|
c1 = ((c1 & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000;
|
|
enc = String.fromCharCode(
|
|
(c1 >> 18) | 240, ((c1 >> 12) & 63) | 128, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128
|
|
);
|
|
}
|
|
if (enc !== null) {
|
|
if (end > start) {
|
|
utftext += string.slice(start, end);
|
|
}
|
|
utftext += enc;
|
|
start = end = n + 1;
|
|
}
|
|
}
|
|
|
|
if (end > start) {
|
|
utftext += string.slice(start, stringl);
|
|
}
|
|
|
|
return utftext;
|
|
}
|