UNPKG

@magic-xpa/utils

Version:

magic utils package

1,008 lines (1,002 loc) • 92 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { NString, RefParam, StringBuilder } from "@magic-xpa/mscorelib"; import { UtilStrByteMode } from "./UtilStrByteMode"; import { Rtf } from "./Rtf"; /** @type {?} */ var HTML_BACKSLASH = "&#092;"; /** @type {?} */ var HTML_COMMA = "&#044;"; /** @type {?} */ var HTML_HYPHEN = "&#045;"; /** @type {?} */ var STR_2_HTML = 1; /** @type {?} */ export var SEQ_2_HTML = 2; /** @type {?} */ export var HTML_2_STR = 3; /** @type {?} */ var HTML_2_SEQ = 4; /** @type {?} */ export var SEQ_2_STR = 5; var StrUtil = /** @class */ (function () { function StrUtil() { } /// <summary> trim the end of the string</summary> /** * @param {?} str * @param {?} len * @return {?} */ StrUtil.mem_trim = /** * @param {?} str * @param {?} len * @return {?} */ function (str, len) { /** @type {?} */ var result; if (len > 0) { if (len > str.length) { result = -1; return result; } while (len > 0 && str[len - 1] === ' ') { len = len - 1; } } result = len; return result; }; /** * @param {?} dest * @param {?} destCount * @param {?} src * @param {?} srcCount * @param {?} len * @return {?} */ StrUtil.memmove = /** * @param {?} dest * @param {?} destCount * @param {?} src * @param {?} srcCount * @param {?} len * @return {?} */ function (dest, destCount, src, srcCount, len) { /** @type {?} */ var stringBuilder = new StringBuilder(dest.length + len); if (UtilStrByteMode.isLocaleDefLangJPN() && dest.length < destCount) { stringBuilder.Append(NString.FromChar(' ', destCount)); } else { stringBuilder.Append(dest.substr(0, destCount)); } stringBuilder.Append(src.substr(srcCount, len)); if (stringBuilder.Length < dest.length) { stringBuilder.Append(dest.substr(stringBuilder.Length)); } return stringBuilder.ToString(); }; /** * @param {?} dest * @param {?} destCount * @param {?} src * @param {?} scrCountOrSrcCount * @param {?} count * @return {?} */ StrUtil.memcpy = /** * @param {?} dest * @param {?} destCount * @param {?} src * @param {?} scrCountOrSrcCount * @param {?} count * @return {?} */ function (dest, destCount, src, scrCountOrSrcCount, count) { if (arguments.length === 5 && (dest === null || dest.constructor === String) && (destCount === null || destCount.constructor === Number) && (src === null || src.constructor === String) && (scrCountOrSrcCount === null || scrCountOrSrcCount.constructor === Number) && (count === null || count.constructor === Number)) { return StrUtil.memcpy_0(dest, destCount, src, scrCountOrSrcCount, count); } StrUtil.memcpy_1(dest, destCount, src, scrCountOrSrcCount, count); }; /** * @param {?} dest * @param {?} destCount * @param {?} src * @param {?} scrCount * @param {?} count * @return {?} */ StrUtil.memcpy_0 = /** * @param {?} dest * @param {?} destCount * @param {?} src * @param {?} scrCount * @param {?} count * @return {?} */ function (dest, destCount, src, scrCount, count) { /** @type {?} */ var stringBuilder = new StringBuilder(dest.substr(0, destCount)); if (scrCount + count < src.length) { stringBuilder.Append(src.substr(scrCount, count - scrCount)); } else { stringBuilder.Append(src.substr(scrCount)); } /** @type {?} */ var size = dest.length - destCount - count; if (size > 0) { stringBuilder.Append(dest.substr(destCount + count)); } return stringBuilder.ToString(); }; /** * @param {?} dest * @param {?} destCount * @param {?} src * @param {?} srcCount * @param {?} count * @return {?} */ StrUtil.memcpy_1 = /** * @param {?} dest * @param {?} destCount * @param {?} src * @param {?} srcCount * @param {?} count * @return {?} */ function (dest, destCount, src, srcCount, count) { while (count > 0 && destCount < dest.length && srcCount < src.length) { dest[destCount++] = src[srcCount++]; count = count - 1; } }; /** * @param {?} dest * @param {?} destCount * @param {?} inVal * @param {?} counter * @return {?} */ StrUtil.memset = /** * @param {?} dest * @param {?} destCount * @param {?} inVal * @param {?} counter * @return {?} */ function (dest, destCount, inVal, counter) { if (arguments.length === 4 && (dest === null || dest.constructor === String) && (destCount === null || destCount.constructor === Number) && (inVal === null || inVal.constructor === Number) && (counter === null || counter.constructor === Number)) { return StrUtil.memset_0(dest, destCount, inVal, counter); } StrUtil.memset_1(dest, destCount, inVal, counter); }; /** * @param {?} dest * @param {?} destCount * @param {?} inVal * @param {?} counter * @return {?} */ StrUtil.memset_0 = /** * @param {?} dest * @param {?} destCount * @param {?} inVal * @param {?} counter * @return {?} */ function (dest, destCount, inVal, counter) { /** @type {?} */ var first = new StringBuilder(dest.substr(0, destCount)); while (counter > 0) { first.Append(inVal); counter = counter - 1; } if (first.Length < dest.length) { first.Append(dest.substr(first.Length)); } return first.ToString(); }; /** * @param {?} dest * @param {?} destCount * @param {?} inVal * @param {?} counter * @return {?} */ StrUtil.memset_1 = /** * @param {?} dest * @param {?} destCount * @param {?} inVal * @param {?} counter * @return {?} */ function (dest, destCount, inVal, counter) { while (counter > 0 && destCount < dest.length) { dest[destCount++] = inVal; counter = counter - 1; } }; /** * @param {?} str * @param {?} substr * @return {?} */ StrUtil.strstr = /** * @param {?} str * @param {?} substr * @return {?} */ function (str, substr) { /** @type {?} */ var from = str.indexOf(substr); /** @type {?} */ var result; if (from < 0) { result = null; } else { result = str.substr(from); } return result; }; /*******************************/ /// <summary> /// Reverses string values. /// </summary> /// <param name="text">The StringBuilder object containing the string to be reversed.</param> /// <returns>The reversed string contained in a StringBuilder object.</returns> /** * *************************** * @param {?} text * @return {?} */ StrUtil.ReverseString = /** * *************************** * @param {?} text * @return {?} */ function (text) { /** @type {?} */ var array = NString.ToCharArray(text.ToString()); array.reverse(); return new StringBuilder(NString.FromChars(array)); }; /// <summary> remove spaces from the right side of string</summary> /// <param name="str">the string to trim /// </param> /** * @param {?} str * @return {?} */ StrUtil.rtrim = /** * @param {?} str * @return {?} */ function (str) { return StrUtil.rtrimWithNull(str, false); }; /// <summary> remove spaces and/or Null chars from the right side of string</summary> /// <param name="str">the string to trim /// </param> /// <param name="trimNullChars">Whether to remove NULL characters or not /// </param> /** * @param {?} str * @param {?} trimNullChars * @return {?} */ StrUtil.rtrimWithNull = /** * @param {?} str * @param {?} trimNullChars * @return {?} */ function (str, trimNullChars) { /** @type {?} */ var result; if (typeof str === "undefined" || str === null || str.length === 0) { result = str; } else { /** @type {?} */ var idx = str.length - 1; if (trimNullChars) { while (idx >= 0 && (str[idx] === ' ' || str[idx] === String.fromCharCode(0) /*''*/)) { idx = idx - 1; } } else { while (idx >= 0 && str[idx] === ' ') { idx = idx - 1; } } idx = idx + 1; if (idx < str.length) { result = str.substr(0, idx); } else { result = str; } } return result; }; /// <summary> remove spaces from the left side of string</summary> /// <param name="str">the string to trim /// </param> /** * @param {?} str * @return {?} */ StrUtil.ltrim = /** * @param {?} str * @return {?} */ function (str) { /** @type {?} */ var length = str.length; /** @type {?} */ var i = 0; /** @type {?} */ var result; if (str === null || length === 0) { result = str; } else { while (i < length && str[i] === ' ' /*' '*/) { i = i + 1; } if (i > 0) { str = str.substr(i); } result = str; } return result; }; /// <summary>This function for Deleting String from end & start of input /// String /// </summary> /// <param name="str">String , which can include strToDelete spaces on input /// </param> /// <param name="strToDelete">need delete this String from start/end of str. /// </param> /// <returns> String without strToDelete on end & start, /// or 'null' if Sting hasn't not characters inside /// </returns> /** * @param {?} str * @param {?} strToDelete * @return {?} */ StrUtil.DeleteStringsFromEnds = /** * @param {?} str * @param {?} strToDelete * @return {?} */ function (str, strToDelete) { if (str.startsWith(strToDelete)) { str = str.substr(strToDelete.length); } if (str.endsWith(strToDelete)) { str = str.substr(0, str.length - strToDelete.length); } /** @type {?} */ var result; if (str.length === 0) { result = null; } else { result = str; } return result; }; /// <summary> pad a string with trailing spaces up to the given length</summary> /// <param name="str">the string to pad /// </param> /// <param name="len">the expected length after padding /// </param> /** * @param {?} str * @param {?} len * @return {?} */ StrUtil.padStr = /** * @param {?} str * @param {?} len * @return {?} */ function (str, len) { /** @type {?} */ var padLen = len - str.length; if (padLen > 0) { if (StrUtil._paddingSpaces === null || StrUtil._paddingSpaces.length < padLen) { StrUtil._paddingSpaces = NString.FromChar(' ', padLen); } /** @type {?} */ var stringBuilder = new StringBuilder(len); stringBuilder.Append(str); stringBuilder.Append(StrUtil._paddingSpaces, 0, padLen); str = stringBuilder.ToString(); } return str; }; /// <summary> this method will serve as a string tokenizer instead of using the c# split method /// since there are diffrences btween java tokenizer and c# split /// the implimentation given by the conversion tool is not Sufficient /// </summary> /// <param name="source">- the source string to be converted /// </param> /// <param name="delim">- the string of delimiters used to split the string (each character in the String is a delimiter /// </param> /// <returns> array of token according which is the same as string tokenizer in java /// </returns> /** * @param {?} source * @param {?} delim * @return {?} */ StrUtil.tokenize = /** * @param {?} source * @param {?} delim * @return {?} */ function (source, delim) { // It is mentioned in the comment that we should not use String.Split() // because its behavior is different than Java's tokenizer. // So, we were suppose to use our own implementation (the commented code below). // But all these years, we were calling XmlParser.getToken() which was actually // using String.Split(). And we didn't face any problem. // So, it seems that we do not have problem in using String.Split(). // But now, we can improve the performance here... // XmlParser.getTokens() was getting a String[] using String.Split(). // It was then creating a List<String> from this String[] and was returning it to // tokenize(). // tokenize() was again converting this List<String> back to String[]. // So why not call String.Split() directly? return source.split(delim); /* String [] tokens = null; char [] delimArry = delim.toCharArray(); //since java discards delimiters from the start and end of the string and c# does not //we need to remove them manually // source = source.TrimEnd(delimArry); // source = source.TrimStart(delimArry); source = source.trim(); //now that we have remove starting and ending delimiters we can split tokens = source.Split(delimArry); /* * only one problem: if we have two Subsequent delimiters for example : * the delimiter is ';' and the string is: "first;;second;third" * then in java String tokenizer will give us only 3 tokens :first,second and third * while is c# split wethod will return 4 tokens: first,empty string,second and third * we need to deal with that */ /* List res = new List(); for (int i = 0 ; i < tokens.length; i++) { if (tokens[i] != "" ) res.addItem(tokens[i]); } return (String [])(res.getAllItems (String.class));*/ }; /// <summary> /// translate from string to hexa dump char by char /// </summary> /// <param name = "string">to translate it to the byte stream</param> /// <param name = "minLength">the minimal length of hexa digits for each char</param> /// <returns> the byte stream in form of string</returns> /** * @param {?} str * @param {?} minLength * @return {?} */ StrUtil.stringToHexaDump = /** * @param {?} str * @param {?} minLength * @return {?} */ function (str, minLength) { /** @type {?} */ var stringBuilder = new StringBuilder(str.length * minLength); for (var indx = 0; indx < str.length; indx = indx + 1) { /** @type {?} */ var currInt = str.charCodeAt(indx); /** @type {?} */ var hexStr = currInt.toString(16); while (hexStr.length < minLength) { hexStr = "0" + hexStr; } stringBuilder.Append(hexStr); } return stringBuilder.ToString().toUpperCase(); }; /** * @param {?} str * @param {?} from * @param {?} to * @return {?} */ StrUtil.searchAndReplace = /** * @param {?} str * @param {?} from * @param {?} to * @return {?} */ function (str, from, to) { if (arguments.length === 3 && (str === null || str.constructor === String) && (from === null || from.constructor === String) && (to === null || to.constructor === String)) { return StrUtil.searchAndReplace_0(str, from, to); } return StrUtil.searchAndReplace_1(str, from, to); }; /** * @param {?} str * @param {?} from * @param {?} to * @return {?} */ StrUtil.searchAndReplace_0 = /** * @param {?} str * @param {?} from * @param {?} to * @return {?} */ function (str, from, to) { /** @type {?} */ var lastSubStr = 0; /** @type {?} */ var startSubStr; /** @type {?} */ var result; if ((startSubStr = str.indexOf(from)) === -1) { result = str; } else { /** @type {?} */ var stringBuilder = new StringBuilder(str.length); while (startSubStr !== -1) { stringBuilder.Append(str.substr(lastSubStr, startSubStr - lastSubStr) + to); startSubStr = startSubStr + from.length; lastSubStr = startSubStr; startSubStr = str.indexOf(from, lastSubStr); } stringBuilder.Append(str.substr(lastSubStr)); result = stringBuilder.ToString(); } return result; }; /** * @param {?} str * @param {?} from * @param {?} to * @return {?} */ StrUtil.searchAndReplace_1 = /** * @param {?} str * @param {?} from * @param {?} to * @return {?} */ function (str, from, to) { /** @type {?} */ var lastSubStr = 0; /** @type {?} */ var sarIndex = 0; /** @type {?} */ var fromCopy = from.slice(); /** @type {?} */ var startSubStr; /** @type {?} */ var SARindex = new RefParam(0); startSubStr = StrUtil.indexOf(str, fromCopy, lastSubStr, SARindex); sarIndex = SARindex.value; if (startSubStr === -1) return str; /** @type {?} */ var result; /** @type {?} */ var tmpBuf = new StringBuilder(str.length); while (startSubStr !== -1) { tmpBuf.Append(str.substr(lastSubStr, startSubStr - lastSubStr) + to[sarIndex]); startSubStr += fromCopy[sarIndex].length; lastSubStr = startSubStr; startSubStr = StrUtil.indexOf(str, fromCopy, lastSubStr, SARindex); sarIndex = SARindex.value; } ; tmpBuf.Append(str.substr(lastSubStr)); result = tmpBuf.ToString(); return result; }; /** * @param {?} str * @param {?} strings * @param {?} offset * @param {?} SARindex * @return {?} */ StrUtil.indexOf = /** * @param {?} str * @param {?} strings * @param {?} offset * @param {?} SARindex * @return {?} */ function (str, strings, offset, SARindex) { /** @type {?} */ var minOffset = -1; for (var i = 0; i < strings.length; i = i + 1) { /** @type {?} */ var flag = strings[i] === null; if (!(strings[i] === null)) { /** @type {?} */ var resultOffset = str.indexOf(strings[i], offset); if (resultOffset === -1) { strings[i] = null; } else { if (resultOffset < minOffset || minOffset === -1) { minOffset = resultOffset; SARindex[0] = i; } } } } /** @type {?} */ var result; if (minOffset > -1) { result = minOffset; } else { SARindex[0] = -1; result = -1; } return result; }; /// <summary> replace tokens in user string by vector values </summary> /// <param name="userString">- user buffer like "User %d, %d string" /// </param> /// <param name="token">- token used in user string - i.e. "%d" /// </param> /// <param name="occurrence">- number of token where replace will take part (1 for first occurrence) /// </param> /// <param name="value">- value to be inserted insted of token /// </param> /** * @param {?} userString * @param {?} token * @param {?} occurrence * @param {?} val * @return {?} */ StrUtil.replaceStringTokens = /** * @param {?} userString * @param {?} token * @param {?} occurrence * @param {?} val * @return {?} */ function (userString, token, occurrence, val) { /** @type {?} */ var tokenLen = token.length; /** @type {?} */ var currPosition = 0; /** @type {?} */ var newString = userString; if (val !== null) { /** @type {?} */ var num2 = 0; while (num2 < occurrence && currPosition !== -1) { currPosition = userString.indexOf(token, currPosition + ((num2 === 0) ? 0 : tokenLen)); num2 = num2 + 1; } if (currPosition !== -1) { newString = userString.substr(0, currPosition) + val + userString.substr(currPosition + tokenLen, userString.length - (currPosition + tokenLen)); } } return newString; }; /** * @param {?} source * @param {?} type * @return {?} */ StrUtil.makePrintableTokens = /** * @param {?} source * @param {?} type * @return {?} */ function (source, type) { if (arguments.length === 2 && (source === null || source.constructor === String) && (type === null || type.constructor === Number)) { return StrUtil.makePrintableTokens_0(source, type); } StrUtil.makePrintableTokens_1(source, type); }; /// <summary> /// converts special characters in a token to a printable format /// </summary> /// <param name = "source">a token </param> /// <param name = "type">type of conversion: STR_2_HTML, SEQ_2_HTML, HTML_2_SEQ, HTML_2_STR, SEQ_2_STR </param> /// <returns> token with converted special characters </returns> /** * @param {?} source * @param {?} type * @return {?} */ StrUtil.makePrintableTokens_0 = /** * @param {?} source * @param {?} type * @return {?} */ function (source, type) { /** @type {?} */ var escStr = [ "\\", "-", "," ]; /** @type {?} */ var escSeq = [ "\\\\", "\\-", "\\," ]; /** @type {?} */ var escHtm = [ HTML_BACKSLASH, HTML_HYPHEN, HTML_COMMA ]; /** @type {?} */ var result; switch (type) { case STR_2_HTML: result = StrUtil.searchAndReplace(source, escStr, escHtm); break; case SEQ_2_HTML: result = StrUtil.searchAndReplace(source, escSeq, escHtm); break; case HTML_2_SEQ: result = StrUtil.searchAndReplace(source, escHtm, escSeq); break; case HTML_2_STR: result = StrUtil.searchAndReplace(source, escHtm, escStr); break; case SEQ_2_STR: result = StrUtil.searchAndReplace(source, escSeq, escStr); break; default: result = source; break; } return result; }; /** * @param {?} source * @param {?} type * @return {?} */ StrUtil.makePrintableTokens_1 = /** * @param {?} source * @param {?} type * @return {?} */ function (source, type) { if (source !== null) { /** @type {?} */ var length_1 = source.length; for (var i = 0; i < length_1; i = i + 1) { /** @type {?} */ var currElm = source.get_Item(i); source.set_Item(i, StrUtil.makePrintableTokens_0(currElm, type)); } } }; /// <summary> /// change non-printable characters like "new line" and "line feed" to their /// printable representation /// </summary> /// <param name = "source">is the string with non-printable characters </param> /// <returns> the new string where all the non-printable characters are converted </returns> /** * @param {?} source * @return {?} */ StrUtil.makePrintable = /** * @param {?} source * @return {?} */ function (source) { /** @type {?} */ var from = [ "\n", "\r", "'", "\\", "\"", "\0" ]; /** @type {?} */ var to = [ "\\n", "\\r", "\\'", "\\\\", "\\\"", "\\0" ]; return StrUtil.searchAndReplace(source, from, to); }; /// <summary> /// change non-printable characters like "new line" and "line feed" to their /// printable representation (simplified version for range error message) /// </summary> /// <param name = "source">is the string with non-printable characters </param> /// <returns> the new string where all the non-printable characters are converted </returns> /** * @param {?} source * @return {?} */ StrUtil.makePrintable2 = /** * @param {?} source * @return {?} */ function (source) { /** @type {?} */ var from = [ "\n", "\r", "\0" ]; /** @type {?} */ var to = [ "\\n", "\\r", "\\0" ]; return StrUtil.searchAndReplace(source, from, to); }; /// <summary> /// /// </summary> /// <param name="s"></param> /// <param name="len"></param> /// <returns></returns> /** * @param {?} s * @param {?} len * @return {?} */ StrUtil.ZstringMake = /** * @param {?} s * @param {?} len * @return {?} */ function (s, len) { len = StrUtil.mem_trim(s, len); return s.substr(0, len); }; /// <summary>(public) /// returns plain text from rtf text /// </summary> /// <param name="rtfText">refer to the summary</param> /// <returns>refer to the summary</returns> /** * @param {?} rtfText * @return {?} */ StrUtil.GetPlainTextfromRtf = /** * @param {?} rtfText * @return {?} */ function (rtfText) { if (Rtf.isRtf(rtfText)) { /** @type {?} */ var rtf = new Rtf(); /** @type {?} */ var outputTxt = new StringBuilder(""); rtf.toTxt(rtfText, outputTxt); rtfText = outputTxt.ToString(); } return rtfText; }; /// <summary> /// Returns true if the string arrays str1 & str2 are equal /// </summary> /// <param name="str1"></param> /// <param name="str2"></param> /// <returns></returns> /** * @param {?} str1 * @param {?} str2 * @return {?} */ StrUtil.StringsArraysEqual = /** * @param {?} str1 * @param {?} str2 * @return {?} */ function (str1, str2) { /** @type {?} */ var result; if (str1 === null && str2 === null) { result = true; } else { if (str1 === null || str2 === null) { result = false; } else { if (str1.length !== str2.length) { result = false; } else { for (var index = 0; index < /** @type {?} */ (str1.length); index = index + 1) { if ((str1[index] !== str2[index])) { result = false; return result; } } result = true; } } } return result; }; /// <summary> /// The code is copied from tsk_open_bnd_wild and SearchAndReplaceWildChars /// The refactoring is not performed for backwards compatibility /// The code replaces special charachters :* ? with recieved filler /// </summary> /// <returns></returns> /** * @param {?} buf * @param {?} len * @param {?} filler * @return {?} */ StrUtil.SearchAndReplaceWildChars = /** * @param {?} buf * @param {?} len * @param {?} filler * @return {?} */ function (buf, len, filler) { buf = NString.PadRight(buf, len); /** @type {?} */ var escChar = false; /** @type {?} */ var stopSearch = false; /** @type {?} */ var tmpBuf = new StringBuilder(len); for (var i = 0; i < len; i = i + 1) { switch (buf[i]) { case ('\\'): { /** @type {?} */ var isNextCharWild = true; //If next char is not wild , then copy '\', if this is first char. if ((i + 1 < len) && (buf[i + 1] != '*' && buf[i + 1] != '\\')) isNextCharWild = false; if (escChar || !isNextCharWild) tmpBuf.Append(buf[i]); escChar = !escChar; } break; case ('*'): if (escChar) tmpBuf.Append(buf[i]); else { tmpBuf.Append(filler, len - tmpBuf.Length); stopSearch = true; } escChar = false; break; case '?': tmpBuf.Append(filler); escChar = false; break; default: tmpBuf.Append(buf[i]); escChar = false; break; } } /** @type {?} */ var text = tmpBuf.ToString(); return NString.TrimEnd(NString.TrimEnd(text, ['\0'])); }; StrUtil._paddingSpaces = null; return StrUtil; }()); export { StrUtil }; if (false) { /** @type {?} */ StrUtil._paddingSpaces; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3RyVXRpbC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BtYWdpYy14cGEvdXRpbHMvIiwic291cmNlcyI6WyJzcmMvU3RyVXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFPLE9BQU8sRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDNUUsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFBQyxHQUFHLEVBQUMsTUFBTSxPQUFPLENBQUM7O0FBRTFCLElBQU0sY0FBYyxHQUFXLFFBQVEsQ0FBQzs7QUFDeEMsSUFBTSxVQUFVLEdBQVcsUUFBUSxDQUFDOztBQUNwQyxJQUFNLFdBQVcsR0FBVyxRQUFRLENBQUM7O0FBQ3JDLElBQU0sVUFBVSxHQUFXLENBQUMsQ0FBQzs7QUFDN0IsV0FBYSxVQUFVLEdBQVcsQ0FBQyxDQUFDOztBQUNwQyxXQUFhLFVBQVUsR0FBVyxDQUFDLENBQUM7O0FBQ3BDLElBQU0sVUFBVSxHQUFXLENBQUMsQ0FBQzs7QUFDN0IsV0FBYSxTQUFTLEdBQVcsQ0FBQyxDQUFDOzs7O0lBS2pDLGtEQUFrRDs7Ozs7O0lBQzNDLGdCQUFROzs7OztJQUFmLFVBQWdCLEdBQVcsRUFBRSxHQUFXOztRQUN0QyxJQUFJLE1BQU0sQ0FBUztRQUNuQixFQUFFLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNaLEVBQUUsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDckIsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUNaLE1BQU0sQ0FBQyxNQUFNLENBQUM7YUFDZjtZQUNELE9BQU8sR0FBRyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUN2QyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMs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