A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from http://www.ncbi.nlm.nih.gov/IEB/ToolBox/CPP_DOC/doxyhtml/gff2__reader_8cpp_source.html below:

NCBI C++ ToolKit: src/objtools/readers/gff2_reader.cpp Source File

89

mCurrentFeatureCount(0),

90

mParsingAlignment(

false

),

91

mAtSequenceData(

false

)

125

annots.push_back(pNext);

146  for

(TAnnots::iterator it = annots.begin();

147

it != annots.end(); ++it) {

251  string

annotId(givenId);

255  if

(annotId.empty()) {

259

pAnnotId->SetLocal().SetStr(annotId);

260

annot.

SetId

().push_back(pAnnotId);

293  if

(!pRecord->AssignFromGff(line)) {

327

score_values.clear();

329  if

(!alignment.IsSetScore()) {

333  for

(

const CRef<CScore>

& score : alignment.GetScore()) {

335  if

(!score->IsSetId() ||

336

!score->GetId().IsStr() ||

337

!score->IsSetValue()) {

340  const string

name = score->GetId().GetStr();

343

score_values[name]->Assign(

value

);

354  if

(score_val1.

IsInt

() &&

355

score_val2.

IsInt

() &&

360  if

(score_val1.

IsReal

() &&

376

matching_scores.clear();

378  for

(

const auto

& score1 : scores_1) {

379  const string

& name = score1.first;

382  const auto

& it = scores_2.find(name);

383  if

(it != scores_2.end() &&

385

matching_scores.insert(name);

401  for

(

const string

&

id

: id_list) {

415

pAnnot->

SetData

().SetAlign().push_back(pAlign);

424

list<string>& id_list,

430  if

( !pRecord->AssignFromGff(strLine) ) {

435  if

( !pRecord->GetAttribute(

"ID"

,

id

) ) {

439  if

(alignments.find(

id

) == alignments.end()) {

440

id_list.push_back(

id

);

448

alignments[id].push_back(alignment);

462  const

list<string> score_names {

"num_ident"

,

"num_mismatch"

};

464  for

(

const string

& score_name : score_names) {

465  if

(score_values.find(score_name) != score_values.end()) {

466

summed_scores[score_name] = score_values.at(score_name)->GetInt();

478  const

list<string> summed_score_names {

"num_ident"

,

"num_mismatch"

};

481

x_GetAlignmentScores(alignment, new_scores);

483  for

(

const string

& score_name : summed_score_names) {

484  if

(new_scores.

find

(score_name) == new_scores.

end

()) {

485

summed_scores.erase(score_name);

486

}

else if

(summed_scores.find(score_name) != summed_scores.end()) {

487

summed_scores[score_name] += new_scores[score_name]->GetInt();

488

new_scores.

erase

(score_name);

493

x_FindMatchingScores(common_scores,

495

matching_score_names);

497

common_scores.clear();

498  for

(

string

score_name : matching_score_names) {

500

common_scores[score_name]->Assign(*new_scores[score_name]);

511  if

(alignment_list.empty()) {

515  if

(alignment_list.size() == 1) {

516

processed = alignment_list.front();

521  const

list<string> summed_score_names {

"num_ident"

,

"num_mismatch"

};

524

list<CRef<CSeq_align>>::const_iterator align_it = alignment_list.

begin

();

532  while

(align_it != alignment_list.end() &&

533

!score_values.

empty

()) {

541  const auto

first_alignment = alignment_list.front();

542  if

(first_alignment->IsSetSegs() &&

543

first_alignment->GetSegs().IsSpliced()) {

547  if

(first_alignment->IsSetDim()) {

548

processed->

SetDim

(first_alignment->GetDim());

551  for

(

auto

& kv : summed_scores) {

553

score->SetId().SetStr(kv.first);

554

score->SetValue().SetInt(kv.second);

555

processed->

SetScore

().push_back(score);

558  for

(

auto

& kv : score_values) {

560

score->SetId().SetStr(kv.first);

561

score->SetValue().Assign(*(kv.second));

562

processed->

SetScore

().push_back(score);

566

spliced->

Assign

(first_alignment->GetSegs().GetSpliced());

567

processed->

SetSegs

().SetSpliced(*spliced);

569  auto

align_it = alignment_list.cbegin();

572  while

(align_it != alignment_list.end()) {

573  const auto

& spliced_seg = (*align_it)->GetSegs().GetSpliced();

574  if

(spliced_seg.IsSetExons()) {

575  for

(

auto

exon : spliced_seg.GetExons()) {

576

processed->

SetSegs

().SetSpliced().SetExons().push_back(exon);

587  for

(

auto

& kv : summed_scores) {

589

score->SetId().SetStr(kv.first);

590

score->SetValue().SetInt(kv.second);

591

processed->

SetScore

().push_back(score);

594  for

(

auto

& kv : score_values) {

596

score->SetId().SetStr(kv.first);

597

score->SetValue().Assign(*(kv.second));

598

processed->

SetScore

().push_back(score);

601  for

(

auto

current : alignment_list) {

603

new_align->Assign(*current);

604

new_align->ResetScore();

607  const string

& score_name = score->GetId().GetStr();

608  if

(score_values.

find

(score_name) == score_values.

end

()) {

609

new_align->SetScore().push_back(score);

612

processed->

SetSegs

().SetDisc().Set().push_back(new_align);

683

annot.

SetData

().SetAlign().push_back( pAlign ) ;

719

segment.

SetExons

().push_back(pExon);

732

vector<string> targetParts;

733  if

(!xGetTargetParts(gff, targetParts)) {

737

pExon->SetGenomic_start(

static_cast<TSeqPos>

(gff.SeqStart()-1));

738

pExon->SetGenomic_end(

static_cast<TSeqPos>

(gff.SeqStop()-1));

739  if

(gff.IsSetStrand()) {

740

pExon->SetGenomic_strand(gff.Strand());

749

pExon->SetProduct_start().SetNucpos(product_start);

750

pExon->SetProduct_end().SetNucpos(product_end);

753  if

(targetParts[3] ==

"-"

) {

756

pExon->SetProduct_strand(targetStrand);

767  if

(!gff.GetAttribute(

"Target"

, targetInfo)) {

772  if

(targetParts.size() != 4) {

782  const

vector<string>& gapParts,

784

vector<int>& starts)

const 788  const size_t

gapCount = gapParts.size();

790  for

(

size_t i

=0;

i

<gapCount; ++

i

) {

791  char

changeType = gapParts[

i

][0];

793  switch

(changeType) {

798

starts.push_back(

offset

+1-changeSize);

804

starts.push_back(

offset

+1-changeSize);

807

starts.push_back(-1);

813

starts.push_back(-1);

815

starts.push_back(

offset

+1-changeSize);

827  const

vector<string>& gapParts,

829

vector<int>& starts)

const 834  for

(

const auto

& gap_part : gapParts) {

835  char

changeType = gap_part[0];

837  switch

(changeType) {

842

starts.push_back(

offset

);

848

starts.push_back(

offset

);

851

starts.push_back(-1);

857

starts.push_back(-1);

859

starts.push_back(

offset

);

879  const size_t

gapCount = gapParts.size();

881  const bool

isTarget =

true

;

882

vector<int> targetStarts;

900

vector<int> identStarts;

901  const bool

isIdent = !isTarget;

923  for

(

size_t i

=0;

i

<gapCount; ++

i

) {

924

denseg.SetStarts().push_back(targetStarts[

i

]);

925

denseg.SetStarts().push_back(identStarts[

i

]);

939  if

(

type

==

"cDNA_match"

||

940  type

==

"EST_match"

||

941  type

==

"translated_nucleotide_match"

) {

955

vector<string> targetParts;

965  if

(

type

==

"translated_nucleotide_match"

) {

972

spliced_seg.SetProduct_id(*product_id);

975

spliced_seg.SetGenomic_id(*genomic_id);

977  if

(targetParts[3] ==

"+"

) {

981  if

(targetParts[3] ==

"-"

) {

987

spliced_seg.SetGenomic_strand(ident_strand);

998

vector<string> gapParts;

1007  for

(

const auto

& gap_part : gapParts) {

1009  char

changeType = gap_part[0];

1011  switch

(changeType) {

1016

chunk->SetMatch(changeSize);

1020

chunk->SetProduct_ins(changeSize);

1024

chunk->SetGenomic_ins(changeSize);

1028

exon->SetParts().push_back(chunk);

1031

spliced_seg.SetExons().push_back(exon);

1043

vector<string> targetParts;

1050  if

(targetParts[3] ==

"-"

) {

1055

identStrand = gff.

Strand

();

1060

vector<string> gapParts;

1068  int

gapCount =

static_cast<int>

(gapParts.size());

1074

denseg.SetNumseg(gapCount);

1077

denseg.SetIds().push_back(

1079

denseg.SetIds().push_back(

1096  for

(

int i

=0;

i

< gapCount; ++

i

) {

1100  for

(

int i

=0;

i

< gapCount; ++

i

) {

1101

denseg.SetStrands().push_back(targetStrand);

1102

denseg.SetStrands().push_back(identStrand);

1118  int

(gff.

Score

()));

1123  const string

intScores[] = {

1134  "common_component"

,

1144  const size_t

intCount(

sizeof

(intScores)/

sizeof

(

string

));

1145  for

(

size_t i

=0;

i

< intCount; ++

i

) {

1152  const string

realScores[] = {

1156  "pct_identity_gap"

,

1157  "pct_identity_ungap"

,

1158  "pct_identity_gapopen_only"

,

1161  "comp_adjustment_method"

,

1162  "pct_coverage_hiqual"

,

1165  "inversion_merge_alignmer"

,

1169  const size_t

realCount(

sizeof

(realScores)/

sizeof

(

string

));

1170  for

(

size_t i

=0;

i

< realCount; ++

i

) {

1196  if

(!pTargetFeature) {

1206

ncbi::CRef<CSeq_feat>& pFeature )

1211

pFeature = it->second;

1223

annot.

SetData

().SetFtable().push_back(pFeature);

1234  static const char

* digits =

"0123456789"

;

1235  string

strDb, strTag;

1240  if

( strDb ==

"NCBI_gi"

) {

1246  if

( ! strTag.empty() ) {

1247

pDbtag->

SetDb

( strDb );

1248  if

(strTag.find_first_not_of(digits, 0) == string::npos)

1251

pDbtag->

SetTag

().SetStr( strTag );

1255

pDbtag->

SetDb

(

"unknown"

);

1277  typedef

list<CRef<CSeq_feat> > FTABLE;

1278  typedef

list<string> PARENTS;

1284  for

(

auto

featIt =

ftable

.begin(); featIt !=

ftable

.end(); ++featIt) {

1286  const string

& parentStr = feat.

GetNamedQual

(

"Parent"

);

1289  for

(

auto

parentIt = parents.begin(); parentIt != parents.end(); ++parentIt) {

1290  const string

& parent = *parentIt;

1303  typedef

list<string> PARENTS;

1305  string

ancestorStr(directParentStr);

1307  while

(!ancestorStr.empty()) {

1315  for

(PARENTS::iterator it = ancestors.begin(); it != ancestors.end(); ++it) {

1316  const string

& ancestorStr = *it;

1328  typedef

vector<CRef<CSeqFeatXref> > XREFS;

1336  if

(

local

.IsId()) {

1337  auto

xrefId =

local

.GetId();

1338  const

XREFS& xrefs = feat.

GetXref

();

1339  for

(XREFS::const_iterator cit = xrefs.begin(); cit != xrefs.end(); ++cit) {

1345  if

(contentId == xrefId) {

1351  if

(

local

.IsStr()) {

1352  auto

xrefId =

local

.GetStr();

1353  const

XREFS& xrefs = feat.

GetXref

();

1354  for

(XREFS::const_iterator cit = xrefs.begin(); cit != xrefs.end(); ++cit) {

1360  if

(contentId == xrefId) {

1379

pToXref->SetId(*pToId);

1380

from.

SetXref

().push_back(pToXref);

1399

vector<CTempStringEx>

columns

;

1465  string

lineLowerCase(line.

substr

(0, 18));

1478  string

lineLowerCase(line.

substr

(0, 8));

1491  for

(

const auto

& lineData: readerData) {

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.

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.

void xProcessData(const TReaderData &, CSeq_annot &) override

void xSetXrefFromTo(CSeq_feat &, CSeq_feat &)

bool xSetDensegStarts(const vector< string > &gapParts, ENa_strand identStrand, ENa_strand targetStrand, const TSeqPos targetStart, const TSeqPos targetEnd, const CGff2Record &gff, CSeq_align::C_Segs::TDenseg &denseg)

void xGetData(ILineReader &, TReaderData &) override

static bool IsAlignmentData(const CTempString &)

bool xUpdateSplicedSegment(const CGff2Record &gff, CSpliced_seg &segment) const

bool xNeedsNewSeqAnnot(const CTempString &)

virtual bool x_ProcessQualifierSpecialCase(CGff2Record::TAttrCit, CRef< CSeq_feat >)

bool xAlignmentSetSpliced_seg(const CGff2Record &, CRef< CSeq_align >)

CRef< CSerialObject > ReadObject(ILineReader &, ILineErrorListener *=nullptr) override

Read an object from a given line reader, render it as the most appropriate Genbank object.

virtual bool x_UpdateAnnotAlignment(const CGff2Record &, CSeq_annot &, ILineErrorListener *=0)

virtual bool x_CreateAlignment(const CGff2Record &gff, CRef< CSeq_align > &pAlign)

bool xGetTargetParts(const CGff2Record &gff, vector< string > &targetParts) const

virtual bool xAddFeatureToAnnot(CRef< CSeq_feat >, CSeq_annot &)

virtual void xProcessSequenceRegionPragma(const CTempString &)

void x_ProcessAlignmentsGff(const list< string > &id_list, const map< string, list< CRef< CSeq_align >>> &alignments, CRef< CSeq_annot > pAnnot)

bool xAlignmentSetDenseg(const CGff2Record &, CRef< CSeq_align >)

bool xFeatureSetQualifier(const CTempString &, const CTempString &, CRef< CSeq_feat >)

bool xGetStartsOnMinusStrand(TSeqPos offset, const vector< string > &gapParts, bool isTarget, vector< int > &starts) const

CRef< CAnnotdesc > m_CurrentBrowserInfo

void xPostProcessAnnot(CSeq_annot &) override

virtual CGff2Record * x_CreateRecord()

CGff2Reader(TReaderFlags iFlags, const string &name="", const string &title="", SeqIdResolver resolver=CReadUtil::AsSeqId, CReaderListener *pListener=nullptr)

static bool xIsFastaMarker(const CTempString &line)

bool xAlignmentSetScore(const CGff2Record &, CRef< CSeq_align >)

bool xGetStartsOnPlusStrand(TSeqPos offset, const vector< string > &gapParts, bool isTarget, vector< int > &starts) const

bool x_GetFeatureById(const CTempString &, CRef< CSeq_feat > &)

virtual bool xIsCurrentDataType(const CTempString &)

IdToFeatureMap m_MapIdToFeature

virtual bool xParseFeature(const CTempString &, CSeq_annot &, ILineErrorListener *)

void x_FindMatchingScores(const TScoreValueMap &scores_1, const TScoreValueMap &scores_2, set< string > &matching_scores) const

static bool xIsSequenceRegion(const CTempString &line)

bool xUpdateSplicedAlignment(const CGff2Record &gff, CRef< CSeq_align > pAlign) const

virtual void xSetAncestorXrefs(CSeq_feat &, CSeq_feat &)

void ReadSeqAnnots(TAnnotList &, CNcbiIstream &, ILineErrorListener *=nullptr) override

Read all objects from given insput stream, returning them as a vector of Seq-annots.

bool xAlignmentSetSegment(const CGff2Record &, CRef< CSeq_align >)

void x_GetAlignmentScores(const CSeq_align &alignment, TScoreValueMap &score_values) const

static CRef< CDbtag > x_ParseDbtag(const CTempString &)

void x_InitializeScoreSums(const TScoreValueMap score_values, map< string, TSeqPos > &summed_scores) const

virtual bool x_ParseAlignmentGff(const CTempString &strLine, list< string > &id_list, map< string, list< CRef< CSeq_align >>> &alignments)

virtual bool xUpdateAnnotFeature(const CGff2Record &, CSeq_annot &, ILineErrorListener *=0)

bool x_MergeAlignments(const list< CRef< CSeq_align >> &alignment_list, CRef< CSeq_align > &processed)

void xSetAncestryLine(CSeq_feat &, const CTempString &)

virtual bool xParseStructuredComment(const CTempString &)

bool xSetSplicedExon(const CGff2Record &gff, CRef< CSpliced_exon > pExon) const

virtual bool xIsIgnoredFeatureType(const CTempString &)

virtual void xAssignAnnotId(CSeq_annot &, const CTempString={})

virtual bool xIsIgnoredFeatureId(const CTempString &)

virtual bool xGenerateParentChildXrefs(CSeq_annot &)

unsigned int mCurrentFeatureCount

virtual bool xAnnotPostProcess(CSeq_annot &)

bool IsInGenbankMode() const

void x_ProcessAlignmentScores(const CSeq_align &alignment, map< string, TSeqPos > &summed_scores, TScoreValueMap &common_scores) const

CRef< CSeq_entry > ReadSeqEntry(ILineReader &, ILineErrorListener *=nullptr) override

Read an object from a given line reader, render it as a single Seq-entry, if possible.

TAttributes::const_iterator TAttrCit

bool GetAttribute(const string &, string &) const

virtual bool InitializeFeature(TReaderFlags, CRef< CSeq_feat >, SeqIdResolver=nullptr) const

static void TokenizeGFF(vector< CTempStringEx > &columns, const CTempStringEx &line)

const string & Type() const

ENa_strand Strand() const

const string & Id() const

Defines and provides stubs for a general interface to a variety of file readers.

virtual bool xParseBrowserLine(const CTempString &, CSeq_annot &)

SeqIdResolver mSeqIdResolve

virtual bool xUngetLine(ILineReader &)

unsigned int m_uLineNumber

unique_ptr< CTrackData > m_pTrackDefaults

virtual bool xProgressInit(ILineReader &istr)

void ProcessError(CObjReaderLineException &, ILineErrorListener *)

vector< TReaderLine > TReaderData

virtual bool xGetLine(ILineReader &, string &)

virtual void xAddConversionInfo(CSeq_annot &, ILineErrorListener *)

virtual bool xParseTrackLine(const CTempString &)

virtual CRef< CSeq_annot > ReadSeqAnnot(CNcbiIstream &istr, ILineErrorListener *pErrors=nullptr)

Read an object from a given input stream, render it as a single Seq-annot.

std::atomic< unsigned int > m_uDataCount

virtual bool xIsTrackTerminator(const CTempString &)

virtual bool xIsTrackLine(const CTempString &)

void SetNamedScore(const string &id, int score)

void SetNameDesc(const string &name)

void SetTitleDesc(const string &title)

bool IsFtable(void) const

namespace ncbi::objects::

const string & GetNamedQual(const CTempString &qual_name) const

Return a named qualifier.

void AddOrReplaceQualifier(const string &qual_name, const string &qual_val)

Add a qualifier to this feature, or replace the value for the first one if it already exists.

Simple implementation of ILineReader for i(o)streams.

CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...

Abstract base class for lightweight line-by-line reading.

const_iterator begin() const

const_iterator end() const

const_iterator find(const key_type &key) const

Include a standard set of the NCBI C++ Toolkit most basic headers.

static const char * str(char *buf, int n)

static const column_t columns[]

bool s_CompareValues(const CScore::TValue &score_val1, const CScore::TValue &score_val2)

bool sFeatureHasXref(const CSeq_feat &feat, const CFeat_id &featId)

unsigned int TSeqPos

Type for sequence locations and lengths.

virtual void Assign(const CSerialObject &source, ESerialRecursionMode how=eRecursive)

Set object to copy of another one.

CRef< C > Ref(C *object)

Helper functions to get CRef<> and CConstRef<> objects.

bool IsNull(void) const THROWS_NONE

Check if pointer is null – same effect as Empty().

#define END_NCBI_SCOPE

End previously defined NCBI scope.

#define BEGIN_NCBI_SCOPE

Define ncbi namespace.

IO_PREFIX::istream CNcbiIstream

Portable alias for istream.

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.

static double StringToDouble(const CTempStringEx str, TStringToNumFlags flags=0)

Convert string to double.

bool empty(void) const

Return true if the represented string is empty (i.e., the length is zero)

static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)

Check if a string starts with a specified prefix value.

static bool SplitInTwo(const CTempString str, const CTempString delim, string &str1, string &str2, TSplitFlags flags=0)

Split a string into two pieces using the specified delimiters.

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.

static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)

Convert numeric value to string.

static string & ToLower(string &str)

Convert string to lower case – string& version.

bool IsStr(void) const

Check if variant Str is selected.

void SetTag(TTag &value)

Assign a value to Tag data member.

bool IsId(void) const

Check if variant Id is selected.

const TStr & GetStr(void) const

Get the variant data.

void SetDb(const TDb &value)

Assign a value to Db data member.

TId GetId(void) const

Get the variant data.

bool IsSetProduct_type(void) const

Check if a value has been assigned to Product_type data member.

TScore & SetScore(void)

Assign a value to Score data member.

TDenseg & SetDenseg(void)

Select the variant.

bool IsReal(void) const

Check if variant Real is selected.

void SetSegs(TSegs &value)

Assign a value to Segs data member.

TExons & SetExons(void)

Assign a value to Exons data member.

void SetDim(TDim value)

Assign a value to Dim data member.

void SetDim(TDim value)

Assign a value to Dim data member.

void SetType(TType value)

Assign a value to Type data member.

bool IsSetType(void) const

Check if a value has been assigned to Type data member.

void SetProduct_type(TProduct_type value)

Assign a value to Product_type data member.

TInt GetInt(void) const

Get the variant data.

bool IsInt(void) const

Check if variant Int is selected.

TSpliced & SetSpliced(void)

Select the variant.

TReal GetReal(void) const

Get the variant data.

@ eType_partial

mapping pieces together

@ eType_disc

discontinuous alignment

@ eProduct_type_transcript

TXref & SetXref(void)

Assign a value to Xref data member.

const TId & GetId(void) const

Get the Id member data.

const TLocal & GetLocal(void) const

Get the variant data.

bool IsSetXref(void) const

cite other relevant features Check if a value has been assigned to Xref data member.

bool IsLocal(void) const

Check if variant Local is selected.

const TId & GetId(void) const

Get the Id member data.

const TXref & GetXref(void) const

Get the Xref member data.

ENa_strand

strand of nucleic acid

TSet & SetSet(void)

Select the variant.

TSeq & SetSeq(void)

Select the variant.

TSeq_set & SetSeq_set(void)

Assign a value to Seq_set data member.

bool IsAlign(void) const

Check if variant Align is selected.

void SetData(TData &value)

Assign a value to Data data member.

TId & SetId(void)

Assign a value to Id data member.

void SetDesc(TDesc &value)

Assign a value to Desc data member.

TAnnot & SetAnnot(void)

Assign a value to Annot data member.

void SetInst(TInst &value)

Assign a value to Inst data member.

const TData & GetData(void) const

Get the Data member data.

TId & SetId(void)

Assign a value to Id data member.

@ eMol_not_set

> cdna = rna

Lightweight interface for getting lines of data with minimal memory copying.

const struct ncbi::grid::netcache::search::fields::KEY key

const GenericPointer< typename T::ValueType > T2 value

static SLJIT_INLINE sljit_ins lr(sljit_gpr dst, sljit_gpr src)


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