Scatter: Added SetSequentialX and SetFastViewX

git-svn-id: svn://ultimatepp.org/upp/trunk@2408 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
koldo 2010-05-18 20:47:31 +00:00
parent 76e951d8bd
commit b60d3bfa07
4 changed files with 231 additions and 34 deletions

View file

@ -24,6 +24,8 @@ ctrl Scatter {
bool ShowVGrid=true;
bool ShowLegend=true;
int SetLegendWeight=80;
bool SetFastViewX=false;
bool SetSequentialXAll=false;
Paint(w) {
r = GetRect();

View file

@ -398,6 +398,7 @@ Scatter &Scatter::AddSeries(Vector<XY> & points,const String& legend,const bool&
vShowMark.Add(true);
vMarkStyles.Add(CIRCLE);
vPPrimaryY.Add(true);
vPSequential.Add(sequentialXAll);
vPPattern.Add(LINE_SOLID);
Refresh();
@ -652,6 +653,29 @@ bool Scatter::IsDataPrimaryY(const int& j) const throw (Exc)
return vPPrimaryY[j];
}
void Scatter::SetSequentialX(const int& j, const bool& sequential)
{
if(IsValid(j))
{
vPSequential[j]=sequential;
Refresh();
}
}
Scatter &Scatter::SetSequentialX(const bool& sequential)
{
SetSequentialX(vPSequential.GetCount()-1, sequential);
return *this;
}
Scatter &Scatter::SetSequentialXAll(const bool& sequential)
{
for (int i = 0; i < vPSequential.GetCount(); ++i)
SetSequentialX(i, sequential);
sequentialXAll = sequential;
return *this;
}
void Scatter::SetFunctPrimaryY(const int& j, const bool& primary)
{
if(IsValid(j))
@ -690,6 +714,7 @@ void Scatter::RemoveSeries(const int& j)
vMarkStyles.Remove(j);
vPPrimaryY.Remove(j);
vPPattern.Remove(j);
vPSequential.Remove(j);
Refresh();
}
@ -708,6 +733,7 @@ void Scatter::RemoveAllSeries()
vShowMark.Clear();
vMarkStyles.Clear();
vPPrimaryY.Clear();
vPSequential.Clear();
vPPattern.Clear();
Refresh();
@ -1206,42 +1232,81 @@ void Scatter::Plot(Draw& w, const int& scale,const int& l,const int& h)const
int ix;//int x points coordinates
int iy;//int y points coordinates
if (!vPointsData.IsEmpty()){
for (int j=0; j<vPointsData.GetCount(); j++){
Vector<Point> p1;
for (int i=0; i<vPointsData[j].GetCount(); i++)
{
ix=fround(l*(vPointsData[j][i].x-xMin)/xRange);
if (vPPrimaryY[j])
iy=fround(h*(vPointsData[j][i].y-yMin)/yRange);
else
iy=fround(h*(vPointsData[j][i].y-yMin2)/yRange2);
p1<<Point(ix,h-iy);
}
if(vJoin[j])
{
if(vSmooth[j]&&vPointsData[j].GetCount()>2)
{
Vector<Point> p2;
Vector<XY> v(Cubic(vPointsData[j]));
for (int i=0; i<v.GetCount(); i++)
{
ix=fround(l*(v[i].x-xMin)/xRange);
if (vPPrimaryY[j])
iy=fround(h*(v[i].y-yMin)/yRange);
else
iy=fround(h*(v[i].y-yMin2)/yRange2);
p2<<Point(ix,h-iy);
for (int j=0; j<vPointsData.GetCount(); j++){
Vector<Point> p1;
int imin, imax;
if (vPSequential[j]) {
imin = imax = Null;
for (int i = 1; i<vPointsData[j].GetCount()-1; ++i) {
if (IsNull(imin)) {
if (vPointsData[j][i].x >= xMin)
imin = i-1;
} else if (IsNull(imax)) {
if (vPointsData[j][i].x >= xMin+xRange)
imax = i+1;
}
}
if(!p2.IsEmpty()) DrawPolylineX(w, p2,fround(scale*vPThickness[j]/6),vPColors[j],vPPattern[j], scale);
if (IsNull(imin))
imin = 0;
if (IsNull(imax))
imax = vPointsData[j].GetCount();
} else {
imin = 0;
imax = vPointsData[j].GetCount();
}
else if (!p1.IsEmpty()) DrawPolylineX(w, p1,fround(scale*vPThickness[j]/6),vPColors[j],vPPattern[j], scale);
}
if(vShowMark[j])
for (int i=0; i<vPointsData[j].GetCount(); i++) {
DrawMark(vMarkStyles[j],w,scale,p1[i],vPWidth[j],vMarkColors[j]);
int numV;
if (fastViewX)
numV = 1+(imax - imin)/h;
else
numV = 1;
for (int i=imin; i<imax; i+=numV)
{
double xx, yy;
if (fastViewX) {
xx = yy = 0;
int ii;
for (ii = 0; ii < numV && i+ii < imax; ++ii) {
yy += vPointsData[j][i+ii].y;
xx += vPointsData[j][i+ii].x;
}
yy /= double(ii);
xx /= double(ii);
} else {
xx = vPointsData[j][i].x;
yy = vPointsData[j][i].y;
}
ix=fround(l*(xx-xMin)/xRange);
if (vPPrimaryY[j])
iy=fround(h*(yy-yMin)/yRange);
else
iy=fround(h*(yy-yMin2)/yRange2);
p1<<Point(ix,h-iy);
}
if(vJoin[j])
{
if(vSmooth[j]&&vPointsData[j].GetCount()>2)
{
Vector<Point> p2;
Vector<XY> v(Cubic(vPointsData[j]));
for (int i=0; i<v.GetCount(); i++)
{
ix=fround(l*(v[i].x-xMin)/xRange);
if (vPPrimaryY[j])
iy=fround(h*(v[i].y-yMin)/yRange);
else
iy=fround(h*(v[i].y-yMin2)/yRange2);
p2<<Point(ix,h-iy);
}
if(!p2.IsEmpty()) DrawPolylineX(w, p2,fround(scale*vPThickness[j]/6),vPColors[j],vPPattern[j], scale);
}
else if (!p1.IsEmpty()) DrawPolylineX(w, p1,fround(scale*vPThickness[j]/6),vPColors[j],vPPattern[j], scale);
}
if(vShowMark[j])
for (int i=0; i<(imax-imin)/numV; i++) {
DrawMark(vMarkStyles[j],w,scale,p1[i],vPWidth[j],vMarkColors[j]);
}
}
}
@ -1520,7 +1585,7 @@ Scatter::Scatter():
showLegend(true),legendWeight(80),
antialiasing(false),
offset(10,12),
minXZoom(-1), maxXZoom(-1), minYZoom(-1), maxYZoom(-1)
minXZoom(-1), maxXZoom(-1), minYZoom(-1), maxYZoom(-1), fastViewX(false), sequentialXAll(false)
{
Color(graphColor);
BackPaint();

View file

@ -151,6 +151,10 @@ public:
Scatter &SetFunctPrimaryY(const bool& primary);
bool IsFunctPrimaryY(const int& j) const throw (Exc);
void SetSequentialX(const int& j, const bool& sequential = true);
Scatter &SetSequentialX(const bool& sequential = true);
Scatter &SetSequentialXAll(const bool& sequential = true);
void RemoveSeries(const int& j);
void RemoveAllSeries();
void SetData(const int& nbSeries, Vector<XY> & points);
@ -187,6 +191,8 @@ public:
Scatter& SetMinZoom(double x, double y = -1) {minXZoom = x; minYZoom = y; return *this;};
Scatter& SetMaxZoom(double x, double y = -1) {maxXZoom = x; maxYZoom = y; return *this;};
Scatter& SetFastViewX(bool set = true) {fastViewX = set; return *this;};
private:
class ::Color graphColor;
String title;
@ -200,6 +206,8 @@ private:
int px, py;
class ::Color plotAreaColor;
bool fastViewX, sequentialXAll;
bool paintInfo;
Point clickPoint;
PopUpInfo popText;
@ -226,6 +234,7 @@ private:
Vector<Vector<XY> > vPointsData,vFunctionData;
Vector<bool> vFPrimaryY, vPPrimaryY;
Vector<bool> /*vFSequential, */vPSequential;
Vector<String> vFPattern, vPPattern;
typedef double (*fAdress)(double);
Vector<fAdress> vAdress;

View file

@ -3772,5 +3772,126 @@ to zoom and move the graphs in X and Y axis.]]
驿 Г<EFBFBD><EFBFBD>
箿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
]]}}&]
[s0; &]
[s0; &]
[s0;i150;O0; [*2 Big datasets]&]
[s0;2%- &]
[ {{4548:5452f0;g0;^ [s0; [2 Big datasets are hard to handle. However there are two functions
that speed up dramatically Scatter response in X axis sequential
datasets like time series:]&]
[s0;2 &]
[s0;i150;O0; [2 SetSequentialX: Indicates that the data has been sequentially
inserted following X axis]&]
[s0;i150;O0; [2 SetFastViewX: Indicates that it will be viewed a point
per horizontal pixel. This point will be the average of all data
that is in that pixel]&]
[s0;2 ]
::= [s0;= [*R2
@@image:1903&1167
<EFBFBD>趿ц<EFBFBD><EFBFBD><EFBFBD>γ<EFBFBD>ú
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>湿<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>縿窿
<EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD>騿<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>姿<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ū<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>羿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>Р<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ü<EFBFBD><EFBFBD>ι
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǒ<EFBFBD>
轿<EFBFBD>簿<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǎ<EFBFBD>
<EFBFBD><EFBFBD>й<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>р<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>庿<EFBFBD>驿<EFBFBD><EFBFBD><EFBFBD>槿<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>χ<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ
騿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>ī<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>К<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
驿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>縿<EFBFBD>
<EFBFBD>鷿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
姿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>妿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ω<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>退<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>縿箿
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>χη<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Σ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>鮿<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>簿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>
<EFBFBD>
]]}}&]
[s0; ]