1
0
Fork 0
forked from lthn/blockchain

Merge branch 'predevelop' into develop

This commit is contained in:
sowle 2020-06-26 15:46:22 +03:00
commit e283e36c06
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
209 changed files with 5759 additions and 5651 deletions

1
.gitignore vendored
View file

@ -5,3 +5,4 @@
._.DS_Store
Thumbs.db
._*
.idea

View file

@ -120,20 +120,28 @@
#elif BOOST_VERSION < 106900
#include <boost/spirit/home/support/detail/math/fpclassify.hpp>
#include <boost/spirit/home/support/detail/endian/endian.hpp>
#elif BOOST_VERSION >= 106900
# define BOOST_MATH_DISABLE_STD_FPCLASSIFY
# include <boost/math/special_functions/fpclassify.hpp>
# include <boost/endian/conversion.hpp>
#else
#include <boost/spirit/home/support/detail/endian/endian.hpp>
# include <boost/spirit/home/support/detail/endian/endian.hpp>
# include <boost/spirit/home/support/detail/math/fpclassify.hpp>
#endif
// namespace alias
#if BOOST_VERSION < 103800 || BOOST_VERSION >= 106900
#if BOOST_VERSION < 103800
namespace fp = boost::math;
#elif BOOST_VERSION >= 106900
namespace fp = boost::math;
#else
namespace fp = boost::spirit::math;
namespace fp = boost::spirit::math;
#endif
// namespace alias endian
#if BOOST_VERSION < 104800
namespace endian = boost::detail;
#elif BOOST_VERSION >= 106900
namespace endian = boost::endian;
#else
namespace endian = boost::spirit::detail;
#endif
@ -352,7 +360,11 @@ namespace eos {
// load the value from little endian - it is then converted
// to the target type T and fits it because size <= sizeof(T)
#if BOOST_VERSION >= 106900
t = endian::little_to_native(temp);
#else
t = endian::load_little_endian<T, sizeof(T)>(&temp);
#endif
}
else t = 0; // zero optimization

View file

@ -123,20 +123,29 @@
#elif BOOST_VERSION < 106900
#include <boost/spirit/home/support/detail/math/fpclassify.hpp>
#include <boost/spirit/home/support/detail/endian/endian.hpp>
#elif BOOST_VERSION >= 106900
#define BOOST_MATH_DISABLE_STD_FPCLASSIFY
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/endian/conversion.hpp>
#else
#include <boost/spirit/home/support/detail/endian/endian.hpp>
#include <boost/spirit/home/support/detail/math/fpclassify.hpp>
#endif
// namespace alias fp_classify
#if BOOST_VERSION < 103800 || BOOST_VERSION >= 106900
#if BOOST_VERSION < 103800
namespace fp = boost::math;
#elif BOOST_VERSION >= 106900
namespace fp = boost::math;
#else
namespace fp = boost::spirit::math;
namespace fp = boost::spirit::math;
#endif
// namespace alias endian
#if BOOST_VERSION < 104800
namespace endian = boost::detail;
#elif BOOST_VERSION >= 106900
namespace endian = boost::endian;
#else
namespace endian = boost::spirit::detail;
#endif
@ -330,7 +339,11 @@ namespace eos {
// we choose to use little endian because this way we just
// save the first size bytes to the stream and skip the rest
endian::store_little_endian<T, sizeof(T)>(&temp, t);
#if BOOST_VERSION >= 106900
temp = endian::native_to_little(temp);
#else
endian::store_little_endian<T, sizeof(T)>(&temp, t);
#endif
save_binary(&temp, size);
}
// zero optimization
@ -388,7 +401,11 @@ namespace eos {
switch (fp::fpclassify(t))
{
//case FP_ZERO: bits = 0; break;
case FP_NAN: bits = traits::exponent | traits::mantissa; break;
#if BOOST_VERSION >= 106900
case FP_NAN: bits = traits::exponent | traits::significand; break;
#else
case FP_NAN: bits = traits::exponent | traits::mantissa; break;
#endif
case FP_INFINITE: bits = traits::exponent | (t<0) * traits::sign; break;
case FP_SUBNORMAL: assert(std::numeric_limits<T>::has_denorm); // pass
case FP_ZERO: // note that floats can be ±0.0

View file

@ -1,56 +0,0 @@
/** tutorial_pba_0.cpp
*
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
*
* Use, modification and distribution is subject to the Boost Software
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
*/
/**
* The intent of this program is to serve as a tutorial for
* users of the portable binary archive in the framework of
* the Boost/Serialization library.
*
* This quick start example shows how to store some variables
* of basic types (bool, integer, floating point numbers, STL string)
* using the portable binary archive format associated to a
* standard output file stream.
*
*/
#include <string>
#include <fstream>
#include <boost/cstdint.hpp>
#include <boost/archive/portable_binary_oarchive.hpp>
int main (void)
{
// The name for the example data file :
std::string filename = "pba_0.data";
// Some variables of various primitive types :
bool b = true;
char c = 'B';
uint32_t answer = 42;
float computing_time = 7.5e6;
double e = 2.71828182845905;
std::string slogan = "DON'T PANIC";
// Open an output file stream in binary mode :
std::ofstream fout (filename.c_str (), std::ios_base::binary);
{
// Create an output portable binary archive attached to the output file :
boost::archive::portable_binary_oarchive opba (fout);
// Store (serializing) variables :
opba & b & c & answer & computing_time & e & slogan;
}
return 0;
}
// end of tutorial_pba_0.cpp

View file

@ -1,68 +0,0 @@
/** tutorial_pba_1.cpp
*
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
*
* Use, modification and distribution is subject to the Boost Software
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
*/
/**
* The intent of this program is to serve as a tutorial for
* users of the portable binary archive in the framework of
* the Boost/Serialization package.
*
* This quick start example shows how to load some variables
* of basic types (bool, integer, floating point numbers, STL string)
* using the portable binary archive format associated to a
* standard input file stream.
*
*/
#include <iostream>
#include <string>
#include <fstream>
#include <boost/cstdint.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
int main (void)
{
using namespace std;
// The name for the example data file :
string filename = "pba_0.data";
// Some variables of various types :
bool b;
char c;
uint32_t answer;
float computing_time;
double e;
string slogan;
// Open an input file stream in binary mode :
ifstream fin (filename.c_str (), ios_base::binary);
{
// Create an input portable binary archive attached to the input file :
boost::archive::portable_binary_iarchive ipba (fin);
// Loading (de-serializing) variables using the same
// order than for serialization (see tutorial_pba_0.cpp) :
ipba & b & c & answer & computing_time & e & slogan;
}
cout.precision (15);
cout << "Variable 'b' is : " << b << " " << "(bool)" << endl;
cout << "Variable 'c' is : '" << c << "' " << " " << "(char)" << endl;
cout << "Variable 'answer' is : " << answer << " " << "(unsigned 32-bit integer)" << endl;
cout << "Variable 'computing_time' is : " << computing_time << " " << "(single precision 32-bit float)" << endl;
cout << "Variable 'e' is : " << e << " " << "(double precision 64-bit float)" << endl;
cout << "Variable 'slogan' is : \"" << slogan << "\" " << "(std::string)" << endl;
return 0;
}
// end of tutorial_pba_1.cpp

View file

@ -1,162 +0,0 @@
/** tutorial_pba_10.cpp
*
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
*
* Use, modification and distribution is subject to the Boost Software
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
*/
/**
* The intent of this program is to serve as a tutorial for
* users of the portable binary archive in the framework of
* the Boost/Serialization library.
*
* This example shows how use PBAs combined with on-the-fly
* compressed I/O streams.
*
*/
#include <string>
#include <fstream>
#include <limits>
#include <vector>
#include <boost/cstdint.hpp>
#include <boost/archive/portable_binary_oarchive.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/vector.hpp>
using namespace std;
class data_type
{
private:
friend class boost::serialization::access;
template<class Archive>
void serialize (Archive & ar, const unsigned int version);
public:
void print (ostream & out, const string & title) const;
public:
vector<double> values;
data_type ();
};
data_type::data_type () : values ()
{
return;
}
void data_type::print (ostream & out, const string & title) const
{
out << endl;
out << title << " :" << endl;
for (int i = 0; i < this->values.size (); ++i)
{
out.precision (16);
out.width (18);
out << this->values [i] << ' ' ;
if ((i%4) == 3) clog << endl;
}
out << endl;
return;
}
template<class Archive>
void data_type::serialize (Archive & ar, const unsigned int version)
{
ar & values;
return;
}
void do_gzipped_out (void)
{
// The name for the output data file :
string filename = "pba_10.data.gz";
// A data structure to be stored :
data_type my_data;
// Fill the vector with arbitrary (possibly non-finite) values :
size_t dim = 1000;
my_data.values.reserve (dim);
for (int i = 0; i < dim; ++i)
{
double val = (i + 1) * (1.0 + 3 * numeric_limits<double>::epsilon ());
if (i == 4) val = numeric_limits<double>::quiet_NaN ();
if (i == 23) val = numeric_limits<double>::infinity ();
if (i == 73) val = -numeric_limits<double>::infinity ();
if (i == 90) val = 0.0;
my_data.values.push_back (val);
}
// Print:
my_data.print (clog, "Stored data");
// Create an output filtering stream :
boost::iostreams::filtering_ostream zout;
zout.push (boost::iostreams::gzip_compressor ());
// Open an output file stream in binary mode :
ofstream fout (filename.c_str (), ios_base::binary);
zout.push (fout);
// Save to PBA :
{
// Create an output portable binary archive attached to the output file :
boost::archive::portable_binary_oarchive opba (zout);
// Store (serializing) the data :
opba & my_data;
}
// Clean termination of the streams :
zout.flush ();
zout.reset ();
return;
}
void do_gzipped_in (void)
{
// The name for the input data file :
string filename = "pba_10.data.gz";
// A data structure to be loaded :
data_type my_data;
// Create an input filtering stream :
boost::iostreams::filtering_istream zin;
zin.push (boost::iostreams::gzip_decompressor ());
// Open an input file stream in binary mode :
ifstream fin (filename.c_str (), ios_base::binary);
zin.push (fin);
// Load from PBA :
{
// Create an input portable binary archive attached to the input file :
boost::archive::portable_binary_iarchive ipba (zin);
// Load (deserializing) the data :
ipba & my_data;
}
// Print:
my_data.print (clog, "Loaded data");
return;
}
int main (void)
{
do_gzipped_out ();
do_gzipped_in ();
return 0;
}
// end of tutorial_pba_10.cpp

View file

@ -1,198 +0,0 @@
/** tutorial_pba_10b.cpp
*
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
*
* Use, modification and distribution is subject to the Boost Software
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
*/
/**
* The intent of this program is to serve as a tutorial for
* users of the portable binary archive in the framework of
* the Boost/Serialization library.
*
* This example shows how use PBAs combined with on-the-fly
* compressed I/O streams.
*
*/
#include <string>
#include <fstream>
#include <limits>
#include <vector>
#include <boost/cstdint.hpp>
#include <boost/archive/portable_binary_oarchive.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/version.hpp>
using namespace std;
class data_type
{
private:
friend class boost::serialization::access;
template<class Archive>
void serialize (Archive & ar, const unsigned int version);
public:
void print (ostream & out, const string & title) const;
public:
vector<double> values;
data_type ();
};
//BOOST_CLASS_VERSION(data_type, 7)
data_type::data_type () : values ()
{
return;
}
void data_type::print (ostream & out, const string & title) const
{
out << endl;
out << title << " :" << endl;
for (int i = 0; i < this->values.size (); ++i)
{
out.precision (16);
out.width (18);
out << this->values [i] << ' ' ;
if ((i%4) == 3) clog << endl;
}
out << endl;
return;
}
template<class Archive>
void data_type::serialize (Archive & ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP (values);
return;
}
class data_type2
{
private:
friend class boost::serialization::access;
template<class Archive>
void serialize (Archive & ar, const unsigned int version);
public:
double value;
data_type2 ();
};
BOOST_CLASS_VERSION(data_type2, 99)
data_type2::data_type2 () : value (666.666)
{
return;
}
template<class Archive>
void data_type2::serialize (Archive & ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP (value);
return;
}
class data_type3
{
private:
friend class boost::serialization::access;
template<class Archive>
void serialize (Archive & ar, const unsigned int version);
public:
vector<data_type2> values;
data_type3 ();
};
BOOST_CLASS_VERSION(data_type3, 33)
data_type3::data_type3 ()
{
{
data_type2 d;
d.value = 6.66;
values.push_back (d);
}
{
data_type2 d;
d.value = 66.66;
values.push_back (d);
}
{
data_type2 d;
d.value = 666.66;
values.push_back (d);
}
return;
}
template<class Archive>
void data_type3::serialize (Archive & ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP (values);
return;
}
/********************/
void do_xml_out (void)
{
// The name for the output data file :
string filename = "pba_10.xml";
// A data structure to be stored :
data_type my_data;
// Fill the vector with arbitrary (possibly non-finite) values :
size_t dim = 6;
my_data.values.reserve (dim);
for (int i = 0; i < dim; ++i)
{
double val = (i + 1) * (1.0 + 3 * numeric_limits<double>::epsilon ());
if (i == 4) val = numeric_limits<double>::quiet_NaN ();
if (i == 7) val = numeric_limits<double>::infinity ();
if (i == 9) val = -numeric_limits<double>::infinity ();
if (i == 13) val = 0.0;
my_data.values.push_back (val);
}
// Print:
my_data.print (clog, "Stored data");
data_type2 my_data2;
data_type3 my_data3;
// Open an output file stream in binary mode :
ofstream fout (filename.c_str ());
// Save to PBA :
{
// Create an output XML archive attached to the output file :
boost::archive::xml_oarchive oxa (fout);
// Store (serializing) the data :
oxa & BOOST_SERIALIZATION_NVP(my_data);
oxa & BOOST_SERIALIZATION_NVP(my_data2);
oxa & BOOST_SERIALIZATION_NVP(my_data3);
}
return;
}
int main (void)
{
do_xml_out ();
return 0;
}
// end of tutorial_pba_10b.cpp

View file

@ -1,187 +0,0 @@
/** tutorial_pba_11.cpp
*
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
*
* Use, modification and distribution is subject to the Boost Software
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
*/
/**
* The intent of this program is to serve as a tutorial for
* users of the portable binary archive in the framework of
* the Boost/Serialization library.
*
* This example program compares the times needed to serialize
* and deserialize some large amount of data using PBA and
* text archives.
*
*/
#include <string>
#include <fstream>
#include <vector>
#include <boost/archive/portable_binary_oarchive.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/timer.hpp>
using namespace std;
class data_type
{
private:
friend class boost::serialization::access;
template<class Archive>
void serialize (Archive & ar, const unsigned int version);
public:
void print (ostream & out, const string & title) const;
public:
vector<double> values;
data_type ();
};
data_type::data_type () : values ()
{
return;
}
void data_type::print (ostream & out, const string & title) const
{
out << endl;
out << title << " :" << endl;
bool skip = false;
for (int i = 0; i < this->values.size (); ++i)
{
if ((i >= 12) && (i < (int) this->values.size () - 8))
{
if (! skip) out << " ..." << endl;
skip = true;
continue;
}
out.precision (16);
out.width (18);
out << this->values [i] << ' ' ;
if ((i%4) == 3) clog << endl;
}
out << endl;
return;
}
template<class Archive>
void data_type::serialize (Archive & ar, const unsigned int version)
{
ar & values;
return;
}
double do_pba_out (const data_type & a_data)
{
string filename = "pba_11.data";
ofstream fout (filename.c_str (), ios_base::binary);
boost::timer io_timer;
{
boost::archive::portable_binary_oarchive opba (fout);
opba & a_data;
}
return io_timer.elapsed ();
}
double do_pba_in (data_type & a_data)
{
string filename = "pba_11.data";
ifstream fin (filename.c_str (), ios_base::binary);
boost::timer io_timer;
{
boost::archive::portable_binary_iarchive ipba (fin);
ipba & a_data;
}
return io_timer.elapsed ();
}
double do_text_out (const data_type & a_data)
{
string filename = "pba_11.txt";
ofstream fout (filename.c_str ());
boost::timer io_timer;
{
boost::archive::text_oarchive ota (fout);
ota & a_data;
}
return io_timer.elapsed ();
}
double do_text_in (data_type & a_data)
{
string filename = "pba_11.txt";
ifstream fin (filename.c_str ());
boost::timer io_timer;
{
boost::archive::text_iarchive ita (fin);
ita & a_data;
}
return io_timer.elapsed ();
}
int main (void)
{
double elapsed_time_pba_out;
double elapsed_time_text_out;
double elapsed_time_pba_in;
double elapsed_time_text_in;
data_type my_data; // A data structure to be stored then loaded.
{
// Fill the vector with random values :
size_t dim = 10000000;
my_data.values.reserve (dim);
boost::random::mt19937 rng;
boost::random::uniform_real_distribution<> flat (0.0, 100.0);
for (int i = 0; i < dim; ++i)
{
double val = flat (rng);
my_data.values.push_back (val);
}
my_data.print (clog, "Stored data in PBA and text archive");
}
{
// Store in PBA :
elapsed_time_pba_out = do_pba_out (my_data);
}
{
// Store in text archive :
elapsed_time_text_out = do_text_out (my_data);
}
{
my_data.values.clear ();
// Load from PBA :
elapsed_time_pba_in = do_pba_in (my_data);
my_data.print (clog, "Loaded data from PBA");
}
{
my_data.values.clear ();
// Load from text archive :
elapsed_time_text_in = do_text_in (my_data);
my_data.print (clog, "Loaded data from text archive");
}
clog << "PBA store I/O elapsed time : " << elapsed_time_pba_out << " (second)" << endl;
clog << "Text store I/O elapsed time : " << elapsed_time_text_out << " (second)" << endl;
clog << "PBA load I/O elapsed time : " << elapsed_time_pba_in << " (second)" << endl;
clog << "Text load I/O elapsed time : " << elapsed_time_text_in << " (second)" << endl;
return 0;
}
// end of tutorial_pba_11.cpp

View file

@ -1,105 +0,0 @@
/** tutorial_pba_2.cpp
*
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
*
* Use, modification and distribution is subject to the Boost Software
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
*/
/**
* The intent of this program is to serve as a tutorial for
* users of the portable binary archive in the framework of
* the Boost/Serialization library.
*
* This sample program shows how to use a portable binary archive
* to store/load floating point numbers including non-finite and
* special (denormalized) values.
*
*/
#include <string>
#include <fstream>
#include <limits>
#include <boost/archive/portable_binary_oarchive.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
int main (void)
{
using namespace std;
// The name for the example data file :
string filename = "pba_2.data";
{
// A normal single precision floating point number :
float pi = 3.14159265;
// Single precision zeroed floating point number :
float zero = 0.0;
// A denormalized single precision floating point number :
float tiny = 1.e-40;
// A single precision floating point number with `+Infinity' value :
float plus_infinity = numeric_limits<float>::infinity ();
// A single precision floating point number with `-Infinity' value :
float minus_infinity = -numeric_limits<float>::infinity ();
// A single precision `Not-a-Number' (NaN):
float nan = numeric_limits<float>::quiet_NaN ();
// Open an output file stream in binary mode :
ofstream fout (filename.c_str (), ios_base::binary);
{
// Create an output portable binary archive attached to the output file :
boost::archive::portable_binary_oarchive opba (fout);
// Store (serialize) variables :
opba & pi & zero & tiny & plus_infinity & minus_infinity & nan;
}
}
{
// Single precision floating point numbers to be loaded :
float x[6];
// Open an input file stream in binary mode :
ifstream fin (filename.c_str (), ios_base::binary);
{
// Create an input portable binary archive attached to the input file :
boost::archive::portable_binary_iarchive ipba (fin);
// Load (de-serialize) variables using the same
// order than for serialization :
for (int i = 0; i < 6; ++i)
{
ipba & x[i];
}
}
// Print :
for (int i = 0; i < 6; ++i)
{
cout.precision (8);
cout << "Loaded x[" << i << "] = " << x[i];
switch (fp::fpclassify(x[i]))
{
case FP_NAN: cout << " (NaN)"; break;
case FP_INFINITE: cout << " (infinite)"; break;
case FP_SUBNORMAL: cout << " (denormalized)"; break;
case FP_NORMAL: cout << " (normalized)"; break;
}
cout << endl;
}
}
return 0;
}
// end of tutorial_pba_2.cpp

View file

@ -1,70 +0,0 @@
/** tutorial_pba_3.cpp
*
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
*
* Use, modification and distribution is subject to the Boost Software
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
*/
/**
* The intent of this program is to serve as a tutorial for
* users of the portable binary archive in the framework of
* the Boost/Serialization library.
*
* This sample program shows how to use a portable binary archive
* and prevent the serialization of non-finite floating numbers.
*
*/
#include <string>
#include <fstream>
#include <limits>
#include <boost/archive/portable_binary_oarchive.hpp>
int main (void)
{
using namespace std;
// The name for the example data file :
string filename = "pba_3.data";
try
{
// An array of single precision floating numbers:
float x[5];
x[0] = 3.14159; // Pi
x[1] = 6.022e22; // Avogadro constant
x[2] = 1.6e-19; // Electron charge magnitude
x[3] = 1.e-40; // A tiny (denormalized) value
x[4] = numeric_limits<float>::infinity (); // This will fail while serializing...
// Open an output file stream in binary mode :
ofstream fout (filename.c_str (), ios_base::binary);
{
// Create an output portable binary archive attached to the output file,
// using the special 'boost::archive::no_infnan' flag :
boost::archive::portable_binary_oarchive opba (fout, boost::archive::no_infnan);
// Store (serialize) variables :
for (int i = 0; i < 5; ++i)
{
clog << "Serializing value : " << x[i] << " ... ";
opba & x[i];
clog << "Ok !" << endl;
}
}
}
catch (exception & x)
{
cerr << "ERROR: " << x.what () << endl;
return 1;
}
return 0;
}
// end of tutorial_pba_3.cpp

View file

@ -1,105 +0,0 @@
/** tutorial_pba_4.cpp
*
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
*
* Use, modification and distribution is subject to the Boost Software
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
*/
/**
* The intent of this program is to serve as a tutorial for
* users of the portable binary archive in the framework of
* the Boost/Serialization library.
*
* This sample program shows how to use a portable binary archive
* to store/load integer numbers of various sizes using the Boost
* portable integer typedefs.
*
*/
#include <string>
#include <fstream>
#include <boost/cstdint.hpp>
#include <boost/archive/portable_binary_oarchive.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
int main (void)
{
using namespace std;
// The name for the example data file :
string filename = "pba_4.data";
{
// Some integer numbers :
bool t = true;
char c = 'c';
unsigned char u = 'u';
int8_t b = -3; // char
uint8_t B = +6; // unsigned char
int16_t s = -16;
uint16_t S = +32;
int32_t l = -128;
uint32_t L = +127;
int64_t ll = -1024;
uint64_t LL = +2048;
// Open an output file stream in binary mode :
ofstream fout (filename.c_str (), ios_base::binary);
{
// Create an output portable binary archive attached to the output file :
boost::archive::portable_binary_oarchive opba (fout);
// Store (serialize) variables :
opba & t & c & u & b & B & s & S & l & L & ll & LL;
}
}
{
// Single precision floating numbers to be loaded :
// Some integer numbers :
bool t;
char c;
unsigned char u;
int8_t b;
uint8_t B;
int16_t s;
uint16_t S;
int32_t l;
uint32_t L;
int64_t ll;
uint64_t LL;
// Open an input file stream in binary mode :
ifstream fin (filename.c_str (), ios_base::binary);
{
// Create an input portable binary archive attached to the input file :
boost::archive::portable_binary_iarchive ipba (fin);
// Load (de-serialize) variables using the same
// order than for serialization :
ipba & t & c & u & b & B & s & S & l & L & ll & LL;
}
clog << "t = " << t << " (bool)" << endl;
clog << "c = '" << c << "' (char)" << endl;
clog << "u = '" << u << "' (unsigned char)" << endl;
clog << "b = " << (int) b << " (int8_t)" << endl;
clog << "B = " << (int) B << " (uint8_t)" << endl;
clog << "s = " << s << " (int16_t)" << endl;
clog << "S = " << S << " (uint16_t)" << endl;
clog << "l = " << l << " (int32_t)" << endl;
clog << "L = " << L << " (uint32_t)" << endl;
clog << "ll = " << ll << " (int64_t)" << endl;
clog << "LL = " << LL << " (uint64_t)" << endl;
}
return 0;
}
// end of tutorial_pba_4.cpp

View file

@ -1,111 +0,0 @@
/** tutorial_pba_5.cpp
*
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
*
* Use, modification and distribution is subject to the Boost Software
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
*/
/**
* The intent of this program is to serve as a tutorial for
* users of the portable binary archive in the framework of
* the Boost/Serialization library.
*
* This sample program shows how to use a portable binary archive
* to store/load data in a memory buffer.
*
*/
#include <string>
#include <vector>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/cstdint.hpp>
#include <boost/archive/portable_binary_oarchive.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
int main (void)
{
using namespace std;
// The memory buffer is implemented using a STL vector :
typedef std::vector<char> buffer_type;
buffer_type buffer;
{
// Some data to be stored :
bool t = true;
char c = 'c';
int16_t s = +16;
int32_t l = -128;
int64_t ll = +10000000000;
float pi = 3.14159;
double nan = numeric_limits<double>::quiet_NaN ();
string hello = "World !";
buffer.reserve (1024); // pre-allocate some memory
// The output stream interface to the buffer :
boost::iostreams::stream<boost::iostreams::back_insert_device<buffer_type> > output_stream (buffer);
{
// Create an output portable binary archive attached to the output file :
boost::archive::portable_binary_oarchive opba (output_stream);
// Store (serialize) variables :
opba & t & c & s & l & ll & pi & nan & hello;
}
}
clog << "Buffer content is " << buffer.size () << " bytes : " << endl << " ";
for (int i = 0; i < buffer.size (); ++i)
{
clog << (int) ((unsigned char) buffer[i]) << ' ';
if ((i + 1) % 20 == 0) clog << endl << " ";
}
clog << endl;
{
// Some data to be loaded :
bool t;
char c;
int16_t s;
int32_t l;
int64_t ll;
float pi;
double nan;
string hello;
// The input stream interface to the buffer :
boost::iostreams::stream<boost::iostreams::array_source> input_stream (&buffer[0],
buffer.size ());
{
// Create an input portable binary archive attached to the input file :
boost::archive::portable_binary_iarchive ipba (input_stream);
// Load (de-serialize) variables :
ipba & t & c & s & l & ll & pi & nan & hello;
}
clog << "Loaded values from the buffer are: " << endl;
clog << " t = " << t << " (bool)" << endl;
clog << " c = '" << c << "' (char)" << endl;
clog << " s = " << s << " (int16_t)" << endl;
clog << " l = " << l << " (int32_t)" << endl;
clog << " ll = " << ll << " (int64_t)" << endl;
clog << " pi = " << pi << " (float)" << endl;
clog << " nan = " << nan << " (double)" << endl;
clog << " hello = \"" << hello << "\" (std::string)" << endl;
}
return 0;
}
// end of tutorial_pba_5.cpp

View file

@ -1,112 +0,0 @@
/** tutorial_pba_6.cpp
*
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
*
* Use, modification and distribution is subject to the Boost Software
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
*/
/**
* The intent of this program is to serve as a tutorial for
* users of the portable binary archive in the framework of
* the Boost/Serialization library.
*
* This sample program shows how to use a portable binary archive
* associated to a memory buffer to copy a non-copyable object.
*
*/
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <boost/utility.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/cstdint.hpp>
#include <boost/archive/portable_binary_oarchive.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
using namespace std;
/* A foo noncopyable class */
struct foo : boost::noncopyable
{
uint32_t status;
double value;
double special;
string to_string () const
{
ostringstream sout;
sout << "foo={status=" << status << "; value=" << value << "; special=" << special<< "}";
return sout.str();
}
template<class Archive>
void serialize (Archive & ar, const unsigned int version)
{
ar & status;
ar & value;
ar & special;
return;
}
};
// A templatized copy function for Boost/Serialization equipped classes.
// Here we use PBAs associated to a memory buffer :
template <class Serializable>
void copy (const Serializable & source, Serializable & target)
{
namespace io = boost::iostreams;
namespace ba = boost::archive;
if (&source == &target) return; // self-copy guard
typedef std::vector<char> buffer_type;
buffer_type buffer;
buffer.reserve (1024);
{
io::stream<io::back_insert_device<buffer_type> > output_stream (buffer);
ba::portable_binary_oarchive opba (output_stream);
opba & source;
}
{
io::stream<io::array_source> input_stream (&buffer[0], buffer.size ());
ba::portable_binary_iarchive ipba (input_stream);
ipba & target;
}
return;
}
int main (void)
{
// Some instance of the 'foo' class :
foo dummy;
dummy.status = 1;
dummy.value = 3.14159;
dummy.special = numeric_limits<double>::quiet_NaN ();
clog << "dummy is : " << dummy.to_string () << endl;
// Another instance of the 'foo' class :
foo clone;
/* The following instruction is forbidden because foo
inherits 'boost::noncopyable' :
clone = dummy; // this ends in a compilation error.
*/
// Anyway, we can use this workaround :
copy (dummy, clone);
clog << "clone is : " << clone.to_string () << endl;
return 0;
}
// end of tutorial_pba_6.cpp

View file

@ -1,54 +0,0 @@
/** tutorial_pba_7.cpp
*
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
*
* Use, modification and distribution is subject to the Boost Software
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
*/
/**
* The intent of this program is to serve as a tutorial for
* users of the portable binary archive in the framework of
* the Boost/Serialization library.
*
* This example shows how the default behaviour of standard
* I/O streams does not support the read/write operations of
* non-finite floating point values in a portable way.
*
*/
#include <string>
#include <iostream>
#include <sstream>
#include <limits>
using namespace std;
int main (void)
{
{
float x = numeric_limits<float>::infinity ();
double y = numeric_limits<double>::quiet_NaN ();
cout.precision (8);
cout << "x = " << x << endl;
cout.precision (16);
cout << "y = " << y << endl;
}
{
string input ("inf nan");
istringstream iss (input);
float x;
double y;
iss >> x >> y;
if (! iss)
{
cerr << "Cannot read 'x' or 'y' : non finite values are not supported !" << endl;
}
}
return 0;
}
// end of tutorial_pba_7.cpp

View file

@ -1,118 +0,0 @@
/** tutorial_pba_8.cpp
*
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
*
* Use, modification and distribution is subject to the Boost Software
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
*/
/**
* The intent of this program is to serve as a tutorial for
* users of the portable binary archive in the framework of
* the Boost/Serialization library.
*
* This example shows how to store some variables
* of basic types (bool, integer, floating point numbers, STL string)
* using the text or XML archive format associated to a
* standard output file stream supporting portable non-finite
* floating point values.
*
*/
#include <string>
#include <fstream>
#include <limits>
#include <locale>
#include <boost/cstdint.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/archive/codecvt_null.hpp>
#include <boost/math/special_functions/nonfinite_num_facets.hpp>
using namespace std;
void do_text_out (void)
{
// The name for the example data text file :
string filename = "pba_8.txt";
// Some variables of various primitive types :
bool b = true;
char c = 'B';
uint32_t answer = 42;
float value = numeric_limits<float>::infinity ();
double precision = numeric_limits<double>::quiet_NaN ();
string question = "What makes you think she's a witch?";
// Open an output file stream :
ofstream fout (filename.c_str ());
// Prepare the output file stream for inf/NaN support :
locale default_locale (locale::classic (),
new boost::archive::codecvt_null<char>);
locale infnan_locale (default_locale,
new boost::math::nonfinite_num_put<char>);
fout.imbue (infnan_locale);
{
// Create an output text archive attached to the output file :
boost::archive::text_oarchive ota (fout, boost::archive::no_codecvt);
// Store (serializing) variables :
ota & b & c & answer & value & precision & question;
}
return;
}
void do_xml_out (void)
{
// The name for the example data XML file :
string filename = "pba_8.xml";
// Some variables of various primitive types :
bool b = true;
char c = 'B';
uint32_t answer = 42;
float value = numeric_limits<float>::infinity ();
double precision = numeric_limits<double>::quiet_NaN ();
string question = "What makes you think she's a witch?";
// Open an output file stream :
ofstream fout (filename.c_str ());
// Prepare the output file stream for inf/NaN support :
locale default_locale (locale::classic (),
new boost::archive::codecvt_null<char>);
locale infnan_locale (default_locale,
new boost::math::nonfinite_num_put<char>);
fout.imbue (infnan_locale);
{
// Create an output text archive attached to the output file :
boost::archive::xml_oarchive oxa (fout, boost::archive::no_codecvt);
// Store (serializing) variables :
oxa & BOOST_SERIALIZATION_NVP(b)
& BOOST_SERIALIZATION_NVP(c)
& BOOST_SERIALIZATION_NVP(answer)
& BOOST_SERIALIZATION_NVP(value)
& BOOST_SERIALIZATION_NVP(precision)
& BOOST_SERIALIZATION_NVP(question);
}
return;
}
int main (void)
{
do_text_out ();
do_xml_out ();
return 0;
}
// end of tutorial_pba_8.cpp

View file

@ -1,134 +0,0 @@
/** tutorial_pba_9.cpp
*
* (C) Copyright 2011 François Mauger, Christian Pfligersdorffer
*
* Use, modification and distribution is subject to the Boost Software
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
*/
/**
* The intent of this program is to serve as a tutorial for
* users of the portable binary archive in the framework of
* the Boost/Serialization library.
*
* This example shows how to load some variables of basic
* types (bool, char, integer, floating point numbers, STL string)
* using the text or XML archive format associated to a
* standard file input stream supporting portable non-finite
* floating point values.
*
*/
#include <string>
#include <fstream>
#include <limits>
#include <locale>
#include <boost/cstdint.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/archive/codecvt_null.hpp>
#include <boost/math/special_functions/nonfinite_num_facets.hpp>
using namespace std;
void do_text_in (void)
{
// The name for the example data text file :
string filename = "pba_8.txt";
// Some variables of various primitive types :
bool b;
char c;
uint32_t answer;
float value;
double precision;
string question;
// Open an input file stream :
ifstream fin (filename.c_str ());
// Prepare the input file stream for inf/NaN support :
locale default_locale (locale::classic (),
new boost::archive::codecvt_null<char>);
locale infnan_locale (default_locale,
new boost::math::nonfinite_num_get<char>);
fin.imbue (infnan_locale);
{
// Create an input text archive attached to the input file :
boost::archive::text_iarchive ita (fin, boost::archive::no_codecvt);
// Store (serializing) variables :
ita & b & c & answer & value & precision & question;
}
clog << "Loaded values from text archive are: " << endl;
clog << " b = " << b << endl;
clog << " c = '" << c << "'" << endl;
clog << " answer = " << answer << endl;
clog << " value = " << value << endl;
clog << " precision = " << precision << endl;
clog << " question = \"" << question << "\"" << endl;
return;
}
void do_xml_in (void)
{
// The name for the example data text file :
string filename = "pba_8.xml";
// Some variables of various primitive types :
bool b;
char c;
uint32_t answer;
float value;
double precision;
string question;
// Open an input file stream :
ifstream fin (filename.c_str ());
// Prepare the input file stream for inf/NaN support :
locale default_locale (locale::classic (),
new boost::archive::codecvt_null<char>);
locale infnan_locale (default_locale,
new boost::math::nonfinite_num_get<char>);
fin.imbue (infnan_locale);
{
// Create an output text archive attached to the output file :
boost::archive::xml_iarchive ixa (fin, boost::archive::no_codecvt);
// Store (serializing) variables :
ixa & BOOST_SERIALIZATION_NVP(b)
& BOOST_SERIALIZATION_NVP(c)
& BOOST_SERIALIZATION_NVP(answer)
& BOOST_SERIALIZATION_NVP(value)
& BOOST_SERIALIZATION_NVP(precision)
& BOOST_SERIALIZATION_NVP(question);
}
clog << "Loaded values from XML archive are: " << endl;
clog << " b = " << b << endl;
clog << " c = '" << c << "'" << endl;
clog << " answer = " << answer << endl;
clog << " value = " << value << endl;
clog << " precision = " << precision << endl;
clog << " question = \"" << question << "\"" << endl;
return;
}
int main (void)
{
do_text_in ();
do_xml_in ();
return 0;
}
// end of tutorial_pba_9.cpp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -1,151 +0,0 @@
/*!
* jQuery JavaScript Library v1.4
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://docs.jquery.com/License
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Wed Jan 13 15:23:05 2010 -0500
*/
(function(A,w){function oa(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(oa,1);return}c.ready()}}function La(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function $(a,b,d,f,e,i){var j=a.length;if(typeof b==="object"){for(var o in b)$(a,o,b[o],f,e,d);return a}if(d!==w){f=!i&&f&&c.isFunction(d);for(o=0;o<j;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,i);return a}return j?
e(a[0],b):null}function K(){return(new Date).getTime()}function aa(){return false}function ba(){return true}function pa(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function qa(a){var b=true,d=[],f=[],e=arguments,i,j,o,p,n,t=c.extend({},c.data(this,"events").live);for(p in t){j=t[p];if(j.live===a.type||j.altLive&&c.inArray(a.type,j.altLive)>-1){i=j.data;i.beforeFilter&&i.beforeFilter[a.type]&&!i.beforeFilter[a.type](a)||f.push(j.selector)}else delete t[p]}i=c(a.target).closest(f,a.currentTarget);
n=0;for(l=i.length;n<l;n++)for(p in t){j=t[p];o=i[n].elem;f=null;if(i[n].selector===j.selector){if(j.live==="mouseenter"||j.live==="mouseleave")f=c(a.relatedTarget).closest(j.selector)[0];if(!f||f!==o)d.push({elem:o,fn:j})}}n=0;for(l=d.length;n<l;n++){i=d[n];a.currentTarget=i.elem;a.data=i.fn.data;if(i.fn.apply(i.elem,e)===false){b=false;break}}return b}function ra(a,b){return["live",a,b.replace(/\./g,"`").replace(/ /g,"&")].join(".")}function sa(a){return!a||!a.parentNode||a.parentNode.nodeType===
11}function ta(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var i in f)for(var j in f[i])c.event.add(this,i,f[i][j],f[i][j].data)}}})}function ua(a,b,d){var f,e,i;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&a[0].indexOf("<option")<0){e=true;if(i=c.fragments[a[0]])if(i!==1)f=i}if(!f){b=b&&b[0]?b[0].ownerDocument||b[0]:s;f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=
i?f:1;return{fragment:f,cacheable:e}}function T(a){for(var b=0,d,f;(d=a[b])!=null;b++)if(!c.noData[d.nodeName.toLowerCase()]&&(f=d[H]))delete c.cache[f]}function L(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ma=A.jQuery,Na=A.$,s=A.document,U,Oa=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Pa=/^.[^:#\[\.,]*$/,Qa=/\S/,
Ra=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Sa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],M,ca=Object.prototype.toString,da=Object.prototype.hasOwnProperty,ea=Array.prototype.push,R=Array.prototype.slice,V=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(typeof a==="string")if((d=Oa.exec(a))&&(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Sa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];
c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=ua([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return U.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a)}else return!b||b.jquery?(b||U).find(a):c(b).find(a);else if(c.isFunction(a))return U.ready(a);if(a.selector!==w){this.selector=a.selector;
this.context=a.context}return c.isArray(a)?this.setArray(a):c.makeArray(a,this)},selector:"",jquery:"1.4",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){a=c(a||null);a.prevObject=this;a.context=this.context;if(b==="find")a.selector=this.selector+(this.selector?" ":"")+d;else if(b)a.selector=this.selector+"."+b+"("+d+")";return a},setArray:function(a){this.length=
0;ea.apply(this,a);return this},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||
c(null)},push:ea,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,i,j,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(i in e){j=a[i];o=e[i];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){j=j&&(c.isPlainObject(j)||c.isArray(j))?j:c.isArray(o)?[]:{};a[i]=c.extend(f,j,o)}else if(o!==w)a[i]=
o}return a};c.extend({noConflict:function(a){A.$=Na;if(a)A.jQuery=Ma;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",M,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",
M);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&oa()}}},isFunction:function(a){return ca.call(a)==="[object Function]"},isArray:function(a){return ca.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||ca.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!da.call(a,"constructor")&&!da.call(a.constructor.prototype,"isPrototypeOf"))return false;var b;for(b in a);return b===w||da.call(a,b)},
isEmptyObject:function(a){for(var b in a)return false;return true},noop:function(){},globalEval:function(a){if(a&&Qa.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,i=a.length,j=i===w||c.isFunction(a);
if(d)if(j)for(f in a){if(b.apply(a[f],d)===false)break}else for(;e<i;){if(b.apply(a[e++],d)===false)break}else if(j)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<i&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Ra,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ea.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=
0,f=b.length;d<f;d++)if(b[d]===a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,i=a.length;e<i;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,i=0,j=a.length;i<j;i++){e=b(a[i],i,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b===
"string"){d=a;a=d[b];b=w}else if(b&&!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){var b={browser:""};a=a.toLowerCase();if(/webkit/.test(a))b={browser:"webkit",version:/webkit[\/ ]([\w.]+)/};else if(/opera/.test(a))b={browser:"opera",version:/version/.test(a)?/version[\/ ]([\w.]+)/:/opera[\/ ]([\w.]+)/};else if(/msie/.test(a))b={browser:"msie",version:/msie ([\w.]+)/};else if(/mozilla/.test(a)&&
!/compatible/.test(a))b={browser:"mozilla",version:/rv:([\w.]+)/};b.version=(b.version&&b.version.exec(a)||[0,"0"])[1];return b},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=true;if(V)c.inArray=function(a,b){return V.call(b,a)};U=c(s);if(s.addEventListener)M=function(){s.removeEventListener("DOMContentLoaded",M,false);c.ready()};else if(s.attachEvent)M=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",
M);c.ready()}};if(V)c.inArray=function(a,b){return V.call(b,a)};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+K();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var e=d.getElementsByTagName("*"),i=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!i)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,
htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(i.getAttribute("style")),hrefNormalized:i.getAttribute("href")==="/a",opacity:/^0.55$/.test(i.style.opacity),cssFloat:!!i.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(j){}a.insertBefore(b,
a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function o(){c.support.noCloneEvent=false;d.detachEvent("onclick",o)});d.cloneNode(true).fireEvent("onclick")}c(function(){var o=s.createElement("div");o.style.width=o.style.paddingLeft="1px";s.body.appendChild(o);c.boxModel=c.support.boxModel=o.offsetWidth===2;s.body.removeChild(o).style.display="none"});a=function(o){var p=s.createElement("div");o="on"+o;var n=o in
p;if(!n){p.setAttribute(o,"return;");n=typeof p[o]==="function"}return n};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=i=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var H="jQuery"+K(),Ta=0,ya={},Ua={};c.extend({cache:{},expando:H,noData:{embed:true,object:true,applet:true},data:function(a,
b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?ya:a;var f=a[H],e=c.cache;if(!b&&!f)return null;f||(f=++Ta);if(typeof b==="object"){a[H]=f;e=e[f]=c.extend(true,{},b)}else e=e[f]?e[f]:typeof d==="undefined"?Ua:(e[f]={});if(d!==w){a[H]=f;e[b]=d}return typeof b==="string"?e[b]:e}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?ya:a;var d=a[H],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{try{delete a[H]}catch(i){a.removeAttribute&&
a.removeAttribute(H)}delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,
a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,
a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var za=/[\n\t]/g,fa=/\s+/,Va=/\r/g,Wa=/href|src|style/,Xa=/(button|input)/i,Ya=/(button|input|object|select|textarea)/i,Za=/^(a|area)$/i,Aa=/radio|checkbox/;c.fn.extend({attr:function(a,
b){return $(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(p){var n=c(this);n.addClass(a.call(this,p,n.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(fa),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className)for(var i=" "+e.className+" ",j=0,o=b.length;j<o;j++){if(i.indexOf(" "+b[j]+" ")<0)e.className+=
" "+b[j]}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(p){var n=c(this);n.removeClass(a.call(this,p,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(fa),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var i=(" "+e.className+" ").replace(za," "),j=0,o=b.length;j<o;j++)i=i.replace(" "+b[j]+" "," ");e.className=i.substring(1,i.length-1)}else e.className=""}return this},toggleClass:function(a,
b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var i=c(this);i.toggleClass(a.call(this,e,i.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,i=0,j=c(this),o=b,p=a.split(fa);e=p[i++];){o=f?o:!j.hasClass(e);j[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=
" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(za," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var i=b?d:0;for(d=b?d+1:e.length;i<d;i++){var j=e[i];if(j.selected){a=c(j).val();if(b)return a;f.push(a)}}return f}if(Aa.test(b.type)&&
!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Va,"")}return w}var o=c.isFunction(a);return this.each(function(p){var n=c(this),t=a;if(this.nodeType===1){if(o)t=a.call(this,p,n.val());if(typeof t==="number")t+="";if(c.isArray(t)&&Aa.test(this.type))this.checked=c.inArray(n.val(),t)>=0;else if(c.nodeName(this,"select")){var z=c.makeArray(t);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),z)>=0});if(!z.length)this.selectedIndex=
-1}else this.value=t}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var i=Wa.test(b);if(b in a&&f&&!i){if(e){if(b==="type"&&Xa.test(a.nodeName)&&a.parentNode)throw"type property can't be changed";a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;
if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Ya.test(a.nodeName)||Za.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&i?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var $a=function(a){return a.replace(/[^\w\s\.\|`]/g,function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===
3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;if(!d.guid)d.guid=c.guid++;if(f!==w){d=c.proxy(d);d.data=f}var e=c.data(a,"events")||c.data(a,"events",{}),i=c.data(a,"handle"),j;if(!i){j=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(j.elem,arguments):w};i=c.data(a,"handle",j)}if(i){i.elem=a;b=b.split(/\s+/);for(var o,p=0;o=b[p++];){var n=o.split(".");o=n.shift();d.type=n.slice(0).sort().join(".");var t=e[o],z=this.special[o]||{};if(!t){t=e[o]={};
if(!z.setup||z.setup.call(a,f,n,d)===false)if(a.addEventListener)a.addEventListener(o,i,false);else a.attachEvent&&a.attachEvent("on"+o,i)}if(z.add)if((n=z.add.call(a,d,f,n,t))&&c.isFunction(n)){n.guid=n.guid||d.guid;d=n}t[d.guid]=d;this.global[o]=true}a=null}}},global:{},remove:function(a,b,d){if(!(a.nodeType===3||a.nodeType===8)){var f=c.data(a,"events"),e,i,j;if(f){if(b===w||typeof b==="string"&&b.charAt(0)===".")for(i in f)this.remove(a,i+(b||""));else{if(b.type){d=b.handler;b=b.type}b=b.split(/\s+/);
for(var o=0;i=b[o++];){var p=i.split(".");i=p.shift();var n=!p.length,t=c.map(p.slice(0).sort(),$a);t=new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.)?")+"(\\.|$)");var z=this.special[i]||{};if(f[i]){if(d){j=f[i][d.guid];delete f[i][d.guid]}else for(var B in f[i])if(n||t.test(f[i][B].type))delete f[i][B];z.remove&&z.remove.call(a,p,j);for(e in f[i])break;if(!e){if(!z.teardown||z.teardown.call(a,p)===false)if(a.removeEventListener)a.removeEventListener(i,c.data(a,"handle"),false);else a.detachEvent&&a.detachEvent("on"+
i,c.data(a,"handle"));e=null;delete f[i]}}}}for(e in f)break;if(!e){if(B=c.data(a,"handle"))B.elem=null;c.removeData(a,"events");c.removeData(a,"handle")}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[H]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();this.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===
8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;var i=c.data(d,"handle");i&&i.apply(d,b);var j,o;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()])){j=d[e];o=d["on"+e]}}catch(p){}i=c.nodeName(d,"a")&&e==="click";if(!f&&j&&!a.isDefaultPrevented()&&!i){this.triggered=true;try{d[e]()}catch(n){}}else if(o&&d["on"+e].apply(d,b)===false)a.result=false;this.triggered=false;if(!a.isPropagationStopped())(d=d.parentNode||d.ownerDocument)&&c.event.trigger(a,b,d,true)},
handle:function(a){var b,d;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;d=a.type.split(".");a.type=d.shift();b=!d.length&&!a.exclusive;var f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)");d=(c.data(this,"events")||{})[a.type];for(var e in d){var i=d[e];if(b||f.test(i.type)){a.handler=i;a.data=i.data;i=i.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}return a.result},
props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[H])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||
s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&
a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a,b){c.extend(a,b||{});a.guid+=b.selector+b.live;c.event.add(this,b.live,qa,b)},remove:function(a){if(a.length){var b=0,d=new RegExp("(^|\\.)"+a[0]+"(\\.|$)");c.each(c.data(this,"events").live||{},function(){d.test(this.type)&&b++});b<1&&c.event.remove(this,a[0],qa)}},special:{}},beforeunload:{setup:function(a,
b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=K();this[H]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=ba;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=
ba;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=ba;this.stopPropagation()},isDefaultPrevented:aa,isPropagationStopped:aa,isImmediatePropagationStopped:aa};var Ba=function(a){for(var b=a.relatedTarget;b&&b!==this;)try{b=b.parentNode}catch(d){break}if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}},Ca=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",
mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ca:Ba,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ca:Ba)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(a,b,d){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="submit"||i==="image")&&c(e).closest("form").length)return pa("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit."+
d.guid,function(f){var e=f.target,i=e.type;if((i==="text"||i==="password")&&c(e).closest("form").length&&f.keyCode===13)return pa("submit",this,arguments)})}else return false},remove:function(a,b){c.event.remove(this,"click.specialSubmit"+(b?"."+b.guid:""));c.event.remove(this,"keypress.specialSubmit"+(b?"."+b.guid:""))}};if(!c.support.changeBubbles){var ga=/textarea|input|select/i;function Da(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>
-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d}function ha(a,b){var d=a.target,f,e;if(!(!ga.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Da(d);if(e!==f){if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",e);if(d.type!=="select"&&(f!=null||e)){a.type="change";return c.event.trigger(a,b,this)}}}}c.event.special.change={filters:{focusout:ha,click:function(a){var b=a.target,d=b.type;if(d===
"radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return ha.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return ha.call(this,a)},beforeactivate:function(a){a=a.target;a.nodeName.toLowerCase()==="input"&&a.type==="radio"&&c.data(a,"_change_data",Da(a))}},setup:function(a,b,d){for(var f in W)c.event.add(this,f+".specialChange."+d.guid,W[f]);return ga.test(this.nodeName)},
remove:function(a,b){for(var d in W)c.event.remove(this,d+".specialChange"+(b?"."+b.guid:""),W[d]);return ga.test(this.nodeName)}};var W=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,
f,e){if(typeof d==="object"){for(var i in d)this[b](i,f,d[i],e);return this}if(c.isFunction(f)){thisObject=e;e=f;f=w}var j=b==="one"?c.proxy(e,function(o){c(this).unbind(o,j);return e.apply(this,arguments)}):e;return d==="unload"&&b!=="one"?this.one(d,f,e,thisObject):this.each(function(){c.event.add(this,d,j,f)})}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&!a.preventDefault){for(var d in a)this.unbind(d,a[d]);return this}return this.each(function(){c.event.remove(this,a,b)})},trigger:function(a,
b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||
a)},live:function(a,b,d){if(c.isFunction(b)){d=b;b=w}c(this.context).bind(ra(a,this.selector),{data:b,selector:this.selector,live:a},d);return this},die:function(a,b){c(this.context).unbind(ra(a,this.selector),b?{guid:b.guid+this.selector+a}:null);return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d){return d?
this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",k,m=0;g[m];m++){k=g[m];if(k.nodeType===3||k.nodeType===4)h+=k.nodeValue;else if(k.nodeType!==8)h+=a(k.childNodes)}return h}function b(g,h,k,m,r,q){r=0;for(var v=m.length;r<v;r++){var u=m[r];if(u){u=u[g];for(var y=false;u;){if(u.sizcache===
k){y=m[u.sizset];break}if(u.nodeType===1&&!q){u.sizcache=k;u.sizset=r}if(u.nodeName.toLowerCase()===h){y=u;break}u=u[g]}m[r]=y}}}function d(g,h,k,m,r,q){r=0;for(var v=m.length;r<v;r++){var u=m[r];if(u){u=u[g];for(var y=false;u;){if(u.sizcache===k){y=m[u.sizset];break}if(u.nodeType===1){if(!q){u.sizcache=k;u.sizset=r}if(typeof h!=="string"){if(u===h){y=true;break}}else if(p.filter(h,[u]).length>0){y=u;break}}u=u[g]}m[r]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
e=0,i=Object.prototype.toString,j=false,o=true;[0,0].sort(function(){o=false;return 0});var p=function(g,h,k,m){k=k||[];var r=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return k;for(var q=[],v,u,y,S,I=true,N=x(h),J=g;(f.exec(""),v=f.exec(J))!==null;){J=v[3];q.push(v[1]);if(v[2]){S=v[3];break}}if(q.length>1&&t.exec(g))if(q.length===2&&n.relative[q[0]])u=ia(q[0]+q[1],h);else for(u=n.relative[q[0]]?[h]:p(q.shift(),h);q.length;){g=q.shift();if(n.relative[g])g+=q.shift();
u=ia(g,u)}else{if(!m&&q.length>1&&h.nodeType===9&&!N&&n.match.ID.test(q[0])&&!n.match.ID.test(q[q.length-1])){v=p.find(q.shift(),h,N);h=v.expr?p.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:q.pop(),set:B(m)}:p.find(q.pop(),q.length===1&&(q[0]==="~"||q[0]==="+")&&h.parentNode?h.parentNode:h,N);u=v.expr?p.filter(v.expr,v.set):v.set;if(q.length>0)y=B(u);else I=false;for(;q.length;){var E=q.pop();v=E;if(n.relative[E])v=q.pop();else E="";if(v==null)v=h;n.relative[E](y,v,N)}}else y=[]}y||(y=u);if(!y)throw"Syntax error, unrecognized expression: "+
(E||g);if(i.call(y)==="[object Array]")if(I)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&F(h,y[g])))k.push(u[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&k.push(u[g]);else k.push.apply(k,y);else B(y,k);if(S){p(S,r,k,m);p.uniqueSort(k)}return k};p.uniqueSort=function(g){if(D){j=o;g.sort(D);if(j)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};p.matches=function(g,h){return p(g,null,null,h)};p.find=function(g,h,k){var m,r;if(!g)return[];
for(var q=0,v=n.order.length;q<v;q++){var u=n.order[q];if(r=n.leftMatch[u].exec(g)){var y=r[1];r.splice(1,1);if(y.substr(y.length-1)!=="\\"){r[1]=(r[1]||"").replace(/\\/g,"");m=n.find[u](r,h,k);if(m!=null){g=g.replace(n.match[u],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};p.filter=function(g,h,k,m){for(var r=g,q=[],v=h,u,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var I in n.filter)if((u=n.leftMatch[I].exec(g))!=null&&u[2]){var N=n.filter[I],J,E;E=u[1];y=false;u.splice(1,1);if(E.substr(E.length-
1)!=="\\"){if(v===q)q=[];if(n.preFilter[I])if(u=n.preFilter[I](u,v,k,q,m,S)){if(u===true)continue}else y=J=true;if(u)for(var X=0;(E=v[X])!=null;X++)if(E){J=N(E,u,X,v);var Ea=m^!!J;if(k&&J!=null)if(Ea)y=true;else v[X]=false;else if(Ea){q.push(E);y=true}}if(J!==w){k||(v=q);g=g.replace(n.match[I],"");if(!y)return[];break}}}if(g===r)if(y==null)throw"Syntax error, unrecognized expression: "+g;else break;r=g}return v};var n=p.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
relative:{"+":function(g,h){var k=typeof h==="string",m=k&&!/\W/.test(h);k=k&&!m;if(m)h=h.toLowerCase();m=0;for(var r=g.length,q;m<r;m++)if(q=g[m]){for(;(q=q.previousSibling)&&q.nodeType!==1;);g[m]=k||q&&q.nodeName.toLowerCase()===h?q||false:q===h}k&&p.filter(h,g,true)},">":function(g,h){var k=typeof h==="string";if(k&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,r=g.length;m<r;m++){var q=g[m];if(q){k=q.parentNode;g[m]=k.nodeName.toLowerCase()===h?k:false}}}else{m=0;for(r=g.length;m<r;m++)if(q=g[m])g[m]=
k?q.parentNode:q.parentNode===h;k&&p.filter(h,g,true)}},"":function(g,h,k){var m=e++,r=d;if(typeof h==="string"&&!/\W/.test(h)){var q=h=h.toLowerCase();r=b}r("parentNode",h,m,g,q,k)},"~":function(g,h,k){var m=e++,r=d;if(typeof h==="string"&&!/\W/.test(h)){var q=h=h.toLowerCase();r=b}r("previousSibling",h,m,g,q,k)}},find:{ID:function(g,h,k){if(typeof h.getElementById!=="undefined"&&!k)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var k=[];
h=h.getElementsByName(g[1]);for(var m=0,r=h.length;m<r;m++)h[m].getAttribute("name")===g[1]&&k.push(h[m]);return k.length===0?null:k}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,k,m,r,q){g=" "+g[1].replace(/\\/g,"")+" ";if(q)return g;q=0;for(var v;(v=h[q])!=null;q++)if(v)if(r^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))k||m.push(v);else if(k)h[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,k,m,r,q){h=g[1].replace(/\\/g,"");if(!q&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,k,m,r){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=p(g[3],null,null,h);else{g=p.filter(g[3],h,k,true^r);k||m.push.apply(m,
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,k){return!!p(k[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
setFilters:{first:function(g,h){return h===0},last:function(g,h,k,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,k){return h<k[3]-0},gt:function(g,h,k){return h>k[3]-0},nth:function(g,h,k){return k[3]-0===h},eq:function(g,h,k){return k[3]-0===h}},filter:{PSEUDO:function(g,h,k,m){var r=h[1],q=n.filters[r];if(q)return q(g,k,h,m);else if(r==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(r==="not"){h=
h[3];k=0;for(m=h.length;k<m;k++)if(h[k]===g)return false;return true}else throw"Syntax error, unrecognized expression: "+r;},CHILD:function(g,h){var k=h[1],m=g;switch(k){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(k==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":k=h[2];var r=h[3];if(k===1&&r===0)return true;h=h[0];var q=g.parentNode;if(q&&(q.sizcache!==h||!g.nodeIndex)){var v=0;for(m=q.firstChild;m;m=
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;q.sizcache=h}g=g.nodeIndex-r;return k===0?g===0:g%k===0&&g/k>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var k=h[1];g=n.attrHandle[k]?n.attrHandle[k](g):g[k]!=null?g[k]:g.getAttribute(k);k=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
"="?k===h:m==="*="?k.indexOf(h)>=0:m==="~="?(" "+k+" ").indexOf(h)>=0:!h?k&&g!==false:m==="!="?k!==h:m==="^="?k.indexOf(h)===0:m==="$="?k.substr(k.length-h.length)===h:m==="|="?k===h||k.substr(0,h.length+1)===h+"-":false},POS:function(g,h,k,m){var r=n.setFilters[h[2]];if(r)return r(g,k,h,m)}}},t=n.match.POS;for(var z in n.match){n.match[z]=new RegExp(n.match[z].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[z]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[z].source.replace(/\\(\d+)/g,function(g,
h){return"\\"+(h-0+1)}))}var B=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){B=function(g,h){h=h||[];if(i.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var k=0,m=g.length;k<m;k++)h.push(g[k]);else for(k=0;g[k];k++)h.push(g[k]);return h}}var D;if(s.documentElement.compareDocumentPosition)D=function(g,h){if(!g.compareDocumentPosition||
!h.compareDocumentPosition){if(g==h)j=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)j=true;return g};else if("sourceIndex"in s.documentElement)D=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)j=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)j=true;return g};else if(s.createRange)D=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)j=true;return g.ownerDocument?-1:1}var k=g.ownerDocument.createRange(),m=
h.ownerDocument.createRange();k.setStart(g,0);k.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=k.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)j=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var k=s.documentElement;k.insertBefore(g,k.firstChild);if(s.getElementById(h)){n.find.ID=function(m,r,q){if(typeof r.getElementById!=="undefined"&&!q)return(r=r.getElementById(m[1]))?r.id===m[1]||typeof r.getAttributeNode!=="undefined"&&
r.getAttributeNode("id").nodeValue===m[1]?[r]:w:[]};n.filter.ID=function(m,r){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===r}}k.removeChild(g);k=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,k){k=k.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;k[m];m++)k[m].nodeType===1&&h.push(k[m]);k=h}return k};g.innerHTML="<a href='#'></a>";
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=p,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){p=function(m,r,q,v){r=r||s;if(!v&&r.nodeType===9&&!x(r))try{return B(r.querySelectorAll(m),q)}catch(u){}return g(m,r,q,v)};for(var k in g)p[k]=g[k];h=null}}();
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,k,m){if(typeof k.getElementsByClassName!=="undefined"&&!m)return k.getElementsByClassName(h[1])};g=null}}})();var F=s.compareDocumentPosition?function(g,h){return g.compareDocumentPosition(h)&16}:function(g,
h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ia=function(g,h){var k=[],m="",r;for(h=h.nodeType?[h]:h;r=n.match.PSEUDO.exec(g);){m+=r[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;r=0;for(var q=h.length;r<q;r++)p(g,h[r],k);return p.filter(m,k)};c.find=p;c.expr=p.selectors;c.expr[":"]=c.expr.filters;c.unique=p.uniqueSort;c.getText=a;c.isXMLDoc=x;c.contains=F})();var ab=/Until$/,bb=/^(?:parents|prevUntil|prevAll)/,
cb=/,/;R=Array.prototype.slice;var Fa=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,i){return!!b.call(e,i,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Pa.test(b))return c.filter(b,f,!d);else b=c.filter(b,a)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
c.find(a,this[f],b);if(f>0)for(var i=d;i<b.length;i++)for(var j=0;j<d;j++)if(b[j]===b[i]){b.splice(i--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Fa(this,a,false),"not",a)},filter:function(a){return this.pushStack(Fa(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,i=
{},j;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){j=a[e];i[j]||(i[j]=c.expr.match.POS.test(j)?c(j,b||this.context):j)}for(;f&&f.ownerDocument&&f!==b;){for(j in i){e=i[j];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:j,elem:f});delete i[j]}}f=f.parentNode}}return d}var p=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,t){for(;t&&t.ownerDocument&&t!==b;){if(p?p.index(t)>-1:c(t).is(a))return t;t=t.parentNode}return null})},index:function(a){if(!a||typeof a===
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(sa(a[0])||sa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);ab.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||cb.test(f))&&bb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||!c(a).is(d));){a.nodeType===
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ga=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,db=/(<([\w:]+)[^>]*?)\/>/g,eb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,Ha=/<([\w:]+)/,fb=/<tbody/i,gb=/<|&\w+;/,hb=function(a,b,d){return eb.test(d)?a:b+"></"+d+">"},G={option:[1,"<select multiple='multiple'>","</select>"],
legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};G.optgroup=G.option;G.tbody=G.tfoot=G.colgroup=G.caption=G.thead;G.th=G.td;if(!c.support.htmlSerialize)G._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);
return d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.getText(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&
this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,
"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ga,"").replace(Y,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ta(this,b);ta(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===
1?this[0].innerHTML.replace(Ga,""):null;else if(typeof a==="string"&&!/<script/i.test(a)&&(c.support.leadingWhitespace||!Y.test(a))&&!G[(Ha.exec(a)||["",""])[1].toLowerCase()])try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){T(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}else c.isFunction(a)?this.each(function(e){var i=c(this),j=i.html();i.empty().append(function(){return a.call(this,e,j)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
this[0].parentNode){c.isFunction(a)||(a=c(a).detach());return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(t){return c.nodeName(t,"table")?t.getElementsByTagName("tbody")[0]||t.appendChild(t.ownerDocument.createElement("tbody")):t}var e,i,j=a[0],o=[];if(c.isFunction(j))return this.each(function(t){var z=
c(this);a[0]=j.call(this,t,b?z.html():w);return z.domManip(a,b,d)});if(this[0]){e=a[0]&&a[0].parentNode&&a[0].parentNode.nodeType===11?{fragment:a[0].parentNode}:ua(a,this,o);if(i=e.fragment.firstChild){b=b&&c.nodeName(i,"tr");for(var p=0,n=this.length;p<n;p++)d.call(b?f(this[p],i):this[p],e.cacheable||this.length>1||p>0?e.fragment.cloneNode(true):e.fragment)}o&&c.each(o,La)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},
function(a,b){c.fn[a]=function(d){var f=[];d=c(d);for(var e=0,i=d.length;e<i;e++){var j=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),j);f=f.concat(j)}return this.pushStack(f,a,d.selector)}});c.each({remove:function(a,b){if(!a||c.filter(a,[this]).length){if(!b&&this.nodeType===1){T(this.getElementsByTagName("*"));T([this])}this.parentNode&&this.parentNode.removeChild(this)}},empty:function(){for(this.nodeType===1&&T(this.getElementsByTagName("*"));this.firstChild;)this.removeChild(this.firstChild)}},
function(a,b){c.fn[a]=function(){return this.each(b,arguments)}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;var e=[];c.each(a,function(i,j){if(typeof j==="number")j+="";if(j){if(typeof j==="string"&&!gb.test(j))j=b.createTextNode(j);else if(typeof j==="string"){j=j.replace(db,hb);var o=(Ha.exec(j)||["",""])[1].toLowerCase(),p=G[o]||G._default,n=p[0];i=b.createElement("div");for(i.innerHTML=p[1]+j+p[2];n--;)i=i.lastChild;
if(!c.support.tbody){n=fb.test(j);o=o==="table"&&!n?i.firstChild&&i.firstChild.childNodes:p[1]==="<table>"&&!n?i.childNodes:[];for(p=o.length-1;p>=0;--p)c.nodeName(o[p],"tbody")&&!o[p].childNodes.length&&o[p].parentNode.removeChild(o[p])}!c.support.leadingWhitespace&&Y.test(j)&&i.insertBefore(b.createTextNode(Y.exec(j)[0]),i.firstChild);j=c.makeArray(i.childNodes)}if(j.nodeType)e.push(j);else e=c.merge(e,j)}});if(d)for(a=0;e[a];a++)if(f&&c.nodeName(e[a],"script")&&(!e[a].type||e[a].type.toLowerCase()===
"text/javascript"))f.push(e[a].parentNode?e[a].parentNode.removeChild(e[a]):e[a]);else{e[a].nodeType===1&&e.splice.apply(e,[a+1,0].concat(c.makeArray(e[a].getElementsByTagName("script"))));d.appendChild(e[a])}return e}});var ib=/z-?index|font-?weight|opacity|zoom|line-?height/i,Ia=/alpha\([^)]*\)/,Ja=/opacity=([^)]*)/,ja=/float/i,ka=/-([a-z])/ig,jb=/([A-Z])/g,kb=/^-?\d+(?:px)?$/i,lb=/^-?\d/,mb={position:"absolute",visibility:"hidden",display:"block"},nb=["Left","Right"],ob=["Top","Bottom"],pb=s.defaultView&&
s.defaultView.getComputedStyle,Ka=c.support.cssFloat?"cssFloat":"styleFloat",la=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return $(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!ib.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""===
"NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=Ia.test(a)?a.replace(Ia,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Ja.exec(f.filter)[1])/100+"":""}if(ja.test(b))b=Ka;b=b.replace(ka,la);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,i=b==="width"?nb:ob;function j(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(i,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=
parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,"border"+this+"Width",true))||0})}a.offsetWidth!==0?j():c.swap(a,mb,j);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Ja.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ja.test(b))b=Ka;if(!d&&e&&e[b])f=e[b];else if(pb){if(ja.test(b))b="float";b=b.replace(jb,"-$1").toLowerCase();e=
a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ka,la);f=a.currentStyle[b]||a.currentStyle[d];if(!kb.test(f)&&lb.test(f)){b=e.left;var i=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=i}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=
f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var qb=K(),rb=/<script(.|\s)*?\/script>/gi,sb=/select|textarea/i,tb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,O=/=\?(&|$)/,ma=/\?/,ub=/(\?|&)_=.*?(&|$)/,vb=/^(\w+:)?\/\/([^\/?#]+)/,
wb=/%20/g;c.fn.extend({_load:c.fn.load,load:function(a,b,d){if(typeof a!=="string")return this._load(a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}c.ajax({url:a,type:f,dataType:"html",data:b,context:this,complete:function(i,j){if(j==="success"||j==="notmodified")this.html(e?c("<div />").append(i.responseText.replace(rb,
"")).find(e):i.responseText);d&&this.each(d,[i.responseText,j,i])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||sb.test(this.nodeName)||tb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});
c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},
ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",
text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&e.success.call(p,o,j,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(p,x,j);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(r,q){(e.context?c(e.context):c.event).trigger(r,q)}var e=c.extend(true,{},c.ajaxSettings,a),i,j,o,p=e.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,
e.traditional);if(e.dataType==="jsonp"){if(n==="GET")O.test(e.url)||(e.url+=(ma.test(e.url)?"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!O.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&O.test(e.data)||O.test(e.url))){i=e.jsonpCallback||"jsonp"+qb++;if(e.data)e.data=(e.data+"").replace(O,"="+i+"$1");e.url=e.url.replace(O,"="+i+"$1");e.dataType="script";A[i]=A[i]||function(r){o=r;b();d();A[i]=w;try{delete A[i]}catch(q){}B&&
B.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===false&&n==="GET"){var t=K(),z=e.url.replace(ub,"$1_="+t+"$2");e.url=z+(z===e.url?(ma.test(e.url)?"&":"?")+"_="+t:"")}if(e.data&&n==="GET")e.url+=(ma.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");t=(t=vb.exec(e.url))&&(t[1]&&t[1]!==location.protocol||t[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&t){var B=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");
C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!i){var D=false;C.onload=C.onreadystatechange=function(){if(!D&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){D=true;b();d();C.onload=C.onreadystatechange=null;B&&C.parentNode&&B.removeChild(C)}}}B.insertBefore(C,B.firstChild);return w}var F=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",
e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}t||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ia){}if(e.beforeSend&&e.beforeSend.call(p,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",
[x,e]);var g=x.onreadystatechange=function(r){if(!x||x.readyState===0){F||d();F=true;if(x)x.onreadystatechange=c.noop}else if(!F&&x&&(x.readyState===4||r==="timeout")){F=true;x.onreadystatechange=c.noop;j=r==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";if(j==="success")try{o=c.httpData(x,e.dataType,e)}catch(q){j="parsererror"}if(j==="success"||j==="notmodified")i||b();else c.handleError(e,x,j);d();r==="timeout"&&x.abort();if(e.async)x=
null}};try{var h=x.abort;x.abort=function(){if(x){h.call(x);if(x)x.readyState=0}g()}}catch(k){}e.async&&e.timeout>0&&setTimeout(function(){x&&!F&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||A,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol===
"file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;if(e&&a.documentElement.nodeName==="parsererror")throw"parsererror";if(d&&
d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&f.indexOf("json")>=0)if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))a=A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+a))();else throw"Invalid JSON: "+a;else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(e,i){i=
c.isFunction(i)?i():i;f[f.length]=encodeURIComponent(e)+"="+encodeURIComponent(i)}var f=[];if(b===w)b=c.ajaxSettings.traditional;c.isArray(a)||a.jquery?c.each(a,function(){d(this.name,this.value)}):c.each(a,function e(i,j){if(c.isArray(j))c.each(j,function(o,p){b?d(i,p):e(i+"["+(typeof p==="object"||c.isArray(p)?o:"")+"]",p)});else!b&&j!=null&&typeof j==="object"?c.each(j,function(o,p){e(i+"["+o+"]",p)}):d(i,j)});return f.join("&").replace(wb,"+")}});var na={},xb=/toggle|show|hide/,yb=/^([+-]=)?([\d+-.]+)(.*)$/,
Z,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a!=null)return this.animate(L("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(na[d])f=na[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();
na[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a!=null)return this.animate(L("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&
c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(L("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var i=c.extend({},e),j,o=this.nodeType===1&&c(this).is(":hidden"),
p=this;for(j in a){var n=j.replace(ka,la);if(j!==n){a[n]=a[j];delete a[j];j=n}if(a[j]==="hide"&&o||a[j]==="show"&&!o)return i.complete.call(this);if((j==="height"||j==="width")&&this.style){i.display=c.css(this,"display");i.overflow=this.style.overflow}if(c.isArray(a[j])){(i.specialEasing=i.specialEasing||{})[j]=a[j][1];a[j]=a[j][0]}}if(i.overflow!=null)this.style.overflow="hidden";i.curAnim=c.extend({},a);c.each(a,function(t,z){var B=new c.fx(p,i,t);if(xb.test(z))B[z==="toggle"?o?"show":"hide":z](a);
else{var C=yb.exec(z),D=B.cur(true)||0;if(C){z=parseFloat(C[2]);var F=C[3]||"px";if(F!=="px"){p.style[t]=(z||1)+F;D=(z||1)/B.cur(true)*D;p.style[t]=D+F}if(C[1])z=(C[1]==="-="?-1:1)*z+D;B.custom(D,z,F)}else B.custom(D,z,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:L("show",1),slideUp:L("hide",1),slideToggle:L("toggle",
1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration==="number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,
b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==
null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(i){return e.step(i)}this.startTime=K();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!Z)Z=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop===
"width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=K(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=
this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=
c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},stop:function(){clearInterval(Z);Z=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=
null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),
f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(t){c.offset.setOffset(this,a,t)});if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=
b,e=b.ownerDocument,i,j=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var p=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==j;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;i=e?e.getComputedStyle(b,null):b.currentStyle;p-=b.scrollTop;n-=b.scrollLeft;if(b===d){p+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){p+=parseFloat(i.borderTopWidth)||
0;n+=parseFloat(i.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&i.overflow!=="visible"){p+=parseFloat(i.borderTopWidth)||0;n+=parseFloat(i.borderLeftWidth)||0}f=i}if(f.position==="relative"||f.position==="static"){p+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&f.position==="fixed"){p+=Math.max(j.scrollTop,o.scrollTop);n+=Math.max(j.scrollLeft,o.scrollLeft)}return{top:p,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),
d,f,e,i=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);
d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i;a.removeChild(b);c.offset.initialize=c.noop},
bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),i=parseInt(c.curCSS(a,"top",true),10)||0,j=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,d,e);d={top:b.top-e.top+i,left:b.left-
e.left+j};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=
this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],i;if(!e)return null;if(f!==w)return this.each(function(){if(i=wa(this))i.scrollTo(!a?f:c(i).scrollLeft(),a?f:c(i).scrollTop());else this[d]=f});else return(i=wa(e))?"pageXOffset"in i?i[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&i.document.documentElement[d]||i.document.body[d]:e[d]}});
c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;return"scrollTo"in e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+
b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);

View file

@ -1,39 +0,0 @@
/*=============================================================================
Copyright 2002 William E. Kempf
Distributed under the Boost Software License, Version 1.0. (See accompany-
ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
H1
{
FONT-SIZE: 200%;
COLOR: #00008B;
}
H2
{
FONT-SIZE: 150%;
}
H3
{
FONT-SIZE: 125%;
}
H4
{
FONT-SIZE: 108%;
}
/*
BODY
{
FONT-SIZE: 100%;
BACKGROUND-COLOR: #ffffff;
COLOR: #000000;
}
*/
/*
PRE
{
MARGIN-LEFT: 2em;
FONT-FAMILY: Courier,
monospace;
}
*/

View file

@ -1,92 +0,0 @@
body
{
font-size: 12pt;
}
pre
{
border-right: gray 1pt solid;
border-top: gray 1pt solid;
border-left: gray 1pt solid;
border-bottom: gray 1pt solid;
margin-left: 0pt;
background-color: #EEEEEE;
font-size: smaller;
}
.button
{
color : black;
background-color : #FFFFFF;
border-radius: 0px;
border: outset 3px #d6d6d6;
text-decoration : none;
outline:none;
}
.fs
{
font-family: courier;
font-size: 11pt;
font-weight: bold;
color: maroon;
}
.code_string
{
font-family: courier;
font-size: 11pt;
font-weight: bold;
color: #bc8f8f;
}
.code
{
/*
top: 0;
border-style: inset;
margin-top: 5pt;
margin-bottom: 5pt;
margin-left: 5pt;
margin-right: 5pt;
border-width: 2px 2px 2px 2px ;
*/
font-family: courier;
font-size: 11pt;
font-weight: bold;
color: #228b22;
}
.byte
{
border-right: gray 1pt solid;
border-top: gray 1pt solid;
border-left: gray 1pt solid;
border-bottom: gray 1pt solid;
margin-left: 2pt;
margin-right: 2pt;
font-family: courier;
font-size: 11pt;
font-weight: bold;
color: #000000;
background-color: #eeeeee;
}
#pre
{
border-right: gray 1pt solid;
border-top: gray 1pt solid;
border-left: gray 1pt solid;
border-bottom: gray 1pt solid;
margin-left: 1pt;
margin-right: 1pt;
background-color: #EEEEEE;
}
/*
(C) Copyright 2011 François Mauger.
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/

File diff suppressed because it is too large Load diff

View file

@ -478,7 +478,7 @@ namespace epee
bool run_handling(const std::string& prompt, const std::string& usage_string)
{
return m_console_handler.run(boost::bind(&console_handlers_binder::process_command_str, this, _1), prompt, usage_string);
return m_console_handler.run(boost::bind(&console_handlers_binder::process_command_str, this, boost::placeholders::_1), prompt, usage_string);
}
bool help(const std::vector<std::string>& /*args*/)

View file

@ -77,6 +77,32 @@ namespace epee
namespace misc_utils
{
template<class _Ty1,
class _Ty2,
class _Ty3>
struct triple
{ // store a pair of values
typedef _Ty1 first_type;
typedef _Ty2 second_type;
typedef _Ty3 third_type;
triple()
: first(), second(), third()
{ // default construct
}
triple(const _Ty1& _Val1, const _Ty2& _Val2, const _Ty3& _Val3)
: first(_Val1), second(_Val2), third(_Val3)
{ // construct from specified values
}
_Ty1 first; // the first stored value
_Ty2 second; // the second stored value
_Ty3 third; // the second stored value
};
template<typename t_type>
t_type get_max_t_val(t_type t)
{

View file

@ -61,7 +61,7 @@ DISABLE_VS_WARNINGS(4100)
#include "misc_helpers.h"
#include "static_initializer.h"
#include "static_helpers.h"
#include "string_tools.h"
#include "time_helper.h"
#include "misc_os_dependent.h"
@ -946,8 +946,8 @@ namespace log_space
typedef std::map<std::string, uint64_t> channels_err_stat_container_type;
inline epee::locked_object_proxy<channels_err_stat_container_type> get_channels_errors_stat_container()
{
static std::recursive_mutex cs;
static channels_err_stat_container_type errors_by_channel;
static epee::static_helpers::wrapper<std::recursive_mutex> cs;
static epee::static_helpers::wrapper<channels_err_stat_container_type> errors_by_channel;
epee::locked_object_proxy<channels_err_stat_container_type> res(errors_by_channel, cs);
return res;
}
@ -1194,7 +1194,7 @@ namespace log_space
class log_singletone
{
public:
friend class initializer<log_singletone>;
friend class static_helpers::initializer<log_singletone>;
friend class logger;
static int get_log_detalisation_level()
{
@ -1205,7 +1205,7 @@ namespace log_space
//get_enabled_channels not thread-safe, at the moment leave it like this because it's configured in main, before other threads started
static std::set<std::string>& get_enabled_channels()
{
static std::set<std::string> genabled_channels;
static epee::static_helpers::wrapper<std::set<std::string>> genabled_channels;
return genabled_channels;
}
@ -1611,7 +1611,7 @@ POP_GCC_WARNINGS
//static int get_set_error_filter(bool is_need_set = false)
};
const static initializer<log_singletone> log_initializer;
const static static_helpers::initializer<log_singletone> log_initializer;
/************************************************************************/
/* */
// /************************************************************************/

View file

@ -44,12 +44,17 @@ namespace epee
const static global_regexp_critical_section gregexplock;
inline const boost::regex* build_regexp(const char* p, boost::regex::flag_type f)
{
return new boost::regex(p, f);
}
#define STATIC_REGEXP_EXPR_1(var_name, xpr_text, reg_exp_flags) \
static volatile uint32_t regexp_initialized_1 = 0;\
volatile uint32_t local_is_initialized_1 = regexp_initialized_1;\
if(!local_is_initialized_1)\
gregexplock.get_lock().lock();\
static const boost::regex var_name(xpr_text , reg_exp_flags);\
static const boost::regex& var_name = *build_regexp(xpr_text, reg_exp_flags);\
if(!local_is_initialized_1)\
{\
boost::interprocess::ipcdetail::atomic_write32(&regexp_initialized_1, 1);\
@ -61,19 +66,32 @@ namespace epee
volatile uint32_t local_is_initialized_2 = regexp_initialized_2;\
if(!local_is_initialized_2)\
gregexplock.get_lock().lock().lock();\
static const boost::regex var_name(xpr_text , reg_exp_flags);\
static const boost::regex& var_name = *build_regexp(xpr_text, reg_exp_flags);\
if(!local_is_initialized_2)\
{\
boost::interprocess::ipcdetail::atomic_write32(&regexp_initialized_2, 1);\
gregexplock.get_lock().lock().unlock();\
}
// #define STATIC_REGEXP_EXPR_2(var_name, xpr_text, reg_exp_flags) \
// static volatile uint32_t regexp_initialized_2 = 0;\
// volatile uint32_t local_is_initialized_2 = regexp_initialized_2;\
// if(!local_is_initialized_2)\
// gregexplock.get_lock().lock().lock();\
// static const boost::regex var_name(xpr_text , reg_exp_flags);\
// if(!local_is_initialized_2)\
// {\
// boost::interprocess::ipcdetail::atomic_write32(&regexp_initialized_2, 1);\
// gregexplock.get_lock().lock().unlock();\
// }
#define STATIC_REGEXP_EXPR_3(var_name, xpr_text, reg_exp_flags) \
static volatile uint32_t regexp_initialized_3 = 0;\
volatile uint32_t local_is_initialized_3 = regexp_initialized_3;\
if(!local_is_initialized_3)\
gregexplock.get_lock().lock().lock();\
static const boost::regex var_name(xpr_text , reg_exp_flags);\
static const boost::regex& var_name = *build_regexp(xpr_text, reg_exp_flags);\
if(!local_is_initialized_3)\
{\
boost::interprocess::ipcdetail::atomic_write32(&regexp_initialized_3, 1);\

View file

@ -84,6 +84,12 @@ namespace epee
return res;
}
//-------------------------------------------------------------------------------------------------------------------
#pragma pack(push, 1)
template<class first_t, class second_t>
struct pod_pair
{
first_t first;
second_t second;
};
#pragma pack(pop)
}

View file

@ -31,7 +31,7 @@
#pragma once
#include <memory>
#include "static_helpers.h"
template<class owned_object_t>
class abstract_singleton
@ -39,7 +39,7 @@ class abstract_singleton
static std::shared_ptr<owned_object_t> get_set_instance_internal(bool is_need_set = false, owned_object_t* pnew_obj = nullptr)
{
static std::shared_ptr<owned_object_t> val_pobj;
static epee::static_helpers::wrapper<std::shared_ptr<owned_object_t>> val_pobj;
if (is_need_set)
val_pobj.reset(pnew_obj);

View file

@ -1,4 +1,4 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// Copyright (c) 2006-2020, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@ -26,59 +26,76 @@
#ifndef _STATIC_INITIALIZER_H_
#define _STATIC_INITIALIZER_H_
#pragma once
#include <limits>
#include <set>
#include <iterator>
#include <boost/thread.hpp>
#include "include_base_utils.h"
#include "auto_val_init.h"
#define DEFINE_SECURE_STATIC_VAR(type, var) static epee::static_helpers::wrapper<type> var##inst; \
static type& var = var##inst;
namespace epee
{
/***********************************************************************
class initializer - useful to initialize some static classes
which have init() and un_init() static members
************************************************************************/
namespace static_helpers
{
template<class to_initialize>
class initializer
{
public:
initializer()
{
to_initialize::init();
//get_set_is_initialized(true, true);
}
~initializer()
{
to_initialize::un_init();
//get_set_is_uninitialized(true, true);
}
};
typedef void(*static_destroy_handler_type)();
template<class to_initialize>
class initializer
{
public:
initializer()
{
to_initialize::init();
//get_set_is_initialized(true, true);
}
~initializer()
{
to_initialize::un_init();
//get_set_is_uninitialized(true, true);
}
inline
bool set_or_call_on_destruct(bool set = false, static_destroy_handler_type destr_ptr = nullptr)
{
volatile static bool deinit_called = false;
volatile static static_destroy_handler_type static_destroy_handler = nullptr;
if (set)
{
static_destroy_handler = destr_ptr;
return true;
}
if (!deinit_called)
{
if (static_destroy_handler)
static_destroy_handler();
deinit_called = true;
}
return true;
}
template<class t_base>
struct wrapper : public t_base
{
~wrapper()
{
set_or_call_on_destruct();
}
};
}
/*static inline bool is_initialized()
{
return get_set_is_initialized();
}
static inline bool is_uninitialized()
{
return get_set_is_uninitialized();
}
private:
static inline bool get_set_is_initialized(bool need_to_set = false, bool val_to_set= false)
{
static bool val_is_initialized = false;
if(need_to_set)
val_is_initialized = val_to_set;
return val_is_initialized;
}
static inline bool get_set_is_uninitialized(bool need_to_set = false, bool val_to_set = false)
{
static bool val_is_uninitialized = false;
if(need_to_set)
val_is_uninitialized = val_to_set;
return val_is_uninitialized;
}*/
};
}
#endif //_STATIC_INITIALIZER_H_

View file

@ -37,6 +37,8 @@
#endif
#include <windows.h>
#endif
#include "warnings.h"
namespace epee
{
@ -59,8 +61,10 @@ namespace string_encoding
inline std::string convert_to_ansii(const std::wstring& str_from)
{
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4244)
std::string res(str_from.begin(), str_from.end());
POP_VS_WARNINGS
return res;
}
#ifdef WIN32

View file

@ -603,6 +603,14 @@ POP_GCC_WARNINGS
s = *(t_pod_type*)bin_buff.data();
return true;
}
//----------------------------------------------------------------------------
template<class t_pod_type>
t_pod_type hex_to_pod(const std::string& hex_str)
{
t_pod_type p = AUTO_VAL_INIT(p);
hex_to_pod(hex_str, p);
return p;
}
//----------------------------------------------------------------------------
inline std::string get_extension(const std::string& str)
{

View file

@ -35,7 +35,7 @@
#include <boost/thread/recursive_mutex.hpp>
#include "singleton.h"
#include "static_initializer.h"
#include "static_helpers.h"
#include "misc_helpers.h"
//#define DISABLE_DEADLOCK_GUARD
@ -532,7 +532,7 @@ namespace epee
}
};
const static initializer<abstract_singleton<deadlock_guard> > singleton_initializer;
//const static initializer<abstract_singleton<deadlock_guard> > singleton_initializer;
/************************************************************************/
/* */
@ -705,7 +705,8 @@ namespace epee
#define EXCLUSIVE_CRITICAL_REGION_LOCAL(x) boost::unique_lock< boost::shared_mutex > critical_region_var(x)
#define SHARED_CRITICAL_REGION_BEGIN(x) { SHARED_CRITICAL_REGION_LOCAL(x)
#define SHARED_CRITICAL_REGION_END() }
#define EXCLUSIVE_CRITICAL_REGION_BEGIN(x) { EXCLUSIVE_CRITICAL_REGION_LOCAL(x)
#define EXCLUSIVE_CRITICAL_REGION_END() }
}

View file

@ -105,7 +105,7 @@ ENABLE_SHARED_PCH(CURRENCY_CORE)
if(CMAKE_SYSTEM_NAME STREQUAL "Android" )
add_library(wallet ${WALLET})
add_dependencies(wallet version ${PCH_LIB_NAME})
target_link_libraries(wallet currency_core crypto common zlibstatic ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
target_link_libraries(wallet currency_core crypto common zlibstatic ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} android log)
else()
add_library(wallet ${WALLET})
add_dependencies(wallet version ${PCH_LIB_NAME})

View file

@ -0,0 +1,32 @@
// Copyright (c) 2014-2018 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#include <atomic>
namespace boost
{
namespace serialization
{
template <class Archive, class value_t>
inline void save(Archive &a, const std::atomic<value_t> &x, const boost::serialization::version_type ver)
{
a << x.load();
}
template <class Archive, class value_t>
inline void load(Archive &a, std::atomic<value_t> &x, const boost::serialization::version_type ver)
{
value_t s = AUTO_VAL_INIT(s);
a >> s;
x.store(s);
}
template <class Archive, class value_t>
inline void serialize(Archive &a, std::atomic<value_t> &x, const boost::serialization::version_type ver)
{
split_free(a, x, ver);
}
}
}

View file

@ -123,9 +123,9 @@ namespace tools
DWORD cb_needed;
std::vector<HMODULE> module_handles(1);
EnumProcessModules(h_process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cb_needed);
EnumProcessModules(h_process, &module_handles[0], static_cast<DWORD>(module_handles.size() * sizeof(HMODULE)), &cb_needed);
module_handles.resize(cb_needed / sizeof(HMODULE));
EnumProcessModules(h_process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cb_needed);
EnumProcessModules(h_process, &module_handles[0], static_cast<DWORD>(module_handles.size() * sizeof(HMODULE)), &cb_needed);
std::vector<module_data> modules;
std::transform(module_handles.begin(), module_handles.end(), std::back_inserter(modules), get_mod_info(h_process));

39
src/common/error_codes.h Normal file
View file

@ -0,0 +1,39 @@
// Copyright (c) 2014-2018 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#define API_RETURN_CODE_OK BASIC_RESPONSE_STATUS_OK
#define API_RETURN_CODE_FAIL BASIC_RESPONSE_STATUS_FAILED
#define API_RETURN_CODE_NOT_FOUND BASIC_RESPONSE_STATUS_NOT_FOUND
#define API_RETURN_CODE_ACCESS_DENIED "ACCESS_DENIED"
#define API_RETURN_CODE_INTERNAL_ERROR "INTERNAL_ERROR"
#define API_RETURN_CODE_NOT_ENOUGH_MONEY "NOT_ENOUGH_MONEY"
#define API_RETURN_CODE_INTERNAL_ERROR_QUE_FULL "INTERNAL_ERROR_QUE_FULL"
#define API_RETURN_CODE_BAD_ARG "BAD_ARG"
#define API_RETURN_CODE_BAD_ARG_EMPTY_DESTINATIONS "BAD_ARG_EMPTY_DESTINATIONS"
#define API_RETURN_CODE_BAD_ARG_WRONG_FEE "BAD_ARG_WRONG_FEE"
#define API_RETURN_CODE_BAD_ARG_INVALID_ADDRESS "BAD_ARG_INVALID_ADDRESS"
#define API_RETURN_CODE_BAD_ARG_WRONG_AMOUNT "BAD_ARG_WRONG_AMOUNT"
#define API_RETURN_CODE_BAD_ARG_WRONG_PAYMENT_ID "BAD_ARG_WRONG_PAYMENT_ID"
#define API_RETURN_CODE_WRONG_PASSWORD "WRONG_PASSWORD"
#define API_RETURN_CODE_WALLET_WRONG_ID "WALLET_WRONG_ID"
#define API_RETURN_CODE_WALLET_WATCH_ONLY_NOT_SUPPORTED "WALLET_WATCH_ONLY_NOT_SUPPORTED"
#define API_RETURN_CODE_FILE_NOT_FOUND "FILE_NOT_FOUND"
#define API_RETURN_CODE_ALREADY_EXISTS "ALREADY_EXISTS"
#define API_RETURN_CODE_CANCELED "CANCELED"
#define API_RETURN_CODE_FILE_RESTORED "FILE_RESTORED"
#define API_RETURN_CODE_TRUE "TRUE"
#define API_RETURN_CODE_FALSE "FALSE"
#define API_RETURN_CODE_CORE_BUSY "CORE_BUSY"
#define API_RETURN_CODE_OVERFLOW "OVERFLOW"
#define API_RETURN_CODE_BUSY "BUSY"
#define API_RETURN_CODE_INVALID_FILE "INVALID_FILE"
#define API_RETURN_CODE_WRONG_SEED "WRONG_SEED"
#define API_RETURN_CODE_GENESIS_MISMATCH "GENESIS_MISMATCH"
#define API_RETURN_CODE_DISCONNECTED "DISCONNECTED"
#define API_RETURN_CODE_UNINITIALIZED "UNINITIALIZED"

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2018 Zano Project
// Copyright (c) 2014-2020 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Copyright (c) 2012-2013 The Boolberry developers
@ -37,3 +37,21 @@ namespace std { \
} \
}; \
}
namespace std
{
// this allows using std::pair<> as a key in unordered std containers
template <class T1, class T2>
struct hash<pair<T1, T2>>
{
size_t operator()(const pair<T1, T2>& p) const
{
auto hash1 = hash<T1>{}(p.first);
auto hash2 = hash<T2>{}(p.second);
return hash1 ^ hash2;
}
};
} // namespace std

View file

@ -48,8 +48,6 @@ namespace tools
{
using namespace std;
const int NUMWORDS = 1626;
const map<string,uint32_t> wordsMap = {
{"like", 0},
{"just", 1},
@ -3358,7 +3356,7 @@ namespace tools
throw runtime_error("Invalid binary data size for mnemonic encoding");
// 4 bytes -> 3 words. 8 digits base 16 -> 3 digits base 1626
string res;
for (unsigned int i=0; i < binary.size() / 4; i++, res += ' ')
for (unsigned int i=0; i < binary.size() / 4; i++)
{
const uint32_t* val =
reinterpret_cast<const uint32_t*>(&binary[i * 4]);
@ -3369,8 +3367,9 @@ namespace tools
res += wordsArray[w1] + " ";
res += wordsArray[w2] + " ";
res += wordsArray[w3];
res += wordsArray[w3] + " ";
}
res.erase(--res.end()); // remove trailing space
return res;
}
std::string word_by_num(uint32_t n)

View file

@ -40,6 +40,8 @@ namespace tools
{
namespace mnemonic_encoding
{
constexpr int NUMWORDS = 1626;
std::vector<unsigned char> text2binary(const std::string& text);
std::string binary2text(const std::vector<unsigned char>& binary);
std::string word_by_num(uint32_t n);

View file

@ -201,7 +201,7 @@ namespace tools
udp_blocking_client ubc(sender_endpoint, socket, io_service);
boost::system::error_code ec;
size_t len = ubc.receive(boost::asio::buffer(&packet_received, sizeof packet_received), boost::posix_time::seconds(static_cast<long>(timeout_sec)), ec);
ubc.receive(boost::asio::buffer(&packet_received, sizeof packet_received), boost::posix_time::seconds(static_cast<long>(timeout_sec)), ec);
if (ec)
{
LOG_PRINT_L3("NTP: get_ntp_time(" << host_name << "): boost error: " << ec.message());

View file

@ -259,14 +259,14 @@ namespace tools
static void handle_signal()
{
static std::mutex m_mutex;
static epee::static_helpers::wrapper<std::mutex> m_mutex;
std::unique_lock<std::mutex> lock(m_mutex);
m_handler();
}
static void handle_fatal_signal(int sig_number, void* address)
{
static std::mutex m_mutex_fatal;
static epee::static_helpers::wrapper<std::mutex> m_mutex_fatal;
std::unique_lock<std::mutex> lock(m_mutex_fatal);
m_fatal_handler(sig_number, address);
uninstall_fatal();

View file

@ -854,7 +854,7 @@ bool handle_update_maintainers_info(po::variables_map& vm)
std::cout << "ERROR: failed to invoke request" << ENDL;
return false;
}
if(res.status != CORE_RPC_STATUS_OK)
if(res.status != API_RETURN_CODE_OK)
{
std::cout << "ERROR: failed to update maintainers info: " << res.status << ENDL;
return false;

View file

@ -85,34 +85,31 @@ namespace crypto {
memcpy(&res, tmp, 32);
}
void crypto_ops::keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec, size_t brain_wallet_seed_size)
{
unsigned char tmp[64] = { 0 };
if (!(sizeof(tmp) >= brain_wallet_seed_size))
{
throw std::runtime_error("size mismatch");
}
memcpy(tmp, a_part, brain_wallet_seed_size);
cn_fast_hash(tmp, 32, (char*)&tmp[32]);
sc_reduce(tmp);
memcpy(&sec, tmp, 32);
ge_p3 point;
ge_scalarmult_base(&point, &sec);
ge_p3_tobytes(&pub, &point);
}
void crypto_ops::generate_brain_keys(public_key &pub, secret_key &sec, std::string& seed, size_t brain_wallet_seed_size)
void crypto_ops::keys_from_default(const unsigned char* a_part, public_key &pub, secret_key &sec, size_t keys_seed_binary_size)
{
std::vector<unsigned char> tmp_vector;
tmp_vector.resize(brain_wallet_seed_size, 0);
unsigned char *tmp = &tmp_vector[0];
generate_random_bytes(brain_wallet_seed_size, tmp);
seed.assign((const char*)tmp, brain_wallet_seed_size);
keys_from_default(tmp, pub, sec, brain_wallet_seed_size);
unsigned char tmp[64] = { 0 };
if (!(sizeof(tmp) >= keys_seed_binary_size))
{
throw std::runtime_error("size mismatch");
}
memcpy(tmp, a_part, keys_seed_binary_size);
cn_fast_hash(tmp, 32, (char*)&tmp[32]);
sc_reduce(tmp);
memcpy(&sec, tmp, 32);
ge_p3 point;
ge_scalarmult_base(&point, &sec);
ge_p3_tobytes(&pub, &point);
}
void crypto_ops::generate_seed_keys(public_key &pub, secret_key &sec, std::vector<unsigned char>& keys_seed_binary, size_t keys_seed_binary_size)
{
keys_seed_binary.resize(keys_seed_binary_size, 0);
generate_random_bytes(keys_seed_binary_size, keys_seed_binary.data());
keys_from_default(keys_seed_binary.data(), pub, sec, keys_seed_binary_size);
}
static inline void hash_to_scalar(const void *data, size_t length, ec_scalar &res)

View file

@ -74,10 +74,10 @@ namespace crypto {
static void generate_keys(public_key &, secret_key &);
friend void generate_keys(public_key &, secret_key &);
static void generate_brain_keys(public_key &, secret_key &, std::string& seed, size_t brain_wallet_seed_size);
friend void generate_brain_keys(public_key &, secret_key &, std::string& seed, size_t brain_wallet_seed_size);
static void keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec, size_t brain_wallet_seed_size);
friend void keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec, size_t brain_wallet_seed_size);
static void generate_seed_keys(public_key &pub, secret_key &sec, std::vector<unsigned char>& keys_seed_binary, size_t keys_seed_binary_size);
friend void generate_seed_keys(public_key &pub, secret_key &sec, std::vector<unsigned char>& keys_seed_binary, size_t keys_seed_binary_size);
static void keys_from_default(const unsigned char* a_part, public_key &pub, secret_key &sec, size_t keys_seed_binary_size);
friend void keys_from_default(const unsigned char* a_part, public_key &pub, secret_key &sec, size_t keys_seed_binary_size);
static void dependent_key(const secret_key& first, secret_key& second);
friend void dependent_key(const secret_key& first, secret_key& second);
static bool check_key(const public_key &);
@ -136,14 +136,14 @@ namespace crypto {
crypto_ops::generate_keys(pub, sec);
}
inline void generate_brain_keys(public_key &pub, secret_key &sec, std::string& seed, size_t brain_wallet_seed_size) {
crypto_ops::generate_brain_keys(pub, sec, seed, brain_wallet_seed_size);
inline void generate_seed_keys(public_key &pub, secret_key &sec, std::vector<unsigned char>& keys_seed_binary, size_t keys_seed_binary_size)
{
crypto_ops::generate_seed_keys(pub, sec, keys_seed_binary, keys_seed_binary_size);
}
inline void keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec, size_t brain_wallet_seed_size)
inline void keys_from_default(const unsigned char* a_part, public_key &pub, secret_key &sec, size_t keys_seed_binary_size)
{
crypto_ops::keys_from_default(a_part, pub, sec, brain_wallet_seed_size);
crypto_ops::keys_from_default(a_part, pub, sec, keys_seed_binary_size);
}
inline void dependent_key(const secret_key& first, secret_key& second){
@ -290,8 +290,7 @@ namespace crypto {
bool m_ready;
};
}
} // namespace crypto
POD_MAKE_HASHABLE(crypto, public_key)
POD_MAKE_COMPARABLE(crypto, secret_key)

View file

@ -17,15 +17,10 @@
using namespace std;
DISABLE_VS_WARNINGS(4244 4345)
//DISABLE_VS_WARNINGS(4244 4345)
namespace currency
{
//-----------------------------------------------------------------
account_base::account_base()
{
@ -35,21 +30,25 @@ namespace currency
void account_base::set_null()
{
// fill sensitive data with random bytes
crypto::generate_random_bytes(sizeof m_keys.m_spend_secret_key, &m_keys.m_spend_secret_key);
crypto::generate_random_bytes(sizeof m_keys.m_view_secret_key, &m_keys.m_view_secret_key);
crypto::generate_random_bytes(m_seed.size(), &m_seed[0]);
crypto::generate_random_bytes(sizeof m_keys.spend_secret_key, &m_keys.spend_secret_key);
crypto::generate_random_bytes(sizeof m_keys.view_secret_key, &m_keys.view_secret_key);
if (m_keys_seed_binary.size())
crypto::generate_random_bytes(m_keys_seed_binary.size(), &m_keys_seed_binary[0]);
// clear
m_keys = account_keys();
m_creation_timestamp = 0;
m_seed.clear();
m_keys_seed_binary.clear();
}
//-----------------------------------------------------------------
void account_base::generate()
void account_base::generate(bool auditable /* = false */)
{
generate_brain_keys(m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key, m_seed, BRAINWALLET_DEFAULT_SEED_SIZE);
dependent_key(m_keys.m_spend_secret_key, m_keys.m_view_secret_key);
if (!crypto::secret_key_to_public_key(m_keys.m_view_secret_key, m_keys.m_account_address.m_view_public_key))
if (auditable)
m_keys.account_address.flags = ACCOUNT_PUBLIC_ADDRESS_FLAG_AUDITABLE;
crypto::generate_seed_keys(m_keys.account_address.spend_public_key, m_keys.spend_secret_key, m_keys_seed_binary, BRAINWALLET_DEFAULT_SEED_SIZE);
crypto::dependent_key(m_keys.spend_secret_key, m_keys.view_secret_key);
if (!crypto::secret_key_to_public_key(m_keys.view_secret_key, m_keys.account_address.view_public_key))
throw std::runtime_error("Failed to create public view key");
@ -61,93 +60,147 @@ namespace currency
return m_keys;
}
//-----------------------------------------------------------------
std::string account_base::get_restore_data() const
{
return m_seed;
}
//-----------------------------------------------------------------
std::string account_base::get_restore_braindata() const
{
std::string restore_buff = get_restore_data();
if (restore_buff.empty())
if (m_keys_seed_binary.empty())
return "";
std::vector<unsigned char> v;
v.assign((unsigned char*)restore_buff.data(), (unsigned char*)restore_buff.data() + restore_buff.size());
std::string seed_brain_data = tools::mnemonic_encoding::binary2text(v);
std::string keys_seed_text = tools::mnemonic_encoding::binary2text(m_keys_seed_binary);
std::string timestamp_word = currency::get_word_from_timstamp(m_creation_timestamp);
seed_brain_data = seed_brain_data + timestamp_word;
return seed_brain_data;
// floor creation time to WALLET_BRAIN_DATE_QUANTUM to make checksum calculation stable
uint64_t creation_timestamp_rounded = get_timstamp_from_word(timestamp_word);
constexpr uint16_t checksum_max = tools::mnemonic_encoding::NUMWORDS >> 1; // maximum value of checksum
crypto::hash h = crypto::cn_fast_hash(m_keys_seed_binary.data(), m_keys_seed_binary.size());
*reinterpret_cast<uint64_t*>(&h) = creation_timestamp_rounded;
h = crypto::cn_fast_hash(&h, sizeof h);
uint64_t h_64 = *reinterpret_cast<uint64_t*>(&h);
uint16_t checksum = h_64 % (checksum_max + 1);
uint8_t auditable_flag = 0;
if (m_keys.account_address.flags & ACCOUNT_PUBLIC_ADDRESS_FLAG_AUDITABLE)
auditable_flag = 1;
uint64_t auditable_flag_and_checksum = (auditable_flag & 1) | (checksum << 1);
std::string auditable_flag_and_checksum_word = tools::mnemonic_encoding::word_by_num(auditable_flag_and_checksum);
return keys_seed_text + " " + timestamp_word + " " + auditable_flag_and_checksum_word;
}
//-----------------------------------------------------------------
bool account_base::restore_keys(const std::string& restore_data)
std::string account_base::get_awo_blob() const
{
//CHECK_AND_ASSERT_MES(restore_data.size() == ACCOUNT_RESTORE_DATA_SIZE, false, "wrong restore data size");
if (restore_data.size() == BRAINWALLET_DEFAULT_SEED_SIZE)
{
crypto::keys_from_default((unsigned char*)restore_data.data(), m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key, BRAINWALLET_DEFAULT_SEED_SIZE);
}
else
{
LOG_ERROR("wrong restore data size=" << restore_data.size());
return false;
}
m_seed = restore_data;
crypto::dependent_key(m_keys.m_spend_secret_key, m_keys.m_view_secret_key);
bool r = crypto::secret_key_to_public_key(m_keys.m_view_secret_key, m_keys.m_account_address.m_view_public_key);
return get_public_address_str() + ":" +
epee::string_tools::pod_to_hex(m_keys.view_secret_key) +
(m_creation_timestamp ? ":" : "") + (m_creation_timestamp ? epee::string_tools::num_to_string_fast(m_creation_timestamp) : "");
}
//-----------------------------------------------------------------
bool account_base::restore_keys(const std::vector<unsigned char>& keys_seed_binary)
{
CHECK_AND_ASSERT_MES(keys_seed_binary.size() == BRAINWALLET_DEFAULT_SEED_SIZE, false, "wrong restore data size: " << keys_seed_binary.size());
crypto::keys_from_default(keys_seed_binary.data(), m_keys.account_address.spend_public_key, m_keys.spend_secret_key, keys_seed_binary.size());
crypto::dependent_key(m_keys.spend_secret_key, m_keys.view_secret_key);
bool r = crypto::secret_key_to_public_key(m_keys.view_secret_key, m_keys.account_address.view_public_key);
CHECK_AND_ASSERT_MES(r, false, "failed to secret_key_to_public_key for view key");
set_createtime(0);
return true;
}
//-----------------------------------------------------------------
bool account_base::restore_keys_from_braindata(const std::string& restore_data_)
bool account_base::restore_from_braindata(const std::string& seed_phrase)
{
//cut the last timestamp word from restore_dats
std::list<std::string> words;
boost::split(words, restore_data_, boost::is_space());
CHECK_AND_ASSERT_MES(words.size() == BRAINWALLET_DEFAULT_WORDS_COUNT, false, "Words count missmatch: " << words.size());
std::string timestamp_word = words.back();
words.erase(--words.end());
std::string restore_data_local = boost::algorithm::join(words, " ");
boost::split(words, seed_phrase, boost::is_space());
std::vector<unsigned char> bin = tools::mnemonic_encoding::text2binary(restore_data_local);
if (!bin.size())
std::string keys_seed_text, timestamp_word, auditable_flag_and_checksum_word;
if (words.size() == SEED_PHRASE_V1_WORDS_COUNT)
{
// 24 seed words + one timestamp word = 25 total
timestamp_word = words.back();
words.erase(--words.end());
keys_seed_text = boost::algorithm::join(words, " ");
}
else if (words.size() == SEED_PHRASE_V2_WORDS_COUNT)
{
// 24 seed words + one timestamp word + one flags & checksum = 26 total
auditable_flag_and_checksum_word = words.back();
words.erase(--words.end());
timestamp_word = words.back();
words.erase(--words.end());
keys_seed_text = boost::algorithm::join(words, " ");
}
else
{
LOG_ERROR("Invalid seed words count: " << words.size());
return false;
}
uint64_t auditable_flag_and_checksum = UINT64_MAX;
if (!auditable_flag_and_checksum_word.empty())
auditable_flag_and_checksum = tools::mnemonic_encoding::num_by_word(auditable_flag_and_checksum_word);
std::vector<unsigned char> keys_seed_binary = tools::mnemonic_encoding::text2binary(keys_seed_text);
CHECK_AND_ASSERT_MES(keys_seed_binary.size(), false, "text2binary failed to convert the given text"); // don't prints event incorrect seed into the log for security
std::string restore_buff((const char*)&bin[0], bin.size());
bool r = restore_keys(restore_buff);
CHECK_AND_ASSERT_MES(r, false, "restore_keys failed");
m_creation_timestamp = get_timstamp_from_word(timestamp_word);
bool auditable_flag = false;
// check the checksum if checksum word provided
if (auditable_flag_and_checksum != UINT64_MAX)
{
auditable_flag = (auditable_flag_and_checksum & 1) != 0; // auditable flag is the lower 1 bit
uint16_t checksum = auditable_flag_and_checksum >> 1; // checksum -- everything else
constexpr uint16_t checksum_max = tools::mnemonic_encoding::NUMWORDS >> 1; // maximum value of checksum
crypto::hash h = crypto::cn_fast_hash(keys_seed_binary.data(), keys_seed_binary.size());
*reinterpret_cast<uint64_t*>(&h) = m_creation_timestamp;
h = crypto::cn_fast_hash(&h, sizeof h);
uint64_t h_64 = *reinterpret_cast<uint64_t*>(&h);
uint16_t checksum_calculated = h_64 % (checksum_max + 1);
CHECK_AND_ASSERT_MES(checksum == checksum_calculated, false, "seed phase has invalid checksum: " << checksum_calculated << ", while " << checksum << " is expected, check your words");
}
bool r = restore_keys(keys_seed_binary);
CHECK_AND_ASSERT_MES(r, false, "restore_keys failed");
m_keys_seed_binary = keys_seed_binary;
if (auditable_flag)
m_keys.account_address.flags |= ACCOUNT_PUBLIC_ADDRESS_FLAG_AUDITABLE;
return true;
}
//-----------------------------------------------------------------
bool account_base::restore_from_awo_blob(const std::string& awo_blob)
{
set_null();
bool r = parse_awo_blob(awo_blob, m_keys.account_address, m_keys.view_secret_key, m_creation_timestamp);
return r;
}
//-----------------------------------------------------------------
std::string account_base::get_public_address_str() const
{
//TODO: change this code into base 58
return get_account_address_as_str(m_keys.m_account_address);
return get_account_address_as_str(m_keys.account_address);
}
//-----------------------------------------------------------------
void account_base::make_account_watch_only()
{
// keep only:
// timestamp
// view pub & spend pub (public address)
// view pub & spend pub + flags (public address)
// view sec
// store to local tmp
uint64_t local_ts = m_creation_timestamp;
account_public_address local_addr = m_keys.m_account_address;
crypto::secret_key local_view_sec = m_keys.m_view_secret_key;
account_public_address local_addr = m_keys.account_address;
crypto::secret_key local_view_sec = m_keys.view_secret_key;
// clear
set_null();
// restore
m_creation_timestamp = local_ts;
m_keys.m_account_address = local_addr;
m_keys.m_view_secret_key = local_view_sec;
m_keys.account_address = local_addr;
m_keys.view_secret_key = local_view_sec;
}
//-----------------------------------------------------------------
std::string transform_addr_to_str(const account_public_address& addr)

View file

@ -12,7 +12,8 @@
#define BRAINWALLET_DEFAULT_SEED_SIZE 32
#define ACCOUNT_RESTORE_DATA_SIZE BRAINWALLET_DEFAULT_SEED_SIZE
#define BRAINWALLET_DEFAULT_WORDS_COUNT 25
#define SEED_PHRASE_V1_WORDS_COUNT 25
#define SEED_PHRASE_V2_WORDS_COUNT 26
@ -29,14 +30,14 @@ namespace currency
struct account_keys
{
account_public_address m_account_address;
crypto::secret_key m_spend_secret_key;
crypto::secret_key m_view_secret_key;
account_public_address account_address;
crypto::secret_key spend_secret_key;
crypto::secret_key view_secret_key;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(m_account_address)
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(m_spend_secret_key)
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(m_view_secret_key)
KV_SERIALIZE_N(account_address, "m_account_address")
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(spend_secret_key, "m_spend_secret_key")
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(view_secret_key, "m_view_secret_key")
END_KV_SERIALIZE_MAP()
};
@ -47,15 +48,15 @@ namespace currency
{
public:
account_base();
void generate();
void generate(bool auditable = false);
const account_keys& get_keys() const;
const account_public_address& get_public_address() const { return m_keys.m_account_address; };
const account_public_address& get_public_address() const { return m_keys.account_address; };
std::string get_public_address_str() const;
std::string get_restore_data() const;
std::string get_restore_braindata() const;
bool restore_keys(const std::string& restore_data);
bool restore_keys_from_braindata(const std::string& restore_data);
std::string get_awo_blob() const;
bool restore_from_braindata(const std::string& seed_phrase);
bool restore_from_awo_blob(const std::string& awo_blob);
uint64_t get_createtime() const { return m_creation_timestamp; }
void set_createtime(uint64_t val) { m_creation_timestamp = val; }
@ -70,20 +71,26 @@ namespace currency
{
a & m_keys;
a & m_creation_timestamp;
a & m_seed;
a & m_keys_seed_binary;
}
static std::string vector_of_chars_to_string(const std::vector<unsigned char>& v) { return std::string(v.begin(), v.end()); }
static std::vector<unsigned char> string_to_vector_of_chars(const std::string& v) { return std::vector<unsigned char>(v.begin(), v.end()); }
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(m_keys)
KV_SERIALIZE(m_creation_timestamp)
KV_SERIALIZE(m_seed)
KV_SERIALIZE_CUSTOM_N(m_keys_seed_binary, std::string, vector_of_chars_to_string, string_to_vector_of_chars, "m_seed")
END_KV_SERIALIZE_MAP()
private:
void set_null();
bool restore_keys(const std::vector<unsigned char>& keys_seed_binary);
account_keys m_keys;
uint64_t m_creation_timestamp;
std::string m_seed;
std::vector<unsigned char> m_keys_seed_binary;
};
@ -92,9 +99,9 @@ namespace currency
inline bool operator==(const account_keys& lhs, const account_keys& rhs)
{
return lhs.m_account_address == rhs.m_account_address &&
lhs.m_spend_secret_key == rhs.m_spend_secret_key &&
lhs.m_view_secret_key == rhs.m_view_secret_key;
return lhs.account_address == rhs.account_address &&
lhs.spend_secret_key == rhs.spend_secret_key &&
lhs.view_secret_key == rhs.view_secret_key;
}
inline bool operator!=(const account_keys& lhs, const account_keys& rhs)
{

View file

@ -17,9 +17,9 @@ namespace boost
template <class Archive>
inline void serialize(Archive &a, currency::account_keys &x, const boost::serialization::version_type ver)
{
a & x.m_account_address;
a & x.m_spend_secret_key;
a & x.m_view_secret_key;
a & x.account_address;
a & x.spend_secret_key;
a & x.view_secret_key;
}
}

View file

@ -37,7 +37,7 @@ namespace tools
if (!cb(req_alias_info, alias_info))
return false;
if (alias_info.status != CORE_RPC_STATUS_OK || !alias_info.alias_details.address.size())
if (alias_info.status != API_RETURN_CODE_OK || !alias_info.alias_details.address.size())
return false;
addr_str_local = alias_info.alias_details.address;

View file

@ -0,0 +1,27 @@
// Copyright (c) 2014-2018 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#include "warnings.h"
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4100)
DISABLE_VS_WARNINGS(4503)
#include "serialization/keyvalue_serialization.h"
#include "storages/portable_storage_template_helper.h"
POP_VS_WARNINGS
namespace currency
{
template<typename t_type>
struct struct_with_one_t_type
{
t_type v;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(v)
END_KV_SERIALIZE_MAP()
};
}

View file

@ -71,6 +71,7 @@ using namespace currency;
#define BLOCK_POS_STRICT_SEQUENCE_LIMIT 20
DISABLE_VS_WARNINGS(4267)
namespace
@ -109,7 +110,8 @@ blockchain_storage::blockchain_storage(tx_memory_pool& tx_pool) :m_db(nullptr, m
m_is_reorganize_in_process(false),
m_deinit_is_done(false),
m_cached_next_pow_difficulty(0),
m_cached_next_pos_difficulty(0)
m_cached_next_pos_difficulty(0),
m_blockchain_launch_timestamp(0)
{
@ -1063,7 +1065,7 @@ wide_difficulty_type blockchain_storage::get_next_diff_conditional(bool pos) con
wide_difficulty_type& dif = pos ? m_cached_next_pos_difficulty : m_cached_next_pow_difficulty;
TIME_MEASURE_FINISH_PD(target_calculating_enum_blocks);
TIME_MEASURE_START_PD(target_calculating_calc);
if (m_db_blocks.size() > m_core_runtime_config.hard_fork1_starts_after_height)
if (m_db_blocks.size() > m_core_runtime_config.hard_fork_01_starts_after_height)
{
dif = next_difficulty_2(timestamps, commulative_difficulties, pos ? DIFFICULTY_POS_TARGET : DIFFICULTY_POW_TARGET);
}
@ -1102,7 +1104,7 @@ wide_difficulty_type blockchain_storage::get_next_diff_conditional2(bool pos, co
enum_blockchain(cb, alt_chain, split_height);
wide_difficulty_type diff = 0;
if(abei.height > m_core_runtime_config.hard_fork1_starts_after_height)
if(abei.height > m_core_runtime_config.hard_fork_01_starts_after_height)
diff = next_difficulty_2(timestamps, commulative_difficulties, pos ? DIFFICULTY_POS_TARGET : DIFFICULTY_POW_TARGET);
else
diff = next_difficulty_1(timestamps, commulative_difficulties, pos ? DIFFICULTY_POS_TARGET : DIFFICULTY_POW_TARGET);
@ -1182,7 +1184,7 @@ bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t
CHECK_AND_ASSERT_MES(b.miner_tx.vin[1].type() == typeid(txin_to_key), false, "coinstake transaction in the block has the wrong type");
}
if (height > m_core_runtime_config.hard_fork1_starts_after_height)
if (height > m_core_runtime_config.hard_fork_01_starts_after_height)
{
// new rules that allow different unlock time in coinbase outputs
uint64_t max_unlock_time = 0;
@ -1353,7 +1355,7 @@ bool blockchain_storage::create_block_template(const create_block_template_param
boost::multiprecision::uint128_t already_generated_coins;
CRITICAL_REGION_BEGIN(m_read_lock);
height = m_db_blocks.size();
if(height <= m_core_runtime_config.hard_fork1_starts_after_height)
if(height <= m_core_runtime_config.hard_fork_01_starts_after_height)
b.major_version = BLOCK_MAJOR_VERSION_INITAL;
else
b.major_version = CURRENT_BLOCK_MAJOR_VERSION;
@ -1720,7 +1722,7 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
if (abei.height >= m_core_runtime_config.pos_minimum_heigh)
cumulative_diff_delta = correct_difficulty_with_sequence_factor(sequence_factor, cumulative_diff_delta);
if (abei.height > BLOCKCHAIN_HEIGHT_FOR_POS_STRICT_SEQUENCE_LIMITATION && abei.height <= m_core_runtime_config.hard_fork1_starts_after_height && pos_block && sequence_factor > BLOCK_POS_STRICT_SEQUENCE_LIMIT)
if (abei.height > BLOCKCHAIN_HEIGHT_FOR_POS_STRICT_SEQUENCE_LIMITATION && abei.height <= m_core_runtime_config.hard_fork_01_starts_after_height && pos_block && sequence_factor > BLOCK_POS_STRICT_SEQUENCE_LIMIT)
{
LOG_PRINT_RED_L0("Alternative block " << id << " @ " << abei.height << " has too big sequence factor: " << sequence_factor << ", rejected");
bvc.m_verification_failed = true;
@ -1845,7 +1847,7 @@ bool blockchain_storage::is_reorganize_required(const block_extended_info& main_
const block_extended_info& alt_chain_bei = alt_chain.back()->second;
const block_extended_info& connection_point = alt_chain.front()->second;
if (connection_point.height <= m_core_runtime_config.hard_fork1_starts_after_height)
if (connection_point.height <= m_core_runtime_config.hard_fork_01_starts_after_height)
{
//use pre-hard fork, old-style comparing
if (main_chain_bei.cumulative_diff_adjusted < alt_chain_bei.cumulative_diff_adjusted)
@ -1866,7 +1868,7 @@ bool blockchain_storage::is_reorganize_required(const block_extended_info& main_
return true;
}
}
else if (alt_chain_bei.height > m_core_runtime_config.hard_fork1_starts_after_height)
else if (alt_chain_bei.height > m_core_runtime_config.hard_fork_01_starts_after_height)
{
//new rules, applied after HARD_FORK_1
//to learn this algo please read https://github.com/hyle-team/docs/blob/master/zano/PoS_Analysis_and_improvements_proposal.pdf
@ -2450,14 +2452,14 @@ bool blockchain_storage::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDO
}
if (result_outs.outs.size() < req.outs_count)
{
LOG_PRINT_RED_L0("Not enough inputs for amount " << amount << ", needed " << req.outs_count << ", added " << result_outs.outs.size() << " good outs from " << up_index_limit << " unlocked of " << outs_container_size << " total");
LOG_PRINT_RED_L0("Not enough inputs for amount " << print_money_brief(amount) << ", needed " << req.outs_count << ", added " << result_outs.outs.size() << " good outs from " << up_index_limit << " unlocked of " << outs_container_size << " total");
}
}else
{
size_t added = 0;
for (size_t i = 0; i != up_index_limit; i++)
added += add_out_to_get_random_outs(result_outs, amount, i, req.outs_count, req.use_forced_mix_outs) ? 1 : 0;
LOG_PRINT_RED_L0("Not enough inputs for amount " << amount << ", needed " << req.outs_count << ", added " << added << " good outs from " << up_index_limit << " unlocked of " << outs_container_size << " total - respond with all good outs");
LOG_PRINT_RED_L0("Not enough inputs for amount " << print_money_brief(amount) << ", needed " << req.outs_count << ", added " << added << " good outs from " << up_index_limit << " unlocked of " << outs_container_size << " total - respond with all good outs");
}
}
return true;
@ -2981,11 +2983,126 @@ bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash
return true;
}
//------------------------------------------------------------------
bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count)const
uint64_t blockchain_storage::get_blockchain_launch_timestamp()const
{
if (m_blockchain_launch_timestamp)
return m_blockchain_launch_timestamp;
if (m_db_blocks.size() > 2)
{
m_blockchain_launch_timestamp = m_db_blocks[1]->bl.timestamp;
}
return m_blockchain_launch_timestamp;
}
//------------------------------------------------------------------
bool blockchain_storage::get_est_height_from_date(uint64_t date, uint64_t& res_h)const
{
CRITICAL_REGION_LOCAL(m_read_lock);
#define GET_EST_HEIGHT_FROM_DATE_THRESHOLD 1440
res_h = 0;
if (date < get_blockchain_launch_timestamp())
{
return true;
}
uint64_t calculated_estimated_height = (date - get_blockchain_launch_timestamp()) / DIFFICULTY_TOTAL_TARGET;
if (date > m_db_blocks[m_db_blocks.size() - 1]->bl.timestamp)
{
//that suspicious but also could be(in case someone just created wallet offline in
//console and then got it synchronyzing and last block had a little timestamp shift)
//let's just return 1 day behind for safety reasons.
if (m_db_blocks.size() > 1440)
{
res_h = m_db_blocks.size() - 1440;
}
else
{
//likely impossible, but just in case
res_h = 0;
}
return true;
}
if (calculated_estimated_height > m_db_blocks.size() - 1)
calculated_estimated_height = m_db_blocks.size() - 1;
//goal is to get timestamp in window in between 1day+1hour and 1 hour before target(1 hour is just to be sure that
//we didn't miss actual wallet start because of timestamp and difficulty fluctuations)
uint64_t low_boundary = date - 90000; //1 day + 1 hour
uint64_t high_boundary = date - 3600; //1 hour
//std::cout << "ENTRY: low_boundary(minutes):" << low_boundary/60 << " high_boundary(minutes): " << high_boundary / 60 << std::endl;
uint64_t iteration_coun = 0;
uint64_t current_low_boundary = 0;
uint64_t current_hight_boundary = m_db_blocks.size() - 1;
while (true)
{
iteration_coun++;
if (iteration_coun > 29) // Log2(CURRENCY_MAX_BLOCK_NUMBER)
{
LOG_ERROR("Internal error: too much iterations on get_est_height_from_date, date = " << date);
return true;
}
uint64_t ts = m_db_blocks[calculated_estimated_height]->bl.timestamp;
if (ts > high_boundary)
{
//we moved too much forward
current_hight_boundary = calculated_estimated_height;
CHECK_AND_ASSERT_MES(current_hight_boundary > current_low_boundary, true,
"Internal error: current_hight_boundary(" << current_hight_boundary << ") > current_low_boundary("<< current_low_boundary << ")");
uint64_t offset = (current_hight_boundary - current_low_boundary)/2;
if (offset <= 2)
{
//something really wrong with distribution of blocks, just use current_low_boundary to be sure that we didn't mess any transactions
res_h = current_low_boundary;
return true;
}
//std::cout << "est_h:" << calculated_estimated_height << ", ts(min): " << ts / 60 << " distance to RIGHT minutes: " << int64_t((int64_t(ts) - int64_t(high_boundary))) / 60 << std::endl;
//std::cout << "OOFFSET: -" << offset << std::endl;
calculated_estimated_height -= offset;
}
else if (ts < low_boundary)
{
//we too much in past
current_low_boundary = calculated_estimated_height;
CHECK_AND_ASSERT_MES(current_hight_boundary > current_low_boundary, true,
"Internal error: current_hight_boundary(" << current_hight_boundary << ") > current_low_boundary(" << current_low_boundary << ")");
uint64_t offset = (current_hight_boundary - current_low_boundary) / 2;
if (offset <= 2)
{
//something really wrong with distribution of blocks, just use current_low_boundary to be sure that we didn't mess any transactions
res_h = current_low_boundary;
return true;
}
//CHECK_AND_ASSERT_MES(offset > 2, true,
// "offset is too low = " << offset);
//std::cout << "est_h:" << calculated_estimated_height << ", ts(min): " << ts / 60 << " distance to LEFT minutes: " << int64_t((int64_t(low_boundary) - int64_t(ts))) / 60 << std::endl;
//std::cout << "OOFFSET: +" << offset << std::endl;
calculated_estimated_height += offset;
}
else
{
res_h = calculated_estimated_height;
break;
}
}
LOG_PRINT_L0("[get_est_height_from_date] returned " << calculated_estimated_height << " with " << iteration_coun << " iterations");
return true;
}
//------------------------------------------------------------------
bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height, bool need_global_indexes)const
{
CRITICAL_REGION_LOCAL(m_read_lock);
blocks_direct_container blocks_direct;
if (!find_blockchain_supplement(qblock_ids, blocks_direct, total_height, start_height, max_count))
if (!find_blockchain_supplement(qblock_ids, blocks_direct, total_height, start_height, max_count, minimum_height))
return false;
for (auto& bd : blocks_direct)
@ -3000,11 +3117,13 @@ bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash
return true;
}
//------------------------------------------------------------------
bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, blocks_direct_container& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count)const
bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, blocks_direct_container& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height, bool request_coinbase_info)const
{
CRITICAL_REGION_LOCAL(m_read_lock);
if (!find_blockchain_supplement(qblock_ids, start_height))
return false;
if (minimum_height > start_height)
start_height = minimum_height;
total_height = get_current_blockchain_size();
size_t count = 0;
@ -3015,6 +3134,8 @@ bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash
std::list<crypto::hash> mis;
get_transactions_direct(m_db_blocks[i]->bl.tx_hashes, blocks.back().second, mis);
CHECK_AND_ASSERT_MES(!mis.size(), false, "internal error, block " << get_block_hash(m_db_blocks[i]->bl) << " [" << i << "] contains missing transactions: " << mis);
if(request_coinbase_info)
blocks.back().third = m_db_transactions.find(get_transaction_hash(m_db_blocks[i]->bl.miner_tx));
}
return true;
}
@ -3305,11 +3426,11 @@ bool blockchain_storage::put_alias_info(const transaction & tx, extra_alias_entr
//std::string signed_buff;
//make_tx_extra_alias_entry(signed_buff, ai, true);
std::string old_address = currency::get_account_address_as_str(local_alias_history.back().m_address);
bool r = crypto::check_signature(get_sign_buff_hash_for_alias_update(ai), local_alias_history.back().m_address.m_spend_public_key, ai.m_sign.back());
bool r = crypto::check_signature(get_sign_buff_hash_for_alias_update(ai), local_alias_history.back().m_address.spend_public_key, ai.m_sign.back());
CHECK_AND_ASSERT_MES(r, false, "Failed to check signature, alias update failed." << ENDL
<< "alias: " << ai.m_alias << ENDL
<< "signed_buff_hash: " << get_sign_buff_hash_for_alias_update(ai) << ENDL
<< "public key: " << local_alias_history.back().m_address.m_spend_public_key << ENDL
<< "public key: " << local_alias_history.back().m_address.spend_public_key << ENDL
<< "new_address: " << get_account_address_as_str(ai.m_address) << ENDL
<< "signature: " << epee::string_tools::pod_to_hex(ai.m_sign) << ENDL
<< "alias_history.size() = " << local_alias_history.size());
@ -3405,7 +3526,7 @@ uint64_t blockchain_storage::validate_alias_reward(const transaction& tx, const
return true;
}
//------------------------------------------------------------------
bool blockchain_storage::prevalidate_alias_info(const transaction& tx, extra_alias_entry& eae)
bool blockchain_storage::prevalidate_alias_info(const transaction& tx, const extra_alias_entry& eae)
{
bool r = validate_alias_name(eae.m_alias);
@ -4543,7 +4664,7 @@ void blockchain_storage::get_pos_mining_estimate(uint64_t amount_coins,
//------------------------------------------------------------------
bool blockchain_storage::validate_tx_for_hardfork_specific_terms(const transaction& tx, const crypto::hash& tx_id, uint64_t block_height) const
{
if (block_height <= m_core_runtime_config.hard_fork1_starts_after_height)
if (block_height <= m_core_runtime_config.hard_fork_01_starts_after_height)
{
// before hardfork 1
@ -4555,6 +4676,26 @@ bool blockchain_storage::validate_tx_for_hardfork_specific_terms(const transacti
return true;
}
if (block_height <= m_core_runtime_config.hard_fork_02_starts_after_height)
{
// before hardfork 2
auto check_lambda = [&](const std::vector<payload_items_v>& container) -> bool
{
for (const auto& el : container)
{
const auto& type = el.type();
CHECK_AND_ASSERT_MES(type != typeid(tx_payer), false, "tx " << tx_id << " contains tx_payer which is not allowed on height " << block_height);
CHECK_AND_ASSERT_MES(type != typeid(tx_receiver), false, "tx " << tx_id << " contains tx_receiver which is not allowed on height " << block_height);
CHECK_AND_ASSERT_MES(type != typeid(extra_alias_entry), false, "tx " << tx_id << " contains extra_alias_entry which is not allowed on height " << block_height);
}
return true;
};
return check_lambda(tx.extra) && check_lambda(tx.attachment);
}
return true;
}
//------------------------------------------------------------------
@ -4570,7 +4711,7 @@ bool blockchain_storage::validate_pos_coinbase_outs_unlock_time(const transactio
return true;
}
CHECK_AND_ASSERT_MES(get_block_height(miner_tx) > m_core_runtime_config.hard_fork1_starts_after_height, false, "error in block [" << get_block_height(miner_tx) << "] etc_tx_details_unlock_time2 can exist only after hard fork point : " << m_core_runtime_config.hard_fork1_starts_after_height);
CHECK_AND_ASSERT_MES(get_block_height(miner_tx) > m_core_runtime_config.hard_fork_01_starts_after_height, false, "error in block [" << get_block_height(miner_tx) << "] etc_tx_details_unlock_time2 can exist only after hard fork point : " << m_core_runtime_config.hard_fork_01_starts_after_height);
//etc_tx_details_unlock_time2 can be kept only after hard_fork_1 point
etc_tx_details_unlock_time2 ut2 = AUTO_VAL_INIT(ut2);
@ -4675,7 +4816,7 @@ bool blockchain_storage::validate_pos_block(const block& b,
r = check_tx_input(b.miner_tx, 1, coinstake_in, id, b.miner_tx.signatures[0], max_related_block_height, source_max_unlock_time_for_pos_coinbase);
CHECK_AND_ASSERT_MES(r, false, "Failed to validate coinstake input in miner tx, block_id = " << get_block_hash(b));
if (get_block_height(b) > m_core_runtime_config.hard_fork1_starts_after_height)
if (get_block_height(b) > m_core_runtime_config.hard_fork_01_starts_after_height)
{
uint64_t last_pow_h = get_last_x_block_height(false);
CHECK_AND_ASSERT_MES(max_related_block_height <= last_pow_h, false, "Failed to validate coinbase in PoS block, condition failed: max_related_block_height(" << max_related_block_height << ") <= last_pow_h(" << last_pow_h << ")");
@ -5021,7 +5162,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
TIME_MEASURE_START_PD(tx_append_time);
if(!add_transaction_from_block(tx, tx_id, id, current_bc_size, actual_timestamp))
{
LOG_PRINT_L0("Block with id: " << id << " failed to add transaction to blockchain storage");
LOG_PRINT_L0("Block " << id << " contains tx " << tx_id << " that can't be added to the blockchain storage");
if (taken_from_pool)
{
currency::tx_verification_context tvc = AUTO_VAL_INIT(tvc);
@ -5305,7 +5446,7 @@ bool blockchain_storage::update_next_comulative_size_limit()
//------------------------------------------------------------------
bool blockchain_storage::prevalidate_block(const block& bl)
{
if (bl.major_version == BLOCK_MAJOR_VERSION_INITAL && get_block_height(bl) <= m_core_runtime_config.hard_fork1_starts_after_height)
if (bl.major_version == BLOCK_MAJOR_VERSION_INITAL && get_block_height(bl) <= m_core_runtime_config.hard_fork_01_starts_after_height)
return true;
if (bl.major_version != CURRENT_BLOCK_MAJOR_VERSION)
{
@ -5567,12 +5708,12 @@ bool blockchain_storage::scan_pos(const COMMAND_RPC_SCAN_POS::request& sp, COMMA
LOG_PRINT_GREEN("Found kernel: amount=" << print_money(sp.pos_entries[i].amount) << ", key_image" << sp.pos_entries[i].keyimage, LOG_LEVEL_0);
rsp.index = i;
rsp.block_timestamp = ts;
rsp.status = CORE_RPC_STATUS_OK;
rsp.status = API_RETURN_CODE_OK;
return true;
}
}
}
rsp.status = CORE_RPC_STATUS_NOT_FOUND;
rsp.status = API_RETURN_CODE_NOT_FOUND;
return false;
}
//------------------------------------------------------------------

View file

@ -168,7 +168,7 @@ namespace currency
typedef tools::db::basic_key_to_array_accessor<uint64_t, global_output_entry, false> outputs_container; // out_amount => ['global_output', ...]
typedef tools::db::cached_key_value_accessor<crypto::key_image, uint64_t, false, false> key_images_container;
typedef std::list<std::pair<std::shared_ptr<const block_extended_info>, std::list<std::shared_ptr<const transaction_chain_entry> > > > blocks_direct_container;
typedef std::list<epee::misc_utils::triple<std::shared_ptr<const block_extended_info>, std::list<std::shared_ptr<const transaction_chain_entry> >, std::shared_ptr<const transaction_chain_entry> > > blocks_direct_container;
friend struct add_transaction_input_visitor;
//---------------------------------------------------------------------------------
@ -254,8 +254,8 @@ namespace currency
bool get_short_chain_history(std::list<crypto::hash>& ids)const;
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp)const;
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, uint64_t& starter_offset)const;
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count)const;
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, blocks_direct_container& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count)const;
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height = 0, bool need_global_indexes = false)const;
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, blocks_direct_container& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height = 0, bool request_coinbase_info = false)const;
//bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count)const;
bool handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NOTIFY_RESPONSE_GET_OBJECTS::request& rsp)const;
bool handle_get_objects(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res)const;
@ -294,7 +294,7 @@ namespace currency
i_core_event_handler* get_event_handler() const;
uint64_t get_last_timestamps_check_window_median() const;
uint64_t get_last_n_blocks_timestamps_median(size_t n) const;
bool prevalidate_alias_info(const transaction& tx, extra_alias_entry& eae);
bool prevalidate_alias_info(const transaction& tx, const extra_alias_entry& eae);
bool validate_miner_transaction(const block& b, size_t cumulative_block_size, uint64_t fee, uint64_t& base_reward, const boost::multiprecision::uint128_t& already_generated_coins) const;
performnce_data& get_performnce_data()const;
bool validate_instance(const std::string& path);
@ -421,7 +421,7 @@ namespace currency
template<class archive_t>
void serialize(archive_t & ar, const unsigned int version);
bool get_est_height_from_date(uint64_t date, uint64_t& res_h)const;
//debug functions
@ -535,7 +535,7 @@ namespace currency
mutable uint64_t m_current_fee_median_effective_index;
bool m_is_reorganize_in_process;
mutable std::atomic<bool> m_deinit_is_done;
mutable uint64_t m_blockchain_launch_timestamp;
bool init_tx_fee_median();
bool update_tx_fee_median();
@ -616,6 +616,7 @@ namespace currency
void pop_block_from_per_block_increments(uint64_t height_);
void calculate_local_gindex_lookup_table_for_height(uint64_t split_height, std::map<uint64_t, uint64_t>& increments) const;
void do_erase_altblock(alt_chain_container::iterator it);
uint64_t get_blockchain_launch_timestamp()const;

View file

@ -37,8 +37,8 @@ namespace boost
template<class archive_t>
void serialize(archive_t & ar, currency::extra_alias_entry_base& ai, const unsigned int version)
{
ar & ai.m_address.m_spend_public_key;
ar & ai.m_address.m_view_public_key;
ar & ai.m_address.spend_public_key;
ar & ai.m_address.view_public_key;
ar & ai.m_view_key;
ar & ai.m_sign;
ar & ai.m_text_comment;

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2018 Zano Project
// Copyright (c) 2014-2020 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Boolberry developers
// Distributed under the MIT/X11 software license, see the accompanying
@ -18,11 +18,13 @@ namespace currency
uint64_t pos_minimum_heigh; //height
uint64_t tx_pool_min_fee;
uint64_t tx_default_fee;
uint64_t hard_fork1_starts_after_height;
uint64_t max_alt_blocks;
crypto::public_key alias_validation_pubkey;
core_time_func_t get_core_time;
uint64_t hard_fork_01_starts_after_height;
uint64_t hard_fork_02_starts_after_height;
static uint64_t _default_core_time_function()
{
return time(NULL);
@ -37,7 +39,10 @@ namespace currency
pc.tx_pool_min_fee = TX_MINIMUM_FEE;
pc.tx_default_fee = TX_DEFAULT_FEE;
pc.max_alt_blocks = CURRENCY_ALT_BLOCK_MAX_COUNT;
pc.hard_fork1_starts_after_height = ZANO_HARDFORK_1_AFTER_HEIGHT;
pc.hard_fork_01_starts_after_height = ZANO_HARDFORK_01_AFTER_HEIGHT;
pc.hard_fork_02_starts_after_height = ZANO_HARDFORK_02_AFTER_HEIGHT;
pc.get_core_time = &core_runtime_config::_default_core_time_function;
bool r = epee::string_tools::hex_to_pod(ALIAS_SHORT_NAMES_VALIDATION_PUB_KEY, pc.alias_validation_pubkey);
CHECK_AND_ASSERT_THROW_MES(r, "failed to parse alias_validation_pub_key");

View file

@ -15,7 +15,7 @@
#include <boost/mpl/unique.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector/vector30.hpp>
#include <boost/type_traits/is_same.hpp>
#include <vector>
@ -51,6 +51,8 @@ namespace currency
const static crypto::signature null_sig = AUTO_VAL_INIT(null_sig);
const static crypto::key_derivation null_derivation = AUTO_VAL_INIT(null_derivation);
const static crypto::hash gdefault_genesis = epee::string_tools::hex_to_pod<crypto::hash>("CC608F59F8080E2FBFE3C8C80EB6E6A953D47CF2D6AEBD345BADA3A1CAB99852");
typedef std::string payment_id_t;
@ -58,25 +60,75 @@ namespace currency
/* */
/************************************************************************/
//since structure used in blockchain as a key accessor, then be sure that there is no padding inside
//since structure used in blockchain as a key accessor, then be sure that there is no padding inside
#pragma pack(push, 1)
struct account_public_address_old
{
crypto::public_key spend_public_key;
crypto::public_key view_public_key;
BEGIN_SERIALIZE_OBJECT()
FIELD(spend_public_key)
FIELD(view_public_key)
END_SERIALIZE()
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(spend_public_key, "m_spend_public_key")
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(view_public_key, "m_view_public_key")
END_KV_SERIALIZE_MAP()
};
#pragma pack(pop)
#define ACCOUNT_PUBLIC_ADDRESS_SERIZALIZATION_VER 1
#define ACCOUNT_PUBLIC_ADDRESS_FLAG_AUDITABLE 0x01 // auditable address
//since structure used in blockchain as a key accessor, then be sure that there is no padding inside
#pragma pack(push, 1)
struct account_public_address
{
crypto::public_key m_spend_public_key;
crypto::public_key m_view_public_key;
crypto::public_key spend_public_key;
crypto::public_key view_public_key;
uint8_t flags;
DEFINE_SERIALIZATION_VERSION(ACCOUNT_PUBLIC_ADDRESS_SERIZALIZATION_VER)
BEGIN_SERIALIZE_OBJECT()
FIELD(m_spend_public_key)
FIELD(m_view_public_key)
FIELD(spend_public_key)
FIELD(view_public_key)
FIELD(flags)
END_SERIALIZE()
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(m_spend_public_key)
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(m_view_public_key)
END_KV_SERIALIZE_MAP()
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(spend_public_key, "m_spend_public_key")
KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(view_public_key, "m_view_public_key")
KV_SERIALIZE(flags)
END_KV_SERIALIZE_MAP()
bool is_auditable() const
{
return (flags & ACCOUNT_PUBLIC_ADDRESS_FLAG_AUDITABLE) != 0;
}
static account_public_address from_old(const account_public_address_old& rhs)
{
account_public_address result = AUTO_VAL_INIT(result);
result.spend_public_key = rhs.spend_public_key;
result.view_public_key = rhs.view_public_key;
return result;
}
account_public_address_old to_old() const
{
account_public_address_old result = AUTO_VAL_INIT(result);
result.spend_public_key = spend_public_key;
result.view_public_key = view_public_key;
return result;
}
};
#pragma pack(pop)
const static account_public_address null_pub_addr = AUTO_VAL_INIT(null_pub_addr);
typedef std::vector<crypto::signature> ring_signature;
@ -224,9 +276,30 @@ namespace currency
END_SERIALIZE()
};
struct tx_payer_old
{
account_public_address_old acc_addr;
BEGIN_SERIALIZE()
FIELD(acc_addr)
END_SERIALIZE()
};
struct tx_payer
{
account_public_address acc_addr;
tx_payer() = default;
tx_payer(const tx_payer_old& old) : acc_addr(account_public_address::from_old(old.acc_addr)) {}
account_public_address acc_addr{};
BEGIN_SERIALIZE()
FIELD(acc_addr)
END_SERIALIZE()
};
struct tx_receiver_old
{
account_public_address_old acc_addr;
BEGIN_SERIALIZE()
FIELD(acc_addr)
@ -235,7 +308,10 @@ namespace currency
struct tx_receiver
{
account_public_address acc_addr;
tx_receiver() = default;
tx_receiver(const tx_receiver_old& old) : acc_addr(account_public_address::from_old(old.acc_addr)) {}
account_public_address acc_addr{};
BEGIN_SERIALIZE()
FIELD(acc_addr)
@ -297,33 +373,83 @@ namespace currency
};
struct extra_alias_entry_base
struct extra_alias_entry_base_old
{
account_public_address m_address;
account_public_address_old m_address;
std::string m_text_comment;
std::vector<crypto::secret_key> m_view_key; // only one or zero elments expected (std::vector is using as memory efficient container for such a case)
std::vector<crypto::signature> m_sign; // only one or zero elments expected (std::vector is using as memory efficient container for such a case)
//uint8_t flags;
BEGIN_SERIALIZE()
FIELD(m_address)
FIELD(m_text_comment)
FIELD(m_view_key)
FIELD(m_sign)
//FIELD(flags)
END_SERIALIZE()
};
struct extra_alias_entry: public extra_alias_entry_base
struct extra_alias_entry_old : public extra_alias_entry_base_old
{
std::string m_alias;
BEGIN_SERIALIZE()
FIELD(m_alias)
FIELDS(*static_cast<extra_alias_entry_base *>(this))
FIELDS(*static_cast<extra_alias_entry_base_old*>(this))
END_SERIALIZE()
};
struct extra_alias_entry_base
{
extra_alias_entry_base() = default;
extra_alias_entry_base(const extra_alias_entry_base_old& old)
: m_address(account_public_address::from_old(old.m_address))
, m_text_comment(old.m_text_comment)
, m_view_key(old.m_view_key)
, m_sign(old.m_sign)
{
}
account_public_address m_address;
std::string m_text_comment;
std::vector<crypto::secret_key> m_view_key; // only one or zero elments expected (std::vector is using as memory efficient container for such a case)
std::vector<crypto::signature> m_sign; // only one or zero elments expected (std::vector is using as memory efficient container for such a case)
BEGIN_SERIALIZE()
FIELD(m_address)
FIELD(m_text_comment)
FIELD(m_view_key)
FIELD(m_sign)
END_SERIALIZE()
};
struct extra_alias_entry : public extra_alias_entry_base
{
extra_alias_entry() = default;
extra_alias_entry(const extra_alias_entry_old& old)
: extra_alias_entry_base(old)
, m_alias(old.m_alias)
{
}
std::string m_alias;
BEGIN_SERIALIZE()
FIELD(m_alias)
FIELDS(*static_cast<extra_alias_entry_base*>(this))
END_SERIALIZE()
extra_alias_entry_old to_old() const
{
extra_alias_entry_old result = AUTO_VAL_INIT(result);
result.m_address = m_address.to_old();
result.m_text_comment = m_text_comment;
result.m_view_key = m_view_key;
result.m_sign = m_sign;
result.m_alias = m_alias;
return result;
}
};
struct extra_padding
@ -390,10 +516,16 @@ namespace currency
END_SERIALIZE()
};
typedef boost::mpl::vector<tx_service_attachment, tx_comment, tx_payer, tx_receiver, tx_derivation_hint, std::string, tx_crypto_checksum, etc_tx_time, etc_tx_details_unlock_time, etc_tx_details_expiration_time, etc_tx_details_flags, crypto::public_key, extra_attachment_info, extra_alias_entry, extra_user_data, extra_padding, etc_tx_uint16_t, etc_tx_details_unlock_time2> all_payload_types;
typedef boost::make_variant_over<all_payload_types>::type attachment_v;
typedef boost::make_variant_over<all_payload_types>::type extra_v;
typedef boost::mpl::vector21<
tx_service_attachment, tx_comment, tx_payer_old, tx_receiver_old, tx_derivation_hint, std::string, tx_crypto_checksum, etc_tx_time, etc_tx_details_unlock_time, etc_tx_details_expiration_time,
etc_tx_details_flags, crypto::public_key, extra_attachment_info, extra_alias_entry_old, extra_user_data, extra_padding, etc_tx_uint16_t, etc_tx_details_unlock_time2,
tx_payer, tx_receiver, extra_alias_entry
> all_payload_types;
typedef boost::make_variant_over<all_payload_types>::type payload_items_v;
typedef payload_items_v extra_v;
typedef payload_items_v attachment_v;
class transaction_prefix
{
@ -599,7 +731,7 @@ SET_VARIANT_TAGS(currency::transaction, 5, "tx");
SET_VARIANT_TAGS(currency::block, 6, "block");
//attachment_v definitions
SET_VARIANT_TAGS(currency::tx_comment, 7, "comment");
SET_VARIANT_TAGS(currency::tx_payer, 8, "payer");
SET_VARIANT_TAGS(currency::tx_payer_old, 8, "payer");
SET_VARIANT_TAGS(std::string, 9, "string");
SET_VARIANT_TAGS(currency::tx_crypto_checksum, 10, "checksum");
SET_VARIANT_TAGS(currency::tx_derivation_hint, 11, "derivation_hint");
@ -613,7 +745,7 @@ SET_VARIANT_TAGS(currency::signed_parts, 17, "signed_outs");
//extra_v definitions
SET_VARIANT_TAGS(currency::extra_attachment_info, 18, "extra_attach_info");
SET_VARIANT_TAGS(currency::extra_user_data, 19, "user_data");
SET_VARIANT_TAGS(currency::extra_alias_entry, 20, "alias_entry");
SET_VARIANT_TAGS(currency::extra_alias_entry_old, 20, "alias_entry");
SET_VARIANT_TAGS(currency::extra_padding, 21, "extra_padding");
SET_VARIANT_TAGS(crypto::public_key, 22, "pub_key");
SET_VARIANT_TAGS(currency::etc_tx_uint16_t, 23, "etc_tx_uint16");
@ -624,7 +756,16 @@ SET_VARIANT_TAGS(uint64_t, 26, "uint64_t");
//etc
SET_VARIANT_TAGS(currency::etc_tx_time, 27, "etc_tx_time");
SET_VARIANT_TAGS(uint32_t, 28, "uint32_t");
SET_VARIANT_TAGS(currency::tx_receiver, 29, "payer");
SET_VARIANT_TAGS(currency::tx_receiver_old, 29, "payer"); // -- original
//SET_VARIANT_TAGS(currency::tx_receiver_old, 29, "receiver");
SET_VARIANT_TAGS(currency::etc_tx_details_unlock_time2, 30, "unlock_time2");
SET_VARIANT_TAGS(currency::tx_payer, 31, "payer2");
SET_VARIANT_TAGS(currency::tx_receiver, 32, "receiver2");
// @#@ TODO @#@
SET_VARIANT_TAGS(currency::extra_alias_entry, 33, "alias_entry2");
#undef SET_VARIANT_TAGS

View file

@ -29,10 +29,18 @@ namespace boost
template <class Archive>
inline void serialize(Archive &a, currency::account_public_address &x, const boost::serialization::version_type ver)
{
a & x.m_spend_public_key;
a & x.m_view_public_key;
//a & x.version;
a & x.flags;
a & x.spend_public_key;
a & x.view_public_key;
}
template <class Archive>
inline void serialize(Archive &a, currency::account_public_address_old &x, const boost::serialization::version_type ver)
{
a & x.spend_public_key;
a & x.view_public_key;
}
template <class Archive>
inline void serialize(Archive &a, currency::txout_to_key &x, const boost::serialization::version_type ver)
@ -90,16 +98,30 @@ namespace boost
a & x.comment;
}
template <class Archive>
inline void serialize(Archive &a, currency::tx_payer_old &x, const boost::serialization::version_type ver)
{
a & x.acc_addr;
}
template <class Archive>
inline void serialize(Archive &a, currency::tx_payer &x, const boost::serialization::version_type ver)
{
a & x.acc_addr;
}
template <class Archive>
inline void serialize(Archive &a, currency::tx_receiver_old &x, const boost::serialization::version_type ver)
{
a & x.acc_addr;
}
template <class Archive>
inline void serialize(Archive &a, currency::tx_receiver &x, const boost::serialization::version_type ver)
{
a & x.acc_addr;
}
template <class Archive>
inline void serialize(Archive &a, currency::tx_crypto_checksum &x, const boost::serialization::version_type ver)
{
@ -135,14 +157,6 @@ namespace boost
a & x.m_sign;
}
template <class Archive>
inline void serialize(Archive &a, currency::signed_parts &x, const boost::serialization::version_type ver)
{
a & x.n_outs;
a & x.n_extras;
}
template <class Archive>
inline void serialize(Archive &a, currency::extra_alias_entry &x, const boost::serialization::version_type ver)
{
@ -150,6 +164,29 @@ namespace boost
a & static_cast<currency::extra_alias_entry_base&>(x);
}
template <class Archive>
inline void serialize(Archive &a, currency::extra_alias_entry_base_old &x, const boost::serialization::version_type ver)
{
a & x.m_address;
a & x.m_text_comment;
a & x.m_view_key;
a & x.m_sign;
}
template <class Archive>
inline void serialize(Archive &a, currency::extra_alias_entry_old &x, const boost::serialization::version_type ver)
{
a & x.m_alias;
a & static_cast<currency::extra_alias_entry_base_old&>(x);
}
template <class Archive>
inline void serialize(Archive &a, currency::signed_parts &x, const boost::serialization::version_type ver)
{
a & x.n_outs;
a & x.n_extras;
}
template <class Archive>
inline void serialize(Archive &a, currency::extra_padding &x, const boost::serialization::version_type ver)
{
@ -189,21 +226,25 @@ namespace boost
{
a & at.v;
}
template <class Archive>
inline void serialize(Archive &a, currency::etc_tx_details_unlock_time2 &at, const boost::serialization::version_type ver)
{
a & at.unlock_time_array;
}
template <class Archive>
inline void serialize(Archive &a, currency::etc_tx_details_expiration_time &at, const boost::serialization::version_type ver)
{
a & at.v;
}
template <class Archive>
inline void serialize(Archive &a, currency::etc_tx_details_flags &at, const boost::serialization::version_type ver)
{
a & at.v;
}
template <class Archive>
inline void serialize(Archive &a, currency::etc_tx_time &at, const boost::serialization::version_type ver)
{

View file

@ -20,8 +20,11 @@
#define CURRENCY_MAX_BLOCK_NUMBER 500000000
#define CURRENCY_MAX_BLOCK_SIZE 500000000 // block header blob limit, never used!
#define CURRENCY_TX_MAX_ALLOWED_OUTS 2000
#define CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX 197 // addresses start with 'Z'
#define CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX 0xc5 // addresses start with 'Zx'
#define CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX 0x3678 // integrated addresses start with 'iZ'
#define CURRENCY_PUBLIC_INTEG_ADDRESS_V2_BASE58_PREFIX 0x36f8 // integrated addresses start with 'iZ' (new format)
#define CURRENCY_PUBLIC_AUDITABLE_ADDRESS_BASE58_PREFIX 0x98c8 // auditable addresses start with 'aZx'
#define CURRENCY_PUBLIC_AUDITABLE_INTEG_ADDRESS_BASE58_PREFIX 0x8a49 // auditable integrated addresses start with 'aiZX'
#define CURRENCY_MINED_MONEY_UNLOCK_WINDOW 10
#define CURRENT_TRANSACTION_VERSION 1
#define CURRENT_BLOCK_MAJOR_VERSION 1
@ -141,7 +144,8 @@
#define POS_MINIMUM_COINSTAKE_AGE 10 // blocks count
#define WALLET_FILE_SIGNATURE 0x1111012101101011LL //Bender's nightmare
#define WALLET_FILE_SIGNATURE_OLD 0x1111012101101011LL // Bender's nightmare
#define WALLET_FILE_SIGNATURE_V2 0x1111011201101011LL // another Bender's nightmare
#define WALLET_FILE_MAX_BODY_SIZE 0x88888888L //2GB
#define WALLET_FILE_MAX_KEYS_SIZE 10000 //
#define WALLET_BRAIN_DATE_OFFSET 1543622400
@ -216,7 +220,8 @@
#define BC_OFFERS_CURRENCY_MARKET_FILENAME "market.bin"
#define WALLET_FILE_SERIALIZATION_VERSION (CURRENCY_FORMATION_VERSION+65)
#define WALLET_FILE_SERIALIZATION_VERSION (CURRENCY_FORMATION_VERSION+67)
#define CURRENT_MEMPOOL_ARCHIVE_VER (CURRENCY_FORMATION_VERSION+31)
@ -225,12 +230,15 @@
#define BLOCK_MINOR_VERSION_GENESIS 0
#define BLOCK_MAJOR_VERSION_INITAL 0
#ifndef TESTNET
#define ZANO_HARDFORK_1_AFTER_HEIGHT 194624
#define ZANO_HARDFORK_01_AFTER_HEIGHT 194624
#define ZANO_HARDFORK_02_AFTER_HEIGHT 999999
#else
#define ZANO_HARDFORK_1_AFTER_HEIGHT 1440
#define ZANO_HARDFORK_01_AFTER_HEIGHT 1440
#define ZANO_HARDFORK_02_AFTER_HEIGHT 999999
#endif
static_assert(CURRENCY_MINER_TX_MAX_OUTS <= CURRENCY_TX_MAX_ALLOWED_OUTS, "Miner tx must obey normal tx max outs limit");
static_assert(PREMINE_AMOUNT / WALLET_MAX_ALLOWED_OUTPUT_AMOUNT < CURRENCY_MINER_TX_MAX_OUTS, "Premine can't be divided into reasonable number of outs");

View file

@ -493,7 +493,17 @@ namespace currency
//-----------------------------------------------------------------------------------------------
bool core::add_new_block(const block& b, block_verification_context& bvc)
{
return m_blockchain_storage.add_new_block(b, bvc);
bool r = m_blockchain_storage.add_new_block(b, bvc);
if (r && bvc.m_added_to_main_chain)
{
uint64_t h = get_block_height(b);
auto& crc = m_blockchain_storage.get_core_runtime_config();
if (h == crc.hard_fork_01_starts_after_height + 1)
{ LOG_PRINT_GREEN("Hardfork 1 activated at height " << h, LOG_LEVEL_0); }
else if (h == crc.hard_fork_02_starts_after_height + 1)
{ LOG_PRINT_GREEN("Hardfork 2 activated at height " << h, LOG_LEVEL_0); }
}
return r;
}
//-----------------------------------------------------------------------------------------------
bool core::parse_block(const blobdata& block_blob, block& b, block_verification_context& bvc)

View file

@ -224,13 +224,13 @@ namespace currency
bool derive_ephemeral_key_helper(const account_keys& ack, const crypto::public_key& tx_public_key, size_t real_output_index, keypair& in_ephemeral)
{
crypto::key_derivation recv_derivation = AUTO_VAL_INIT(recv_derivation);
bool r = crypto::generate_key_derivation(tx_public_key, ack.m_view_secret_key, recv_derivation);
CHECK_AND_ASSERT_MES(r, false, "key image helper: failed to generate_key_derivation(" << tx_public_key << ", " << ack.m_view_secret_key << ")");
bool r = crypto::generate_key_derivation(tx_public_key, ack.view_secret_key, recv_derivation);
CHECK_AND_ASSERT_MES(r, false, "key image helper: failed to generate_key_derivation(" << tx_public_key << ", " << ack.view_secret_key << ")");
r = crypto::derive_public_key(recv_derivation, real_output_index, ack.m_account_address.m_spend_public_key, in_ephemeral.pub);
CHECK_AND_ASSERT_MES(r, false, "key image helper: failed to derive_public_key(" << recv_derivation << ", " << real_output_index << ", " << ack.m_account_address.m_spend_public_key << ")");
r = crypto::derive_public_key(recv_derivation, real_output_index, ack.account_address.spend_public_key, in_ephemeral.pub);
CHECK_AND_ASSERT_MES(r, false, "key image helper: failed to derive_public_key(" << recv_derivation << ", " << real_output_index << ", " << ack.account_address.spend_public_key << ")");
crypto::derive_secret_key(recv_derivation, real_output_index, ack.m_spend_secret_key, in_ephemeral.sec);
crypto::derive_secret_key(recv_derivation, real_output_index, ack.spend_secret_key, in_ephemeral.sec);
return true;
}
//---------------------------------------------------------------
@ -313,6 +313,46 @@ namespace currency
return string_tools::get_xtype_from_string(amount, str_amount);
}
//--------------------------------------------------------------------------------
bool parse_awo_blob(const std::string& awo_blob, account_public_address& address, crypto::secret_key& view_sec_key, uint64_t& creation_timestamp)
{
std::vector<std::string> parts;
boost::split(parts, awo_blob, [](char x){ return x == ':'; } );
if (parts.size() != 2 && parts.size() != 3)
return false;
if (!get_account_address_from_str(address, parts[0]))
return false;
if (!address.is_auditable())
return false;
if (!epee::string_tools::parse_tpod_from_hex_string(parts[1], view_sec_key))
return false;
crypto::public_key view_pub_key = AUTO_VAL_INIT(view_pub_key);
if (!crypto::secret_key_to_public_key(view_sec_key, view_pub_key))
return false;
if (view_pub_key != address.view_public_key)
return false;
creation_timestamp = 0;
if (parts.size() == 3)
{
// parse timestamp
int64_t ts = 0;
if (!epee::string_tools::string_to_num_fast(parts[2], ts))
return false;
if (ts < WALLET_BRAIN_DATE_OFFSET)
return false;
creation_timestamp = ts;
}
return true;
}
//--------------------------------------------------------------------------------
std::string print_stake_kernel_info(const stake_kernel& sk)
{
std::stringstream ss;
@ -379,15 +419,10 @@ namespace currency
//---------------------------------------------------------------
crypto::hash get_sign_buff_hash_for_alias_update(const extra_alias_entry& ai)
{
const extra_alias_entry* pale = &ai;
extra_alias_entry eae_local = AUTO_VAL_INIT(eae_local);
if (ai.m_sign.size())
{
eae_local = ai;
eae_local.m_sign.clear();
pale = &eae_local;
}
return get_object_hash(*pale);
extra_alias_entry_old ai_old = ai.to_old();
if (ai_old.m_sign.size())
ai_old.m_sign.clear();
return get_object_hash(ai_old);
}
//---------------------------------------------------------------
struct tx_extra_handler : public boost::static_visitor<bool>
@ -421,13 +456,16 @@ namespace currency
rei.m_attachment_info = ai;
return true;
}
bool operator()(const extra_alias_entry& ae) const
{
ENSURE_ONETIME(was_alias, "alias");
rei.m_alias = ae;
return true;
}
bool operator()(const extra_alias_entry_old& ae) const
{
return operator()(static_cast<const extra_alias_entry&>(ae));
}
bool operator()(const extra_user_data& ud) const
{
ENSURE_ONETIME(was_userdata, "userdata");
@ -510,11 +548,11 @@ namespace currency
//---------------------------------------------------------------
bool derive_public_key_from_target_address(const account_public_address& destination_addr, const crypto::secret_key& tx_sec_key, size_t index, crypto::public_key& out_eph_public_key, crypto::key_derivation& derivation)
{
bool r = crypto::generate_key_derivation(destination_addr.m_view_public_key, tx_sec_key, derivation);
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << destination_addr.m_view_public_key << ", " << tx_sec_key << ")");
bool r = crypto::generate_key_derivation(destination_addr.view_public_key, tx_sec_key, derivation);
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << destination_addr.view_public_key << ", " << tx_sec_key << ")");
r = crypto::derive_public_key(derivation, index, destination_addr.m_spend_public_key, out_eph_public_key);
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to derive_public_key(" << derivation << ", " << index << ", " << destination_addr.m_view_public_key << ")");
r = crypto::derive_public_key(derivation, index, destination_addr.spend_public_key, out_eph_public_key);
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to derive_public_key(" << derivation << ", " << index << ", " << destination_addr.view_public_key << ")");
return r;
}
//---------------------------------------------------------------
@ -561,7 +599,7 @@ namespace currency
for (auto& apa : de.addr)
{
crypto::public_key out_eph_public_key = AUTO_VAL_INIT(out_eph_public_key);
if (apa.m_spend_public_key == null_pkey && apa.m_view_public_key == null_pkey)
if (apa.spend_public_key == null_pkey && apa.view_public_key == null_pkey)
{
//burning money(for example alias reward)
out_eph_public_key = null_pkey;
@ -589,7 +627,12 @@ namespace currency
//out to key
txout_to_key tk;
tk.key = target_keys.back();
tk.mix_attr = tx_outs_attr;
if (de.addr.front().is_auditable()) // check only the first address because there's only one in this branch
tk.mix_attr = CURRENCY_TO_KEY_OUT_FORCED_NO_MIX; // override mix_attr to 1 for auditable target addresses
else
tk.mix_attr = tx_outs_attr;
out.target = tk;
}
else
@ -778,15 +821,15 @@ namespace currency
{
crypto::public_key tx_pub_key = currency::get_tx_pub_key_from_extra(tx);
bool r = crypto::generate_key_derivation(tx_pub_key, acc_keys.m_view_secret_key, derivation);
bool r = crypto::generate_key_derivation(tx_pub_key, acc_keys.view_secret_key, derivation);
CHECK_AND_ASSERT_MES(r, null_derivation, "failed to generate_key_derivation");
LOG_PRINT_GREEN("DECRYPTING ON KEY: " << epee::string_tools::pod_to_hex(derivation) << ", key derived from destination addr: " << currency::get_account_address_as_str(acc_keys.m_account_address), LOG_LEVEL_0);
LOG_PRINT_GREEN("DECRYPTING ON KEY: " << epee::string_tools::pod_to_hex(derivation) << ", key derived from destination addr: " << currency::get_account_address_as_str(acc_keys.account_address), LOG_LEVEL_0);
}
else
{
derivation = crypto_info.encrypted_key_derivation;
crypto::chacha_crypt(derivation, acc_keys.m_spend_secret_key);
LOG_PRINT_GREEN("DECRYPTING ON KEY: " << epee::string_tools::pod_to_hex(derivation) << ", key decrypted from sender address: " << currency::get_account_address_as_str(acc_keys.m_account_address), LOG_LEVEL_0);
crypto::chacha_crypt(derivation, acc_keys.spend_secret_key);
LOG_PRINT_GREEN("DECRYPTING ON KEY: " << epee::string_tools::pod_to_hex(derivation) << ", key decrypted from sender address: " << currency::get_account_address_as_str(acc_keys.account_address), LOG_LEVEL_0);
}
//validate derivation we here. Yoda style
@ -833,7 +876,7 @@ namespace currency
void encrypt_attachments(transaction& tx, const account_keys& sender_keys, const account_public_address& destination_addr, const keypair& tx_random_key)
{
crypto::key_derivation derivation = AUTO_VAL_INIT(derivation);
bool r = crypto::generate_key_derivation(destination_addr.m_view_public_key, tx_random_key.sec, derivation);
bool r = crypto::generate_key_derivation(destination_addr.view_public_key, tx_random_key.sec, derivation);
CHECK_AND_ASSERT_MES(r, void(), "failed to generate_key_derivation");
bool was_attachment_crypted_entries = false;
bool was_extra_crypted_entries = false;
@ -855,7 +898,7 @@ namespace currency
chs.derivation_hash = *(uint32_t*)&hash_for_check_sum;
//put encrypted derivation to let sender decrypt all this data from attachment/extra
chs.encrypted_key_derivation = derivation;
crypto::chacha_crypt(chs.encrypted_key_derivation, sender_keys.m_spend_secret_key);
crypto::chacha_crypt(chs.encrypted_key_derivation, sender_keys.spend_secret_key);
if (was_extra_crypted_entries)
tx.extra.push_back(chs);
else
@ -976,7 +1019,7 @@ namespace currency
{
CHECK_AND_ASSERT_MES(destinations.size() <= CURRENCY_TX_MAX_ALLOWED_OUTS, false, "Too many outs (" << destinations.size() << ")! Tx can't be constructed.");
bool watch_only_mode = sender_account_keys.m_spend_secret_key == null_skey;
bool watch_only_mode = sender_account_keys.spend_secret_key == null_skey;
bool append_mode = false;
if (flags&TX_FLAG_SIGNATURE_MODE_SEPARATE && tx.vin.size())
@ -1106,7 +1149,7 @@ namespace currency
//fill outputs
size_t output_index = tx.vout.size(); // in case of append mode we need to start output indexing from the last one + 1
std::set<uint16_t> deriv_cache;
BOOST_FOREACH(const tx_destination_entry& dst_entr, shuffled_dsts)
for(const tx_destination_entry& dst_entr : shuffled_dsts)
{
CHECK_AND_ASSERT_MES(dst_entr.amount > 0, false, "Destination with wrong amount: " << dst_entr.amount);
bool r = construct_tx_out(dst_entr, txkey.sec, output_index, tx, deriv_cache, tx_outs_attr);
@ -1138,7 +1181,7 @@ namespace currency
{
CHECK_AND_ASSERT_MES(tsa.security.size() == 1, false, "Wrong tsa.security.size() = " << tsa.security.size());
bool r = derive_public_key_from_target_address(sender_account_keys.m_account_address, one_time_secret_key, att_count, tsa.security.back());
bool r = derive_public_key_from_target_address(sender_account_keys.account_address, one_time_secret_key, att_count, tsa.security.back());
CHECK_AND_ASSERT_MES(r, false, "Failed to derive_public_key_from_target_address");
}
att_count++;
@ -1251,7 +1294,7 @@ namespace currency
{
uint64_t date_offset = timestamp > WALLET_BRAIN_DATE_OFFSET ? timestamp - WALLET_BRAIN_DATE_OFFSET : 0;
uint64_t weeks_count = date_offset / WALLET_BRAIN_DATE_QUANTUM;
CHECK_AND_ASSERT_THROW_MES(weeks_count < std::numeric_limits<uint32_t>::max(), "internal error: unable to converto to uint32, val = " << weeks_count);
CHECK_AND_ASSERT_THROW_MES(weeks_count < std::numeric_limits<uint32_t>::max(), "internal error: unable to convert to uint32, val = " << weeks_count);
uint32_t weeks_count_32 = static_cast<uint32_t>(weeks_count);
return tools::mnemonic_encoding::word_by_num(weeks_count_32);
@ -1524,7 +1567,7 @@ namespace currency
bool is_out_to_acc(const account_keys& acc, const txout_to_key& out_key, const crypto::key_derivation& derivation, size_t output_index)
{
crypto::public_key pk;
if (!derive_public_key(derivation, output_index, acc.m_account_address.m_spend_public_key, pk))
if (!derive_public_key(derivation, output_index, acc.account_address.spend_public_key, pk))
return false;
return pk == out_key.key;
}
@ -1532,7 +1575,7 @@ namespace currency
bool is_out_to_acc(const account_keys& acc, const txout_multisig& out_multisig, const crypto::key_derivation& derivation, size_t output_index)
{
crypto::public_key pk;
if (!derive_public_key(derivation, output_index, acc.m_account_address.m_spend_public_key, pk))
if (!derive_public_key(derivation, output_index, acc.account_address.spend_public_key, pk))
return false;
auto it = std::find(out_multisig.keys.begin(), out_multisig.keys.end(), pk);
if (out_multisig.keys.end() == it)
@ -1576,7 +1619,7 @@ namespace currency
bool lookup_acc_outs_genesis(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector<size_t>& outs, uint64_t& money_transfered, crypto::key_derivation& derivation)
{
uint64_t offset = 0;
bool r = get_account_genesis_offset_by_address(get_account_address_as_str(acc.m_account_address), offset);
bool r = get_account_genesis_offset_by_address(get_account_address_as_str(acc.account_address), offset);
if (!r)
return true;
@ -1594,7 +1637,7 @@ namespace currency
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector<size_t>& outs, uint64_t& money_transfered, crypto::key_derivation& derivation)
{
money_transfered = 0;
bool r = generate_key_derivation(tx_pub_key, acc.m_view_secret_key, derivation);
bool r = generate_key_derivation(tx_pub_key, acc.view_secret_key, derivation);
CHECK_AND_ASSERT_MES(r, false, "unable to generate derivation from tx_pub = " << tx_pub_key << " * view_sec, invalid tx_pub?");
if (is_coinbase(tx) && get_block_height(tx) == 0 && tx_pub_key == ggenesis_tx_pub_key)
@ -1691,12 +1734,24 @@ namespace currency
bool r = currency::parse_and_validate_block_from_blob(bl_entry.block, blextin_ptr->bl);
bdde.block_ptr = blextin_ptr;
CHECK_AND_ASSERT_MES(r, false, "failed to parse block from blob: " << string_tools::buff_to_hex_nodelimer(bl_entry.block));
size_t i = 0;
if (bl_entry.tx_global_outs.size())
{
CHECK_AND_ASSERT_MES(bl_entry.tx_global_outs.size() == bl_entry.txs.size(), false, "tx_global_outs count " << bl_entry.tx_global_outs.size() << " count missmatch with bl_entry.txs count " << bl_entry.txs.size());
}
for (const auto& tx_blob : bl_entry.txs)
{
std::shared_ptr<currency::transaction_chain_entry> tche_ptr(new currency::transaction_chain_entry());
r = parse_and_validate_tx_from_blob(tx_blob, tche_ptr->tx);
CHECK_AND_ASSERT_MES(r, false, "failed to parse tx from blob: " << string_tools::buff_to_hex_nodelimer(tx_blob));
bdde.txs_ptr.push_back(tche_ptr);
if (bl_entry.tx_global_outs.size())
{
CHECK_AND_ASSERT_MES(bl_entry.tx_global_outs[i].v.size() == tche_ptr->tx.vout.size(), false, "tx_global_outs for tx" << bl_entry.tx_global_outs[i].v.size() << " count missmatch with tche_ptr->tx.vout.size() count " << tche_ptr->tx.vout.size());
tche_ptr->m_global_output_indexes = bl_entry.tx_global_outs[i].v;
}
i++;
}
}
return true;
@ -2026,7 +2081,7 @@ namespace currency
//---------------------------------------------------------------
bool is_showing_sender_addres(const transaction& tx)
{
return have_type_in_variant_container<tx_payer>(tx.attachment);
return have_type_in_variant_container<tx_payer>(tx.attachment) || have_type_in_variant_container<tx_payer_old>(tx.attachment);
}
//---------------------------------------------------------------
bool is_mixin_tx(const transaction& tx)
@ -2060,8 +2115,8 @@ namespace currency
//---------------------------------------------------------------
bool get_aliases_reward_account(account_public_address& acc)
{
bool r = string_tools::parse_tpod_from_hex_string(ALIAS_REWARDS_ACCOUNT_SPEND_PUB_KEY, acc.m_spend_public_key);
r &= string_tools::parse_tpod_from_hex_string(ALIAS_REWARDS_ACCOUNT_VIEW_PUB_KEY, acc.m_view_public_key);
bool r = string_tools::parse_tpod_from_hex_string(ALIAS_REWARDS_ACCOUNT_SPEND_PUB_KEY, acc.spend_public_key);
r &= string_tools::parse_tpod_from_hex_string(ALIAS_REWARDS_ACCOUNT_VIEW_PUB_KEY, acc.view_public_key);
return r;
}
//------------------------------------------------------------------
@ -2181,6 +2236,10 @@ namespace currency
return true;
}
bool operator()(const extra_alias_entry_old& ee)
{
return operator()(static_cast<const extra_alias_entry&>(ee));
}
bool operator()(const extra_user_data& ee)
{
tv.type = "user_data";
@ -2214,7 +2273,13 @@ namespace currency
return true;
}
bool operator()(const tx_payer_old&)
{
tv.type = "payer_old";
tv.short_view = "(encrypted)";
return true;
}
bool operator()(const tx_receiver& ee)
{
//const tx_payer& ee = boost::get<tx_payer>(extra);
@ -2223,6 +2288,13 @@ namespace currency
return true;
}
bool operator()(const tx_receiver_old& ee)
{
tv.type = "receiver_old";
tv.short_view = "(encrypted)";
return true;
}
bool operator()(const tx_derivation_hint& ee)
{
tv.type = "derivation_hint";
@ -2511,12 +2583,24 @@ namespace currency
//-----------------------------------------------------------------------
std::string get_account_address_as_str(const account_public_address& addr)
{
return tools::base58::encode_addr(CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr));
if (addr.flags == 0)
return tools::base58::encode_addr(CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr.to_old())); // classic Zano address
if (addr.flags & ACCOUNT_PUBLIC_ADDRESS_FLAG_AUDITABLE)
return tools::base58::encode_addr(CURRENCY_PUBLIC_AUDITABLE_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr)); // new format Zano address (auditable)
return tools::base58::encode_addr(CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr)); // new format Zano address (normal)
}
//-----------------------------------------------------------------------
std::string get_account_address_and_payment_id_as_str(const account_public_address& addr, const payment_id_t& payment_id)
{
return tools::base58::encode_addr(CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr) + payment_id);
if (addr.flags == 0)
return tools::base58::encode_addr(CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr.to_old()) + payment_id); // classic integrated Zano address
if (addr.flags & ACCOUNT_PUBLIC_ADDRESS_FLAG_AUDITABLE)
return tools::base58::encode_addr(CURRENCY_PUBLIC_AUDITABLE_INTEG_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr) + payment_id); // new format integrated Zano address (auditable)
return tools::base58::encode_addr(CURRENCY_PUBLIC_INTEG_ADDRESS_V2_BASE58_PREFIX, t_serializable_object_to_blob(addr) + payment_id); // new format integrated Zano address (normal)
}
//-----------------------------------------------------------------------
bool get_account_address_from_str(account_public_address& addr, const std::string& str)
@ -2527,7 +2611,7 @@ namespace currency
//-----------------------------------------------------------------------
bool get_account_address_and_payment_id_from_str(account_public_address& addr, payment_id_t& payment_id, const std::string& str)
{
static const size_t addr_blob_size = sizeof(account_public_address);
payment_id.clear();
blobdata blob;
uint64_t prefix;
if (!tools::base58::decode_addr(str, prefix, blob))
@ -2536,42 +2620,88 @@ namespace currency
return false;
}
if (blob.size() < addr_blob_size)
if (blob.size() < sizeof(account_public_address_old))
{
LOG_PRINT_L1("Address " << str << " has invalid format: blob size is " << blob.size() << " which is less, than expected " << addr_blob_size);
LOG_PRINT_L1("Address " << str << " has invalid format: blob size is " << blob.size() << " which is less, than expected " << sizeof(account_public_address_old));
return false;
}
if (blob.size() > addr_blob_size + BC_PAYMENT_ID_SERVICE_SIZE_MAX)
if (blob.size() > sizeof(account_public_address) + BC_PAYMENT_ID_SERVICE_SIZE_MAX)
{
LOG_PRINT_L1("Address " << str << " has invalid format: blob size is " << blob.size() << " which is more, than allowed " << addr_blob_size + BC_PAYMENT_ID_SERVICE_SIZE_MAX);
LOG_PRINT_L1("Address " << str << " has invalid format: blob size is " << blob.size() << " which is more, than allowed " << sizeof(account_public_address) + BC_PAYMENT_ID_SERVICE_SIZE_MAX);
return false;
}
bool parse_as_old_format = false;
if (prefix == CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX)
{
// nothing
// normal address
if (blob.size() == sizeof(account_public_address_old))
{
parse_as_old_format = true;
}
else if (blob.size() == sizeof(account_public_address))
{
parse_as_old_format = false;
}
else
{
LOG_PRINT_L1("Account public address cannot be parsed from \"" << str << "\", incorrect size");
return false;
}
}
else if (prefix == CURRENCY_PUBLIC_AUDITABLE_ADDRESS_BASE58_PREFIX)
{
// auditable, parse as new format
parse_as_old_format = false;
}
else if (prefix == CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX)
{
payment_id = blob.substr(addr_blob_size);
blob = blob.substr(0, addr_blob_size);
payment_id = blob.substr(sizeof(account_public_address_old));
blob = blob.substr(0, sizeof(account_public_address_old));
parse_as_old_format = true;
}
else if (prefix == CURRENCY_PUBLIC_AUDITABLE_INTEG_ADDRESS_BASE58_PREFIX || prefix == CURRENCY_PUBLIC_INTEG_ADDRESS_V2_BASE58_PREFIX)
{
payment_id = blob.substr(sizeof(account_public_address));
blob = blob.substr(0, sizeof(account_public_address));
parse_as_old_format = false;
}
else
{
LOG_PRINT_L1("Address " << str << " has wrong prefix " << prefix << ", expected " << CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX << " or " << CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX);
LOG_PRINT_L1("Address " << str << " has wrong prefix " << prefix);
return false;
}
if (!::serialization::parse_binary(blob, addr))
if (parse_as_old_format)
{
LOG_PRINT_L1("Account public address keys can't be parsed for address \"" << str << "\"");
account_public_address_old addr_old = AUTO_VAL_INIT(addr_old);
if (!::serialization::parse_binary(blob, addr_old))
{
LOG_PRINT_L1("Account public address (old) cannot be parsed from \"" << str << "\"");
return false;
}
addr = account_public_address::from_old(addr_old);
}
else
{
if (!::serialization::parse_binary(blob, addr))
{
LOG_PRINT_L1("Account public address cannot be parsed from \"" << str << "\"");
return false;
}
}
if (payment_id.size() > BC_PAYMENT_ID_SERVICE_SIZE_MAX)
{
LOG_PRINT_L1("Failed to parse address from \"" << str << "\": payment id size exceeded: " << payment_id.size());
return false;
}
if (!crypto::check_key(addr.m_spend_public_key) || !crypto::check_key(addr.m_view_public_key))
if (!crypto::check_key(addr.spend_public_key) || !crypto::check_key(addr.view_public_key))
{
LOG_PRINT_L1("Failed to validate address keys for address \"" << str << "\"");
LOG_PRINT_L1("Failed to validate address keys for public address \"" << str << "\"");
return false;
}

View file

@ -27,6 +27,7 @@
#include "blockchain_storage_basic.h"
#include "currency_format_utils_blocks.h"
#include "currency_format_utils_transactions.h"
#include "core_runtime_config.h"
// ------ get_tx_type_definition -------------
@ -47,9 +48,6 @@
namespace currency
{
bool operator ==(const currency::transaction& a, const currency::transaction& b);
@ -57,9 +55,8 @@ namespace currency
bool operator ==(const currency::extra_attachment_info& a, const currency::extra_attachment_info& b);
typedef boost::multiprecision::uint128_t uint128_tl;
struct tx_extra_info
{
@ -242,6 +239,7 @@ namespace currency
bool check_inputs_types_supported(const transaction& tx);
bool check_outs_valid(const transaction& tx);
bool parse_amount(uint64_t& amount, const std::string& str_amount);
bool parse_awo_blob(const std::string& awo_blob, account_public_address& address, crypto::secret_key& view_sec_key, uint64_t& creation_timestamp);
@ -348,7 +346,7 @@ namespace currency
bool is_out_to_acc(const account_keys& acc, const tx_out_t& out_key, const crypto::public_key& tx_pub_key, size_t output_index)
{
crypto::key_derivation derivation;
generate_key_derivation(tx_pub_key, acc.m_view_secret_key, derivation);
generate_key_derivation(tx_pub_key, acc.view_secret_key, derivation);
return is_out_to_acc(acc, out_key, derivation, output_index);
}
//----------------------------------------------------------------------------------------------------
@ -593,6 +591,51 @@ namespace currency
return boost::apply_visitor(input_amount_getter(), v);
}
//---------------------------------------------------------------
template <typename container_t>
void create_and_add_tx_payer_to_container_from_address(container_t& container, const account_public_address& addr, uint64_t top_block_height, const core_runtime_config& crc)
{
if (top_block_height > crc.hard_fork_02_starts_after_height)
{
// after hardfork 2
tx_payer result = AUTO_VAL_INIT(result);
result.acc_addr = addr;
container.push_back(result);
}
else
{
// before hardfork 2 -- add only if addr is not auditable
if (!addr.is_auditable())
{
tx_payer_old result = AUTO_VAL_INIT(result);
result.acc_addr = addr.to_old();
container.push_back(result);
}
}
}
//---------------------------------------------------------------
template <typename container_t>
void create_and_add_tx_receiver_to_container_from_address(container_t& container, const account_public_address& addr, uint64_t top_block_height, const core_runtime_config& crc)
{
if (top_block_height > crc.hard_fork_02_starts_after_height)
{
// after hardfork 2
tx_receiver result = AUTO_VAL_INIT(result);
result.acc_addr = addr;
container.push_back(result);
}
else
{
// before hardfork 2 -- add only if addr is not auditable
if (!addr.is_auditable())
{
tx_receiver_old result = AUTO_VAL_INIT(result);
result.acc_addr = addr.to_old();
container.push_back(result);
}
}
}
//---------------------------------------------------------------
//---------------------------------------------------------------
std::ostream& operator <<(std::ostream& o, const ref_by_id& r);
//---------------------------------------------------------------
#ifndef ANDROID_BUILD
@ -615,6 +658,3 @@ namespace currency
} // namespace currency

View file

@ -68,12 +68,12 @@ namespace currency
return t_unserializable_object_from_blob(b, b_blob);
}
//---------------------------------------------------------------
template<typename specic_type_t, typename variant_t_container>
template<typename specific_type_t, typename variant_t_container>
bool have_type_in_variant_container(const variant_t_container& av)
{
for (auto& ai : av)
{
if (ai.type() == typeid(specic_type_t))
if (ai.type() == typeid(specific_type_t))
{
return true;
}
@ -81,32 +81,55 @@ namespace currency
return false;
}
//---------------------------------------------------------------
template<typename specic_type_t, typename variant_t_container>
template<typename specific_type_t, typename variant_t_container>
size_t count_type_in_variant_container(const variant_t_container& av)
{
size_t result = 0;
for (auto& ai : av)
{
if (ai.type() == typeid(specic_type_t))
if (ai.type() == typeid(specific_type_t))
++result;
}
return result;
}
//---------------------------------------------------------------
template<typename specic_type_t, typename variant_t_container>
bool get_type_in_variant_container(const variant_t_container& av, specic_type_t& a)
template<typename specific_type_t, typename variant_t_container>
bool get_type_in_variant_container(const variant_t_container& av, specific_type_t& a)
{
for (auto& ai : av)
{
if (ai.type() == typeid(specic_type_t))
if (ai.type() == typeid(specific_type_t))
{
a = boost::get<specic_type_t>(ai);
a = boost::get<specific_type_t>(ai);
return true;
}
}
return false;
}
//---------------------------------------------------------------
// callback should return true to continue iterating through the container
template <typename A, typename B, typename container_t, typename callback_t>
bool handle_2_alternative_types_in_variant_container(const container_t& container, callback_t cb)
{
bool found = false;
for (auto& item : container)
{
if (item.type() == typeid(A))
{
found = true;
if (!cb(boost::get<A>(item)))
break;
}
else if (item.type() == typeid(B))
{
found = true;
if (!cb(boost::get<B>(item)))
break;
}
}
return found;
}
//---------------------------------------------------------------
template<typename variant_container_t>
bool check_allowed_types_in_variant_container(const variant_container_t& container, const std::unordered_set<std::type_index>& allowed_types, bool elements_must_be_unique = true)
{

View file

@ -16,10 +16,10 @@ namespace currency
{
for (const auto& de : destinations)
{
if (de.addr.size() == 1 && sender_account_keys.m_account_address != de.addr.back())
if (de.addr.size() == 1 && sender_account_keys.account_address != de.addr.back())
return de.addr.back(); // return the first destination address that is non-multisig and not equal to the sender's address
}
return sender_account_keys.m_account_address; // otherwise, fallback to sender's address
return sender_account_keys.account_address; // otherwise, fallback to sender's address
}
//------------------------------------------------------------------
bool is_tx_expired(const transaction& tx, uint64_t expiration_ts_median)

View file

@ -324,8 +324,9 @@ namespace currency
{
LOCAL_READONLY_TRANSACTION();
extra_alias_entry eai = AUTO_VAL_INIT(eai);
if (get_type_in_variant_container(tx.extra, eai))
{
bool r = false;
bool found = handle_2_alternative_types_in_variant_container<extra_alias_entry, extra_alias_entry_old>(tx.extra, [this, &r, &tx, is_in_block](const extra_alias_entry& eai) {
//check in blockchain
extra_alias_entry eai2 = AUTO_VAL_INIT(eai2);
bool already_have_alias_registered = m_blockchain.get_alias_info(eai.m_alias, eai2);
@ -334,7 +335,8 @@ namespace currency
if (!is_in_block && !eai.m_sign.size() && already_have_alias_registered)
{
LOG_PRINT_L0("Alias \"" << eai.m_alias << "\" already registered in blockchain, transaction rejected");
return false;
r = false;
return false; // stop handling
}
std::string prev_alias = m_blockchain.get_alias_by_address(eai.m_address);
@ -343,8 +345,9 @@ namespace currency
{
LOG_PRINT_L0("Address \"" << get_account_address_as_str(eai.m_address)
<< "\" already registered with \""<< prev_alias
<< "\" aliass in blockchain (new alias: \"" << eai.m_alias << "\"), transaction rejected");
return false;
<< "\" alias in blockchain (new alias: \"" << eai.m_alias << "\"), transaction rejected");
r = false;
return false; // stop handling
}
if (!is_in_block)
@ -352,24 +355,29 @@ namespace currency
if (m_db_alias_names.get(eai.m_alias))
{
LOG_PRINT_L0("Alias \"" << eai.m_alias << "\" already in transaction pool, transaction rejected");
return false;
r = false;
return false; // stop handling
}
if (m_db_alias_addresses.get(eai.m_address))
{
LOG_PRINT_L0("Alias \"" << eai.m_alias << "\" already in transaction pool by it's address(" << get_account_address_as_str(eai.m_address) << ") , transaction rejected");
return false;
r = false;
return false; // stop handling
}
//validate alias reward
if (!m_blockchain.prevalidate_alias_info(tx, eai))
{
LOG_PRINT_L0("Alias \"" << eai.m_alias << "\" reward validation failed, transaction rejected");
return false;
r = false;
return false; // stop handling
}
}
r = true;
return true; // continue handling
});
}
return true;
return !found || r; // if found, r must be true for success
}
//---------------------------------------------------------------------------------
bool tx_memory_pool::add_tx(const transaction &tx, tx_verification_context& tvc, bool kept_by_block, bool from_core)

View file

@ -13,6 +13,7 @@
#include "currency_core/connection_context.h"
#include "currency_core/blockchain_storage_basic.h"
#include "currency_protocol/blobdatatype.h"
#include "currency_core/basic_kv_structs.h"
namespace currency
{
@ -20,7 +21,7 @@ namespace currency
#define BC_COMMANDS_POOL_BASE 2000
/************************************************************************/
/* */
/************************************************************************/
@ -28,15 +29,19 @@ namespace currency
{
blobdata block;
std::list<blobdata> txs;
std::vector<struct_with_one_t_type<std::vector<uint64_t> > > tx_global_outs;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(block)
KV_SERIALIZE(txs)
KV_SERIALIZE(tx_global_outs)
END_KV_SERIALIZE_MAP()
};
struct block_direct_data_entry
{
std::shared_ptr<const block_extended_info> block_ptr;
std::shared_ptr<const transaction_chain_entry> coinbase_ptr;
std::list<std::shared_ptr<const transaction_chain_entry> > txs_ptr;
};

View file

@ -13,6 +13,7 @@
#include "gui_utils.h"
#include "notification_helper.h"
#include "common/config_encrypt_helper.h"
#include "currency_core/basic_kv_structs.h"
#define PREPARE_ARG_FROM_JSON(arg_type, var_name) \
arg_type var_name = AUTO_VAL_INIT(var_name); \
@ -93,23 +94,92 @@ std::wstring convert_to_lower_via_qt(const std::wstring& w)
return QString().fromStdWString(w).toLower().toStdWString();
}
MainWindow::MainWindow()
: m_gui_deinitialize_done_1(false)
, m_backend_stopped_2(false)
, m_system_shutdown(false)
, m_view(nullptr)
, m_channel(nullptr)
{
#ifndef _MSC_VER
//workaround for macos broken tolower from std, very dirty hack
bc_services::set_external_to_low_converter(convert_to_lower_via_qt);
#endif
}
MainWindow::MainWindow():
//m_quit_requested(false),
m_gui_deinitialize_done_1(false),
m_backend_stopped_2(false),
m_system_shutdown(false)
MainWindow::~MainWindow()
{
m_backend.subscribe_to_core_events(nullptr);
if (m_view)
{
m_view->page()->setWebChannel(nullptr);
m_view = nullptr;
}
if (m_channel)
{
m_channel->deregisterObject(this);
delete m_channel;
m_channel = nullptr;
}
}
void MainWindow::on_load_finished(bool ok)
{
TRY_ENTRY();
LOG_PRINT("MainWindow::on_load_finished(ok = " << (ok ? "true" : "false") << ")", LOG_LEVEL_0);
CATCH_ENTRY2(void());
}
bool MainWindow::init_window()
{
m_view = new QWebEngineView(this);
m_channel = new QWebChannel(m_view->page());
m_view->page()->setWebChannel(m_channel);
QWidget* central_widget_to_be_set = m_view;
std::string qt_dev_tools_option = m_backend.get_qt_dev_tools_option();
if (!qt_dev_tools_option.empty())
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
std::vector<std::string> qt_dev_tools_option_parts;
boost::split(qt_dev_tools_option_parts, qt_dev_tools_option, [](char c) { return c == ','; });
Qt::Orientation orientation = Qt::Vertical;
if (qt_dev_tools_option_parts.size() >= 1 && qt_dev_tools_option_parts[0] == "horizontal")
orientation = Qt::Horizontal;
double zoom_factor = 1.3;
if (qt_dev_tools_option_parts.size() >= 2)
epee::string_tools::get_xtype_from_string(zoom_factor, qt_dev_tools_option_parts[1]);
QSplitter* spliter = new QSplitter(orientation);
spliter->addWidget(m_view);
QWebEngineView* inspector = new QWebEngineView();
spliter->addWidget(inspector);
m_view->page()->setDevToolsPage(inspector->page());
inspector->setZoomFactor(zoom_factor);
spliter->setCollapsible(0, false);
spliter->setCollapsible(1, false);
QList<int> Sizes;
Sizes.append(0.5 * m_view->sizeHint().height());
Sizes.append(0.5 * m_view->sizeHint().height());
spliter->setSizes(Sizes);
central_widget_to_be_set = spliter;
#else
LOG_ERROR("Qt Dev Tool is not available for this Qt version, try building with Qt 5.11.0 or higher");
#endif
}
// register QObjects to be exposed to JavaScript
m_channel->registerObject(QStringLiteral("mediator_object"), this);
connect(m_view, SIGNAL(loadFinished(bool)), SLOT(on_load_finished(bool)));
setCentralWidget(m_view);
connect(m_view, SIGNAL(loadFinished(bool)), SLOT(on_load_finished(bool)));
setCentralWidget(central_widget_to_be_set);
//this->setMouseTracking(true);
m_view->page()->settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessFileUrls, true);
@ -133,30 +203,9 @@ MainWindow::MainWindow():
m_localization[localization_id_tray_menu_show] = "localization_id_tray_menu_show";
m_localization[localization_id_tray_menu_minimize] = "localization_id_tray_menu_minimize";
#ifndef _MSC_VER
//workaround for macos broken tolower from std, very dirty hack
bc_services::set_external_to_low_converter(convert_to_lower_via_qt);
#endif
return true;
}
MainWindow::~MainWindow()
{
m_backend.subscribe_to_core_events(nullptr);
m_view->page()->setWebChannel(nullptr);
m_channel->deregisterObject(this);
delete m_channel;
}
void MainWindow::on_load_finished(bool ok)
{
TRY_ENTRY();
LOG_PRINT("MainWindow::on_load_finished(ok = " << (ok ? "true" : "false") << ")", LOG_LEVEL_0);
CATCH_ENTRY2(void());
}
//-------------
QString MainWindow::get_default_user_dir(const QString& param)
{
TRY_ENTRY();
@ -172,6 +221,7 @@ bool MainWindow::toggle_mining()
return true;
CATCH_ENTRY2(false);
}
QString MainWindow::get_exchange_last_top(const QString& params)
{
TRY_ENTRY();
@ -188,10 +238,6 @@ QString MainWindow::get_tx_pool_info()
return MAKE_RESPONSE(ar);
CATCH_ENTRY_FAIL_API_RESPONCE();
}
// bool MainWindow::store_config()
// {
// return true;
// }
QString MainWindow::get_default_fee()
{
@ -359,8 +405,8 @@ bool MainWindow::init(const std::string& html_path)
}
//----
this->setContextMenuPolicy(Qt::ContextMenuPolicy::NoContextMenu);
m_view->setContextMenuPolicy(Qt::ContextMenuPolicy::NoContextMenu);
//this->setContextMenuPolicy(Qt::ContextMenuPolicy::NoContextMenu);
//m_view->setContextMenuPolicy(Qt::ContextMenuPolicy::NoContextMenu);
return true;
CATCH_ENTRY2(false);
@ -659,7 +705,13 @@ void qt_log_message_handler(QtMsgType type, const QMessageLogContext &context, c
bool MainWindow::init_backend(int argc, char* argv[])
{
TRY_ENTRY();
if (!m_backend.init(argc, argv, this))
if (!m_backend.init_command_line(argc, argv))
return false;
if (!init_window())
return false;
if (!m_backend.init(this))
return false;
if (m_backend.is_qt_logs_enabled())
@ -867,7 +919,7 @@ QString MainWindow::get_alias_coast(const QString& param)
{
TRY_ENTRY();
LOG_API_TIMING();
PREPARE_ARG_FROM_JSON(view::struct_with_one_t_type<std::string>, lvl);
PREPARE_ARG_FROM_JSON(currency::struct_with_one_t_type<std::string>, lvl);
view::get_alias_coast_response resp;
resp.error_code = m_backend.get_alias_coast(lvl.v, resp.coast);
return epee::serialization::store_t_to_json(resp, 0, epee::serialization::eol_lf).c_str();
@ -1333,7 +1385,7 @@ QString MainWindow::get_all_aliases()
{
TRY_ENTRY();
LOG_API_TIMING();
//PREPARE_ARG_FROM_JSON(view::struct_with_one_t_type<uint64_t>, param);
//PREPARE_ARG_FROM_JSON(currency::struct_with_one_t_type<uint64_t>, param);
PREPARE_RESPONSE(view::alias_set, rsp);
rsp.error_code = m_backend.get_aliases(rsp.response_data);
@ -1373,7 +1425,7 @@ QString MainWindow::set_log_level(const QString& param)
{
TRY_ENTRY();
LOG_API_TIMING();
PREPARE_ARG_FROM_JSON(view::struct_with_one_t_type<int64_t>, lvl);
PREPARE_ARG_FROM_JSON(currency::struct_with_one_t_type<int64_t>, lvl);
epee::log_space::get_set_log_detalisation_level(true, lvl.v);
default_ar.error_code = API_RETURN_CODE_OK;
LOG_PRINT("[LOG LEVEL]: set to " << lvl.v, LOG_LEVEL_MIN);
@ -1385,7 +1437,7 @@ QString MainWindow::get_log_level(const QString& param)
{
TRY_ENTRY();
LOG_API_TIMING();
PREPARE_RESPONSE(view::struct_with_one_t_type<int>, ar);
PREPARE_RESPONSE(currency::struct_with_one_t_type<int>, ar);
ar.response_data.v = epee::log_space::get_set_log_detalisation_level();
ar.error_code = API_RETURN_CODE_OK;
return MAKE_RESPONSE(ar);
@ -1851,7 +1903,7 @@ QString MainWindow::toggle_autostart(const QString& param)
{
TRY_ENTRY();
LOG_API_TIMING();
PREPARE_ARG_FROM_JSON(view::struct_with_one_t_type<bool>, as);
PREPARE_ARG_FROM_JSON(currency::struct_with_one_t_type<bool>, as);
if (gui_tools::SetStartOnSystemStartup(as.v))
default_ar.error_code = API_RETURN_CODE_OK;

View file

@ -212,6 +212,7 @@ private:
void restore_pos(bool consider_showed = false);
bool store_app_config();
bool load_app_config();
bool init_window();
std::string get_wallet_log_prefix(size_t wallet_id) const { return m_backend.get_wallet_log_prefix(wallet_id); }

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -113,7 +113,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",
@ -153,7 +153,7 @@
"TIME4": "Never"
},
"SCALE": {
"75": "75% scale",
"75": "75% scale",
"100": "100% scale",
"125": "125% scale",
"150": "150% scale"

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

View file

@ -108,7 +108,7 @@
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"LABEL_PHRASE_KEY": "Seed phrase / tracking seed",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -5800,8 +5800,8 @@ __webpack_require__.r(__webpack_exports__);
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
__webpack_require__(/*! C:\Users\Admin\Desktop\zano\src\gui\qt-daemon\html_source\src\polyfills.ts */"./src/polyfills.ts");
module.exports = __webpack_require__(/*! C:\Users\Admin\Desktop\zano\src\gui\qt-daemon\html_source\node_modules\@angular-devkit\build-angular\src\angular-cli-files\models\jit-polyfills.js */"./node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/jit-polyfills.js");
__webpack_require__(/*! /var/www/zano-project/zano/src/gui/qt-daemon/html_source/src/polyfills.ts */"./src/polyfills.ts");
module.exports = __webpack_require__(/*! /var/www/zano-project/zano/src/gui/qt-daemon/html_source/node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/jit-polyfills.js */"./node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/jit-polyfills.js");
/***/ })

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -93461,17 +93461,6 @@ function Buffer (arg, encodingOrOffset, length) {
return from(arg, encodingOrOffset, length)
}
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
if (typeof Symbol !== 'undefined' && Symbol.species != null &&
Buffer[Symbol.species] === Buffer) {
Object.defineProperty(Buffer, Symbol.species, {
value: null,
configurable: true,
enumerable: false,
writable: false
})
}
Buffer.poolSize = 8192 // not used by this implementation
function from (value, encodingOrOffset, length) {
@ -97893,7 +97882,7 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Base", function() { return Base; });
var defaultDocumentEvents = [
var DEFAULT_DOCUMENT_EVENTS = [
'click',
'mousemove',
'mouseenter',
@ -97903,7 +97892,6 @@ var defaultDocumentEvents = [
];
var Base = /** @class */ (function () {
function Base() {
this.timer = 0;
this.interactions = [];
}
/**
@ -97923,7 +97911,7 @@ var Base = /** @class */ (function () {
};
Base.prototype.start = function () {
if (this.interactions.length === 0) {
throw Error('There is no interaction to watch!');
throw new Error('There is no interaction to watch!');
}
this.addListeners();
this.setInterval();
@ -97939,7 +97927,7 @@ var Base = /** @class */ (function () {
var interaction = _a[_i];
for (var _b = 0, _c = interaction.events; _b < _c.length; _b++) {
var event_1 = _c[_b];
interaction.target.addEventListener(event_1, this.listenerAction);
interaction.target.addEventListener(event_1, this.onInteraction);
}
}
};
@ -97948,19 +97936,13 @@ var Base = /** @class */ (function () {
var interaction = _a[_i];
for (var _b = 0, _c = interaction.events; _b < _c.length; _b++) {
var event_2 = _c[_b];
interaction.target.removeEventListener(event_2, this.listenerAction);
interaction.target.removeEventListener(event_2, this.onInteraction);
}
}
};
Base.prototype.clearInterval = function () {
clearInterval(this.intervalId);
};
Base.prototype.setInterval = function () {
this.intervalId = setInterval(this.tick, this.factor);
};
Base.prototype.pushDefaultInteraction = function () {
Base.prototype.pushDefaultInteractions = function () {
this.interactions.push({
events: defaultDocumentEvents,
events: DEFAULT_DOCUMENT_EVENTS,
target: document,
});
};
@ -97968,10 +97950,16 @@ var Base = /** @class */ (function () {
this.interactions = this.interactions
.concat(interactions);
};
Base.prototype.clearInterval = function () {
clearInterval(this.activeIntervalId);
};
Base.prototype.setInterval = function () {
this.activeIntervalId = setInterval(this.onInterval, this.timeout * this.factor);
};
return Base;
}());
//# sourceMappingURL=/home/travis/build/harunurhan/idlejs/src/base.js.map
//# sourceMappingURL=/Users/haurhan/ts/idlejs/src/base.js.map
/***/ }),
@ -98002,15 +97990,14 @@ var Idle = /** @class */ (function (_super) {
function Idle() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.repetitive = false;
_this.listenerAction = function () {
_this.timer = 0;
_this.onInteraction = function () {
_this.clearInterval();
_this.setInterval();
};
_this.tick = function () {
_this.timer += 1;
if (_this.timer === _this.timeout || (_this.repetitive && _this.timer % _this.timeout === 0)) {
_this.callback();
_this.onInterval = function () {
_this.callback();
if (!_this.repetitive) {
_this.clearInterval();
}
};
return _this;
@ -98026,11 +98013,11 @@ var Idle = /** @class */ (function (_super) {
* Adds default interactions to decide if user is not interacting with page.
*/
Idle.prototype.whenNotInteractive = function () {
this.pushDefaultInteraction();
this.pushDefaultInteractions();
return this;
};
/**
* Repeat calling idle action for each timeout frame.
* Repeat calling the callback for each timeout frame.
*
* - Does NOT repeat by default
*/
@ -98041,16 +98028,16 @@ var Idle = /** @class */ (function (_super) {
};
/**
* Restart away timer
* incase of custom situations other than events on `EventTarget`
* Can be used incase of something different than events on `EventTarget`s
*/
Idle.prototype.restart = function () {
this.listenerAction();
this.onInteraction();
return this;
};
return Idle;
}(_base__WEBPACK_IMPORTED_MODULE_0__["Base"]));
//# sourceMappingURL=/home/travis/build/harunurhan/idlejs/src/idle.js.map
//# sourceMappingURL=/Users/haurhan/ts/idlejs/src/idle.js.map
/***/ }),
@ -98071,7 +98058,7 @@ __webpack_require__.r(__webpack_exports__);
//# sourceMappingURL=/home/travis/build/harunurhan/idlejs/src/index.js.map
//# sourceMappingURL=/Users/haurhan/ts/idlejs/src/index.js.map
/***/ }),
@ -98102,22 +98089,18 @@ var NotIdle = /** @class */ (function (_super) {
function NotIdle() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.immediate = false;
_this.listenerAction = function () {
_this.wasInteractiveLastPeriod = true;
};
_this.tick = function () {
_this.timer += 1;
if (_this.immediate && _this.wasInteractiveLastPeriod) {
_this.interactedWithin = false;
_this.onInteraction = function () {
if (!_this.interactedWithin && _this.immediate) {
_this.callback();
_this.wasInteractiveLastPeriod = false;
}
if (_this.timer === _this.timeout) {
_this.timer = 0;
if (!_this.immediate && _this.wasInteractiveLastPeriod) {
_this.callback();
_this.wasInteractiveLastPeriod = false;
}
_this.interactedWithin = true;
};
_this.onInterval = function () {
if (_this.interactedWithin && !_this.immediate) {
_this.callback();
}
_this.interactedWithin = false;
};
return _this;
}
@ -98132,7 +98115,7 @@ var NotIdle = /** @class */ (function (_super) {
* Adds default interactions to decide if user is not interacting with page.
*/
NotIdle.prototype.whenInteractive = function () {
this.pushDefaultInteraction();
this.pushDefaultInteractions();
return this;
};
/**
@ -98149,7 +98132,7 @@ var NotIdle = /** @class */ (function (_super) {
return NotIdle;
}(_base__WEBPACK_IMPORTED_MODULE_0__["Base"]));
//# sourceMappingURL=/home/travis/build/harunurhan/idlejs/src/not-idle.js.map
//# sourceMappingURL=/Users/haurhan/ts/idlejs/src/not-idle.js.map
/***/ }),
@ -119024,7 +119007,7 @@ __webpack_require__.r(__webpack_exports__);
/*!*****************************************!*\
!*** ./node_modules/tslib/tslib.es6.js ***!
\*****************************************/
/*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault, __classPrivateFieldGet, __classPrivateFieldSet */
/*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __createBinding, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault, __classPrivateFieldGet, __classPrivateFieldSet */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -119037,6 +119020,7 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__metadata", function() { return __metadata; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__awaiter", function() { return __awaiter; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__generator", function() { return __generator; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__createBinding", function() { return __createBinding; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__exportStar", function() { return __exportStar; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__values", function() { return __values; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__read", function() { return __read; });
@ -119052,18 +119036,18 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__classPrivateFieldGet", function() { return __classPrivateFieldGet; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__classPrivateFieldSet", function() { return __classPrivateFieldSet; });
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
Copyright (c) Microsoft Corporation.
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */
@ -119156,8 +119140,13 @@ function __generator(thisArg, body) {
}
}
function __createBinding(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}
function __exportStar(m, exports) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) exports[p] = m[p];
}
function __values(o) {

File diff suppressed because one or more lines are too long

View file

@ -17,7 +17,7 @@
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"outputPath": "../html",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",

View file

@ -12,6 +12,8 @@ export class Wallet {
unlocked_balance: BigNumber;
mined_total: number;
tracking_hey: string;
is_auditable: boolean;
is_watch_only: boolean;
alias_available: boolean;
alias?: object;

View file

@ -0,0 +1,3 @@
export const MIXIN: number = 10;
export const AUDITABLE_WALLET_HELP_PAGE: string = 'zano.org';
export const RCV_ADDR_QR_SCALE: number = 2;

Some files were not shown because too many files have changed in this diff Show more