/** Breakup the line of text based on the delimiting characters passed in and return a vector of 'words'. */ std::vector<wxString> Tokens( const wxString wxLine, const wxString wxDelimiters ) { std::vector<wxString> tokens; wxString line(wxLine); // non-const copy wxString::size_type offset; while ((offset = find_first_of( line, wxDelimiters )) != line.npos) { if (offset > 0) { tokens.push_back( line.substr(0, offset) ); } // End if - then else break; line.Remove(0, offset+1); } // End while if (line.size() > 0) { tokens.push_back( line ); } // End if - then return(tokens); } // End Tokens() method
CL_StringData8::size_type CL_StringData8::find_first_of(const char *s, size_type pos) const { size_type len = 0; while (s[len] != 0) len++; return find_first_of(s, pos, len); }
http::header_set http::request_reader::read_request_headers() { http::header_set headers; while(true) { auto line = read_line(); // end of headers if(line.length() == 0) break; const auto double_colon_index = line.find_first_of(':'); // if ':' not found: invalid header line, continue to next line... if(double_colon_index == std::string::npos) continue; const auto key = line.substr(0, double_colon_index); // strip leading spaces (by moving the start-index-pointer right) auto value_start_index = double_colon_index+1; while(line[value_start_index] == ' ') ++value_start_index; const auto value = line.substr(value_start_index, std::string::npos); headers[key] = value; } return headers; }
std::vector<std::string> getProcArgs(int pid, size_t argmax) { auto raw_args = getProcRawArgs(pid, argmax); std::vector<std::string> args; bool collect = false; // Iterate from the back until we stop seing environment vars // Then start pushing args (in reverse order) onto a vector. // We trim the args of leading/trailing whitespace to make // analysis easier. for (auto itr = raw_args.rbegin(); itr < raw_args.rend(); ++itr) { if (collect) { std::string arg = *itr; boost::algorithm::trim(arg); args.push_back(arg); } else { size_t idx = itr->find_first_of("="); if (idx == std::string::npos) { collect = true; } } } // We pushed them on backwards, so we need to fix that. std::reverse(args.begin(), args.end()); return args; }
/** * [FuzzyFilter::rank calc a score how the target string matches the source string] * @param source [str1] * @param target [str2] * @return [score that 2 strings match] */ int FuzzyFilter::rank(const String &source, const String &target) const { if(source.empty()) return 999999; int lendiff = target.length() - source.length(); if(lendiff < 0) return -1; if(lendiff == 0 && source == target) return 0; int chardiff = 0; int idx = 0; for(int i=0; i<source.length(); i++) { int last = idx; idx = find_first_of(target, idx, source[i]); if(idx == -1) return -1; chardiff += idx - last; idx++; } //rest of the target chardiff += target.length() - idx; return chardiff; }
void pure_numeric_algo(){ cout<<endl<<"pure_numeric_algo :"<<endl; int ia[11] = {0, 1, 2, 3, 4, 5, 6,6,6, 7, 8 }; vector<int> iv(ia,ia+11); vector<int> iv2(ia+6,ia+8); vector<int>::iterator itr; itr = adjacent_find(iv.begin(),iv.end(), equal_to<int>()); //找到相邻元素相等的第一个元素 cout<<"adjacent_find: "<<*itr<<endl; cout<<"count: "<<count(iv.begin(),iv.end(), 6)<<endl; //找到元素值等于6的个数 cout<<"count_if: "<<count_if(iv.begin(),iv.end(), bind2nd(less<int>() , 7))<<endl; //找到小于7的元素个数 itr = find(iv.begin(),iv.end(), 4); //找到元素等于4的第一个元素位置 cout<<"find: "<<*itr<<endl; itr = find_if(iv.begin(),iv.end(), bind2nd(greater<int>() , 2)); //找到元素大于2的第一个元素位置 cout<<"find_if: "<<*itr<<endl; itr = find_end(iv.begin(),iv.end(), iv2.begin(),iv2.end()); //找到iv序列中最后子序列匹配出现的位置 cout<<"find_end: "<<*(itr+3)<<endl; itr = find_first_of(iv.begin(),iv.end(), iv2.begin(),iv2.end()); //找到iv序列中最先子序列匹配出现的位置 cout<<"find_end: "<<*(itr+3)<<endl; remove(iv.begin(),iv.end(), 6); //删除元素,向前移,但是容器size不变,后面会剩余数据 cout<<"remove: "<<iv<<endl; vector<int> iv3(12,-1); remove_copy(iv.begin(),iv.end(), iv3.begin(), 6); //删除元素,将数据拷贝到新容器,后面会剩余数据 cout<<"remove_copy: "<<iv3<<endl; remove_if(iv.begin(),iv.end(), bind2nd(less<int>(), 6)); //删除小于6的元素,后面会剩余数据 cout<<"remove_if: "<<iv<<endl; remove_copy_if(iv.begin(),iv.end(), iv3.begin(), bind2nd(less<int>(), 7)); //删除小于7的元素,并拷贝到新容器 cout<<"remove_copy_if: "<<iv3<<endl; replace(iv.begin(),iv.end(), 6, 3); //将所有元素值为6的改为3 cout<<"replace: "<<iv<<endl; replace_copy(iv.begin(),iv.end(),iv3.begin(), 3, 5); //将所有元素值为3的改为5,结果保存在新容器中 cout<<"replace_copy: "<<iv3<<endl; replace_if(iv.begin(),iv.end(), bind2nd(less<int>(),5), 2); //将所有元素值小于5的改为2 cout<<"replace_if: "<<iv<<endl; replace_copy_if(iv.begin(),iv.end(),iv3.begin(), bind2nd(equal_to<int>(),8), 9); //将所有元素值为8的改为9,结果保存在新容器中 cout<<"replace_copy_if: "<<iv3<<endl; reverse(iv.begin(),iv.end()); cout<<"reverse: "<<iv<<endl; //反转 reverse_copy(iv.begin(),iv.end(),iv3.begin()); cout<<"reverse_copy: "<<iv3<<endl; //反转,结果保存在新容器 rotate(iv.begin(),iv.begin() + 4, iv.end()); cout<<"rotate: "<<iv<<endl; //互换元素 rotate_copy(iv.begin(),iv.begin() + 5,iv.end(),iv3.begin()); cout<<"rotate_copy: "<<iv3<<endl; //互换元素,结果保存在新容器 int ia2[] = {2, 8}; vector<int> iv4(ia2,ia2+2); cout<<"search: "<<*search(iv.begin(),iv.end(),iv4.begin(),iv4.end())<<endl; //查找子序列出现的第一次出现地点 swap_ranges(iv4.begin(),iv4.end(),iv.begin()); //按区域交换 cout<<"swap_ranges: "<<iv<<endl<<iv4<<endl; transform(iv.begin(),iv.end(),iv.begin(),bind2nd(minus<int>(), 2)); //所有元素减2 cout<<"transform: "<<iv<<endl; transform(iv4.begin(),iv4.end(),iv.begin(),iv4.begin(),plus<int>()); //区间对应元素相加 cout<<"transform: "<<iv4<<endl; /************************************************************************/ vector<int> iv5(ia,ia+11); vector<int> iv6(ia+4,ia+8); vector<int> iv7(15); cout<<"max_element: "<<*max_element(iv5.begin(), iv5.end())<<endl; //最大元素游标 cout<<"min_element: "<<*min_element(iv5.begin(), iv5.end())<<endl; cout<<"includes: "<<includes(iv5.begin(),iv5.end(),iv6.begin(),iv6.end())<<endl; //iv6中元素是不是都在iv5中,这两个必须排过序 merge(iv5.begin(),iv5.end(),iv6.begin(),iv6.end(),iv7.begin()); //两个排序号的容器合并 cout<<"merge: "<<iv7<<endl; partition(iv7.begin(),iv7.end(),bind2nd(equal_to<int>(), 5)); //满足条件的放在左边,不满足条件的放在右边 cout<<"partition: "<<iv7<<endl; unique(iv5.begin(),iv5.end()); //去重,重复的元素放在后面 cout<<"unique: "<<iv5<<endl; unique_copy(iv5.begin(),iv5.end(),iv7.begin()); //去重,结果保存在新容器 cout<<"unique_copy: "<<iv7<<endl; }
std::string profile_for(const std::string & email) { auto strippedEmail = email; std::size_t pos = 0; while ((pos = strippedEmail.find_first_of("&=", pos)) != std::string::npos) strippedEmail.erase(pos, 1); return "email=" + strippedEmail + "&uid=10&role=user"; }
std::vector<xts::uri> find_image_url(const std::vector<char>& buffer, const std::string& pattern, const astd::string_view& chapter_num) { typedef std::regex_iterator<std::vector<char>::const_iterator> vregex_iterator; std::vector<xts::uri> result; bool keep_searching = true; auto beg = buffer.begin(); while (keep_searching) { auto search_result = std::search(beg, buffer.end(), pattern.begin(), pattern.end()); if (search_result != buffer.end()) { auto start_quote = std::find(search_result, buffer.end(), '"'); auto end_quote = std::find(search_result + pattern.size(), buffer.end(), '"'); xts::uri url_image; if (start_quote != end_quote) { url_image = xts::uri(std::string{ start_quote + 1, end_quote }); } else { url_image = xts::uri(std::string{ search_result, end_quote }); } bool chapte_num_found = false; bool image_num_validated = false; for (auto& path : url_image.paths()) { if (!chapte_num_found && std::search(path.begin(), path.end(), chapter_num.begin(), chapter_num.end()) != path.end()) { chapte_num_found = true; } } auto image_name = find_image_name(url_image); auto start = image_name.find_first_of("0123456789"); image_num_validated = start != astd::string_view::npos; if (chapte_num_found && image_num_validated) { keep_searching = false; result.emplace_back(url_image); } else { beg = search_result + pattern.size(); } } else { keep_searching = false; } } return result; }
inline size_t find_domain_in_url(const T* buf, size_t buflen, size_t& domain_len) { const T* dbeg = search_n(buf, buf + buflen, 2, '/') + 2; if (dbeg < buf + buflen) { const T stop[] = { '/', ':' }; const T* dend = find_first_of(dbeg, buf + buflen, stop, stop + 2); domain_len = dend - dbeg; return dbeg - buf; } return buflen; }
void LoadShedConfiguration::addWhitelistAddr(folly::StringPiece input) { auto addr = input.str(); size_t separator = addr.find_first_of('/'); if (separator == string::npos) { whitelistAddrs_.insert(SocketAddress(addr, 0)); } else { unsigned prefixLen = folly::to<unsigned>(addr.substr(separator + 1)); addr.erase(separator); whitelistNetworks_.insert(NetworkAddress(SocketAddress(addr, 0), prefixLen)); } }
std::string reduce(const std::string& str, const std::string& fill, const std::string& whitespace) { // trim first auto result = trim(str, whitespace); // replace sub ranges auto beginSpace = result.find_first_of(whitespace); while (beginSpace != std::string::npos) { const auto endSpace = result.find_first_not_of(whitespace, beginSpace); const auto range = endSpace - beginSpace; result.replace(beginSpace, range, fill); const auto newStart = beginSpace + fill.length(); beginSpace = result.find_first_of(whitespace, newStart); } return result; }
void test() { int data[5] = {0, 1, 2, 3, 4}; int search_array[2] = {0, 4}; const int const_search_array[2] = {0, 4}; range<int> data_range(data, 5); range<const int> const_data_range= data_range; range<int> search_range(data, 2); range<const int> const_search_range(data, 2); find_first_of(data_range, 2); find_first_of(data_range, search_range); find_first_of(data_range, const_search_range); find_first_of(data_range, search_array); find_first_of(data_range, const_search_array); find_first_of(const_data_range, 2); find_first_of(const_data_range, search_range); find_first_of(const_data_range, const_search_range); find_first_of(const_data_range, search_array); find_first_of(const_data_range, const_search_array); find_last_of(data_range, 2); find_last_of(data_range, search_range); find_last_of(data_range, const_search_range); find_last_of(data_range, search_array); find_last_of(data_range, const_search_array); find_last_of(const_data_range, 2); find_last_of(const_data_range, search_range); find_last_of(const_data_range, const_search_range); find_last_of(const_data_range, search_array); find_last_of(const_data_range, const_search_array); // range algorithms }
Decomposed::Decomposed(string const &uri) { char const *b = uri.data(); char const *const e = b + uri.size(); // Scheme { char const *c = ":/?#"; char const *p = find_first_of(b, e, c, c+4); if (p != e && *p == ':') { scheme.assign(b, ++p); b = p; } } // Authority if (2 <= e-b && b[0] == '/' && b[1] == '/') { char const *c = "/?#"; char const *const p = find_first_of(b+2, e, c, c+3); auth.assign(b, p); b = p; } // Path { char const *c = "?#"; char const *const p = find_first_of(b, e, c, c+2); path.assign(b, p); b = p; } // Query { char const *const p = find(b, e, '#'); query.assign(b, p); b = p; } // Fragment frag.assign(b, e); }
// Get the root name of a filename ......................................... // TODO: Check if it is really needed FileName FileName::getRoot() const { size_t skip_directories = find_last_of("/") + 1; size_t point = find_first_of(".", skip_directories); if (point == npos) point = length(); size_t root_end = find_last_not_of("0123456789", point - 1); if (root_end + 1 != point) if (point - root_end > FILENAMENUMBERLENGTH) root_end = point - FILENAMENUMBERLENGTH - 1; return substr(0, root_end + 1); }
int server_type::mknod(shared_ptr<fs_entry> file_ent, path_type const& path, mode_t, dev_t) { auto filename = path.filename().string(); auto pos = filename.find_first_of(host_port_delimiter); auto host = filename.substr(0, pos); int port = std::stoi(filename.substr(pos + 1)); BOOST_LOG_TRIVIAL(info) << "server_type::mknod: establishing server host=" << host << " port=" << port; int serverfd = establish_server(host, port); BOOST_LOG_TRIVIAL(info) << "server_type::mknod: established server " << host << ":" << port << " fd=" << serverfd; detail::fdtable.insert(path.string(), serverfd); return 0; }
void readWriteMatrix::getFromFile(std::string fName, std::vector<std::vector<double>*>* mat,std::vector<double>* b){ if(!mat->empty()){ for(auto v : *mat) delete v; mat->clear(); } if(!b->empty()) b->clear(); std::string line; std::ifstream in(fName,std::ios::in); std::vector<std::string> lines; if(in.is_open()) while(std::getline(in,line)) lines.emplace_back(line); auto fl = lines[0]; auto fSpace = fl.find_first_of(" "); int m = std::stoi(fl.substr(0,fSpace)), n = std::stoi(fl.substr(fSpace+1)), cnt = 0, vcnt = 0; std::cout<<fName<<" m= "<<m<<" n="<<n<<" N="<<m*n<<std::endl; m = m*n; lines.erase(lines.begin()); mat->push_back(new std::vector<double>()); for(auto l : lines){ if(l.find(".") != std::string::npos){ auto lastPos = l.find_first_not_of(" ", 0); auto pos = l.find_first_of(" ", lastPos); while(pos != std::string::npos || lastPos != std::string::npos){ auto mvar = l.substr(lastPos, pos - lastPos); auto val = std::stod(mvar); ++cnt; if(vcnt >= m) b->push_back(val); else{ if(cnt <= m) mat->at(vcnt)->push_back(val); else{ vcnt++; cnt = 1; if(vcnt < m){ mat->push_back(new std::vector<double>()); mat->at(vcnt)->push_back(val); }else b->push_back(val); } } lastPos = l.find_first_not_of(" ", pos); pos = l.find_first_of(" ", lastPos); } } } }
wxString wxStringTokenizer::GetNextToken() { wxString token; do { if ( !HasMoreTokens() ) { break; } m_hasMoreTokens = MoreTokens_Unknown; // find the end of this token wxString::const_iterator pos = find_first_of(m_delims, m_delimsLen, m_pos, m_stringEnd); // and the start of the next one if ( pos == m_stringEnd ) { // no more delimiters, the token is everything till the end of // string token.assign(m_pos, m_stringEnd); // skip the token m_pos = m_stringEnd; // it wasn't terminated m_lastDelim = wxT('\0'); } else // we found a delimiter at pos { // in wxTOKEN_RET_DELIMS mode we return the delimiter character // with token, otherwise leave it out wxString::const_iterator tokenEnd(pos); if ( m_mode == wxTOKEN_RET_DELIMS ) ++tokenEnd; token.assign(m_pos, tokenEnd); // skip the token and the trailing delimiter m_pos = pos + 1; m_lastDelim = (pos == m_stringEnd) ? wxT('\0') : (wxChar)*pos; } } while ( !AllowEmpty() && token.empty() ); return token; }
void ClubLectura::cargarLibros(string archivoLibros) { string rutaFichero(archivoLibros); string lineaActual; pair<int, Libro> pairLibro; std::ifstream inputStream; pair<map<int, Libro>::iterator, bool> encontrado; list<int> repetidos; inputStream.exceptions(std::ifstream::failbit | std::ifstream::badbit); inputStream.open(rutaFichero); int num = 1; try { while (!inputStream.eof()) { //Parseamos la linea. getline(inputStream, lineaActual); auto pos = lineaActual.find('|'); auto id = lineaActual.substr(0, pos); auto mid = atoi(id.c_str()); auto linea = lineaActual.substr(pos + 1, lineaActual.length()); pos = linea.find_first_of('|'); auto autor = linea.substr(0, pos); linea = linea.substr(pos + 1, linea.length()); pos = linea.find_first_of('|'); auto titulo = linea.substr(0, pos); auto tematica = linea.substr(pos + 1, linea.length()); Libro libro(mid, autor, titulo, tematica); pairLibro.first = mid; pairLibro.second = libro; encontrado = libros.insert(pairLibro); if (!encontrado.second) repetidos.push_back(mid); } } catch (std::ifstream::failure& error) { cout << "Fin de la lectura de los libros." << endl; } inputStream.close(); }
std::string FilePath::baseName() const { auto path = this->path(); auto i = path.find_last_of('/'); if (i != std::string::npos) { path = path.substr(++i); } auto pos = path.find_first_of('.', 1); // Make sure the filename doesn't start with '.' if (pos == std::string::npos) return path; return path.substr(0, pos); }
proc_args getProcRawArgs(int pid, size_t argmax) { proc_args args; uid_t euid = geteuid(); char procargs[argmax]; int mib[3] = {CTL_KERN, KERN_PROCARGS2, pid}; if (sysctl(mib, 3, &procargs, &argmax, nullptr, 0) == -1 || argmax == 0) { if (euid == 0) { TLOG << "An error occurred retrieving the env for pid: " << pid; } return args; } // The number of arguments is an integer in front of the result buffer. int nargs = 0; memcpy(&nargs, procargs, sizeof(nargs)); // Walk the \0-tokenized list of arguments until reaching the returned 'max' // number of arguments or the number appended to the front. const char *current_arg = &procargs[0] + sizeof(nargs); // Then skip the exec/program name. auto exec_name = std::string(current_arg); current_arg += exec_name.size() + 1; while (current_arg < &procargs[argmax]) { // Skip optional null-character padding. if (*current_arg == '\0') { current_arg++; continue; } auto string_arg = std::string(current_arg); if (string_arg.size() > 0) { if (nargs > 0) { // The first nargs are CLI arguments, afterward they are environment. args.args.push_back(string_arg); nargs--; } else { size_t idx = string_arg.find_first_of("="); if (idx != std::string::npos && idx > 0) { args.env[string_arg.substr(0, idx)] = string_arg.substr(idx + 1); } } } current_arg += string_arg.size() + 1; } return args; }
// Get number from file base name .................................................... int FileName::getNumber() const { size_t skip_directories = find_last_of("/") + 1; size_t point = find_first_of(".", skip_directories); if (point == npos) point = length(); size_t root_end = find_last_not_of("0123456789", point - 1); if (root_end + 1 != point) { if (point - root_end > FILENAMENUMBERLENGTH) root_end = point - FILENAMENUMBERLENGTH - 1; String aux = substr(root_end + 1, point - root_end + 1); return atoi(aux.c_str()); } else return -1; }
size_type StringPiece::find_first_of(const StringPiece& s, size_type pos) const { if (m_length == 0 || s.m_length == 0) return npos; // Avoid the cost of BuildLookupTable() for a single-character search. if (s.m_length == 1) return find_first_of(s.m_ptr[0], pos); bool lookup[UCHAR_MAX + 1] = { false }; BuildLookupTable(s, lookup); for (size_type i = pos; i < m_length; ++i) { if (lookup[static_cast<unsigned char>(m_ptr[i])]) { return i; } } return npos; }
/* Check if a file exists remove leading @ and tailing : */ bool FileName::existsTrim() const { FileName auxF(*this); size_t found = find_first_of(AT); if (found != String::npos) auxF = substr(found+1); found = auxF.find_first_of(NUM); if ( found != String::npos) auxF = auxF.substr(0, found); found = auxF.find_first_of(COLON); if (found != String::npos) auxF = auxF.substr(0, found); return fileExists(auxF.c_str()); }
// XED callback function to get a symbol from an address static int addressToSymbol(xed_uint64_t address, char* symbolBuffer, xed_uint32_t bufferLength, xed_uint64_t* offset, void* context) { auto name = boost::trim_copy(getNativeFunctionName((void*)address)); if (boost::starts_with(name, "0x")) { return 0; } auto pos = name.find_first_of('('); auto copyLength = pos != std::string::npos ? std::min(pos, size_t(bufferLength - 1)) : bufferLength - 1; strncpy(symbolBuffer, name.c_str(), copyLength); symbolBuffer[copyLength] = '\0'; *offset = 0; return 1; }
void HttpConnection::solveHttpFields(std::string& header, HttpResponse &httpResponse, std::string &error) { std::reference_wrapper<HttpResponse::headermap_type> httpFields( httpResponse.m_header_map ); header.erase(std::remove(header.begin(), header.end(), '\r'), header.end()); std::vector<std::string> header_vec(32); auto end_iter = split(header, '\n', header_vec.begin() ); for(auto curIter = header_vec.begin() ; curIter != end_iter ; ++curIter) { auto pos = curIter->find_first_of(':'); if( pos != curIter->npos ) httpFields.get().insert(std::make_pair(curIter->substr(0,pos), curIter->substr(pos + 2 , curIter->length() - pos - 2))); } }
Symbol(const char* symbol) : raw_(symbol) { auto first = raw_.find_first_of("("); auto last = raw_.find_last_of(")"); if (first != std::string::npos && last != std::string::npos) { auto mangled_symbol = raw_.substr(first+1, (last-1) - (first+1)); auto plus = mangled_symbol.find_first_of("+"); if (plus != std::string::npos) mangled_symbol.erase(plus); std::tie(demangled_, is_cxx_) = demangle(mangled_symbol); if (!is_cxx_) demangled_ = raw_; } }
/// Prints a string within single quotes, with proper escaping. /// /// \param [in,out] line The line to be printed. This is a non-const pointer /// and the input string is modified to simplify tokenization. /// \param [in,out] output Buffer onto which to write the quoted string. /// \param surrounding If true, surround the printed value with single quotes. static void print_quoted(char* line, FILE* output, const bool surrounding) { if (surrounding) fprintf(output, "'"); char* quoteptr; while ((quoteptr = find_first_of(line, "\'\\")) != NULL) { const char quote = *quoteptr; *quoteptr = '\0'; fprintf(output, "%s\\%c", line, quote); line = quoteptr + 1; } if (surrounding) fprintf(output, "%s'", line); else fprintf(output, "%s", line); }
void z_string::stringize(z_string &to) { to.clear(); to.append("\""); size_t start=0; size_t dq=0; while( (dq=find_first_of("\"",start))!=z_string::npos) { to.append(*this,start,dq-start); to.append("\""); start=dq+1; } to.append(*this,start,size()-start); to.append("\""); }
bool FileName::isMetaData(bool failIfNotExists) const { //check empty string if (empty()) REPORT_ERROR(ERR_ARG_INCORRECT, "FileName::isMetaData: Empty string is not a MetaData"); //file names containing : or % are not metadatas //size_t found = this->find('@'); if (find_first_of(":#") != npos) return false; //check if file exists if (failIfNotExists && !existsTrim()) REPORT_ERROR(ERR_IO_NOTFILE, formatString("FileName::isMetaData: File: '%s' does not exist", c_str())); //This is dangerous and should be removed //in next version. only star1 files should be OK //ROB //FIXME return (hasMetadataExtension() || isStar1(failIfNotExists)); }
void genProcessEnvironment(const std::string& pid, QueryData& results) { auto attr = getProcAttr("environ", pid); std::string content; readFile(attr, content); const char* variable = content.c_str(); // Stop at the end of nul-delimited string content. while (*variable > 0) { auto buf = std::string(variable); size_t idx = buf.find_first_of("="); Row r; r["pid"] = pid; r["key"] = buf.substr(0, idx); r["value"] = buf.substr(idx + 1); results.push_back(r); variable += buf.size() + 1; } }