& mix = pLoc->
SetMix();
91 for(
const auto& token : tokens) {
92 autodivPos = token.find(
"..");
93 if(divPos == string::npos) {
95mix.AddInterval(
id, point, point, strand);
99mix.AddInterval(
id, from, to, strand);
113 const stringcdstr_start =
"(pos:";
114 const stringcdstr_div =
",aa:";
115 const stringcdstr_end =
")";
121 size_tpos_start = cdstr_start.length();
122 size_tpos_stop =
str.find(cdstr_div);
123 stringposstr =
str.substr(pos_start, pos_stop-pos_start);
124 stringaaa =
str.substr(pos_stop+cdstr_div.length());
125aaa = aaa.substr(0, aaa.length()-cdstr_end.length());
127 const stringposstr_compl =
"complement(";
130posstr = posstr.substr(posstr_compl.length());
131posstr = posstr.substr(0, posstr.length()-1);
137posstr = posstr.substr(5);
138 _ASSERT(posstr.back() ==
')');
139posstr = posstr.substr(0, posstr.length() - 1);
142pCodeBreak->
SetLoc(*pLoc);
144 const stringposstr_div =
"..";
145 size_tpos_div = posstr.find(posstr_div);
146 if(pos_div == string::npos) {
151 const autoto =
NStr::StringToInt(posstr.substr(pos_div + posstr_div.length())) - 1;
154pCodeBreak->
SetLoc().SetInt().SetId(
id);
155pCodeBreak->
SetLoc().SetInt().SetFrom(from);
156pCodeBreak->
SetLoc().SetInt().SetTo(to);
157pCodeBreak->
SetLoc().SetInt().SetStrand(strand);
194 autoit = AminoAcidMap.find(aaa);
195 charaacode = (it != AminoAcidMap.end()) ? it->second :
'X';
197pCodeBreak->
SetAa().SetNcbieaa(aacode);
203 const string& genome,
209GENOME_MAP& sGenomeMap = *s_GenomeMap;
210 if(sGenomeMap.empty()) {
234GENOME_MAP::const_iterator cit = sGenomeMap.find(genome);
235 if(cit != sGenomeMap.end()) {
243vector<CTempStringEx>&
columns,
273 if(!isNumericCol3 && isNumericCol4 && isNumericNext) {
277 size_tstartof_col1 =
columns[1].begin() - in_line.
begin();
292 const string& strRawInput )
295vector< CTempStringEx >
columns;
303 "Bad data line: not enough columns",
320 stringmessage =
"Bad data line: Both \"start\" and \"stop\" must be positive integers.";
328 stringmessage =
"Bad data line: location start is greater than location stop (start=" 383 const string& strKey,
384 string& strValue )
const 387 TAttrCitit = m_Attributes.find( strKey );
388 if( it == m_Attributes.end() ) {
392strValue = it->second;
398 const string& strKey,
399list<string>& values )
const 403 TAttrCitit = m_Attributes.find(strKey);
404 if(it == m_Attributes.end()) {
408 return!values.empty();
426strValue = strValue.
substr( 1, string::npos );
429strValue = strValue.
substr( 0, strValue.
length() - 1 );
439 boolinQuotes =
false;
441 for(;
i<
input.length();
i++)
444 if(
input[
i] ==
'\"') {
449 if(
input[
i] ==
';') {
458 if(
input[
i] ==
'\"') {
478 boolinQuotes =
false;
480 while(
input[
i] ==
';') {
484 for(
i=0;
i<
input.length();
i++)
487 if(
input[
i] ==
'\"') {
516semicolon =
input.length();
519equal =
min(space, semicolon);
526 return!
key.empty();
530 const string& strType,
531 const string& strRawAttributes )
549 const string& strRawAttributes,
553 stringstrCurrAttrib;
554 boolinQuotes =
false;
556 ITERATE(
string, iterChar, strRawAttributes) {
558 if(*iterChar ==
'\"') {
561strCurrAttrib += *iterChar;
563 if(*iterChar ==
';') {
565 if(!strCurrAttrib.empty())
567strCurrAttrib.clear();
569 if(*iterChar ==
'\"') {
572strCurrAttrib += *iterChar;
578 if(!strCurrAttrib.empty())
594 returnxMigrateAttributes(
flags, pFeature);
604 autosubtype = pFeature->GetData().GetSubtype();
605 autorecType = NormalizedType();
608pFeature->SetLocation().SetMix().AddSeqLoc(*pAddLoc);
609 if(!xUpdateFeatureData(
flags, pFeature)) {
614GetAttribute(
"ID", cdsId);
615 if(!cdsId.empty()) {
616pFeature->AddOrReplaceQualifier(
"ID", cdsId);
629 const CSeq_loc& target = pFeature->GetLocation();
647 if(curStart == newStart) {
648pFeature->SetData().SetCdregion().SetFrame(Phase());
655 if(curStop == newStop) {
656pFeature->SetData().SetCdregion().SetFrame(Phase());
671 TAttributesattrs_left(m_Attributes.begin(), m_Attributes.end());
674it = attrs_left.
find(
"Note");
675 if(it != attrs_left.
end()) {
676pFeature->SetComment(xNormalizedAttributeValue(it->second));
677attrs_left.
erase(it);
680it = attrs_left.
find(
"Dbxref");
681 if(it != attrs_left.
end()) {
682vector<string> dbxrefs;
684 for(vector<string>::iterator it1 = dbxrefs.begin(); it1 != dbxrefs.end();
686 stringdbtag = xNormalizedAttributeValue(*it1);
689attrs_left.
erase(it);
692it = attrs_left.
find(
"Is_circular");
693 if(it != attrs_left.
end()) {
694 if(pFeature->GetData().IsBiosrc()) {
697pSubSource->
SetName(
"is_circular");
698pFeature->SetData().SetBiosrc().SetSubtype().push_back(pSubSource);
702it = attrs_left.
find(
"Parent");
703 if(it != attrs_left.
end()) {
704 if(
Type() !=
"CDS") {
705xMigrateAttributeSingle(
706attrs_left,
"Parent", pFeature,
"Parent",
flags);
708 elseattrs_left.
erase(it);
711it = attrs_left.
find(
"Name");
712 if(it != attrs_left.
end()) {
713 autosoType = NormalizedType();
715GetAttribute(
"gbkey", gbKey);
716 if(soType ==
"cds"|| soType ==
"mrna"|| soType ==
"biological_region"||
717(soType ==
"region"&& gbKey !=
"Src")) {
718attrs_left.
erase(it);
722it = attrs_left.
find(
"codon_start");
723 if(it != attrs_left.
end()) {
726 switch(codon_start) {
739attrs_left.
erase(it);
743it = attrs_left.
find(
"description");
744 if(it != attrs_left.
end()) {
745 if(pFeature->GetData().IsGene()) {
746 stringdescription = xNormalizedAttributeValue(it->second);
747pFeature->SetData().SetGene().SetDesc(description);
748attrs_left.
erase(it);
752it = attrs_left.
find(
"exception");
753 if(it != attrs_left.
end()) {
754pFeature->SetExcept(
true);
755pFeature->SetExcept_text(xNormalizedAttributeValue(it->second));
756attrs_left.
erase(it);
759it = attrs_left.
find(
"exon_number");
760 if(it != attrs_left.
end()) {
763pQual->
SetVal(it->second);
764pFeature->SetQual().push_back(pQual);
765attrs_left.
erase(it);
768it = attrs_left.
find(
"experiment");
769 if(it != attrs_left.
end()) {
770 const stringstrExperimentDefault(
771 "experimental evidence, no additional details recorded");
772 string value= xNormalizedAttributeValue(it->second);
773 if(
value== strExperimentDefault) {
778pQual->
SetQual(
"experiment");
780pFeature->SetQual().push_back(pQual);
782attrs_left.
erase(it);
785it = attrs_left.
find(
"gbkey");
786 if(it != attrs_left.
end()) {
787attrs_left.
erase(it);
790it = attrs_left.
find(
"gene");
791 if(it != attrs_left.
end()) {
792 if(pFeature->GetData().IsGene()) {
793list<string> geneValues;
796list<string>::const_iterator cit = geneValues.begin();
797 if(cit != geneValues.end()) {
798 value= xNormalizedAttributeValue(*cit);
799pFeature->SetData().SetGene().SetLocus(
value);
801 while(cit != geneValues.end()) {
802 value= xNormalizedAttributeValue(*cit);
803pFeature->SetData().SetGene().SetSyn().push_back(
value);
807attrs_left.
erase(it);
811it = attrs_left.
find(
"genome");
812 if(it != attrs_left.
end()) {
813 if(pFeature->GetData().IsBiosrc()) {
814pFeature->SetData().SetBiosrc().SetGenome(
816attrs_left.
erase(it);
820it = attrs_left.
find(
"gene_synonym");
821 if(it != attrs_left.
end()) {
822 if(pFeature->GetData().IsGene()) {
823vector<string> synonyms;
825 for(vector<string>::iterator it1 = synonyms.begin(); it1 != synonyms.end();
827 stringsynonym = xNormalizedAttributeValue(*it1);
828pFeature->SetData().SetGene().SetSyn().push_back(synonym);
831attrs_left.
erase(it);
834it = attrs_left.
find(
"inference");
835 if(it != attrs_left.
end()) {
836 autoinferenceVal = it->second;
837 const stringstrInferenceDefault(
838 "non-experimental evidence, no additional details recorded");
839 auto value= xNormalizedAttributeValue(inferenceVal);
840 if(
value== strInferenceDefault) {
844vector<string> inferenceVals;
846 for(
auto val: inferenceVals) {
848pQual->
SetQual(
"inference");
849pQual->
SetVal(xNormalizedAttributeValue(
val));
850pFeature->SetQual().push_back(pQual);
853attrs_left.
erase(it);
856it = attrs_left.
find(
"locus_tag");
857 if(it != attrs_left.
end()) {
858 if(pFeature->GetData().IsGene()) {
859 string tag= xNormalizedAttributeValue(it->second);
860pFeature->SetData().SetGene().SetLocus_tag(
tag);
862attrs_left.
erase(it);
865it = attrs_left.
find(
"map");
866 if(it != attrs_left.
end()) {
867 if(pFeature->GetData().IsGene()) {
868pFeature->SetData().SetGene().SetMaploc(
869xNormalizedAttributeValue(it->second));
873it = attrs_left.
find(
"ncrna_class");
874 if(it != attrs_left.
end()) {
876pFeature->SetData().SetRna().SetExt().SetGen().SetClass(
877xNormalizedAttributeValue(it->second));
879attrs_left.
erase(it);
882it = attrs_left.
find(
"partial");
883 if(it != attrs_left.
end()) {
885pFeature->AddQualifier(
"partial", it->second);
887attrs_left.
erase(it);
890it = attrs_left.
find(
"pseudo");
891 if(it != attrs_left.
end()) {
892pFeature->SetPseudo(
true);
893attrs_left.
erase(it);
896it = attrs_left.
find(
"regulatory_class");
897 if(it != attrs_left.
end()) {
898 if(pFeature->GetData().IsImp() && (pFeature->GetData().GetImp().GetKey() ==
"regulatory")) {
900pFeature->RemoveQualifier(
"regulatory_class");
901pFeature->AddQualifier(
"regulatory_class", it->second);
902attrs_left.
erase(it);
907it = attrs_left.
find(
"rpt_type");
908 if(it != attrs_left.
end()) {
910{
"microsatellite",
"microsatellite"},
911{
"minisatellite",
"minisatellite"},
912{
"satellite_DNA",
"satellite"},
913{
"satellite",
"satellite"},
915pFeature->RemoveQualifier(
"rpt_type");
916pFeature->RemoveQualifier(
"satellite");
917 autorpt_type = it->second;
918 autosatelliteIt = satellites.
find(rpt_type);
919 if(satelliteIt != satellites.
end()) {
920pFeature->AddQualifier(
"satellite", satelliteIt->second);
923pFeature->AddQualifier(
"rpt_type", rpt_type);
925attrs_left.
erase(it);
928it = attrs_left.
find(
"satellite");
929 if(it != attrs_left.
end()) {
930 if(pFeature->GetData().IsImp() && pFeature->GetData().GetImp().GetKey() ==
"repeat_region") {
931attrs_left.
erase(it);
935it = attrs_left.
find(
"transl_except");
936 if(it != attrs_left.
end()) {
937 if(pFeature->GetData().IsCdregion()) {
938vector<string> codebreaks;
940 for(vector<string>::iterator it1 = codebreaks.begin();
941it1 != codebreaks.end(); ++it1 ) {
942 stringbreakData = xNormalizedAttributeValue(*it1);
948 stringmessage =
"Unable to parse code-break : \""+ it->second +
"\"";
953pFeature->SetData().SetCdregion().SetCode_break().push_back(
957attrs_left.
erase(it);
961it = attrs_left.
find(
"transl_table");
962 if(it != attrs_left.
end()) {
963 if(pFeature->GetData().IsCdregion()) {
966pFeature->SetData().SetCdregion().SetCode().Set().push_back(pCe);
967attrs_left.
erase(it);
971 if(!xMigrateAttributesGo(
flags, pFeature, attrs_left)) {
975 if(pFeature->GetData().IsBiosrc()) {
976 if(!xMigrateAttributesSubSource(
flags, pFeature, attrs_left)) {
979 if(!xMigrateAttributesOrgName(
flags, pFeature, attrs_left)) {
987 while(!attrs_left.
empty()) {
988 const string&
key= attrs_left.
begin()->first;
989 if(!xMigrateAttributeDefault(attrs_left,
key, pFeature,
key,
flags)) {
999 const string& attrKey,
1001 const string& qualKey,
1021 const string& attrKey,
1023 const string& qualKey,
1034list<CTempStringEx> values;
1036 for(list<CTempStringEx>::const_iterator cit = values.begin(); cit != values.end();
1057ORGMOD_MAP& sOrgModMap = *s_OrgModMap;
1058 if(sOrgModMap.empty()) {
1098list<CRef<COrgMod> >& orgMod =
1099pFeature->SetData().SetBiosrc().SetOrg().SetOrgname().SetMod();
1100 for( ORGMOD_MAP::const_iterator sit = sOrgModMap.begin();
1101sit != sOrgModMap.end(); ++sit) {
1103 if(ait == attrs_left.end()) {
1109orgMod.push_back(pOrgMod);
1110attrs_left.erase(ait);
1122 for(
autoit = attrs.begin(); it != attrs.end();
) {
1129it = attrs.erase(it);
1147SUBSOURCE_MAP& sSubSourceMap = *s_SubSourceMap;
1148 if(sSubSourceMap.empty()) {
1195list<CRef<CSubSource> >& subType =
1196pFeature->SetData().SetBiosrc().SetSubtype();
1197 for( SUBSOURCE_MAP::const_iterator sit = sSubSourceMap.begin();
1198sit != sSubSourceMap.end(); ++sit) {
1200 if(ait == attrs_left.end()) {
1205pSubSource->
SetName(xNormalizedAttributeValue(ait->second));
1206subType.push_back(pSubSource);
1207attrs_left.erase(ait);
1218 autorecognizedType = NormalizedType();
1220 if(recognizedType ==
"region"|| recognizedType ==
"biological_region") {
1222 if(GetAttribute(
"gbkey", gbkey)) {
1223 if(gbkey ==
"Src") {
1224pFeature->SetData().SetBiosrc();
1230GetAttribute(
"Name", name);
1231pFeature->SetData().SetRegion(name);
1235 if(recognizedType ==
"start_codon"|| recognizedType ==
"stop_codon") {
1236recognizedType =
"cds";
1241 Type(), *pFeature, invalidFeaturesToRegion)) {
1242 stringmessage =
"Bad data line: Invalid feature type \""+
Type() +
"\"";
1257list<string> parentIds;
1261 return(parentIds.size() > 1);
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
@ eExtreme_Positional
numerical value
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
@Gb_qual.hpp User-defined methods of the data storage class.
static CRef< CDbtag > x_ParseDbtag(const CTempString &)
virtual bool xUpdateFeatureData(TReaderFlags, CRef< CSeq_feat >, SeqIdResolver=nullptr) const
bool IsMultiParent() const
TAttributes::const_iterator TAttrCit
static string xNormalizedAttributeValue(const CTempString &)
virtual bool xMigrateAttributes(TReaderFlags, CRef< CSeq_feat >) const
TAttributes::iterator TAttrIt
bool GetAttribute(const string &, string &) const
virtual bool UpdateFeature(TReaderFlags, CRef< CSeq_feat >, SeqIdResolver=nullptr) const
virtual bool AssignFromGff(const string &)
virtual bool InitializeFeature(TReaderFlags, CRef< CSeq_feat >, SeqIdResolver=nullptr) const
static void TokenizeGFF(vector< CTempStringEx > &columns, const CTempStringEx &line)
virtual bool xInitFeatureData(TReaderFlags, CRef< CSeq_feat >) const
static bool xMigrateAttributeDefault(TAttributes &, const string &, CRef< CSeq_feat >, const string &, TReaderFlags)
static bool xMigrateAttributeSingle(TAttributes &, const string &, CRef< CSeq_feat >, const string &, TReaderFlags)
virtual bool xMigrateAttributesGo(TReaderFlags, CRef< CSeq_feat >, TAttributes &) const
virtual bool xMigrateAttributesOrgName(TReaderFlags, CRef< CSeq_feat >, TAttributes &) const
virtual bool xMigrateAttributesSubSource(TReaderFlags, CRef< CSeq_feat >, TAttributes &) const
bool xSplitGffAttributes(const string &, vector< string > &) const
static string xNormalizedAttributeKey(const CTempString &)
virtual bool xAssignAttributesFromGff(const string &, const string &)
virtual bool xInitFeatureData(TReaderFlags, CRef< CSeq_feat >) const
virtual bool InitializeFeature(TReaderFlags, CRef< CSeq_feat >, SeqIdResolver=nullptr) const
string m_strNormalizedType
static CObjReaderLineException * Create(EDiagSev eSeverity, unsigned int uLine, const std::string &strMessage, EProblem eProblem=eProblem_GeneralParsingError, const std::string &strSeqId=string(""), const std::string &strFeatureName=string(""), const std::string &strQualifierName=string(""), const std::string &strQualifierValue=string(""), CObjReaderLineException::EErrCode eErrCode=eFormat, const TVecOfLines &vecOfOtherLines=TVecOfLines())
Please use this instead of the constructor because the ctor is protected.
@OrgMod.hpp User-defined methods of the data storage class.
static void AddGeneOntologyTerm(CSeq_feat &feature, const CTempString &qual, const CTempString &val)
void AddQualifier(const string &qual_name, const string &qual_val)
Add a qualifier to this feature.
static bool SoTypeToFeature(std::string_view, CSeq_feat &, bool=false)
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
@ eProblem_FeatureBadStartAndOrStop
container_type::iterator iterator
const_iterator begin() const
const_iterator end() const
const_iterator find(const key_type &key) const
#define MAKE_CONST_MAP(name, type1, type2,...)
Include a standard set of the NCBI C++ Toolkit most basic headers.
static DLIST_TYPE *DLIST_NAME() next(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
static const struct attribute attributes[]
static const char * str(char *buf, int n)
static const column_t columns[]
CBioSource::EGenome s_StringToGenome(const string &genome, CGff2Record::TReaderFlags flags)
CRef< CSeq_loc > s_GetCodeBreakSeqLocMix(const string &locString, const CSeq_id &id, ENa_strand strand)
CTempString x_GetNextAttribute(CTempString &input)
CRef< CCode_break > s_StringToCodeBreak(const string &str, CSeq_id &id, CGff2Record::TReaderFlags flags)
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
@ eDiag_Error
Error message.
TSeqPos GetStart(ESeqLocExtremes ext) const
Return start and stop positions of the seq-loc.
TSeqPos GetStop(ESeqLocExtremes ext) const
CRef< C > Ref(C *object)
Helper functions to get CRef<> and CConstRef<> objects.
void Reset(void)
Reset reference object.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
static CTempString TruncateSpaces_Unsafe(const CTempString str, ETrunc where=eTrunc_Both)
Truncate whitespace in a string.
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
static bool EndsWith(const CTempString str, const CTempString end, ECase use_case=eCase)
Check if a string ends with a specified suffix value.
CTempStringEx substr(size_type pos) const
Obtain a substring from this string, beginning at a given offset.
static double StringToDouble(const CTempStringEx str, TStringToNumFlags flags=0)
Convert string to double.
static string URLDecode(const CTempString str, EUrlDecode flag=eUrlDec_All)
URL-decode string.
static void TruncateSpacesInPlace(string &str, ETrunc where=eTrunc_Both)
Truncate whitespace in a string (in-place)
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
size_type length(void) const
Return the length of the represented array.
static unsigned int StringToUInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to unsigned int.
CTempString substr(size_type pos) const
Obtain a substring from this string, beginning at a given offset.
size_type find_first_not_of(const CTempString match, size_type pos=0) const
Find the first occurrence of any character not in the matching string within the current string,...
size_type find_first_of(const CTempString match, size_type pos=0) const
Find the first occurrence of any character in the matching string within the current string,...
static string & ToLower(string &str)
Convert string to lower case â string& version.
static const size_type npos
const_iterator begin() const
Return an iterator to the string's starting position.
@ fAllowLeadingSpaces
Ignore leading whitespace characters in converted string.
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
@ eUrlDec_Percent
Decode only XX.
void SetSubtype(TSubtype value)
Assign a value to Subtype data member.
void SetName(const TName &value)
Assign a value to Name data member.
EGenome
biological context
@ eSubtype_collection_date
DD-MMM-YYYY format.
@ eSubtype_insertion_seq_name
@ eSubtype_transposon_name
@ eSubtype_fwd_primer_seq
sequence (possibly more than one; semicolon-separated)
@ eSubtype_lat_lon
+/- decimal degrees
@ eSubtype_rev_primer_name
@ eSubtype_collected_by
name of person who collected the sample
@ eSubtype_fwd_primer_name
@ eSubtype_rev_primer_seq
sequence (possibly more than one; semicolon-separated)
@ eSubtype_isolation_source
@ eSubtype_environmental_sample
@ eSubtype_endogenous_virus_name
@ eSubtype_identified_by
name of person who identified the sample
@ eSubtype_whole_replicon
@ eGenome_endogenous_virus
void SetSubtype(TSubtype value)
Assign a value to Subtype data member.
void SetSubname(const TSubname &value)
Assign a value to Subname data member.
@ eSubtype_gb_acronym
used by taxonomy database
@ eSubtype_gb_synonym
used by taxonomy database
@ eSubtype_other
ASN5: old-name (254) will be added to next spec.
@ eSubtype_dosage
chromosome dosage of hybrid
@ eSubtype_nat_host
natural host of this specimen
@ eSubtype_specimen_voucher
@ eSubtype_gb_anamorph
used by taxonomy database
@ eSubtype_culture_collection
@ eSubtype_forma_specialis
void SetAa(TAa &value)
Assign a value to Aa data member.
void SetQual(const TQual &value)
Assign a value to Qual data member.
void SetLoc(TLoc &value)
Assign a value to Loc data member.
void SetVal(const TVal &value)
Assign a value to Val data member.
@ eExp_ev_experimental
any reasonable experimental check
@ eExp_ev_not_experimental
similarity, pattern, etc
@ eFrame_not_set
not set, code uses one
@ eFrame_three
reading frame
ENa_strand
strand of nucleic acid
bool CanGetStrand(void) const
Check if it is safe to call GetStrand method.
TStrand GetStrand(void) const
Get the Strand member data.
const TInt & GetInt(void) const
Get the variant data.
@ eNa_strand_both
in forward orientation
std::false_type tagStrNocase
const struct ncbi::grid::netcache::search::fields::KEY key
const GenericPointer< typename T::ValueType > T2 value
static bool GetSeqId(const T &d, set< string > &labels, const string name="", bool detect=false, bool found=false)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4