UNPKG

@magic-xpa/utils

Version:

magic utils package

867 lines (862 loc) • 89.3 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 {?} */ const HTML_BACKSLASH = "&#092;"; /** @type {?} */ const HTML_COMMA = "&#044;"; /** @type {?} */ const HTML_HYPHEN = "&#045;"; /** @type {?} */ const STR_2_HTML = 1; /** @type {?} */ export const SEQ_2_HTML = 2; /** @type {?} */ export const HTML_2_STR = 3; /** @type {?} */ const HTML_2_SEQ = 4; /** @type {?} */ export const SEQ_2_STR = 5; export class StrUtil { /// <summary> trim the end of the string</summary> /** * @param {?} str * @param {?} len * @return {?} */ static mem_trim(str, len) { /** @type {?} */ let 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 {?} */ static memmove(dest, destCount, src, srcCount, len) { /** @type {?} */ let 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 {?} */ static memcpy(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); } /// <summary> /// copy part of string into another string, like memcpy of C, but 4 string only /// </summary> /// <param name = "dest">string</param> /// <param name = "destCount">of counter start from in destignation string</param> /// <param name = "src">string</param> /// <param name = "scrCount">of counter start from in source string</param> /// <param name = "count"></param> /// <returns> new value of destignation string</returns> /** * @param {?} dest * @param {?} destCount * @param {?} src * @param {?} scrCount * @param {?} count * @return {?} */ static memcpy_0(dest, destCount, src, scrCount, count) { /** @type {?} */ let 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 {?} */ let 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 {?} */ static memcpy_1(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 {?} */ static memset(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); } /// <summary> /// insert to string chars n times /// </summary> /// <param name = "dest">string</param> /// <param name = "destCount">of counter start from in destignation string to start insertion of char from</param> /// <param name = "inVal">2 insert</param> /// <param name = "counter">- number of times to insert the char</param> /// <returns> new value of destignation string</returns> /** * @param {?} dest * @param {?} destCount * @param {?} inVal * @param {?} counter * @return {?} */ static memset_0(dest, destCount, inVal, counter) { /** @type {?} */ let 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 {?} */ static memset_1(dest, destCount, inVal, counter) { while (counter > 0 && destCount < dest.length) { dest[destCount++] = inVal; counter = counter - 1; } } /** * @param {?} str * @param {?} substr * @return {?} */ static strstr(str, substr) { /** @type {?} */ let from = str.indexOf(substr); /** @type {?} */ let result; if (from < 0) { result = null; } else { result = str.substr(from); } return result; } /** * *************************** * @param {?} text * @return {?} */ /// <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> static ReverseString(text) { // TODO: use string.Reverse() /** @type {?} */ let 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 {?} */ static rtrim(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 {?} */ static rtrimWithNull(str, trimNullChars) { /** @type {?} */ let result; if (typeof str === "undefined" || str === null || str.length === 0) { result = str; } else { /** @type {?} */ let 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 {?} */ static ltrim(str) { /** @type {?} */ let length = str.length; /** @type {?} */ let i = 0; /** @type {?} */ let 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 {?} */ static DeleteStringsFromEnds(str, strToDelete) { if (str.startsWith(strToDelete)) { str = str.substr(strToDelete.length); } if (str.endsWith(strToDelete)) { str = str.substr(0, str.length - strToDelete.length); } /** @type {?} */ let 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 {?} */ static padStr(str, len) { /** @type {?} */ let padLen = len - str.length; if (padLen > 0) { if (StrUtil._paddingSpaces === null || StrUtil._paddingSpaces.length < padLen) { StrUtil._paddingSpaces = NString.FromChar(' ', padLen); } /** @type {?} */ let 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 {?} */ static tokenize(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 {?} */ static stringToHexaDump(str, minLength) { /** @type {?} */ let stringBuilder = new StringBuilder(str.length * minLength); for (let indx = 0; indx < str.length; indx = indx + 1) { /** @type {?} */ let currInt = str.charCodeAt(indx); /** @type {?} */ let 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 {?} */ static searchAndReplace(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); } /// <summary> replace every appearance of 'from' in 'str' with 'to'</summary> /// <param name="str">the working base source string </param> /// <param name="from">the string to replace </param> /// <param name="to">the string use instead 'from' </param> /// <returns> modified String </returns> /** * @param {?} str * @param {?} from * @param {?} to * @return {?} */ static searchAndReplace_0(str, from, to) { /** @type {?} */ let lastSubStr = 0; /** @type {?} */ let startSubStr; /** @type {?} */ let result; if ((startSubStr = str.indexOf(from)) === -1) { result = str; } else { /** @type {?} */ let 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; } /// <summary> replace every appearance of strings of 'from' in 'str' with the according string in 'to'</summary> /// <param name="str">the working base source string </param> /// <param name="from">the string to replace </param> /// <param name="to">the string use instead 'from' </param> /// <returns> modified String </returns> /** * @param {?} str * @param {?} from * @param {?} to * @return {?} */ static searchAndReplace_1(str, from, to) { /** @type {?} */ let lastSubStr = 0; /** @type {?} */ let sarIndex = 0; /** @type {?} */ let fromCopy = from.slice(); /** @type {?} */ let startSubStr; /** @type {?} */ let SARindex = new RefParam(0); startSubStr = StrUtil.indexOf(str, fromCopy, lastSubStr, SARindex); sarIndex = SARindex.value; if (startSubStr === -1) return str; /** @type {?} */ let result; /** @type {?} */ let 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; } /// <summary> this functions is for use by the searchAndReplace() function - /// searches the offset of the strings from the array in the given string /// and returns the minimum offset found and sets the index of the found string /// to SARindex /// </summary> /// <param name="str">the string to search in </param> /// <param name="strings">an array of strings to search for </param> /// <param name="offset">where to start the search </param> /** * @param {?} str * @param {?} strings * @param {?} offset * @param {?} SARindex * @return {?} */ static indexOf(str, strings, offset, SARindex) { /** @type {?} */ let minOffset = -1; for (let i = 0; i < strings.length; i = i + 1) { /** @type {?} */ let flag = strings[i] === null; if (!(strings[i] === null)) { /** @type {?} */ let resultOffset = str.indexOf(strings[i], offset); if (resultOffset === -1) { strings[i] = null; } else { if (resultOffset < minOffset || minOffset === -1) { minOffset = resultOffset; SARindex.value = i; } } } } /** @type {?} */ let result; if (minOffset > -1) { result = minOffset; } else { SARindex.value = -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 {?} */ static replaceStringTokens(userString, token, occurrence, val) { /** @type {?} */ let tokenLen = token.length; /** @type {?} */ let currPosition = 0; /** @type {?} */ let newString = userString; if (val !== null) { /** @type {?} */ let 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 {?} */ static makePrintableTokens(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 {?} */ static makePrintableTokens_0(source, type) { /** @type {?} */ let escStr = [ "\\", "-", "," ]; /** @type {?} */ let escSeq = [ "\\\\", "\\-", "\\," ]; /** @type {?} */ let escHtm = [ HTML_BACKSLASH, HTML_HYPHEN, HTML_COMMA ]; /** @type {?} */ let 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; } /// <summary> /// converts special characters in a tokens collection to a printable format /// </summary> /// <param name = "source">vector of strings before tokenaizer </param> /// <param name = "type">type of conversion: STR_2_HTML, SEQ_2_HTML, HTML_2_SEQ, HTML_2_STR </param> /** * @param {?} source * @param {?} type * @return {?} */ static makePrintableTokens_1(source, type) { if (source !== null) { /** @type {?} */ let length = source.length; for (let i = 0; i < length; i = i + 1) { /** @type {?} */ let 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 {?} */ static makePrintable(source) { /** @type {?} */ let from = [ "\n", "\r", "'", "\\", "\"", "\0" ]; /** @type {?} */ let 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 {?} */ static makePrintable2(source) { /** @type {?} */ let from = [ "\n", "\r", "\0" ]; /** @type {?} */ let 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 {?} */ static ZstringMake(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 {?} */ static GetPlainTextfromRtf(rtfText) { if (Rtf.isRtf(rtfText)) { /** @type {?} */ let rtf = new Rtf(); /** @type {?} */ let 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 {?} */ static StringsArraysEqual(str1, str2) { /** @type {?} */ let 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 (let 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 {?} */ static SearchAndReplaceWildChars(buf, len, filler) { buf = NString.PadRight(buf, len); /** @type {?} */ let escChar = false; /** @type {?} */ let stopSearch = false; /** @type {?} */ let tmpBuf = new StringBuilder(len); for (let i = 0; i < len; i = i + 1) { switch (buf[i]) { case ('\\'): { /** @type {?} */ let 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 {?} */ let text = tmpBuf.ToString(); return NString.TrimEnd(NString.TrimEnd(text, ['\0'])); } } StrUtil._paddingSpaces = null; if (false) { /** @type {?} */ StrUtil._paddingSpaces; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3RyVXRpbC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BtYWdpYy14cGEvdXRpbHMvIiwic291cmNlcyI6WyJzcmMvU3RyVXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFPLE9BQU8sRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDNUUsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFBQyxHQUFHLEVBQUMsTUFBTSxPQUFPLENBQUM7O01BRXBCLGNBQWMsR0FBVyxRQUFROztNQUNqQyxVQUFVLEdBQVcsUUFBUTs7TUFDN0IsV0FBVyxHQUFXLFFBQVE7O01BQzlCLFVBQVUsR0FBVyxDQUFDOztBQUM1QixNQUFNLE9BQU8sVUFBVSxHQUFXLENBQUM7O0FBQ25DLE1BQU0sT0FBTyxVQUFVLEdBQVcsQ0FBQzs7TUFDN0IsVUFBVSxHQUFXLENBQUM7O0FBQzVCLE1BQU0sT0FBTyxTQUFTLEdBQVcsQ0FBQztBQUVsQyxNQUFNOzs7Ozs7O0lBSUosTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFXLEVBQUUsR0FBVzs7WUFDbEMsTUFBYztRQUNsQixFQUFFLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNaLEVBQUUsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDckIsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUNaLE1BQU0sQ0FBQyxNQUFNLENBQUM7WUFDaEIsQ0FBQztZQUNELE9BQU8sR0FBRyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUN2QyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztZQUNoQixDQUFDO1FBQ0gsQ0FBQztRQUNELE1BQU0sR0FBRyxHQUFHLENBQUM7UUFDYixNQUFN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