mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-22 16:14:50 +01:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb420a1dfc | ||
|
|
0184604aaf | ||
|
|
75199de534 | ||
|
|
c6ab3cf6d9 | ||
|
|
e480659765 | ||
|
|
2b63e68bbf | ||
|
|
5253d1ab77 | ||
|
|
64a474a49b | ||
|
|
c4319e678f | ||
|
|
c85dfb148a | ||
|
|
98500d70a8 | ||
|
|
fa9dbd6b62 | ||
|
|
75990a46a7 | ||
|
|
c41226d847 | ||
|
|
082e725b33 | ||
|
|
53d508072b | ||
|
|
8be979d9ae | ||
|
|
cb0f89646f | ||
|
|
9a36562347 | ||
|
|
312c2c42b6 |
41
bignum.h
41
bignum.h
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -64,12 +64,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
explicit CBigNum(const std::string& str)
|
||||
{
|
||||
BN_init(this);
|
||||
SetHex(str);
|
||||
}
|
||||
|
||||
CBigNum& operator=(const CBigNum& b)
|
||||
{
|
||||
if (!BN_copy(this, &b))
|
||||
@@ -309,6 +303,37 @@ public:
|
||||
*this = 0 - *this;
|
||||
}
|
||||
|
||||
std::string ToString(int nBase=10) const
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum bnBase = nBase;
|
||||
CBigNum bn0 = 0;
|
||||
string str;
|
||||
CBigNum bn = *this;
|
||||
BN_set_negative(&bn, false);
|
||||
CBigNum dv;
|
||||
CBigNum rem;
|
||||
if (BN_cmp(&bn, &bn0) == 0)
|
||||
return "0";
|
||||
while (BN_cmp(&bn, &bn0) > 0)
|
||||
{
|
||||
if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
|
||||
throw bignum_error("CBigNum::ToString() : BN_div failed");
|
||||
bn = dv;
|
||||
unsigned int c = rem.getulong();
|
||||
str += "0123456789abcdef"[c];
|
||||
}
|
||||
if (BN_is_negative(this))
|
||||
str += "-";
|
||||
reverse(str.begin(), str.end());
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string GetHex() const
|
||||
{
|
||||
return ToString(16);
|
||||
}
|
||||
|
||||
unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
|
||||
{
|
||||
return ::GetSerializeSize(getvch(), nType, nVersion);
|
||||
@@ -376,6 +401,7 @@ public:
|
||||
|
||||
CBigNum& operator>>=(unsigned int shift)
|
||||
{
|
||||
// Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number
|
||||
if (!BN_rshift(this, this, shift))
|
||||
throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
|
||||
return *this;
|
||||
@@ -485,6 +511,7 @@ inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
|
||||
inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
|
||||
{
|
||||
CBigNum r;
|
||||
// Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number
|
||||
if (!BN_rshift(&r, &a, shift))
|
||||
throw bignum_error("CBigNum:operator>> : BN_rshift failed");
|
||||
return r;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Bitcoin v0.2.0 BETA
|
||||
|
||||
Copyright (c) 2009 Satoshi Nakamoto
|
||||
Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
Distributed under the MIT/X11 software license, see the accompanying
|
||||
file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
This product includes software developed by the OpenSSL Project for use in
|
||||
@@ -13,20 +13,27 @@ WINDOWS BUILD NOTES
|
||||
|
||||
Compilers Supported
|
||||
-------------------
|
||||
MinGW GCC
|
||||
Microsoft Visual C++ 6.0 SP6
|
||||
MinGW GCC (recommended)
|
||||
|
||||
MSVC 6.0 SP6: You'll need Boost version 1.34 because they dropped support
|
||||
for MSVC 6.0 after that. However, they didn't add Asio until 1.35.
|
||||
You should still be able to build with MSVC 6.0 by adding Asio to 1.34 by
|
||||
unpacking boost_asio_*.zip into the boost directory:
|
||||
http://sourceforge.net/projects/asio/files/asio
|
||||
|
||||
MSVC 8.0 (2005) SP1 has been tested. Note: MSVC 7.0 and up have a habit of
|
||||
linking to runtime DLLs that are not installed on XP by default.
|
||||
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
Libraries you need to download separately and build:
|
||||
|
||||
default path download
|
||||
wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/
|
||||
or prebuilt: http://wxpack.sourceforge.net
|
||||
OpenSSL \openssl http://www.openssl.org/source/
|
||||
Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html
|
||||
Boost \boost http://www.boost.org/users/download/
|
||||
default path download
|
||||
wxWidgets-2.9 \wxwidgets http://www.wxwidgets.org/downloads/
|
||||
OpenSSL \openssl http://www.openssl.org/source/
|
||||
Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html
|
||||
Boost \boost http://www.boost.org/users/download/
|
||||
|
||||
Their licenses:
|
||||
wxWidgets LGPL 2.1 with very liberal exceptions
|
||||
@@ -36,10 +43,10 @@ Boost MIT-like license
|
||||
|
||||
Versions used in this release:
|
||||
MinGW GCC 3.4.5
|
||||
wxWidgets 2.8.9
|
||||
wxWidgets 2.9.0
|
||||
OpenSSL 0.9.8k
|
||||
Berkeley DB 4.7.25.NC
|
||||
Boost 1.34.1
|
||||
Boost 1.42.1
|
||||
|
||||
|
||||
Notes
|
||||
@@ -52,6 +59,14 @@ The release is built with GCC and then "strip bitcoin.exe" to strip the debug
|
||||
symbols, which reduces the executable size by about 90%.
|
||||
|
||||
|
||||
wxWidgets
|
||||
---------
|
||||
cd \wxwidgets\build\msw
|
||||
make -f makefile.gcc
|
||||
or
|
||||
nmake -f makefile.vc
|
||||
|
||||
|
||||
OpenSSL
|
||||
-------
|
||||
Bitcoin does not use any encryption. If you want to do a no-everything
|
||||
@@ -89,3 +104,13 @@ Using MinGW and MSYS:
|
||||
cd \db\build_unix
|
||||
sh ../dist/configure --enable-mingw --enable-cxx
|
||||
make
|
||||
|
||||
|
||||
Boost
|
||||
-----
|
||||
download bjam.exe from
|
||||
http://sourceforge.net/project/showfiles.php?group_id=7586&package_id=72941
|
||||
cd \boost
|
||||
bjam toolset=gcc --build-type=complete stage
|
||||
or
|
||||
bjam toolset=msvc --build-type=complete stage
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Bitcoin v0.2.0 BETA
|
||||
|
||||
Copyright (c) 2009 Satoshi Nakamoto
|
||||
Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
Distributed under the MIT/X11 software license, see the accompanying
|
||||
file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
This product includes software developed by the OpenSSL Project for use in
|
||||
@@ -13,15 +13,22 @@ UNIX BUILD NOTES
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
apt-get install build-essential
|
||||
apt-get install libgtk2.0-dev
|
||||
apt-get install libssl-dev
|
||||
apt-get install libdb4.7-dev
|
||||
apt-get install libdb4.7++-dev
|
||||
apt-get install libboost-dev
|
||||
sudo apt-get install build-essential
|
||||
sudo apt-get install libgtk2.0-dev
|
||||
sudo apt-get install libssl-dev
|
||||
sudo apt-get install libdb4.7-dev
|
||||
sudo apt-get install libdb4.7++-dev
|
||||
sudo apt-get install libboost-dev
|
||||
|
||||
We're now using wxWidgets 2.9, which uses UTF-8.
|
||||
|
||||
There isn't currently a debian package of wxWidgets we can use. The 2.8
|
||||
packages for Karmic are UTF-16 unicode and won't work for us, and we've had
|
||||
trouble building 2.8 on 64-bit.
|
||||
|
||||
You need to download wxWidgets from http://www.wxwidgets.org/downloads/
|
||||
and build it yourself.
|
||||
and build it yourself. See the build instructions and configure parameters
|
||||
below.
|
||||
|
||||
Licenses of statically linked libraries:
|
||||
wxWidgets LGPL 2.1 with very liberal exceptions
|
||||
@@ -31,9 +38,9 @@ Boost MIT-like license
|
||||
Versions used in this release:
|
||||
GCC 4.3.3
|
||||
OpenSSL 0.9.8k
|
||||
wxWidgets 2.8.9
|
||||
wxWidgets 2.9.0
|
||||
Berkeley DB 4.7.25.NC
|
||||
Boost 1.40.0
|
||||
Boost 1.38.0
|
||||
|
||||
|
||||
Notes
|
||||
@@ -48,12 +55,14 @@ symbols, which reduces the executable size by about 90%.
|
||||
|
||||
wxWidgets
|
||||
---------
|
||||
cd /usr/local/wxWidgets-2.8.9
|
||||
cd /usr/local
|
||||
tar -xzvf wxWidgets-2.9.0.tar.gz
|
||||
cd /usr/local/wxWidgets-2.9.0
|
||||
mkdir buildgtk
|
||||
cd buildgtk
|
||||
../configure --with-gtk --enable-debug --disable-shared --enable-monolithic
|
||||
make
|
||||
su
|
||||
sudo su
|
||||
make install
|
||||
ldconfig
|
||||
|
||||
@@ -61,7 +70,7 @@ ldconfig
|
||||
Boost
|
||||
-----
|
||||
If you want to build Boost yourself,
|
||||
cd /usr/local/boost_1_40_0
|
||||
cd /usr/local/boost_1_38_0
|
||||
su
|
||||
./bootstrap.sh
|
||||
./bjam install
|
||||
|
||||
40
db.cpp
40
db.cpp
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -134,8 +134,6 @@ void CDB::Close()
|
||||
|
||||
CRITICAL_BLOCK(cs_db)
|
||||
--mapFileUseCount[strFile];
|
||||
|
||||
RandAddSeed();
|
||||
}
|
||||
|
||||
void CloseDb(const string& strFile)
|
||||
@@ -456,7 +454,7 @@ bool CAddrDB::LoadAddresses()
|
||||
CAddress addr(psz, NODE_NETWORK);
|
||||
addr.nTime = 0; // so it won't relay unless successfully connected
|
||||
if (addr.IsValid())
|
||||
AddAddress(*this, addr);
|
||||
AddAddress(addr);
|
||||
}
|
||||
}
|
||||
catch (...) { }
|
||||
@@ -509,27 +507,6 @@ bool LoadAddresses()
|
||||
|
||||
|
||||
|
||||
//
|
||||
// CReviewDB
|
||||
//
|
||||
|
||||
bool CReviewDB::ReadReviews(uint256 hash, vector<CReview>& vReviews)
|
||||
{
|
||||
vReviews.size(); // msvc workaround, just need to do anything with vReviews
|
||||
return Read(make_pair(string("reviews"), hash), vReviews);
|
||||
}
|
||||
|
||||
bool CReviewDB::WriteReviews(uint256 hash, const vector<CReview>& vReviews)
|
||||
{
|
||||
return Write(make_pair(string("reviews"), hash), vReviews);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// CWalletDB
|
||||
//
|
||||
@@ -595,14 +572,17 @@ bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
|
||||
// wtx.hashBlock.ToString().substr(0,16).c_str(),
|
||||
// wtx.mapValue["message"].c_str());
|
||||
}
|
||||
else if (strType == "key")
|
||||
else if (strType == "key" || strType == "wkey")
|
||||
{
|
||||
vector<unsigned char> vchPubKey;
|
||||
ssKey >> vchPubKey;
|
||||
CPrivKey vchPrivKey;
|
||||
ssValue >> vchPrivKey;
|
||||
CWalletKey wkey;
|
||||
if (strType == "key")
|
||||
ssValue >> wkey.vchPrivKey;
|
||||
else
|
||||
ssValue >> wkey;
|
||||
|
||||
mapKeys[vchPubKey] = vchPrivKey;
|
||||
mapKeys[vchPubKey] = wkey.vchPrivKey;
|
||||
mapPubKeys[Hash160(vchPubKey)] = vchPubKey;
|
||||
}
|
||||
else if (strType == "defaultkey")
|
||||
@@ -619,7 +599,6 @@ bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
|
||||
ssKey >> strKey;
|
||||
|
||||
// Menu state
|
||||
if (strKey == "fShowGenerated") ssValue >> fShowGenerated;
|
||||
if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins;
|
||||
|
||||
// Options
|
||||
@@ -638,7 +617,6 @@ bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
|
||||
}
|
||||
|
||||
printf("nFileVersion = %d\n", nFileVersion);
|
||||
printf("fShowGenerated = %d\n", fShowGenerated);
|
||||
printf("fGenerateBitcoins = %d\n", fGenerateBitcoins);
|
||||
printf("nTransactionFee = %"PRI64d"\n", nTransactionFee);
|
||||
printf("addrIncoming = %s\n", addrIncoming.ToString().c_str());
|
||||
|
||||
49
db.h
49
db.h
@@ -1,8 +1,7 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <db_cxx.h>
|
||||
class CTransaction;
|
||||
class CTxIndex;
|
||||
class CDiskBlockIndex;
|
||||
@@ -14,6 +13,7 @@ class CAddress;
|
||||
class CWalletTx;
|
||||
|
||||
extern map<string, string> mapAddressBook;
|
||||
extern CCriticalSection cs_mapAddressBook;
|
||||
extern bool fClient;
|
||||
|
||||
|
||||
@@ -285,45 +285,6 @@ public:
|
||||
|
||||
|
||||
|
||||
class CReviewDB : public CDB
|
||||
{
|
||||
public:
|
||||
CReviewDB(const char* pszMode="r+") : CDB("reviews.dat", pszMode) { }
|
||||
private:
|
||||
CReviewDB(const CReviewDB&);
|
||||
void operator=(const CReviewDB&);
|
||||
public:
|
||||
bool ReadUser(uint256 hash, CUser& user)
|
||||
{
|
||||
return Read(make_pair(string("user"), hash), user);
|
||||
}
|
||||
|
||||
bool WriteUser(uint256 hash, const CUser& user)
|
||||
{
|
||||
return Write(make_pair(string("user"), hash), user);
|
||||
}
|
||||
|
||||
bool ReadReviews(uint256 hash, vector<CReview>& vReviews);
|
||||
bool WriteReviews(uint256 hash, const vector<CReview>& vReviews);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CMarketDB : public CDB
|
||||
{
|
||||
public:
|
||||
CMarketDB(const char* pszMode="r+") : CDB("market.dat", pszMode) { }
|
||||
private:
|
||||
CMarketDB(const CMarketDB&);
|
||||
void operator=(const CMarketDB&);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CAddrDB : public CDB
|
||||
{
|
||||
public:
|
||||
@@ -359,15 +320,17 @@ public:
|
||||
|
||||
bool WriteName(const string& strAddress, const string& strName)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
||||
mapAddressBook[strAddress] = strName;
|
||||
nWalletDBUpdated++;
|
||||
mapAddressBook[strAddress] = strName;
|
||||
return Write(make_pair(string("name"), strAddress), strName);
|
||||
}
|
||||
|
||||
bool EraseName(const string& strAddress)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
||||
mapAddressBook.erase(strAddress);
|
||||
nWalletDBUpdated++;
|
||||
mapAddressBook.erase(strAddress);
|
||||
return Erase(make_pair(string("name"), strAddress));
|
||||
}
|
||||
|
||||
|
||||
20
headers.h
20
headers.h
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -29,15 +29,15 @@
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/ripemd.h>
|
||||
#include <db_cxx.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
#include <assert.h>
|
||||
#include <malloc.h>
|
||||
#include <memory>
|
||||
#define BOUNDSCHECK 1
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -55,6 +55,8 @@
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#ifdef __WXMSW__
|
||||
#include <windows.h>
|
||||
@@ -64,6 +66,7 @@
|
||||
#include <shlwapi.h>
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
@@ -74,16 +77,16 @@
|
||||
#include <errno.h>
|
||||
#include <net/if.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#endif
|
||||
#ifdef __BSD__
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
|
||||
#pragma hdrstop
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
|
||||
|
||||
#include "strlcpy.h"
|
||||
#include "serialize.h"
|
||||
#include "uint256.h"
|
||||
@@ -96,7 +99,7 @@ using namespace boost;
|
||||
#include "net.h"
|
||||
#include "irc.h"
|
||||
#include "main.h"
|
||||
#include "market.h"
|
||||
#include "rpc.h"
|
||||
#include "uibase.h"
|
||||
#include "ui.h"
|
||||
|
||||
@@ -110,3 +113,4 @@ using namespace boost;
|
||||
#include "xpm/send16.xpm"
|
||||
#include "xpm/send16noshadow.xpm"
|
||||
#include "xpm/send20.xpm"
|
||||
#include "xpm/about.xpm"
|
||||
|
||||
5
irc.cpp
5
irc.cpp
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -265,8 +265,7 @@ void ThreadIRCSeed(void* parg)
|
||||
if (DecodeAddress(pszName, addr))
|
||||
{
|
||||
addr.nTime = GetAdjustedTime() - 51 * 60;
|
||||
CAddrDB addrdb;
|
||||
if (AddAddress(addrdb, addr))
|
||||
if (AddAddress(addr))
|
||||
printf("IRC got new address\n");
|
||||
nGotIRCAddresses++;
|
||||
}
|
||||
|
||||
6
irc.h
6
irc.h
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
extern bool RecvLine(SOCKET hSocket, string& strLine);
|
||||
extern void ThreadIRCSeed(void* parg);
|
||||
bool RecvLine(SOCKET hSocket, string& strLine);
|
||||
void ThreadIRCSeed(void* parg);
|
||||
|
||||
extern int nGotIRCAddresses;
|
||||
|
||||
24
json/LICENSE.txt
Normal file
24
json/LICENSE.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007 - 2009 John W. Wilkinson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
18
json/json_spirit.h
Normal file
18
json/json_spirit.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef JSON_SPIRIT
|
||||
#define JSON_SPIRIT
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
#include "json_spirit_reader.h"
|
||||
#include "json_spirit_writer.h"
|
||||
#include "json_spirit_utils.h"
|
||||
|
||||
#endif
|
||||
54
json/json_spirit_error_position.h
Normal file
54
json/json_spirit_error_position.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef JSON_SPIRIT_ERROR_POSITION
|
||||
#define JSON_SPIRIT_ERROR_POSITION
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
// An Error_position exception is thrown by the "read_or_throw" functions below on finding an error.
|
||||
// Note the "read_or_throw" functions are around 3 times slower than the standard functions "read"
|
||||
// functions that return a bool.
|
||||
//
|
||||
struct Error_position
|
||||
{
|
||||
Error_position();
|
||||
Error_position( unsigned int line, unsigned int column, const std::string& reason );
|
||||
bool operator==( const Error_position& lhs ) const;
|
||||
unsigned int line_;
|
||||
unsigned int column_;
|
||||
std::string reason_;
|
||||
};
|
||||
|
||||
inline Error_position::Error_position()
|
||||
: line_( 0 )
|
||||
, column_( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason )
|
||||
: line_( line )
|
||||
, column_( column )
|
||||
, reason_( reason )
|
||||
{
|
||||
}
|
||||
|
||||
inline bool Error_position::operator==( const Error_position& lhs ) const
|
||||
{
|
||||
if( this == &lhs ) return true;
|
||||
|
||||
return ( reason_ == lhs.reason_ ) &&
|
||||
( line_ == lhs.line_ ) &&
|
||||
( column_ == lhs.column_ );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
137
json/json_spirit_reader.cpp
Normal file
137
json/json_spirit_reader.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#include "json_spirit_reader.h"
|
||||
#include "json_spirit_reader_template.h"
|
||||
|
||||
using namespace json_spirit;
|
||||
|
||||
bool json_spirit::read( const std::string& s, Value& value )
|
||||
{
|
||||
return read_string( s, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( const std::string& s, Value& value )
|
||||
{
|
||||
read_string_or_throw( s, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::istream& is, Value& value )
|
||||
{
|
||||
return read_stream( is, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::istream& is, Value& value )
|
||||
{
|
||||
read_stream_or_throw( is, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value )
|
||||
{
|
||||
return read_range( begin, end, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value )
|
||||
{
|
||||
begin = read_range_or_throw( begin, end, value );
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
bool json_spirit::read( const std::wstring& s, wValue& value )
|
||||
{
|
||||
return read_string( s, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( const std::wstring& s, wValue& value )
|
||||
{
|
||||
read_string_or_throw( s, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::wistream& is, wValue& value )
|
||||
{
|
||||
return read_stream( is, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::wistream& is, wValue& value )
|
||||
{
|
||||
read_stream_or_throw( is, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value )
|
||||
{
|
||||
return read_range( begin, end, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value )
|
||||
{
|
||||
begin = read_range_or_throw( begin, end, value );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool json_spirit::read( const std::string& s, mValue& value )
|
||||
{
|
||||
return read_string( s, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( const std::string& s, mValue& value )
|
||||
{
|
||||
read_string_or_throw( s, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::istream& is, mValue& value )
|
||||
{
|
||||
return read_stream( is, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::istream& is, mValue& value )
|
||||
{
|
||||
read_stream_or_throw( is, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value )
|
||||
{
|
||||
return read_range( begin, end, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value )
|
||||
{
|
||||
begin = read_range_or_throw( begin, end, value );
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
bool json_spirit::read( const std::wstring& s, wmValue& value )
|
||||
{
|
||||
return read_string( s, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( const std::wstring& s, wmValue& value )
|
||||
{
|
||||
read_string_or_throw( s, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::wistream& is, wmValue& value )
|
||||
{
|
||||
return read_stream( is, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::wistream& is, wmValue& value )
|
||||
{
|
||||
read_stream_or_throw( is, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value )
|
||||
{
|
||||
return read_range( begin, end, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value )
|
||||
{
|
||||
begin = read_range_or_throw( begin, end, value );
|
||||
}
|
||||
|
||||
#endif
|
||||
62
json/json_spirit_reader.h
Normal file
62
json/json_spirit_reader.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef JSON_SPIRIT_READER
|
||||
#define JSON_SPIRIT_READER
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
#include "json_spirit_error_position.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
// functions to reads a JSON values
|
||||
|
||||
bool read( const std::string& s, Value& value );
|
||||
bool read( std::istream& is, Value& value );
|
||||
bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value );
|
||||
|
||||
void read_or_throw( const std::string& s, Value& value );
|
||||
void read_or_throw( std::istream& is, Value& value );
|
||||
void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value );
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
bool read( const std::wstring& s, wValue& value );
|
||||
bool read( std::wistream& is, wValue& value );
|
||||
bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value );
|
||||
|
||||
void read_or_throw( const std::wstring& s, wValue& value );
|
||||
void read_or_throw( std::wistream& is, wValue& value );
|
||||
void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value );
|
||||
|
||||
#endif
|
||||
|
||||
bool read( const std::string& s, mValue& value );
|
||||
bool read( std::istream& is, mValue& value );
|
||||
bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value );
|
||||
|
||||
void read_or_throw( const std::string& s, mValue& value );
|
||||
void read_or_throw( std::istream& is, mValue& value );
|
||||
void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value );
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
bool read( const std::wstring& s, wmValue& value );
|
||||
bool read( std::wistream& is, wmValue& value );
|
||||
bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value );
|
||||
|
||||
void read_or_throw( const std::wstring& s, wmValue& value );
|
||||
void read_or_throw( std::wistream& is, wmValue& value );
|
||||
void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
612
json/json_spirit_reader_template.h
Normal file
612
json/json_spirit_reader_template.h
Normal file
@@ -0,0 +1,612 @@
|
||||
#ifndef JSON_SPIRIT_READER_TEMPLATE
|
||||
#define JSON_SPIRIT_READER_TEMPLATE
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
#include "json_spirit_error_position.h"
|
||||
|
||||
//#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#if BOOST_VERSION >= 103800
|
||||
#include <boost/spirit/include/classic_core.hpp>
|
||||
#include <boost/spirit/include/classic_confix.hpp>
|
||||
#include <boost/spirit/include/classic_escape_char.hpp>
|
||||
#include <boost/spirit/include/classic_multi_pass.hpp>
|
||||
#include <boost/spirit/include/classic_position_iterator.hpp>
|
||||
#define spirit_namespace boost::spirit::classic
|
||||
#else
|
||||
#include <boost/spirit/core.hpp>
|
||||
#include <boost/spirit/utility/confix.hpp>
|
||||
#include <boost/spirit/utility/escape_char.hpp>
|
||||
#include <boost/spirit/iterator/multi_pass.hpp>
|
||||
#include <boost/spirit/iterator/position_iterator.hpp>
|
||||
#define spirit_namespace boost::spirit
|
||||
#endif
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
const spirit_namespace::int_parser < boost::int64_t > int64_p = spirit_namespace::int_parser < boost::int64_t >();
|
||||
const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >();
|
||||
|
||||
template< class Iter_type >
|
||||
bool is_eq( Iter_type first, Iter_type last, const char* c_str )
|
||||
{
|
||||
for( Iter_type i = first; i != last; ++i, ++c_str )
|
||||
{
|
||||
if( *c_str == 0 ) return false;
|
||||
|
||||
if( *i != *c_str ) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template< class Char_type >
|
||||
Char_type hex_to_num( const Char_type c )
|
||||
{
|
||||
if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0';
|
||||
if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10;
|
||||
if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template< class Char_type, class Iter_type >
|
||||
Char_type hex_str_to_char( Iter_type& begin )
|
||||
{
|
||||
const Char_type c1( *( ++begin ) );
|
||||
const Char_type c2( *( ++begin ) );
|
||||
|
||||
return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 );
|
||||
}
|
||||
|
||||
template< class Char_type, class Iter_type >
|
||||
Char_type unicode_str_to_char( Iter_type& begin )
|
||||
{
|
||||
const Char_type c1( *( ++begin ) );
|
||||
const Char_type c2( *( ++begin ) );
|
||||
const Char_type c3( *( ++begin ) );
|
||||
const Char_type c4( *( ++begin ) );
|
||||
|
||||
return ( hex_to_num( c1 ) << 12 ) +
|
||||
( hex_to_num( c2 ) << 8 ) +
|
||||
( hex_to_num( c3 ) << 4 ) +
|
||||
hex_to_num( c4 );
|
||||
}
|
||||
|
||||
template< class String_type >
|
||||
void append_esc_char_and_incr_iter( String_type& s,
|
||||
typename String_type::const_iterator& begin,
|
||||
typename String_type::const_iterator end )
|
||||
{
|
||||
typedef typename String_type::value_type Char_type;
|
||||
|
||||
const Char_type c2( *begin );
|
||||
|
||||
switch( c2 )
|
||||
{
|
||||
case 't': s += '\t'; break;
|
||||
case 'b': s += '\b'; break;
|
||||
case 'f': s += '\f'; break;
|
||||
case 'n': s += '\n'; break;
|
||||
case 'r': s += '\r'; break;
|
||||
case '\\': s += '\\'; break;
|
||||
case '/': s += '/'; break;
|
||||
case '"': s += '"'; break;
|
||||
case 'x':
|
||||
{
|
||||
if( end - begin >= 3 ) // expecting "xHH..."
|
||||
{
|
||||
s += hex_str_to_char< Char_type >( begin );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'u':
|
||||
{
|
||||
if( end - begin >= 5 ) // expecting "uHHHH..."
|
||||
{
|
||||
s += unicode_str_to_char< Char_type >( begin );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< class String_type >
|
||||
String_type substitute_esc_chars( typename String_type::const_iterator begin,
|
||||
typename String_type::const_iterator end )
|
||||
{
|
||||
typedef typename String_type::const_iterator Iter_type;
|
||||
|
||||
if( end - begin < 2 ) return String_type( begin, end );
|
||||
|
||||
String_type result;
|
||||
|
||||
result.reserve( end - begin );
|
||||
|
||||
const Iter_type end_minus_1( end - 1 );
|
||||
|
||||
Iter_type substr_start = begin;
|
||||
Iter_type i = begin;
|
||||
|
||||
for( ; i < end_minus_1; ++i )
|
||||
{
|
||||
if( *i == '\\' )
|
||||
{
|
||||
result.append( substr_start, i );
|
||||
|
||||
++i; // skip the '\'
|
||||
|
||||
append_esc_char_and_incr_iter( result, i, end );
|
||||
|
||||
substr_start = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
result.append( substr_start, end );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template< class String_type >
|
||||
String_type get_str_( typename String_type::const_iterator begin,
|
||||
typename String_type::const_iterator end )
|
||||
{
|
||||
assert( end - begin >= 2 );
|
||||
|
||||
typedef typename String_type::const_iterator Iter_type;
|
||||
|
||||
Iter_type str_without_quotes( ++begin );
|
||||
Iter_type end_without_quotes( --end );
|
||||
|
||||
return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes );
|
||||
}
|
||||
|
||||
inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end )
|
||||
{
|
||||
return get_str_< std::string >( begin, end );
|
||||
}
|
||||
|
||||
inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end )
|
||||
{
|
||||
return get_str_< std::wstring >( begin, end );
|
||||
}
|
||||
|
||||
template< class String_type, class Iter_type >
|
||||
String_type get_str( Iter_type begin, Iter_type end )
|
||||
{
|
||||
const String_type tmp( begin, end ); // convert multipass iterators to string iterators
|
||||
|
||||
return get_str( tmp.begin(), tmp.end() );
|
||||
}
|
||||
|
||||
// this class's methods get called by the spirit parse resulting
|
||||
// in the creation of a JSON object or array
|
||||
//
|
||||
// NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator
|
||||
//
|
||||
template< class Value_type, class Iter_type >
|
||||
class Semantic_actions
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename Value_type::Config_type Config_type;
|
||||
typedef typename Config_type::String_type String_type;
|
||||
typedef typename Config_type::Object_type Object_type;
|
||||
typedef typename Config_type::Array_type Array_type;
|
||||
typedef typename String_type::value_type Char_type;
|
||||
|
||||
Semantic_actions( Value_type& value )
|
||||
: value_( value )
|
||||
, current_p_( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
void begin_obj( Char_type c )
|
||||
{
|
||||
assert( c == '{' );
|
||||
|
||||
begin_compound< Object_type >();
|
||||
}
|
||||
|
||||
void end_obj( Char_type c )
|
||||
{
|
||||
assert( c == '}' );
|
||||
|
||||
end_compound();
|
||||
}
|
||||
|
||||
void begin_array( Char_type c )
|
||||
{
|
||||
assert( c == '[' );
|
||||
|
||||
begin_compound< Array_type >();
|
||||
}
|
||||
|
||||
void end_array( Char_type c )
|
||||
{
|
||||
assert( c == ']' );
|
||||
|
||||
end_compound();
|
||||
}
|
||||
|
||||
void new_name( Iter_type begin, Iter_type end )
|
||||
{
|
||||
assert( current_p_->type() == obj_type );
|
||||
|
||||
name_ = get_str< String_type >( begin, end );
|
||||
}
|
||||
|
||||
void new_str( Iter_type begin, Iter_type end )
|
||||
{
|
||||
add_to_current( get_str< String_type >( begin, end ) );
|
||||
}
|
||||
|
||||
void new_true( Iter_type begin, Iter_type end )
|
||||
{
|
||||
assert( is_eq( begin, end, "true" ) );
|
||||
|
||||
add_to_current( true );
|
||||
}
|
||||
|
||||
void new_false( Iter_type begin, Iter_type end )
|
||||
{
|
||||
assert( is_eq( begin, end, "false" ) );
|
||||
|
||||
add_to_current( false );
|
||||
}
|
||||
|
||||
void new_null( Iter_type begin, Iter_type end )
|
||||
{
|
||||
assert( is_eq( begin, end, "null" ) );
|
||||
|
||||
add_to_current( Value_type() );
|
||||
}
|
||||
|
||||
void new_int( boost::int64_t i )
|
||||
{
|
||||
add_to_current( i );
|
||||
}
|
||||
|
||||
void new_uint64( boost::uint64_t ui )
|
||||
{
|
||||
add_to_current( ui );
|
||||
}
|
||||
|
||||
void new_real( double d )
|
||||
{
|
||||
add_to_current( d );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Semantic_actions& operator=( const Semantic_actions& );
|
||||
// to prevent "assignment operator could not be generated" warning
|
||||
|
||||
Value_type* add_first( const Value_type& value )
|
||||
{
|
||||
assert( current_p_ == 0 );
|
||||
|
||||
value_ = value;
|
||||
current_p_ = &value_;
|
||||
return current_p_;
|
||||
}
|
||||
|
||||
template< class Array_or_obj >
|
||||
void begin_compound()
|
||||
{
|
||||
if( current_p_ == 0 )
|
||||
{
|
||||
add_first( Array_or_obj() );
|
||||
}
|
||||
else
|
||||
{
|
||||
stack_.push_back( current_p_ );
|
||||
|
||||
Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place
|
||||
|
||||
current_p_ = add_to_current( new_array_or_obj );
|
||||
}
|
||||
}
|
||||
|
||||
void end_compound()
|
||||
{
|
||||
if( current_p_ != &value_ )
|
||||
{
|
||||
current_p_ = stack_.back();
|
||||
|
||||
stack_.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
Value_type* add_to_current( const Value_type& value )
|
||||
{
|
||||
if( current_p_ == 0 )
|
||||
{
|
||||
return add_first( value );
|
||||
}
|
||||
else if( current_p_->type() == array_type )
|
||||
{
|
||||
current_p_->get_array().push_back( value );
|
||||
|
||||
return ¤t_p_->get_array().back();
|
||||
}
|
||||
|
||||
assert( current_p_->type() == obj_type );
|
||||
|
||||
return &Config_type::add( current_p_->get_obj(), name_, value );
|
||||
}
|
||||
|
||||
Value_type& value_; // this is the object or array that is being created
|
||||
Value_type* current_p_; // the child object or array that is currently being constructed
|
||||
|
||||
std::vector< Value_type* > stack_; // previous child objects and arrays
|
||||
|
||||
String_type name_; // of current name/value pair
|
||||
};
|
||||
|
||||
template< typename Iter_type >
|
||||
void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason )
|
||||
{
|
||||
throw Error_position( i.get_position().line, i.get_position().column, reason );
|
||||
}
|
||||
|
||||
template< typename Iter_type >
|
||||
void throw_error( Iter_type i, const std::string& reason )
|
||||
{
|
||||
throw reason;
|
||||
}
|
||||
|
||||
// the spirit grammer
|
||||
//
|
||||
template< class Value_type, class Iter_type >
|
||||
class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t;
|
||||
|
||||
Json_grammer( Semantic_actions_t& semantic_actions )
|
||||
: actions_( semantic_actions )
|
||||
{
|
||||
}
|
||||
|
||||
static void throw_not_value( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "not a value" );
|
||||
}
|
||||
|
||||
static void throw_not_array( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "not an array" );
|
||||
}
|
||||
|
||||
static void throw_not_object( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "not an object" );
|
||||
}
|
||||
|
||||
static void throw_not_pair( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "not a pair" );
|
||||
}
|
||||
|
||||
static void throw_not_colon( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "no colon in pair" );
|
||||
}
|
||||
|
||||
static void throw_not_string( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "not a string" );
|
||||
}
|
||||
|
||||
template< typename ScannerT >
|
||||
class definition
|
||||
{
|
||||
public:
|
||||
|
||||
definition( const Json_grammer& self )
|
||||
{
|
||||
using namespace spirit_namespace;
|
||||
|
||||
typedef typename Value_type::String_type::value_type Char_type;
|
||||
|
||||
// first we convert the semantic action class methods to functors with the
|
||||
// parameter signature expected by spirit
|
||||
|
||||
typedef boost::function< void( Char_type ) > Char_action;
|
||||
typedef boost::function< void( Iter_type, Iter_type ) > Str_action;
|
||||
typedef boost::function< void( double ) > Real_action;
|
||||
typedef boost::function< void( boost::int64_t ) > Int_action;
|
||||
typedef boost::function< void( boost::uint64_t ) > Uint64_action;
|
||||
|
||||
Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) );
|
||||
Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) );
|
||||
Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) );
|
||||
Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) );
|
||||
Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) );
|
||||
Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) );
|
||||
Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) );
|
||||
Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) );
|
||||
Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) );
|
||||
Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) );
|
||||
Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) );
|
||||
Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) );
|
||||
|
||||
// actual grammer
|
||||
|
||||
json_
|
||||
= value_ | eps_p[ &throw_not_value ]
|
||||
;
|
||||
|
||||
value_
|
||||
= string_[ new_str ]
|
||||
| number_
|
||||
| object_
|
||||
| array_
|
||||
| str_p( "true" ) [ new_true ]
|
||||
| str_p( "false" )[ new_false ]
|
||||
| str_p( "null" ) [ new_null ]
|
||||
;
|
||||
|
||||
object_
|
||||
= ch_p('{')[ begin_obj ]
|
||||
>> !members_
|
||||
>> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] )
|
||||
;
|
||||
|
||||
members_
|
||||
= pair_ >> *( ',' >> pair_ )
|
||||
;
|
||||
|
||||
pair_
|
||||
= string_[ new_name ]
|
||||
>> ( ':' | eps_p[ &throw_not_colon ] )
|
||||
>> ( value_ | eps_p[ &throw_not_value ] )
|
||||
;
|
||||
|
||||
array_
|
||||
= ch_p('[')[ begin_array ]
|
||||
>> !elements_
|
||||
>> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] )
|
||||
;
|
||||
|
||||
elements_
|
||||
= value_ >> *( ',' >> value_ )
|
||||
;
|
||||
|
||||
string_
|
||||
= lexeme_d // this causes white space inside a string to be retained
|
||||
[
|
||||
confix_p
|
||||
(
|
||||
'"',
|
||||
*lex_escape_ch_p,
|
||||
'"'
|
||||
)
|
||||
]
|
||||
;
|
||||
|
||||
number_
|
||||
= strict_real_p[ new_real ]
|
||||
| int64_p [ new_int ]
|
||||
| uint64_p [ new_uint64 ]
|
||||
;
|
||||
}
|
||||
|
||||
spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_;
|
||||
|
||||
const spirit_namespace::rule< ScannerT >& start() const { return json_; }
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning
|
||||
|
||||
Semantic_actions_t& actions_;
|
||||
};
|
||||
|
||||
template< class Iter_type, class Value_type >
|
||||
Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
|
||||
{
|
||||
Semantic_actions< Value_type, Iter_type > semantic_actions( value );
|
||||
|
||||
const spirit_namespace::parse_info< Iter_type > info =
|
||||
spirit_namespace::parse( begin, end,
|
||||
Json_grammer< Value_type, Iter_type >( semantic_actions ),
|
||||
spirit_namespace::space_p );
|
||||
|
||||
if( !info.hit )
|
||||
{
|
||||
assert( false ); // in theory exception should already have been thrown
|
||||
throw_error( info.stop, "error" );
|
||||
}
|
||||
|
||||
return info.stop;
|
||||
}
|
||||
|
||||
template< class Iter_type, class Value_type >
|
||||
void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
|
||||
{
|
||||
typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t;
|
||||
|
||||
const Posn_iter_t posn_begin( begin, end );
|
||||
const Posn_iter_t posn_end( end, end );
|
||||
|
||||
read_range_or_throw( posn_begin, posn_end, value );
|
||||
}
|
||||
|
||||
template< class Iter_type, class Value_type >
|
||||
bool read_range( Iter_type& begin, Iter_type end, Value_type& value )
|
||||
{
|
||||
try
|
||||
{
|
||||
begin = read_range_or_throw( begin, end, value );
|
||||
|
||||
return true;
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template< class String_type, class Value_type >
|
||||
void read_string_or_throw( const String_type& s, Value_type& value )
|
||||
{
|
||||
add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value );
|
||||
}
|
||||
|
||||
template< class String_type, class Value_type >
|
||||
bool read_string( const String_type& s, Value_type& value )
|
||||
{
|
||||
typename String_type::const_iterator begin = s.begin();
|
||||
|
||||
return read_range( begin, s.end(), value );
|
||||
}
|
||||
|
||||
template< class Istream_type >
|
||||
struct Multi_pass_iters
|
||||
{
|
||||
typedef typename Istream_type::char_type Char_type;
|
||||
typedef std::istream_iterator< Char_type, Char_type > istream_iter;
|
||||
typedef spirit_namespace::multi_pass< istream_iter > Mp_iter;
|
||||
|
||||
Multi_pass_iters( Istream_type& is )
|
||||
{
|
||||
is.unsetf( std::ios::skipws );
|
||||
|
||||
begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) );
|
||||
end_ = spirit_namespace::make_multi_pass( istream_iter() );
|
||||
}
|
||||
|
||||
Mp_iter begin_;
|
||||
Mp_iter end_;
|
||||
};
|
||||
|
||||
template< class Istream_type, class Value_type >
|
||||
bool read_stream( Istream_type& is, Value_type& value )
|
||||
{
|
||||
Multi_pass_iters< Istream_type > mp_iters( is );
|
||||
|
||||
return read_range( mp_iters.begin_, mp_iters.end_, value );
|
||||
}
|
||||
|
||||
template< class Istream_type, class Value_type >
|
||||
void read_stream_or_throw( Istream_type& is, Value_type& value )
|
||||
{
|
||||
const Multi_pass_iters< Istream_type > mp_iters( is );
|
||||
|
||||
add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
70
json/json_spirit_stream_reader.h
Normal file
70
json/json_spirit_stream_reader.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#ifndef JSON_SPIRIT_READ_STREAM
|
||||
#define JSON_SPIRIT_READ_STREAM
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "json_spirit_reader_template.h"
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
// these classes allows you to read multiple top level contiguous values from a stream,
|
||||
// the normal stream read functions have a bug that prevent multiple top level values
|
||||
// from being read unless they are separated by spaces
|
||||
|
||||
template< class Istream_type, class Value_type >
|
||||
class Stream_reader
|
||||
{
|
||||
public:
|
||||
|
||||
Stream_reader( Istream_type& is )
|
||||
: iters_( is )
|
||||
{
|
||||
}
|
||||
|
||||
bool read_next( Value_type& value )
|
||||
{
|
||||
return read_range( iters_.begin_, iters_.end_, value );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef Multi_pass_iters< Istream_type > Mp_iters;
|
||||
|
||||
Mp_iters iters_;
|
||||
};
|
||||
|
||||
template< class Istream_type, class Value_type >
|
||||
class Stream_reader_thrower
|
||||
{
|
||||
public:
|
||||
|
||||
Stream_reader_thrower( Istream_type& is )
|
||||
: iters_( is )
|
||||
, posn_begin_( iters_.begin_, iters_.end_ )
|
||||
, posn_end_( iters_.end_, iters_.end_ )
|
||||
{
|
||||
}
|
||||
|
||||
void read_next( Value_type& value )
|
||||
{
|
||||
posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef Multi_pass_iters< Istream_type > Mp_iters;
|
||||
typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t;
|
||||
|
||||
Mp_iters iters_;
|
||||
Posn_iter_t posn_begin_, posn_end_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
61
json/json_spirit_utils.h
Normal file
61
json/json_spirit_utils.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef JSON_SPIRIT_UTILS
|
||||
#define JSON_SPIRIT_UTILS
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
#include <map>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
template< class Obj_t, class Map_t >
|
||||
void obj_to_map( const Obj_t& obj, Map_t& mp_obj )
|
||||
{
|
||||
mp_obj.clear();
|
||||
|
||||
for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i )
|
||||
{
|
||||
mp_obj[ i->name_ ] = i->value_;
|
||||
}
|
||||
}
|
||||
|
||||
template< class Obj_t, class Map_t >
|
||||
void map_to_obj( const Map_t& mp_obj, Obj_t& obj )
|
||||
{
|
||||
obj.clear();
|
||||
|
||||
for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i )
|
||||
{
|
||||
obj.push_back( typename Obj_t::value_type( i->first, i->second ) );
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::map< std::string, Value > Mapped_obj;
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
typedef std::map< std::wstring, wValue > wMapped_obj;
|
||||
#endif
|
||||
|
||||
template< class Object_type, class String_type >
|
||||
const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name )
|
||||
{
|
||||
for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i )
|
||||
{
|
||||
if( i->name_ == name )
|
||||
{
|
||||
return i->value_;
|
||||
}
|
||||
}
|
||||
|
||||
return Object_type::value_type::Value_type::null;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
8
json/json_spirit_value.cpp
Normal file
8
json/json_spirit_value.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
/* Copyright (c) 2007 John W Wilkinson
|
||||
|
||||
This source code can be used for any purpose as long as
|
||||
this comment is retained. */
|
||||
|
||||
// json spirit version 2.00
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
534
json/json_spirit_value.h
Normal file
534
json/json_spirit_value.h
Normal file
@@ -0,0 +1,534 @@
|
||||
#ifndef JSON_SPIRIT_VALUE
|
||||
#define JSON_SPIRIT_VALUE
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
|
||||
static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"};
|
||||
|
||||
template< class Config > // Config determines whether the value uses std::string or std::wstring and
|
||||
// whether JSON Objects are represented as vectors or maps
|
||||
class Value_impl
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Config Config_type;
|
||||
typedef typename Config::String_type String_type;
|
||||
typedef typename Config::Object_type Object;
|
||||
typedef typename Config::Array_type Array;
|
||||
typedef typename String_type::const_pointer Const_str_ptr; // eg const char*
|
||||
|
||||
Value_impl(); // creates null value
|
||||
Value_impl( Const_str_ptr value );
|
||||
Value_impl( const String_type& value );
|
||||
Value_impl( const Object& value );
|
||||
Value_impl( const Array& value );
|
||||
Value_impl( bool value );
|
||||
Value_impl( int value );
|
||||
Value_impl( boost::int64_t value );
|
||||
Value_impl( boost::uint64_t value );
|
||||
Value_impl( double value );
|
||||
|
||||
Value_impl( const Value_impl& other );
|
||||
|
||||
bool operator==( const Value_impl& lhs ) const;
|
||||
|
||||
Value_impl& operator=( const Value_impl& lhs );
|
||||
|
||||
Value_type type() const;
|
||||
|
||||
bool is_uint64() const;
|
||||
bool is_null() const;
|
||||
|
||||
const String_type& get_str() const;
|
||||
const Object& get_obj() const;
|
||||
const Array& get_array() const;
|
||||
bool get_bool() const;
|
||||
int get_int() const;
|
||||
boost::int64_t get_int64() const;
|
||||
boost::uint64_t get_uint64() const;
|
||||
double get_real() const;
|
||||
|
||||
Object& get_obj();
|
||||
Array& get_array();
|
||||
|
||||
template< typename T > T get_value() const; // example usage: int i = value.get_value< int >();
|
||||
// or double d = value.get_value< double >();
|
||||
|
||||
static const Value_impl null;
|
||||
|
||||
private:
|
||||
|
||||
void check_type( const Value_type vtype ) const;
|
||||
|
||||
typedef boost::variant< String_type,
|
||||
boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >,
|
||||
bool, boost::int64_t, double > Variant;
|
||||
|
||||
Value_type type_;
|
||||
Variant v_;
|
||||
bool is_uint64_;
|
||||
};
|
||||
|
||||
// vector objects
|
||||
|
||||
template< class Config >
|
||||
struct Pair_impl
|
||||
{
|
||||
typedef typename Config::String_type String_type;
|
||||
typedef typename Config::Value_type Value_type;
|
||||
|
||||
Pair_impl( const String_type& name, const Value_type& value );
|
||||
|
||||
bool operator==( const Pair_impl& lhs ) const;
|
||||
|
||||
String_type name_;
|
||||
Value_type value_;
|
||||
};
|
||||
|
||||
template< class String >
|
||||
struct Config_vector
|
||||
{
|
||||
typedef String String_type;
|
||||
typedef Value_impl< Config_vector > Value_type;
|
||||
typedef Pair_impl < Config_vector > Pair_type;
|
||||
typedef std::vector< Value_type > Array_type;
|
||||
typedef std::vector< Pair_type > Object_type;
|
||||
|
||||
static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
|
||||
{
|
||||
obj.push_back( Pair_type( name , value ) );
|
||||
|
||||
return obj.back().value_;
|
||||
}
|
||||
|
||||
static String_type get_name( const Pair_type& pair )
|
||||
{
|
||||
return pair.name_;
|
||||
}
|
||||
|
||||
static Value_type get_value( const Pair_type& pair )
|
||||
{
|
||||
return pair.value_;
|
||||
}
|
||||
};
|
||||
|
||||
// typedefs for ASCII
|
||||
|
||||
typedef Config_vector< std::string > Config;
|
||||
|
||||
typedef Config::Value_type Value;
|
||||
typedef Config::Pair_type Pair;
|
||||
typedef Config::Object_type Object;
|
||||
typedef Config::Array_type Array;
|
||||
|
||||
// typedefs for Unicode
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
typedef Config_vector< std::wstring > wConfig;
|
||||
|
||||
typedef wConfig::Value_type wValue;
|
||||
typedef wConfig::Pair_type wPair;
|
||||
typedef wConfig::Object_type wObject;
|
||||
typedef wConfig::Array_type wArray;
|
||||
#endif
|
||||
|
||||
// map objects
|
||||
|
||||
template< class String >
|
||||
struct Config_map
|
||||
{
|
||||
typedef String String_type;
|
||||
typedef Value_impl< Config_map > Value_type;
|
||||
typedef std::vector< Value_type > Array_type;
|
||||
typedef std::map< String_type, Value_type > Object_type;
|
||||
typedef typename Object_type::value_type Pair_type;
|
||||
|
||||
static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
|
||||
{
|
||||
return obj[ name ] = value;
|
||||
}
|
||||
|
||||
static String_type get_name( const Pair_type& pair )
|
||||
{
|
||||
return pair.first;
|
||||
}
|
||||
|
||||
static Value_type get_value( const Pair_type& pair )
|
||||
{
|
||||
return pair.second;
|
||||
}
|
||||
};
|
||||
|
||||
// typedefs for ASCII
|
||||
|
||||
typedef Config_map< std::string > mConfig;
|
||||
|
||||
typedef mConfig::Value_type mValue;
|
||||
typedef mConfig::Object_type mObject;
|
||||
typedef mConfig::Array_type mArray;
|
||||
|
||||
// typedefs for Unicode
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
typedef Config_map< std::wstring > wmConfig;
|
||||
|
||||
typedef wmConfig::Value_type wmValue;
|
||||
typedef wmConfig::Object_type wmObject;
|
||||
typedef wmConfig::Array_type wmArray;
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// implementation
|
||||
|
||||
template< class Config >
|
||||
const Value_impl< Config > Value_impl< Config >::null;
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl()
|
||||
: type_( null_type )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( const Const_str_ptr value )
|
||||
: type_( str_type )
|
||||
, v_( String_type( value ) )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( const String_type& value )
|
||||
: type_( str_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( const Object& value )
|
||||
: type_( obj_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( const Array& value )
|
||||
: type_( array_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( bool value )
|
||||
: type_( bool_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( int value )
|
||||
: type_( int_type )
|
||||
, v_( static_cast< boost::int64_t >( value ) )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( boost::int64_t value )
|
||||
: type_( int_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( boost::uint64_t value )
|
||||
: type_( int_type )
|
||||
, v_( static_cast< boost::int64_t >( value ) )
|
||||
, is_uint64_( true )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( double value )
|
||||
: type_( real_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
|
||||
: type_( other.type() )
|
||||
, v_( other.v_ )
|
||||
, is_uint64_( other.is_uint64_ )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs )
|
||||
{
|
||||
Value_impl tmp( lhs );
|
||||
|
||||
std::swap( type_, tmp.type_ );
|
||||
std::swap( v_, tmp.v_ );
|
||||
std::swap( is_uint64_, tmp.is_uint64_ );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
bool Value_impl< Config >::operator==( const Value_impl& lhs ) const
|
||||
{
|
||||
if( this == &lhs ) return true;
|
||||
|
||||
if( type() != lhs.type() ) return false;
|
||||
|
||||
return v_ == lhs.v_;
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_type Value_impl< Config >::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
bool Value_impl< Config >::is_uint64() const
|
||||
{
|
||||
return is_uint64_;
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
bool Value_impl< Config >::is_null() const
|
||||
{
|
||||
return type() == null_type;
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
void Value_impl< Config >::check_type( const Value_type vtype ) const
|
||||
{
|
||||
if( type() != vtype )
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
/// satoshi: tell the types by name instead of by number
|
||||
os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype];
|
||||
|
||||
throw std::runtime_error( os.str() );
|
||||
}
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
const typename Config::String_type& Value_impl< Config >::get_str() const
|
||||
{
|
||||
check_type( str_type );
|
||||
|
||||
return *boost::get< String_type >( &v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const
|
||||
{
|
||||
check_type( obj_type );
|
||||
|
||||
return *boost::get< Object >( &v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const
|
||||
{
|
||||
check_type( array_type );
|
||||
|
||||
return *boost::get< Array >( &v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
bool Value_impl< Config >::get_bool() const
|
||||
{
|
||||
check_type( bool_type );
|
||||
|
||||
return boost::get< bool >( v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
int Value_impl< Config >::get_int() const
|
||||
{
|
||||
check_type( int_type );
|
||||
|
||||
return static_cast< int >( get_int64() );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
boost::int64_t Value_impl< Config >::get_int64() const
|
||||
{
|
||||
check_type( int_type );
|
||||
|
||||
return boost::get< boost::int64_t >( v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
boost::uint64_t Value_impl< Config >::get_uint64() const
|
||||
{
|
||||
check_type( int_type );
|
||||
|
||||
return static_cast< boost::uint64_t >( get_int64() );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
double Value_impl< Config >::get_real() const
|
||||
{
|
||||
if( type() == int_type )
|
||||
{
|
||||
return is_uint64() ? static_cast< double >( get_uint64() )
|
||||
: static_cast< double >( get_int64() );
|
||||
}
|
||||
|
||||
check_type( real_type );
|
||||
|
||||
return boost::get< double >( v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
typename Value_impl< Config >::Object& Value_impl< Config >::get_obj()
|
||||
{
|
||||
check_type( obj_type );
|
||||
|
||||
return *boost::get< Object >( &v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
typename Value_impl< Config >::Array& Value_impl< Config >::get_array()
|
||||
{
|
||||
check_type( array_type );
|
||||
|
||||
return *boost::get< Array >( &v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value )
|
||||
: name_( name )
|
||||
, value_( value )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const
|
||||
{
|
||||
if( this == &lhs ) return true;
|
||||
|
||||
return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ );
|
||||
}
|
||||
|
||||
// converts a C string, ie. 8 bit char array, to a string object
|
||||
//
|
||||
template < class String_type >
|
||||
String_type to_str( const char* c_str )
|
||||
{
|
||||
String_type result;
|
||||
|
||||
for( const char* p = c_str; *p != 0; ++p )
|
||||
{
|
||||
result += *p;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
namespace internal_
|
||||
{
|
||||
template< typename T >
|
||||
struct Type_to_type
|
||||
{
|
||||
};
|
||||
|
||||
template< class Value >
|
||||
int get_value( const Value& value, Type_to_type< int > )
|
||||
{
|
||||
return value.get_int();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > )
|
||||
{
|
||||
return value.get_int64();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > )
|
||||
{
|
||||
return value.get_uint64();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
double get_value( const Value& value, Type_to_type< double > )
|
||||
{
|
||||
return value.get_real();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
|
||||
{
|
||||
return value.get_str();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > )
|
||||
{
|
||||
return value.get_array();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > )
|
||||
{
|
||||
return value.get_obj();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
bool get_value( const Value& value, Type_to_type< bool > )
|
||||
{
|
||||
return value.get_bool();
|
||||
}
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
template< typename T >
|
||||
T Value_impl< Config >::get_value() const
|
||||
{
|
||||
return internal_::get_value( *this, internal_::Type_to_type< T >() );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
95
json/json_spirit_writer.cpp
Normal file
95
json/json_spirit_writer.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#include "json_spirit_writer.h"
|
||||
#include "json_spirit_writer_template.h"
|
||||
|
||||
void json_spirit::write( const Value& value, std::ostream& os )
|
||||
{
|
||||
write_stream( value, os, false );
|
||||
}
|
||||
|
||||
void json_spirit::write_formatted( const Value& value, std::ostream& os )
|
||||
{
|
||||
write_stream( value, os, true );
|
||||
}
|
||||
|
||||
std::string json_spirit::write( const Value& value )
|
||||
{
|
||||
return write_string( value, false );
|
||||
}
|
||||
|
||||
std::string json_spirit::write_formatted( const Value& value )
|
||||
{
|
||||
return write_string( value, true );
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
void json_spirit::write( const wValue& value, std::wostream& os )
|
||||
{
|
||||
write_stream( value, os, false );
|
||||
}
|
||||
|
||||
void json_spirit::write_formatted( const wValue& value, std::wostream& os )
|
||||
{
|
||||
write_stream( value, os, true );
|
||||
}
|
||||
|
||||
std::wstring json_spirit::write( const wValue& value )
|
||||
{
|
||||
return write_string( value, false );
|
||||
}
|
||||
|
||||
std::wstring json_spirit::write_formatted( const wValue& value )
|
||||
{
|
||||
return write_string( value, true );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void json_spirit::write( const mValue& value, std::ostream& os )
|
||||
{
|
||||
write_stream( value, os, false );
|
||||
}
|
||||
|
||||
void json_spirit::write_formatted( const mValue& value, std::ostream& os )
|
||||
{
|
||||
write_stream( value, os, true );
|
||||
}
|
||||
|
||||
std::string json_spirit::write( const mValue& value )
|
||||
{
|
||||
return write_string( value, false );
|
||||
}
|
||||
|
||||
std::string json_spirit::write_formatted( const mValue& value )
|
||||
{
|
||||
return write_string( value, true );
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
void json_spirit::write( const wmValue& value, std::wostream& os )
|
||||
{
|
||||
write_stream( value, os, false );
|
||||
}
|
||||
|
||||
void json_spirit::write_formatted( const wmValue& value, std::wostream& os )
|
||||
{
|
||||
write_stream( value, os, true );
|
||||
}
|
||||
|
||||
std::wstring json_spirit::write( const wmValue& value )
|
||||
{
|
||||
return write_string( value, false );
|
||||
}
|
||||
|
||||
std::wstring json_spirit::write_formatted( const wmValue& value )
|
||||
{
|
||||
return write_string( value, true );
|
||||
}
|
||||
|
||||
#endif
|
||||
50
json/json_spirit_writer.h
Normal file
50
json/json_spirit_writer.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef JSON_SPIRIT_WRITER
|
||||
#define JSON_SPIRIT_WRITER
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
// functions to convert JSON Values to text,
|
||||
// the "formatted" versions add whitespace to format the output nicely
|
||||
|
||||
void write ( const Value& value, std::ostream& os );
|
||||
void write_formatted( const Value& value, std::ostream& os );
|
||||
std::string write ( const Value& value );
|
||||
std::string write_formatted( const Value& value );
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
void write ( const wValue& value, std::wostream& os );
|
||||
void write_formatted( const wValue& value, std::wostream& os );
|
||||
std::wstring write ( const wValue& value );
|
||||
std::wstring write_formatted( const wValue& value );
|
||||
|
||||
#endif
|
||||
|
||||
void write ( const mValue& value, std::ostream& os );
|
||||
void write_formatted( const mValue& value, std::ostream& os );
|
||||
std::string write ( const mValue& value );
|
||||
std::string write_formatted( const mValue& value );
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
void write ( const wmValue& value, std::wostream& os );
|
||||
void write_formatted( const wmValue& value, std::wostream& os );
|
||||
std::wstring write ( const wmValue& value );
|
||||
std::wstring write_formatted( const wmValue& value );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
245
json/json_spirit_writer_template.h
Normal file
245
json/json_spirit_writer_template.h
Normal file
@@ -0,0 +1,245 @@
|
||||
#ifndef JSON_SPIRIT_WRITER_TEMPLATE
|
||||
#define JSON_SPIRIT_WRITER_TEMPLATE
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
inline char to_hex_char( unsigned int c )
|
||||
{
|
||||
assert( c <= 0xF );
|
||||
|
||||
const char ch = static_cast< char >( c );
|
||||
|
||||
if( ch < 10 ) return '0' + ch;
|
||||
|
||||
return 'A' - 10 + ch;
|
||||
}
|
||||
|
||||
template< class String_type >
|
||||
String_type non_printable_to_string( unsigned int c )
|
||||
{
|
||||
typedef typename String_type::value_type Char_type;
|
||||
|
||||
String_type result( 6, '\\' );
|
||||
|
||||
result[1] = 'u';
|
||||
|
||||
result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4;
|
||||
result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4;
|
||||
result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4;
|
||||
result[ 2 ] = to_hex_char( c & 0x000F );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template< typename Char_type, class String_type >
|
||||
bool add_esc_char( Char_type c, String_type& s )
|
||||
{
|
||||
switch( c )
|
||||
{
|
||||
case '"': s += to_str< String_type >( "\\\"" ); return true;
|
||||
case '\\': s += to_str< String_type >( "\\\\" ); return true;
|
||||
case '\b': s += to_str< String_type >( "\\b" ); return true;
|
||||
case '\f': s += to_str< String_type >( "\\f" ); return true;
|
||||
case '\n': s += to_str< String_type >( "\\n" ); return true;
|
||||
case '\r': s += to_str< String_type >( "\\r" ); return true;
|
||||
case '\t': s += to_str< String_type >( "\\t" ); return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template< class String_type >
|
||||
String_type add_esc_chars( const String_type& s )
|
||||
{
|
||||
typedef typename String_type::const_iterator Iter_type;
|
||||
typedef typename String_type::value_type Char_type;
|
||||
|
||||
String_type result;
|
||||
|
||||
const Iter_type end( s.end() );
|
||||
|
||||
for( Iter_type i = s.begin(); i != end; ++i )
|
||||
{
|
||||
const Char_type c( *i );
|
||||
|
||||
if( add_esc_char( c, result ) ) continue;
|
||||
|
||||
const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c );
|
||||
|
||||
if( iswprint( unsigned_c ) )
|
||||
{
|
||||
result += c;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += non_printable_to_string< String_type >( unsigned_c );
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// this class generates the JSON text,
|
||||
// it keeps track of the indentation level etc.
|
||||
//
|
||||
template< class Value_type, class Ostream_type >
|
||||
class Generator
|
||||
{
|
||||
typedef typename Value_type::Config_type Config_type;
|
||||
typedef typename Config_type::String_type String_type;
|
||||
typedef typename Config_type::Object_type Object_type;
|
||||
typedef typename Config_type::Array_type Array_type;
|
||||
typedef typename String_type::value_type Char_type;
|
||||
typedef typename Object_type::value_type Obj_member_type;
|
||||
|
||||
public:
|
||||
|
||||
Generator( const Value_type& value, Ostream_type& os, bool pretty )
|
||||
: os_( os )
|
||||
, indentation_level_( 0 )
|
||||
, pretty_( pretty )
|
||||
{
|
||||
output( value );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void output( const Value_type& value )
|
||||
{
|
||||
switch( value.type() )
|
||||
{
|
||||
case obj_type: output( value.get_obj() ); break;
|
||||
case array_type: output( value.get_array() ); break;
|
||||
case str_type: output( value.get_str() ); break;
|
||||
case bool_type: output( value.get_bool() ); break;
|
||||
case int_type: output_int( value ); break;
|
||||
case real_type: os_ << std::showpoint << std::setprecision( 16 )
|
||||
<< value.get_real(); break;
|
||||
case null_type: os_ << "null"; break;
|
||||
default: assert( false );
|
||||
}
|
||||
}
|
||||
|
||||
void output( const Object_type& obj )
|
||||
{
|
||||
output_array_or_obj( obj, '{', '}' );
|
||||
}
|
||||
|
||||
void output( const Array_type& arr )
|
||||
{
|
||||
output_array_or_obj( arr, '[', ']' );
|
||||
}
|
||||
|
||||
void output( const Obj_member_type& member )
|
||||
{
|
||||
output( Config_type::get_name( member ) ); space();
|
||||
os_ << ':'; space();
|
||||
output( Config_type::get_value( member ) );
|
||||
}
|
||||
|
||||
void output_int( const Value_type& value )
|
||||
{
|
||||
if( value.is_uint64() )
|
||||
{
|
||||
os_ << value.get_uint64();
|
||||
}
|
||||
else
|
||||
{
|
||||
os_ << value.get_int64();
|
||||
}
|
||||
}
|
||||
|
||||
void output( const String_type& s )
|
||||
{
|
||||
os_ << '"' << add_esc_chars( s ) << '"';
|
||||
}
|
||||
|
||||
void output( bool b )
|
||||
{
|
||||
os_ << to_str< String_type >( b ? "true" : "false" );
|
||||
}
|
||||
|
||||
template< class T >
|
||||
void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char )
|
||||
{
|
||||
os_ << start_char; new_line();
|
||||
|
||||
++indentation_level_;
|
||||
|
||||
for( typename T::const_iterator i = t.begin(); i != t.end(); ++i )
|
||||
{
|
||||
indent(); output( *i );
|
||||
|
||||
typename T::const_iterator next = i;
|
||||
|
||||
if( ++next != t.end())
|
||||
{
|
||||
os_ << ',';
|
||||
}
|
||||
|
||||
new_line();
|
||||
}
|
||||
|
||||
--indentation_level_;
|
||||
|
||||
indent(); os_ << end_char;
|
||||
}
|
||||
|
||||
void indent()
|
||||
{
|
||||
if( !pretty_ ) return;
|
||||
|
||||
for( int i = 0; i < indentation_level_; ++i )
|
||||
{
|
||||
os_ << " ";
|
||||
}
|
||||
}
|
||||
|
||||
void space()
|
||||
{
|
||||
if( pretty_ ) os_ << ' ';
|
||||
}
|
||||
|
||||
void new_line()
|
||||
{
|
||||
if( pretty_ ) os_ << '\n';
|
||||
}
|
||||
|
||||
Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning
|
||||
|
||||
Ostream_type& os_;
|
||||
int indentation_level_;
|
||||
bool pretty_;
|
||||
};
|
||||
|
||||
template< class Value_type, class Ostream_type >
|
||||
void write_stream( const Value_type& value, Ostream_type& os, bool pretty )
|
||||
{
|
||||
Generator< Value_type, Ostream_type >( value, os, pretty );
|
||||
}
|
||||
|
||||
template< class Value_type >
|
||||
typename Value_type::String_type write_string( const Value_type& value, bool pretty )
|
||||
{
|
||||
typedef typename Value_type::String_type::value_type Char_type;
|
||||
|
||||
std::basic_ostringstream< Char_type > os;
|
||||
|
||||
write_stream( value, os, pretty );
|
||||
|
||||
return os.str();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2009 Satoshi Nakamoto
|
||||
Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
5
locale/readme.txt
Normal file
5
locale/readme.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
put bitcoin.po and bitcoin.mo files at:
|
||||
locale/<langcode>/LC_MESSAGES/bitcoin.mo and .po
|
||||
|
||||
.po is the sourcefile
|
||||
.mo is the compiled translation
|
||||
376
main.cpp
376
main.cpp
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -26,6 +26,7 @@ CBlockIndex* pindexGenesisBlock = NULL;
|
||||
int nBestHeight = -1;
|
||||
uint256 hashBestChain = 0;
|
||||
CBlockIndex* pindexBest = NULL;
|
||||
int64 nTimeBestReceived = 0;
|
||||
|
||||
map<uint256, CBlock*> mapOrphanBlocks;
|
||||
multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
|
||||
@@ -45,6 +46,9 @@ CKey keyUser;
|
||||
map<uint256, int> mapRequestCount;
|
||||
CCriticalSection cs_mapRequestCount;
|
||||
|
||||
map<string, string> mapAddressBook;
|
||||
CCriticalSection cs_mapAddressBook;
|
||||
|
||||
// Settings
|
||||
int fGenerateBitcoins = false;
|
||||
int64 nTransactionFee = 0;
|
||||
@@ -168,6 +172,27 @@ bool EraseFromWallet(uint256 hash)
|
||||
return true;
|
||||
}
|
||||
|
||||
void WalletUpdateSpent(const COutPoint& prevout)
|
||||
{
|
||||
// Anytime a signature is successfully verified, it's proof the outpoint is spent.
|
||||
// Update the wallet spent flag if it doesn't know due to wallet.dat being
|
||||
// restored from backup or the user making copies of wallet.dat.
|
||||
CRITICAL_BLOCK(cs_mapWallet)
|
||||
{
|
||||
map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
|
||||
if (mi != mapWallet.end())
|
||||
{
|
||||
CWalletTx& wtx = (*mi).second;
|
||||
if (!wtx.fSpent && wtx.vout[prevout.n].IsMine())
|
||||
{
|
||||
printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
|
||||
wtx.fSpent = true;
|
||||
wtx.WriteToDisk();
|
||||
vWalletUpdated.push_back(prevout.hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -552,7 +577,7 @@ bool CTransaction::RemoveFromMemoryPool()
|
||||
|
||||
|
||||
|
||||
int CMerkleTx::GetDepthInMainChain() const
|
||||
int CMerkleTx::GetDepthInMainChain(int& nHeightRet) const
|
||||
{
|
||||
if (hashBlock == 0 || nIndex == -1)
|
||||
return 0;
|
||||
@@ -573,6 +598,7 @@ int CMerkleTx::GetDepthInMainChain() const
|
||||
fMerkleVerified = true;
|
||||
}
|
||||
|
||||
nHeightRet = pindex->nHeight;
|
||||
return pindexBest->nHeight - pindex->nHeight + 1;
|
||||
}
|
||||
|
||||
@@ -622,15 +648,44 @@ bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
|
||||
|
||||
void ReacceptWalletTransactions()
|
||||
{
|
||||
// Reaccept any txes of ours that aren't already in a block
|
||||
CTxDB txdb("r");
|
||||
CRITICAL_BLOCK(cs_mapWallet)
|
||||
{
|
||||
foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
|
||||
{
|
||||
CWalletTx& wtx = item.second;
|
||||
if (!wtx.IsCoinBase() && !txdb.ContainsTx(wtx.GetHash()))
|
||||
wtx.AcceptWalletTransaction(txdb, false);
|
||||
if (wtx.fSpent && wtx.IsCoinBase())
|
||||
continue;
|
||||
|
||||
CTxIndex txindex;
|
||||
if (txdb.ReadTxIndex(wtx.GetHash(), txindex))
|
||||
{
|
||||
// Update fSpent if a tx got spent somewhere else by a copy of wallet.dat
|
||||
if (!wtx.fSpent)
|
||||
{
|
||||
if (txindex.vSpent.size() != wtx.vout.size())
|
||||
{
|
||||
printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %d != wtx.vout.size() %d\n", txindex.vSpent.size(), wtx.vout.size());
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < txindex.vSpent.size(); i++)
|
||||
{
|
||||
if (!txindex.vSpent[i].IsNull() && wtx.vout[i].IsMine())
|
||||
{
|
||||
printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
|
||||
wtx.fSpent = true;
|
||||
wtx.WriteToDisk();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reaccept any txes of ours that aren't already in a block
|
||||
if (!wtx.IsCoinBase())
|
||||
wtx.AcceptWalletTransaction(txdb, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -658,15 +713,20 @@ void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
|
||||
}
|
||||
}
|
||||
|
||||
void RelayWalletTransactions()
|
||||
void ResendWalletTransactions()
|
||||
{
|
||||
static int64 nLastTime;
|
||||
if (GetTime() - nLastTime < 10 * 60)
|
||||
// Do this infrequently and randomly to avoid giving away
|
||||
// that these are our transactions.
|
||||
static int64 nNextTime;
|
||||
if (GetTime() < nNextTime)
|
||||
return;
|
||||
bool fFirst = (nNextTime == 0);
|
||||
nNextTime = GetTime() + GetRand(120 * 60);
|
||||
if (fFirst)
|
||||
return;
|
||||
nLastTime = GetTime();
|
||||
|
||||
// Rebroadcast any of our txes that aren't in a block yet
|
||||
printf("RelayWalletTransactions()\n");
|
||||
printf("ResendWalletTransactions()\n");
|
||||
CTxDB txdb("r");
|
||||
CRITICAL_BLOCK(cs_mapWallet)
|
||||
{
|
||||
@@ -675,7 +735,10 @@ void RelayWalletTransactions()
|
||||
foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
|
||||
{
|
||||
CWalletTx& wtx = item.second;
|
||||
mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
|
||||
// Don't rebroadcast until it's had plenty of time that
|
||||
// it should have gotten in already by now.
|
||||
if (nTimeBestReceived - wtx.nTimeReceived > 60 * 60)
|
||||
mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
|
||||
}
|
||||
foreach(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
|
||||
{
|
||||
@@ -1169,10 +1232,11 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
|
||||
}
|
||||
}
|
||||
|
||||
// New best link
|
||||
// New best block
|
||||
hashBestChain = hash;
|
||||
pindexBest = pindexNew;
|
||||
nBestHeight = pindexBest->nHeight;
|
||||
nTimeBestReceived = GetTime();
|
||||
nTransactionsUpdated++;
|
||||
printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight);
|
||||
}
|
||||
@@ -1182,9 +1246,6 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
|
||||
|
||||
if (pindexNew == pindexBest)
|
||||
{
|
||||
// Relay wallet transactions that haven't gotten in yet
|
||||
RelayWalletTransactions();
|
||||
|
||||
// Notify UI to display prev block's coinbase if it was ours
|
||||
static uint256 hashPrevBestCoinBase;
|
||||
CRITICAL_BLOCK(cs_mapWallet)
|
||||
@@ -1254,11 +1315,10 @@ bool CBlock::AcceptBlock()
|
||||
if (nTime <= pindexPrev->GetMedianTimePast())
|
||||
return error("AcceptBlock() : block's timestamp is too early");
|
||||
|
||||
// Check that all transactions are finalized (starting around Mar 2010)
|
||||
if (nBestHeight > 36000)
|
||||
foreach(const CTransaction& tx, vtx)
|
||||
if (!tx.IsFinal(nTime))
|
||||
return error("AcceptBlock() : contains a non-final transaction");
|
||||
// Check that all transactions are finalized
|
||||
foreach(const CTransaction& tx, vtx)
|
||||
if (!tx.IsFinal(nTime))
|
||||
return error("AcceptBlock() : contains a non-final transaction");
|
||||
|
||||
// Check proof of work
|
||||
if (nBits != GetNextWorkRequired(pindexPrev))
|
||||
@@ -1274,7 +1334,9 @@ bool CBlock::AcceptBlock()
|
||||
if (!AddToBlockIndex(nFile, nBlockPos))
|
||||
return error("AcceptBlock() : AddToBlockIndex failed");
|
||||
|
||||
if (hashBestChain == hash && nBestHeight > 28000)
|
||||
// Don't relay old inventory during initial block download.
|
||||
// Please keep this number updated to a few thousand below current block count.
|
||||
if (hashBestChain == hash && nBestHeight > 40000)
|
||||
RelayInventory(CInv(MSG_BLOCK, hash));
|
||||
|
||||
// // Add atoms to user reviews for coins created
|
||||
@@ -1399,27 +1461,13 @@ bool ScanMessageStart(Stream& s)
|
||||
|
||||
bool CheckDiskSpace(int64 nAdditionalBytes)
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
uint64 nFreeBytesAvailable = 0; // bytes available to caller
|
||||
uint64 nTotalNumberOfBytes = 0; // bytes on disk
|
||||
uint64 nTotalNumberOfFreeBytes = 0; // free bytes on disk
|
||||
if (!GetDiskFreeSpaceEx(GetDataDir().c_str(),
|
||||
(PULARGE_INTEGER)&nFreeBytesAvailable,
|
||||
(PULARGE_INTEGER)&nTotalNumberOfBytes,
|
||||
(PULARGE_INTEGER)&nTotalNumberOfFreeBytes))
|
||||
{
|
||||
printf("ERROR: GetDiskFreeSpaceEx() failed\n");
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available;
|
||||
#endif
|
||||
|
||||
// Check for 15MB because database could create another 10MB log file at any time
|
||||
if (nFreeBytesAvailable < (int64)15000000 + nAdditionalBytes)
|
||||
{
|
||||
fShutdown = true;
|
||||
ThreadSafeMessageBox("Warning: Your disk space is low ", "Bitcoin", wxOK | wxICON_EXCLAMATION);
|
||||
ThreadSafeMessageBox(_("Warning: Disk space is low "), "Bitcoin", wxOK | wxICON_EXCLAMATION);
|
||||
CreateThread(Shutdown, NULL);
|
||||
return false;
|
||||
}
|
||||
@@ -1507,9 +1555,11 @@ bool LoadBlockIndex(bool fAllowNew)
|
||||
CTransaction txNew;
|
||||
txNew.vin.resize(1);
|
||||
txNew.vout.resize(1);
|
||||
txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
|
||||
txNew.vout[0].nValue = 50 * COIN;
|
||||
txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG;
|
||||
txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
|
||||
txNew.vout[0].nValue = 50 * COIN;
|
||||
CBigNum bnPubKey;
|
||||
bnPubKey.SetHex("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704");
|
||||
txNew.vout[0].scriptPubKey = CScript() << bnPubKey << OP_CHECKSIG;
|
||||
CBlock block;
|
||||
block.vtx.push_back(txNew);
|
||||
block.hashPrevBlock = 0;
|
||||
@@ -1643,10 +1693,8 @@ bool AlreadyHave(CTxDB& txdb, const CInv& inv)
|
||||
{
|
||||
switch (inv.type)
|
||||
{
|
||||
case MSG_TX: return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash);
|
||||
case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash);
|
||||
case MSG_REVIEW: return true;
|
||||
case MSG_PRODUCT: return mapProducts.count(inv.hash);
|
||||
case MSG_TX: return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash);
|
||||
case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash);
|
||||
}
|
||||
// Don't know what it is, just say we already got one
|
||||
return true;
|
||||
@@ -1734,6 +1782,11 @@ bool ProcessMessages(CNode* pfrom)
|
||||
// Allow exceptions from underlength message on vRecv
|
||||
printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what());
|
||||
}
|
||||
else if (strstr(e.what(), ": size too large"))
|
||||
{
|
||||
// Allow exceptions from overlong size
|
||||
printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what());
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintException(&e, "ProcessMessage()");
|
||||
@@ -1840,7 +1893,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
return error("message addr size() = %d", vAddr.size());
|
||||
|
||||
// Store the new addresses
|
||||
CAddrDB addrdb;
|
||||
foreach(CAddress& addr, vAddr)
|
||||
{
|
||||
if (fShutdown)
|
||||
@@ -1848,7 +1900,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
addr.nTime = GetAdjustedTime() - 2 * 60 * 60;
|
||||
if (pfrom->fGetAddr)
|
||||
addr.nTime -= 5 * 24 * 60 * 60;
|
||||
AddAddress(addrdb, addr, false);
|
||||
AddAddress(addr, false);
|
||||
pfrom->AddAddressKnown(addr);
|
||||
if (!pfrom->fGetAddr && addr.IsRoutable())
|
||||
{
|
||||
@@ -2041,24 +2093,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
}
|
||||
|
||||
|
||||
else if (strCommand == "review")
|
||||
{
|
||||
CDataStream vMsg(vRecv);
|
||||
CReview review;
|
||||
vRecv >> review;
|
||||
|
||||
CInv inv(MSG_REVIEW, review.GetHash());
|
||||
pfrom->AddInventoryKnown(inv);
|
||||
|
||||
if (review.AcceptReview())
|
||||
{
|
||||
// Relay the original message as-is in case it's a higher version than we know how to parse
|
||||
RelayMessage(inv, vMsg);
|
||||
mapAlreadyAskedFor.erase(inv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
else if (strCommand == "block")
|
||||
{
|
||||
auto_ptr<CBlock> pblock(new CBlock);
|
||||
@@ -2194,7 +2228,7 @@ bool SendMessages(CNode* pto)
|
||||
return true;
|
||||
|
||||
// Keep-alive ping
|
||||
if (pto->nLastSend && GetTime() - pto->nLastSend > 12 * 60 && pto->vSend.empty())
|
||||
if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty())
|
||||
pto->PushMessage("ping");
|
||||
|
||||
// Address refresh broadcast
|
||||
@@ -2216,60 +2250,81 @@ bool SendMessages(CNode* pto)
|
||||
}
|
||||
}
|
||||
|
||||
// Delay tx inv messages to protect privacy,
|
||||
// trickle them out to a few nodes at a time.
|
||||
bool fSendTxInv = false;
|
||||
if (GetTimeMillis() - pto->nLastSentTxInv > 1800 + GetRand(200))
|
||||
{
|
||||
pto->nLastSentTxInv = GetTimeMillis();
|
||||
fSendTxInv = true;
|
||||
}
|
||||
|
||||
// Resend wallet transactions that haven't gotten in a block yet
|
||||
ResendWalletTransactions();
|
||||
|
||||
|
||||
//
|
||||
// Message: addr
|
||||
//
|
||||
vector<CAddress> vAddrToSend;
|
||||
vAddrToSend.reserve(pto->vAddrToSend.size());
|
||||
vector<CAddress> vAddr;
|
||||
vAddr.reserve(pto->vAddrToSend.size());
|
||||
foreach(const CAddress& addr, pto->vAddrToSend)
|
||||
{
|
||||
// returns true if wasn't already contained in the set
|
||||
if (pto->setAddrKnown.insert(addr).second)
|
||||
{
|
||||
vAddrToSend.push_back(addr);
|
||||
if (vAddrToSend.size() >= 1000)
|
||||
vAddr.push_back(addr);
|
||||
if (vAddr.size() >= 1000)
|
||||
{
|
||||
pto->PushMessage("addr", vAddrToSend);
|
||||
vAddrToSend.clear();
|
||||
pto->PushMessage("addr", vAddr);
|
||||
vAddr.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
pto->vAddrToSend.clear();
|
||||
if (!vAddrToSend.empty())
|
||||
pto->PushMessage("addr", vAddrToSend);
|
||||
if (!vAddr.empty())
|
||||
pto->PushMessage("addr", vAddr);
|
||||
|
||||
|
||||
//
|
||||
// Message: inventory
|
||||
//
|
||||
vector<CInv> vInventoryToSend;
|
||||
vector<CInv> vInv;
|
||||
vector<CInv> vInvWait;
|
||||
CRITICAL_BLOCK(pto->cs_inventory)
|
||||
{
|
||||
vInventoryToSend.reserve(pto->vInventoryToSend.size());
|
||||
vInv.reserve(pto->vInventoryToSend.size());
|
||||
vInvWait.reserve(pto->vInventoryToSend.size());
|
||||
foreach(const CInv& inv, pto->vInventoryToSend)
|
||||
{
|
||||
// delay txes
|
||||
if (!fSendTxInv && inv.type == MSG_TX)
|
||||
{
|
||||
vInvWait.push_back(inv);
|
||||
continue;
|
||||
}
|
||||
|
||||
// returns true if wasn't already contained in the set
|
||||
if (pto->setInventoryKnown.insert(inv).second)
|
||||
{
|
||||
vInventoryToSend.push_back(inv);
|
||||
if (vInventoryToSend.size() >= 1000)
|
||||
vInv.push_back(inv);
|
||||
if (vInv.size() >= 1000)
|
||||
{
|
||||
pto->PushMessage("inv", vInventoryToSend);
|
||||
vInventoryToSend.clear();
|
||||
pto->PushMessage("inv", vInv);
|
||||
vInv.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
pto->vInventoryToSend.clear();
|
||||
pto->vInventoryToSend = vInvWait;
|
||||
}
|
||||
if (!vInventoryToSend.empty())
|
||||
pto->PushMessage("inv", vInventoryToSend);
|
||||
if (!vInv.empty())
|
||||
pto->PushMessage("inv", vInv);
|
||||
|
||||
|
||||
//
|
||||
// Message: getdata
|
||||
//
|
||||
vector<CInv> vAskFor;
|
||||
vector<CInv> vGetData;
|
||||
int64 nNow = GetTime() * 1000000;
|
||||
CTxDB txdb("r");
|
||||
while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
|
||||
@@ -2278,17 +2333,17 @@ bool SendMessages(CNode* pto)
|
||||
if (!AlreadyHave(txdb, inv))
|
||||
{
|
||||
printf("sending getdata: %s\n", inv.ToString().c_str());
|
||||
vAskFor.push_back(inv);
|
||||
if (vAskFor.size() >= 1000)
|
||||
vGetData.push_back(inv);
|
||||
if (vGetData.size() >= 1000)
|
||||
{
|
||||
pto->PushMessage("getdata", vAskFor);
|
||||
vAskFor.clear();
|
||||
pto->PushMessage("getdata", vGetData);
|
||||
vGetData.clear();
|
||||
}
|
||||
}
|
||||
pto->mapAskFor.erase(pto->mapAskFor.begin());
|
||||
}
|
||||
if (!vAskFor.empty())
|
||||
pto->PushMessage("getdata", vAskFor);
|
||||
if (!vGetData.empty())
|
||||
pto->PushMessage("getdata", vGetData);
|
||||
|
||||
}
|
||||
return true;
|
||||
@@ -2351,7 +2406,6 @@ void ThreadBitcoinMiner(void* parg)
|
||||
vnThreadsRunning[3]--;
|
||||
PrintException(NULL, "ThreadBitcoinMiner()");
|
||||
}
|
||||
|
||||
printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]);
|
||||
}
|
||||
|
||||
@@ -2592,7 +2646,12 @@ void BitcoinMiner()
|
||||
do
|
||||
{
|
||||
pindexTmp = pindexBest;
|
||||
Sleep(10000);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
Sleep(1000);
|
||||
if (fShutdown)
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (pindexTmp != pindexBest);
|
||||
}
|
||||
@@ -2788,14 +2847,24 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK
|
||||
// Fill a vout back to self with any change
|
||||
if (nValueIn > nTotalValue)
|
||||
{
|
||||
// Note: We use a new key here to keep it from being obvious which side is the change.
|
||||
// The drawback is that by not reusing a previous key, the change may be lost if a
|
||||
// backup is restored, if the backup doesn't have the new private key for the change.
|
||||
// If we reused the old key, it would be possible to add code to look for and
|
||||
// rediscover unknown transactions that were written with keys of ours to recover
|
||||
// post-backup change.
|
||||
|
||||
// New private key
|
||||
if (keyRet.IsNull())
|
||||
keyRet.MakeNewKey();
|
||||
|
||||
// Fill a vout to ourself
|
||||
CScript scriptPubKey;
|
||||
scriptPubKey << keyRet.GetPubKey() << OP_CHECKSIG;
|
||||
wtxNew.vout.push_back(CTxOut(nValueIn - nTotalValue, scriptPubKey));
|
||||
// Fill a vout to ourself, using same address type as the payment
|
||||
CScript scriptChange;
|
||||
if (scriptPubKey.GetBitcoinAddressHash160() != 0)
|
||||
scriptChange.SetBitcoinAddress(keyRet.GetPubKey());
|
||||
else
|
||||
scriptChange << keyRet.GetPubKey() << OP_CHECKSIG;
|
||||
wtxNew.vout.push_back(CTxOut(nValueIn - nTotalValue, scriptChange));
|
||||
}
|
||||
|
||||
// Fill a vout to the payee
|
||||
@@ -2834,38 +2903,50 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK
|
||||
}
|
||||
|
||||
// Call after CreateTransaction unless you want to abort
|
||||
bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key)
|
||||
bool CommitTransaction(CWalletTx& wtxNew, const CKey& key)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_main)
|
||||
CRITICAL_BLOCK(cs_mapWallet)
|
||||
{
|
||||
//// todo: eventually should make this transactional, never want to add a
|
||||
//// transaction without marking spent transactions, although the risk of
|
||||
//// interruption during this step is remote.
|
||||
|
||||
// This is only to keep the database open to defeat the auto-flush for the
|
||||
// duration of this scope. This is the only place where this optimization
|
||||
// maybe makes sense; please don't do it anywhere else.
|
||||
CWalletDB walletdb("r");
|
||||
|
||||
// Add the change's private key to wallet
|
||||
if (!key.IsNull() && !AddKey(key))
|
||||
throw runtime_error("CommitTransactionSpent() : AddKey failed\n");
|
||||
|
||||
// Add tx to wallet, because if it has change it's also ours,
|
||||
// otherwise just for transaction history.
|
||||
AddToWallet(wtxNew);
|
||||
|
||||
// Mark old coins as spent
|
||||
set<CWalletTx*> setCoins;
|
||||
foreach(const CTxIn& txin, wtxNew.vin)
|
||||
setCoins.insert(&mapWallet[txin.prevout.hash]);
|
||||
foreach(CWalletTx* pcoin, setCoins)
|
||||
printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
|
||||
CRITICAL_BLOCK(cs_mapWallet)
|
||||
{
|
||||
pcoin->fSpent = true;
|
||||
pcoin->WriteToDisk();
|
||||
vWalletUpdated.push_back(pcoin->GetHash());
|
||||
// This is only to keep the database open to defeat the auto-flush for the
|
||||
// duration of this scope. This is the only place where this optimization
|
||||
// maybe makes sense; please don't do it anywhere else.
|
||||
CWalletDB walletdb("r");
|
||||
|
||||
// Add the change's private key to wallet
|
||||
if (!key.IsNull() && !AddKey(key))
|
||||
throw runtime_error("CommitTransaction() : AddKey failed\n");
|
||||
|
||||
// Add tx to wallet, because if it has change it's also ours,
|
||||
// otherwise just for transaction history.
|
||||
AddToWallet(wtxNew);
|
||||
|
||||
// Mark old coins as spent
|
||||
set<CWalletTx*> setCoins;
|
||||
foreach(const CTxIn& txin, wtxNew.vin)
|
||||
setCoins.insert(&mapWallet[txin.prevout.hash]);
|
||||
foreach(CWalletTx* pcoin, setCoins)
|
||||
{
|
||||
pcoin->fSpent = true;
|
||||
pcoin->WriteToDisk();
|
||||
vWalletUpdated.push_back(pcoin->GetHash());
|
||||
}
|
||||
}
|
||||
|
||||
// Track how many getdata requests our transaction gets
|
||||
CRITICAL_BLOCK(cs_mapRequestCount)
|
||||
mapRequestCount[wtxNew.GetHash()] = 0;
|
||||
|
||||
// Broadcast
|
||||
if (!wtxNew.AcceptTransaction())
|
||||
{
|
||||
// This must not fail. The transaction has already been signed and recorded.
|
||||
printf("CommitTransaction() : Error: Transaction not valid");
|
||||
return false;
|
||||
}
|
||||
wtxNew.RelayWalletTransaction();
|
||||
}
|
||||
MainFrameRepaint();
|
||||
return true;
|
||||
@@ -2874,7 +2955,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key)
|
||||
|
||||
|
||||
|
||||
bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew)
|
||||
string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
|
||||
{
|
||||
CRITICAL_BLOCK(cs_main)
|
||||
{
|
||||
@@ -2884,34 +2965,37 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew)
|
||||
{
|
||||
string strError;
|
||||
if (nValue + nFeeRequired > GetBalance())
|
||||
strError = strprintf("Error: This is an oversized transaction that requires a transaction fee of %s ", FormatMoney(nFeeRequired).c_str());
|
||||
strError = strprintf(_("Error: This is an oversized transaction that requires a transaction fee of %s "), FormatMoney(nFeeRequired).c_str());
|
||||
else
|
||||
strError = "Error: Transaction creation failed ";
|
||||
wxMessageBox(strError, "Sending...");
|
||||
return error("SendMoney() : %s", strError.c_str());
|
||||
}
|
||||
if (!CommitTransactionSpent(wtxNew, key))
|
||||
{
|
||||
wxMessageBox("Error finalizing transaction ", "Sending...");
|
||||
return error("SendMoney() : Error finalizing transaction");
|
||||
strError = _("Error: Transaction creation failed ");
|
||||
printf("SendMoney() : %s", strError.c_str());
|
||||
return strError;
|
||||
}
|
||||
|
||||
// Track how many getdata requests our transaction gets
|
||||
CRITICAL_BLOCK(cs_mapRequestCount)
|
||||
mapRequestCount[wtxNew.GetHash()] = 0;
|
||||
if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL))
|
||||
return "ABORTED";
|
||||
|
||||
printf("SendMoney: %s\n", wtxNew.GetHash().ToString().substr(0,6).c_str());
|
||||
|
||||
// Broadcast
|
||||
if (!wtxNew.AcceptTransaction())
|
||||
{
|
||||
// This must not fail. The transaction has already been signed and recorded.
|
||||
throw runtime_error("SendMoney() : wtxNew.AcceptTransaction() failed\n");
|
||||
wxMessageBox("Error: Transaction not valid ", "Sending...");
|
||||
return error("SendMoney() : Error: Transaction not valid");
|
||||
}
|
||||
wtxNew.RelayWalletTransaction();
|
||||
if (!CommitTransaction(wtxNew, key))
|
||||
return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
|
||||
}
|
||||
MainFrameRepaint();
|
||||
return true;
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
|
||||
{
|
||||
// Check amount
|
||||
if (nValue <= 0)
|
||||
return _("Invalid amount");
|
||||
if (nValue + nTransactionFee > GetBalance())
|
||||
return _("You don't have enough money");
|
||||
|
||||
// Parse bitcoin address
|
||||
CScript scriptPubKey;
|
||||
if (!scriptPubKey.SetBitcoinAddress(strAddress))
|
||||
return _("Invalid bitcoin address");
|
||||
|
||||
return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
|
||||
}
|
||||
|
||||
44
main.h
44
main.h
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -36,6 +36,8 @@ extern CBlockIndex* pindexBest;
|
||||
extern unsigned int nTransactionsUpdated;
|
||||
extern map<uint256, int> mapRequestCount;
|
||||
extern CCriticalSection cs_mapRequestCount;
|
||||
extern map<string, string> mapAddressBook;
|
||||
extern CCriticalSection cs_mapAddressBook;
|
||||
|
||||
// Settings
|
||||
extern int fGenerateBitcoins;
|
||||
@@ -56,8 +58,8 @@ FILE* AppendBlockFile(unsigned int& nFileRet);
|
||||
bool AddKey(const CKey& key);
|
||||
vector<unsigned char> GenerateNewKey();
|
||||
bool AddToWallet(const CWalletTx& wtxIn);
|
||||
void WalletUpdateSpent(const COutPoint& prevout);
|
||||
void ReacceptWalletTransactions();
|
||||
void RelayWalletTransactions();
|
||||
bool LoadBlockIndex(bool fAllowNew=true);
|
||||
void PrintBlockTree();
|
||||
bool ProcessMessages(CNode* pfrom);
|
||||
@@ -65,8 +67,10 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv);
|
||||
bool SendMessages(CNode* pto);
|
||||
int64 GetBalance();
|
||||
bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet);
|
||||
bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key);
|
||||
bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew);
|
||||
bool CommitTransaction(CWalletTx& wtxNew, const CKey& key);
|
||||
bool BroadcastTransaction(CWalletTx& wtxNew);
|
||||
string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
|
||||
string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
|
||||
void GenerateBitcoins(bool fGenerate);
|
||||
void ThreadBitcoinMiner(void* parg);
|
||||
void BitcoinMiner();
|
||||
@@ -679,7 +683,8 @@ public:
|
||||
|
||||
|
||||
int SetMerkleBranch(const CBlock* pblock=NULL);
|
||||
int GetDepthInMainChain() const;
|
||||
int GetDepthInMainChain(int& nHeightRet) const;
|
||||
int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
|
||||
bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
|
||||
int GetBlocksToMaturity() const;
|
||||
bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true);
|
||||
@@ -1370,6 +1375,35 @@ public:
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Private key that includes an expiration date in case it never gets used.
|
||||
//
|
||||
class CWalletKey
|
||||
{
|
||||
public:
|
||||
CPrivKey vchPrivKey;
|
||||
int64 nTimeCreated;
|
||||
int64 nTimeExpires;
|
||||
string strComment;
|
||||
//// todo: add something to note what created it (user, getnewaddress, change)
|
||||
//// maybe should have a map<string, string> property map
|
||||
|
||||
CWalletKey(int64 nTimeExpiresIn=0)
|
||||
{
|
||||
nTimeCreated = (nTimeExpiresIn ? GetTime() : 0);
|
||||
nTimeExpires = nTimeExpiresIn;
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
if (!(nType & SER_GETHASH))
|
||||
READWRITE(nVersion);
|
||||
READWRITE(vchPrivKey);
|
||||
READWRITE(nTimeCreated);
|
||||
READWRITE(nTimeExpires);
|
||||
READWRITE(strComment);
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,37 +1,41 @@
|
||||
# Copyright (c) 2009 Satoshi Nakamoto
|
||||
# Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
ifneq "$(BUILD)" "debug"
|
||||
ifneq "$(BUILD)" "release"
|
||||
BUILD=debug
|
||||
endif
|
||||
endif
|
||||
ifeq "$(BUILD)" "debug"
|
||||
D=d
|
||||
DEBUGFLAGS=-g -D__WXDEBUG__
|
||||
endif
|
||||
# for wxWidgets-2.8.x, search and replace "mswud"->"mswd" and "29u"->"28"
|
||||
|
||||
INCLUDEPATHS= \
|
||||
-I"/boost" \
|
||||
-I"/db/build_unix" \
|
||||
-I"/openssl/include" \
|
||||
-I"/wxwidgets/lib/gcc_lib/mswud" \
|
||||
-I"/wxwidgets/include"
|
||||
|
||||
LIBPATHS= \
|
||||
-L"/boost/stage/lib" \
|
||||
-L"/db/build_unix" \
|
||||
-L"/openssl/out" \
|
||||
-L"/wxwidgets/lib/gcc_lib"
|
||||
|
||||
INCLUDEPATHS=-I"/boost" -I"/db/build_unix" -I"/openssl/include" -I"/wxwidgets/lib/vc_lib/mswd" -I"/wxwidgets/include"
|
||||
LIBPATHS=-L"/db/build_unix" -L"/openssl/out" -L"/wxwidgets/lib/gcc_lib"
|
||||
LIBS= \
|
||||
-l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \
|
||||
-l db_cxx \
|
||||
-l eay32 \
|
||||
-l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxmsw28$(D)_adv -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \
|
||||
-l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd \
|
||||
-l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
|
||||
|
||||
WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH
|
||||
DEBUGFLAGS=-g -D__WXDEBUG__
|
||||
CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
|
||||
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h
|
||||
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h
|
||||
|
||||
|
||||
|
||||
all: bitcoin.exe
|
||||
|
||||
|
||||
headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h
|
||||
headers.h.gch: headers.h $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/util.o: util.cpp $(HEADERS)
|
||||
@@ -40,19 +44,16 @@ obj/util.o: util.cpp $(HEADERS)
|
||||
obj/script.o: script.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/db.o: db.cpp $(HEADERS) market.h
|
||||
obj/db.o: db.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/net.o: net.cpp $(HEADERS) net.h
|
||||
obj/net.o: net.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h
|
||||
obj/main.o: main.cpp $(HEADERS) sha.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/market.o: market.cpp $(HEADERS) market.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h
|
||||
obj/ui.o: ui.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/uibase.o: uibase.cpp uibase.h
|
||||
@@ -64,13 +65,17 @@ obj/sha.o: sha.cpp sha.h
|
||||
obj/irc.o: irc.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/rpc.o: rpc.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
|
||||
windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $<
|
||||
|
||||
|
||||
|
||||
OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \
|
||||
obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o
|
||||
OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \
|
||||
obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o \
|
||||
obj/ui_res.o
|
||||
|
||||
bitcoin.exe: headers.h.gch $(OBJS)
|
||||
-kill /f bitcoin.exe
|
||||
@@ -1,24 +1,13 @@
|
||||
# Copyright (c) 2009 Satoshi Nakamoto
|
||||
# Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
ifneq "$(BUILD)" "debug"
|
||||
ifneq "$(BUILD)" "release"
|
||||
BUILD=debug
|
||||
endif
|
||||
endif
|
||||
ifeq "$(BUILD)" "debug"
|
||||
D=d
|
||||
DEBUGFLAGS=-g -D__WXDEBUG__
|
||||
endif
|
||||
|
||||
|
||||
|
||||
INCLUDEPATHS= \
|
||||
-I"/usr/include" \
|
||||
-I"/usr/local/include/wx-2.8" \
|
||||
-I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8"
|
||||
-I"/usr/local/include/wx-2.9" \
|
||||
-I"/usr/local/lib/wx/include/gtk2-unicode-debug-static-2.9"
|
||||
|
||||
LIBPATHS= \
|
||||
-L"/usr/lib" \
|
||||
@@ -26,23 +15,24 @@ LIBPATHS= \
|
||||
|
||||
LIBS= \
|
||||
-Wl,-Bstatic \
|
||||
-l boost_system -l boost_filesystem \
|
||||
-l boost_system-mt -l boost_filesystem-mt \
|
||||
-l db_cxx \
|
||||
-l wx_gtk2$(D)-2.8 \
|
||||
-l wx_gtk2ud-2.9 \
|
||||
-Wl,-Bdynamic \
|
||||
-l crypto \
|
||||
-l gtk-x11-2.0 -l gthread-2.0 -l SM
|
||||
|
||||
WXDEFS=-D__WXGTK__ -DNOPCH
|
||||
DEBUGFLAGS=-g -D__WXDEBUG__
|
||||
CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
|
||||
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h
|
||||
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h
|
||||
|
||||
|
||||
|
||||
all: bitcoin
|
||||
|
||||
|
||||
headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h
|
||||
headers.h.gch: headers.h $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/util.o: util.cpp $(HEADERS)
|
||||
@@ -51,19 +41,16 @@ obj/util.o: util.cpp $(HEADERS)
|
||||
obj/script.o: script.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/db.o: db.cpp $(HEADERS) market.h
|
||||
obj/db.o: db.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/net.o: net.cpp $(HEADERS) net.h
|
||||
obj/net.o: net.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h
|
||||
obj/main.o: main.cpp $(HEADERS) sha.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/market.o: market.cpp $(HEADERS) market.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h
|
||||
obj/ui.o: ui.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/uibase.o: uibase.cpp uibase.h
|
||||
@@ -75,11 +62,13 @@ obj/sha.o: sha.cpp sha.h
|
||||
obj/irc.o: irc.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/rpc.o: rpc.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
|
||||
|
||||
OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \
|
||||
obj/ui.o obj/uibase.o obj/sha.o obj/irc.o
|
||||
OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \
|
||||
obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o
|
||||
|
||||
bitcoin: headers.h.gch $(OBJS)
|
||||
g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS)
|
||||
|
||||
59
makefile.vc
59
makefile.vc
@@ -1,28 +1,34 @@
|
||||
# Copyright (c) 2009 Satoshi Nakamoto
|
||||
# Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
!IF "$(BUILD)" != "debug" && "$(BUILD)" != "release"
|
||||
BUILD=debug
|
||||
!ENDIF
|
||||
!IF "$(BUILD)" == "debug"
|
||||
D=d
|
||||
DEBUGFLAGS=/Zi /Od /D__WXDEBUG__
|
||||
!ENDIF
|
||||
# for wxWidgets-2.8.x, search and replace "mswud"->"mswd" and "29u"->"28"
|
||||
|
||||
INCLUDEPATHS= \
|
||||
/I"/boost" \
|
||||
/I"/db/build_windows" \
|
||||
/I"/openssl/include" \
|
||||
/I"/wxwidgets/lib/vc_lib/mswud" \
|
||||
/I"/wxwidgets/include"
|
||||
|
||||
LIBPATHS= \
|
||||
/LIBPATH:"/boost/stage/lib" \
|
||||
/LIBPATH:"/db/build_windows/debug" \
|
||||
/LIBPATH:"/openssl/out" \
|
||||
/LIBPATH:"/wxwidgets/lib/vc_lib"
|
||||
|
||||
INCLUDEPATHS=/I"/boost" /I"/db/build_windows" /I"/openssl/include" /I"/wxwidgets/lib/vc_lib/mswd" /I"/wxwidgets/include"
|
||||
LIBPATHS=/LIBPATH:"/db/build_windows/$(BUILD)" /LIBPATH:"/openssl/out" /LIBPATH:"/wxwidgets/lib/vc_lib"
|
||||
LIBS= \
|
||||
libdb47s$(D).lib \
|
||||
libeay32.lib \
|
||||
wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxmsw28$(D)_adv.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).lib \
|
||||
kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib shlwapi.lib
|
||||
libboost_system-vc80-mt-gd.lib libboost_filesystem-vc80-mt-gd.lib \
|
||||
libdb47sd.lib \
|
||||
libeay32.lib \
|
||||
wxmsw29ud_html.lib wxmsw29ud_core.lib wxmsw29ud_adv.lib wxbase29ud.lib wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.lib \
|
||||
kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib shlwapi.lib
|
||||
|
||||
WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH
|
||||
CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 /YX /Fpobj/headers.pch $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
|
||||
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h
|
||||
DEBUGFLAGS=/Zi /Od /D__WXDEBUG__
|
||||
CFLAGS=/c /nologo /Ob0 /MDd /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
|
||||
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h
|
||||
|
||||
|
||||
|
||||
@@ -35,37 +41,38 @@ obj\util.obj: util.cpp $(HEADERS)
|
||||
obj\script.obj: script.cpp $(HEADERS)
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\db.obj: db.cpp $(HEADERS) market.h
|
||||
obj\db.obj: db.cpp $(HEADERS)
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\net.obj: net.cpp $(HEADERS) net.h
|
||||
obj\net.obj: net.cpp $(HEADERS)
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\main.obj: main.cpp $(HEADERS) net.h market.h
|
||||
obj\main.obj: main.cpp $(HEADERS) sha.h
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\market.obj: market.cpp $(HEADERS) market.h
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\ui.obj: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h
|
||||
obj\ui.obj: ui.cpp $(HEADERS)
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\uibase.obj: uibase.cpp uibase.h
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\sha.obj: sha.cpp sha.h
|
||||
obj\sha.obj: sha.cpp sha.h
|
||||
cl $(CFLAGS) /O2 /Fo$@ %s
|
||||
|
||||
obj\irc.obj: irc.cpp $(HEADERS)
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\rpc.obj: rpc.cpp $(HEADERS)
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
|
||||
rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s
|
||||
|
||||
|
||||
|
||||
OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj obj\market.obj \
|
||||
obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\ui.res
|
||||
OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj \
|
||||
obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\rpc.obj \
|
||||
obj\ui.res
|
||||
|
||||
bitcoin.exe: $(OBJS)
|
||||
-kill /f bitcoin.exe & sleep 1
|
||||
|
||||
264
market.cpp
264
market.cpp
@@ -1,264 +0,0 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "headers.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Global state variables
|
||||
//
|
||||
|
||||
//// later figure out how these are persisted
|
||||
map<uint256, CProduct> mapMyProducts;
|
||||
|
||||
|
||||
|
||||
|
||||
map<uint256, CProduct> mapProducts;
|
||||
CCriticalSection cs_mapProducts;
|
||||
|
||||
bool AdvertInsert(const CProduct& product)
|
||||
{
|
||||
uint256 hash = product.GetHash();
|
||||
bool fNew = false;
|
||||
bool fUpdated = false;
|
||||
|
||||
CRITICAL_BLOCK(cs_mapProducts)
|
||||
{
|
||||
// Insert or find existing product
|
||||
pair<map<uint256, CProduct>::iterator, bool> item = mapProducts.insert(make_pair(hash, product));
|
||||
CProduct* pproduct = &(*(item.first)).second;
|
||||
fNew = item.second;
|
||||
|
||||
// Update if newer
|
||||
if (product.nSequence > pproduct->nSequence)
|
||||
{
|
||||
*pproduct = product;
|
||||
fUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
//if (fNew)
|
||||
// NotifyProductAdded(hash);
|
||||
//else if (fUpdated)
|
||||
// NotifyProductUpdated(hash);
|
||||
|
||||
return (fNew || fUpdated);
|
||||
}
|
||||
|
||||
void AdvertErase(const CProduct& product)
|
||||
{
|
||||
uint256 hash = product.GetHash();
|
||||
CRITICAL_BLOCK(cs_mapProducts)
|
||||
mapProducts.erase(hash);
|
||||
//NotifyProductDeleted(hash);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
unsigned int Union(T& v1, T& v2)
|
||||
{
|
||||
// v1 = v1 union v2
|
||||
// v1 and v2 must be sorted
|
||||
// returns the number of elements added to v1
|
||||
|
||||
///// need to check that this is equivalent, then delete this comment
|
||||
//vector<unsigned short> vUnion(v1.size() + v2.size());
|
||||
//vUnion.erase(set_union(v1.begin(), v1.end(),
|
||||
// v2.begin(), v2.end(),
|
||||
// vUnion.begin()),
|
||||
// vUnion.end());
|
||||
|
||||
T vUnion;
|
||||
vUnion.reserve(v1.size() + v2.size());
|
||||
set_union(v1.begin(), v1.end(),
|
||||
v2.begin(), v2.end(),
|
||||
back_inserter(vUnion));
|
||||
unsigned int nAdded = vUnion.size() - v1.size();
|
||||
if (nAdded > 0)
|
||||
v1 = vUnion;
|
||||
return nAdded;
|
||||
}
|
||||
|
||||
void CUser::AddAtom(unsigned short nAtom, bool fOrigin)
|
||||
{
|
||||
// Ignore duplicates
|
||||
if (binary_search(vAtomsIn.begin(), vAtomsIn.end(), nAtom) ||
|
||||
find(vAtomsNew.begin(), vAtomsNew.end(), nAtom) != vAtomsNew.end())
|
||||
return;
|
||||
|
||||
//// instead of zero atom, should change to free atom that propagates,
|
||||
//// limited to lower than a certain value like 5 so conflicts quickly
|
||||
// The zero atom never propagates,
|
||||
// new atoms always propagate through the user that created them
|
||||
if (nAtom == 0 || fOrigin)
|
||||
{
|
||||
vector<unsigned short> vTmp(1, nAtom);
|
||||
Union(vAtomsIn, vTmp);
|
||||
if (fOrigin)
|
||||
vAtomsOut.push_back(nAtom);
|
||||
return;
|
||||
}
|
||||
|
||||
vAtomsNew.push_back(nAtom);
|
||||
|
||||
if (vAtomsNew.size() >= nFlowthroughRate || vAtomsOut.empty())
|
||||
{
|
||||
// Select atom to flow through to vAtomsOut
|
||||
vAtomsOut.push_back(vAtomsNew[GetRand(vAtomsNew.size())]);
|
||||
|
||||
// Merge vAtomsNew into vAtomsIn
|
||||
sort(vAtomsNew.begin(), vAtomsNew.end());
|
||||
Union(vAtomsIn, vAtomsNew);
|
||||
vAtomsNew.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool AddAtomsAndPropagate(uint256 hashUserStart, const vector<unsigned short>& vAtoms, bool fOrigin)
|
||||
{
|
||||
CReviewDB reviewdb;
|
||||
map<uint256, vector<unsigned short> > pmapPropagate[2];
|
||||
pmapPropagate[0][hashUserStart] = vAtoms;
|
||||
|
||||
for (int side = 0; !pmapPropagate[side].empty(); side = 1 - side)
|
||||
{
|
||||
map<uint256, vector<unsigned short> >& mapFrom = pmapPropagate[side];
|
||||
map<uint256, vector<unsigned short> >& mapTo = pmapPropagate[1 - side];
|
||||
|
||||
for (map<uint256, vector<unsigned short> >::iterator mi = mapFrom.begin(); mi != mapFrom.end(); ++mi)
|
||||
{
|
||||
const uint256& hashUser = (*mi).first;
|
||||
const vector<unsigned short>& vReceived = (*mi).second;
|
||||
|
||||
///// this would be a lot easier on the database if it put the new atom at the beginning of the list,
|
||||
///// so the change would be right next to the vector size.
|
||||
|
||||
// Read user
|
||||
CUser user;
|
||||
reviewdb.ReadUser(hashUser, user);
|
||||
unsigned int nIn = user.vAtomsIn.size();
|
||||
unsigned int nNew = user.vAtomsNew.size();
|
||||
unsigned int nOut = user.vAtomsOut.size();
|
||||
|
||||
// Add atoms received
|
||||
foreach(unsigned short nAtom, vReceived)
|
||||
user.AddAtom(nAtom, fOrigin);
|
||||
fOrigin = false;
|
||||
|
||||
// Don't bother writing to disk if no changes
|
||||
if (user.vAtomsIn.size() == nIn && user.vAtomsNew.size() == nNew)
|
||||
continue;
|
||||
|
||||
// Propagate
|
||||
if (user.vAtomsOut.size() > nOut)
|
||||
foreach(const uint256& hash, user.vLinksOut)
|
||||
mapTo[hash].insert(mapTo[hash].end(), user.vAtomsOut.begin() + nOut, user.vAtomsOut.end());
|
||||
|
||||
// Write back
|
||||
if (!reviewdb.WriteUser(hashUser, user))
|
||||
return false;
|
||||
}
|
||||
mapFrom.clear();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool CReview::AcceptReview()
|
||||
{
|
||||
// Timestamp
|
||||
nTime = GetTime();
|
||||
|
||||
// Check signature
|
||||
if (!CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig))
|
||||
return false;
|
||||
|
||||
CReviewDB reviewdb;
|
||||
|
||||
// Add review text to recipient
|
||||
vector<CReview> vReviews;
|
||||
reviewdb.ReadReviews(hashTo, vReviews);
|
||||
vReviews.push_back(*this);
|
||||
if (!reviewdb.WriteReviews(hashTo, vReviews))
|
||||
return false;
|
||||
|
||||
// Add link from sender
|
||||
CUser user;
|
||||
uint256 hashFrom = Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end());
|
||||
reviewdb.ReadUser(hashFrom, user);
|
||||
user.vLinksOut.push_back(hashTo);
|
||||
if (!reviewdb.WriteUser(hashFrom, user))
|
||||
return false;
|
||||
|
||||
reviewdb.Close();
|
||||
|
||||
// Propagate atoms to recipient
|
||||
vector<unsigned short> vZeroAtom(1, 0);
|
||||
if (!AddAtomsAndPropagate(hashTo, user.vAtomsOut.size() ? user.vAtomsOut : vZeroAtom, false))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool CProduct::CheckSignature()
|
||||
{
|
||||
return (CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig));
|
||||
}
|
||||
|
||||
bool CProduct::CheckProduct()
|
||||
{
|
||||
if (!CheckSignature())
|
||||
return false;
|
||||
|
||||
// Make sure it's a summary product
|
||||
if (!mapDetails.empty() || !vOrderForm.empty())
|
||||
return false;
|
||||
|
||||
// Look up seller's atom count
|
||||
CReviewDB reviewdb("r");
|
||||
CUser user;
|
||||
reviewdb.ReadUser(GetUserHash(), user);
|
||||
nAtoms = user.GetAtomCount();
|
||||
reviewdb.Close();
|
||||
|
||||
////// delme, this is now done by AdvertInsert
|
||||
//// Store to memory
|
||||
//CRITICAL_BLOCK(cs_mapProducts)
|
||||
// mapProducts[GetHash()] = *this;
|
||||
|
||||
return true;
|
||||
}
|
||||
182
market.h
182
market.h
@@ -1,182 +0,0 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
class CUser;
|
||||
class CReview;
|
||||
class CProduct;
|
||||
|
||||
static const unsigned int nFlowthroughRate = 2;
|
||||
|
||||
|
||||
|
||||
|
||||
bool AdvertInsert(const CProduct& product);
|
||||
void AdvertErase(const CProduct& product);
|
||||
bool AddAtomsAndPropagate(uint256 hashUserStart, const vector<unsigned short>& vAtoms, bool fOrigin);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CUser
|
||||
{
|
||||
public:
|
||||
vector<unsigned short> vAtomsIn;
|
||||
vector<unsigned short> vAtomsNew;
|
||||
vector<unsigned short> vAtomsOut;
|
||||
vector<uint256> vLinksOut;
|
||||
|
||||
CUser()
|
||||
{
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
if (!(nType & SER_GETHASH))
|
||||
READWRITE(nVersion);
|
||||
READWRITE(vAtomsIn);
|
||||
READWRITE(vAtomsNew);
|
||||
READWRITE(vAtomsOut);
|
||||
READWRITE(vLinksOut);
|
||||
)
|
||||
|
||||
void SetNull()
|
||||
{
|
||||
vAtomsIn.clear();
|
||||
vAtomsNew.clear();
|
||||
vAtomsOut.clear();
|
||||
vLinksOut.clear();
|
||||
}
|
||||
|
||||
uint256 GetHash() const { return SerializeHash(*this); }
|
||||
|
||||
|
||||
int GetAtomCount() const
|
||||
{
|
||||
return (vAtomsIn.size() + vAtomsNew.size());
|
||||
}
|
||||
|
||||
void AddAtom(unsigned short nAtom, bool fOrigin);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CReview
|
||||
{
|
||||
public:
|
||||
int nVersion;
|
||||
uint256 hashTo;
|
||||
map<string, string> mapValue;
|
||||
vector<unsigned char> vchPubKeyFrom;
|
||||
vector<unsigned char> vchSig;
|
||||
|
||||
// memory only
|
||||
unsigned int nTime;
|
||||
int nAtoms;
|
||||
|
||||
|
||||
CReview()
|
||||
{
|
||||
nVersion = 1;
|
||||
hashTo = 0;
|
||||
nTime = 0;
|
||||
nAtoms = 0;
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
READWRITE(this->nVersion);
|
||||
nVersion = this->nVersion;
|
||||
if (!(nType & SER_DISK))
|
||||
READWRITE(hashTo);
|
||||
READWRITE(mapValue);
|
||||
READWRITE(vchPubKeyFrom);
|
||||
if (!(nType & SER_GETHASH))
|
||||
READWRITE(vchSig);
|
||||
)
|
||||
|
||||
uint256 GetHash() const { return SerializeHash(*this); }
|
||||
uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); }
|
||||
uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); }
|
||||
|
||||
|
||||
bool AcceptReview();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CProduct
|
||||
{
|
||||
public:
|
||||
int nVersion;
|
||||
CAddress addr;
|
||||
map<string, string> mapValue;
|
||||
map<string, string> mapDetails;
|
||||
vector<pair<string, string> > vOrderForm;
|
||||
unsigned int nSequence;
|
||||
vector<unsigned char> vchPubKeyFrom;
|
||||
vector<unsigned char> vchSig;
|
||||
|
||||
// disk only
|
||||
int nAtoms;
|
||||
|
||||
// memory only
|
||||
set<unsigned int> setSources;
|
||||
|
||||
CProduct()
|
||||
{
|
||||
nVersion = 1;
|
||||
nAtoms = 0;
|
||||
nSequence = 0;
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
READWRITE(this->nVersion);
|
||||
nVersion = this->nVersion;
|
||||
READWRITE(addr);
|
||||
READWRITE(mapValue);
|
||||
if (!(nType & SER_GETHASH))
|
||||
{
|
||||
READWRITE(mapDetails);
|
||||
READWRITE(vOrderForm);
|
||||
READWRITE(nSequence);
|
||||
}
|
||||
READWRITE(vchPubKeyFrom);
|
||||
if (!(nType & SER_GETHASH))
|
||||
READWRITE(vchSig);
|
||||
if (nType & SER_DISK)
|
||||
READWRITE(nAtoms);
|
||||
)
|
||||
|
||||
uint256 GetHash() const { return SerializeHash(*this); }
|
||||
uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); }
|
||||
uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); }
|
||||
|
||||
|
||||
bool CheckSignature();
|
||||
bool CheckProduct();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern map<uint256, CProduct> mapProducts;
|
||||
extern CCriticalSection cs_mapProducts;
|
||||
extern map<uint256, CProduct> mapMyProducts;
|
||||
40
net.cpp
40
net.cpp
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -223,7 +223,7 @@ bool GetMyExternalIP(unsigned int& ipRet)
|
||||
|
||||
|
||||
|
||||
bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline)
|
||||
bool AddAddress(CAddress addr, bool fCurrentlyOnline)
|
||||
{
|
||||
if (!addr.IsRoutable())
|
||||
return false;
|
||||
@@ -239,7 +239,7 @@ bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline)
|
||||
// New address
|
||||
printf("AddAddress(%s)\n", addr.ToStringLog().c_str());
|
||||
mapAddresses.insert(make_pair(addr.GetKey(), addr));
|
||||
addrdb.WriteAddress(addr);
|
||||
CAddrDB().WriteAddress(addr);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -260,7 +260,7 @@ bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline)
|
||||
fUpdated = true;
|
||||
}
|
||||
if (fUpdated)
|
||||
addrdb.WriteAddress(addrFound);
|
||||
CAddrDB().WriteAddress(addrFound);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -381,11 +381,6 @@ void CNode::CancelSubscribe(unsigned int nChannel)
|
||||
foreach(CNode* pnode, vNodes)
|
||||
if (pnode != this)
|
||||
pnode->PushMessage("sub-cancel", nChannel);
|
||||
|
||||
// Clear memory, no longer subscribed
|
||||
if (nChannel == MSG_PRODUCT)
|
||||
CRITICAL_BLOCK(cs_mapProducts)
|
||||
mapProducts.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,10 +492,6 @@ void CNode::Cleanup()
|
||||
// All of a nodes broadcasts and subscriptions are automatically torn down
|
||||
// when it goes down, so a node has to stay up to keep its broadcast going.
|
||||
|
||||
CRITICAL_BLOCK(cs_mapProducts)
|
||||
for (map<uint256, CProduct>::iterator mi = mapProducts.begin(); mi != mapProducts.end();)
|
||||
AdvertRemoveSource(this, MSG_PRODUCT, 0, (*(mi++)).second);
|
||||
|
||||
// Cancel subscriptions
|
||||
for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
|
||||
if (vfSubscribe[nChannel])
|
||||
@@ -522,7 +513,6 @@ void CNode::Cleanup()
|
||||
void ThreadSocketHandler(void* parg)
|
||||
{
|
||||
IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
|
||||
|
||||
try
|
||||
{
|
||||
vnThreadsRunning[0]++;
|
||||
@@ -536,7 +526,6 @@ void ThreadSocketHandler(void* parg)
|
||||
vnThreadsRunning[0]--;
|
||||
throw; // support pthread_cancel()
|
||||
}
|
||||
|
||||
printf("ThreadSocketHandler exiting\n");
|
||||
}
|
||||
|
||||
@@ -657,11 +646,7 @@ void ThreadSocketHandler2(void* parg)
|
||||
if (FD_ISSET(hListenSocket, &fdsetRecv))
|
||||
{
|
||||
struct sockaddr_in sockaddr;
|
||||
#ifdef __WXMSW__
|
||||
int len = sizeof(sockaddr);
|
||||
#else
|
||||
socklen_t len = sizeof(sockaddr);
|
||||
#endif
|
||||
SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
|
||||
CAddress addr(sockaddr);
|
||||
if (hSocket == INVALID_SOCKET)
|
||||
@@ -816,7 +801,6 @@ void ThreadSocketHandler2(void* parg)
|
||||
void ThreadOpenConnections(void* parg)
|
||||
{
|
||||
IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
|
||||
|
||||
try
|
||||
{
|
||||
vnThreadsRunning[1]++;
|
||||
@@ -830,7 +814,6 @@ void ThreadOpenConnections(void* parg)
|
||||
vnThreadsRunning[1]--;
|
||||
PrintException(NULL, "ThreadOpenConnections()");
|
||||
}
|
||||
|
||||
printf("ThreadOpenConnections exiting\n");
|
||||
}
|
||||
|
||||
@@ -881,11 +864,11 @@ void ThreadOpenConnections2(void* parg)
|
||||
vnThreadsRunning[1]--;
|
||||
Sleep(500);
|
||||
const int nMaxConnections = 15;
|
||||
while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size())
|
||||
while (vNodes.size() >= nMaxConnections)
|
||||
{
|
||||
Sleep(2000);
|
||||
if (fShutdown)
|
||||
return;
|
||||
Sleep(2000);
|
||||
}
|
||||
vnThreadsRunning[1]++;
|
||||
if (fShutdown)
|
||||
@@ -928,7 +911,7 @@ void ThreadOpenConnections2(void* parg)
|
||||
// 30 days 27 hours
|
||||
// 90 days 46 hours
|
||||
// 365 days 93 hours
|
||||
int64 nDelay = (int64)(3600.0 * sqrt(fabs(nSinceLastSeen) / 3600.0) + nRandomizer);
|
||||
int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
|
||||
|
||||
// Fast reconnect for one hour after last seen
|
||||
if (nSinceLastSeen < 60 * 60)
|
||||
@@ -1016,7 +999,6 @@ bool OpenNetworkConnection(const CAddress& addrConnect)
|
||||
void ThreadMessageHandler(void* parg)
|
||||
{
|
||||
IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
|
||||
|
||||
try
|
||||
{
|
||||
vnThreadsRunning[2]++;
|
||||
@@ -1030,7 +1012,6 @@ void ThreadMessageHandler(void* parg)
|
||||
vnThreadsRunning[2]--;
|
||||
PrintException(NULL, "ThreadMessageHandler()");
|
||||
}
|
||||
|
||||
printf("ThreadMessageHandler exiting\n");
|
||||
}
|
||||
|
||||
@@ -1038,7 +1019,7 @@ void ThreadMessageHandler2(void* parg)
|
||||
{
|
||||
printf("ThreadMessageHandler started\n");
|
||||
SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
|
||||
loop
|
||||
while (!fShutdown)
|
||||
{
|
||||
// Poll the connected nodes for messages
|
||||
vector<CNode*> vNodesCopy;
|
||||
@@ -1329,7 +1310,7 @@ bool StopNode()
|
||||
fShutdown = true;
|
||||
nTransactionsUpdated++;
|
||||
int64 nStart = GetTime();
|
||||
while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0)
|
||||
while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0)
|
||||
{
|
||||
if (GetTime() - nStart > 20)
|
||||
break;
|
||||
@@ -1339,7 +1320,8 @@ bool StopNode()
|
||||
if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
|
||||
if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
|
||||
if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
|
||||
while (vnThreadsRunning[2] > 0)
|
||||
if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
|
||||
while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
|
||||
Sleep(20);
|
||||
Sleep(50);
|
||||
|
||||
|
||||
13
net.h
13
net.h
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -23,7 +23,7 @@ enum
|
||||
|
||||
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet);
|
||||
bool GetMyExternalIP(unsigned int& ipRet);
|
||||
bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline=true);
|
||||
bool AddAddress(CAddress addr, bool fCurrentlyOnline=true);
|
||||
void AddressCurrentlyConnected(const CAddress& addr);
|
||||
CNode* FindNode(unsigned int ip);
|
||||
CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
|
||||
@@ -341,9 +341,6 @@ enum
|
||||
{
|
||||
MSG_TX = 1,
|
||||
MSG_BLOCK,
|
||||
MSG_REVIEW,
|
||||
MSG_PRODUCT,
|
||||
MSG_TABLE,
|
||||
};
|
||||
|
||||
static const char* ppszTypeName[] =
|
||||
@@ -351,9 +348,6 @@ static const char* ppszTypeName[] =
|
||||
"ERROR",
|
||||
"tx",
|
||||
"block",
|
||||
"review",
|
||||
"product",
|
||||
"table",
|
||||
};
|
||||
|
||||
class CInv
|
||||
@@ -518,6 +512,7 @@ public:
|
||||
vector<CInv> vInventoryToSend;
|
||||
CCriticalSection cs_inventory;
|
||||
multimap<int64, CInv> mapAskFor;
|
||||
int64 nLastSentTxInv;
|
||||
|
||||
// publish and subscription
|
||||
vector<char> vfSubscribe;
|
||||
@@ -627,7 +622,7 @@ public:
|
||||
// We're using mapAskFor as a priority queue,
|
||||
// the key is the earliest time the request can be sent
|
||||
int64& nRequestTime = mapAlreadyAskedFor[inv];
|
||||
printf("askfor %s %"PRI64d"\n", inv.ToString().c_str(), nRequestTime);
|
||||
printf("askfor %s %"PRI64d"\n", inv.ToString().c_str(), nRequestTime);
|
||||
|
||||
// Make sure not to reuse time indexes to keep things in the same order
|
||||
int64 nNow = (GetTime() - 1) * 1000000;
|
||||
|
||||
733
rpc.cpp
Normal file
733
rpc.cpp
Normal file
@@ -0,0 +1,733 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "headers.h"
|
||||
#undef printf
|
||||
#include <boost/asio.hpp>
|
||||
#include "json/json_spirit_reader_template.h"
|
||||
#include "json/json_spirit_writer_template.h"
|
||||
#include "json/json_spirit_utils.h"
|
||||
#define printf OutputDebugStringF
|
||||
// MinGW 3.4.5 gets "fatal error: had to relocate PCH" if the json headers are
|
||||
// precompiled in headers.h. The problem might be when the pch file goes over
|
||||
// a certain size around 145MB. If we need access to json_spirit outside this
|
||||
// file, we could use the compiled json_spirit option.
|
||||
|
||||
using boost::asio::ip::tcp;
|
||||
using namespace json_spirit;
|
||||
|
||||
void ThreadRPCServer2(void* parg);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// Note: I'm not finished designing this interface, it's still subject to change.
|
||||
///
|
||||
|
||||
|
||||
|
||||
Value stop(const Array& params)
|
||||
{
|
||||
if (params.size() != 0)
|
||||
throw runtime_error(
|
||||
"stop (no parameters)\n"
|
||||
"Stop bitcoin server.");
|
||||
|
||||
// Shutdown will take long enough that the response should get back
|
||||
CreateThread(Shutdown, NULL);
|
||||
return "bitcoin server stopping";
|
||||
}
|
||||
|
||||
|
||||
Value getblockcount(const Array& params)
|
||||
{
|
||||
if (params.size() != 0)
|
||||
throw runtime_error(
|
||||
"getblockcount (no parameters)\n"
|
||||
"Returns the number of blocks in the longest block chain.");
|
||||
|
||||
return nBestHeight + 1;
|
||||
}
|
||||
|
||||
|
||||
Value getblocknumber(const Array& params)
|
||||
{
|
||||
if (params.size() != 0)
|
||||
throw runtime_error(
|
||||
"getblocknumber (no parameters)\n"
|
||||
"Returns the block number of the latest block in the longest block chain.");
|
||||
|
||||
return nBestHeight;
|
||||
}
|
||||
|
||||
|
||||
Value getconnectioncount(const Array& params)
|
||||
{
|
||||
if (params.size() != 0)
|
||||
throw runtime_error(
|
||||
"getconnectioncount (no parameters)\n"
|
||||
"Returns the number of connections to other nodes.");
|
||||
|
||||
return (int)vNodes.size();
|
||||
}
|
||||
|
||||
|
||||
Value getdifficulty(const Array& params)
|
||||
{
|
||||
if (params.size() != 0)
|
||||
throw runtime_error(
|
||||
"getdifficulty (no parameters)\n"
|
||||
"Returns the proof-of-work difficulty as a multiple of the minimum difficulty.");
|
||||
|
||||
if (pindexBest == NULL)
|
||||
throw runtime_error("block chain not loaded");
|
||||
|
||||
// Floating point number that is a multiple of the minimum difficulty,
|
||||
// minimum difficulty = 1.0.
|
||||
int nShift = 256 - 32 - 31; // to fit in a uint
|
||||
double dMinimum = (CBigNum().SetCompact(bnProofOfWorkLimit.GetCompact()) >> nShift).getuint();
|
||||
double dCurrently = (CBigNum().SetCompact(pindexBest->nBits) >> nShift).getuint();
|
||||
return dMinimum / dCurrently;
|
||||
}
|
||||
|
||||
|
||||
Value getbalance(const Array& params)
|
||||
{
|
||||
if (params.size() != 0)
|
||||
throw runtime_error(
|
||||
"getbalance (no parameters)\n"
|
||||
"Returns the server's available balance.");
|
||||
|
||||
return ((double)GetBalance() / (double)COIN);
|
||||
}
|
||||
|
||||
|
||||
Value getgenerate(const Array& params)
|
||||
{
|
||||
if (params.size() != 0)
|
||||
throw runtime_error(
|
||||
"getgenerate (no parameters)\n"
|
||||
"Returns true or false.");
|
||||
|
||||
return (bool)fGenerateBitcoins;
|
||||
}
|
||||
|
||||
|
||||
Value setgenerate(const Array& params)
|
||||
{
|
||||
if (params.size() < 1 || params.size() > 2)
|
||||
throw runtime_error(
|
||||
"setgenerate <generate> [genproclimit]\n"
|
||||
"<generate> is true or false to turn generation on or off.\n"
|
||||
"Generation is limited to [genproclimit] processors, -1 is unlimited.");
|
||||
|
||||
bool fGenerate = true;
|
||||
if (params.size() > 0)
|
||||
fGenerate = params[0].get_bool();
|
||||
|
||||
if (params.size() > 1)
|
||||
{
|
||||
int nGenProcLimit = params[1].get_int();
|
||||
fLimitProcessors = (nGenProcLimit != -1);
|
||||
CWalletDB().WriteSetting("fLimitProcessors", fLimitProcessors);
|
||||
if (nGenProcLimit != -1)
|
||||
CWalletDB().WriteSetting("nLimitProcessors", nLimitProcessors = nGenProcLimit);
|
||||
}
|
||||
|
||||
GenerateBitcoins(fGenerate);
|
||||
return Value::null;
|
||||
}
|
||||
|
||||
|
||||
Value getinfo(const Array& params)
|
||||
{
|
||||
if (params.size() != 0)
|
||||
throw runtime_error(
|
||||
"getinfo (no parameters)");
|
||||
|
||||
Object obj;
|
||||
obj.push_back(Pair("balance", (double)GetBalance() / (double)COIN));
|
||||
obj.push_back(Pair("blocks", (int)nBestHeight + 1));
|
||||
obj.push_back(Pair("connections", (int)vNodes.size()));
|
||||
obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string())));
|
||||
obj.push_back(Pair("generate", (bool)fGenerateBitcoins));
|
||||
obj.push_back(Pair("genproclimit", (int)(fLimitProcessors ? nLimitProcessors : -1)));
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
Value getnewaddress(const Array& params)
|
||||
{
|
||||
if (params.size() > 1)
|
||||
throw runtime_error(
|
||||
"getnewaddress [label]\n"
|
||||
"Returns a new bitcoin address for receiving payments. "
|
||||
"If [label] is specified (recommended), it is added to the address book "
|
||||
"so payments received with the address will be labeled.");
|
||||
|
||||
// Parse the label first so we don't generate a key if there's an error
|
||||
string strLabel;
|
||||
if (params.size() > 0)
|
||||
strLabel = params[0].get_str();
|
||||
|
||||
// Generate a new key that is added to wallet
|
||||
string strAddress = PubKeyToAddress(GenerateNewKey());
|
||||
|
||||
SetAddressBookName(strAddress, strLabel);
|
||||
return strAddress;
|
||||
}
|
||||
|
||||
|
||||
Value sendtoaddress(const Array& params)
|
||||
{
|
||||
if (params.size() < 2 || params.size() > 4)
|
||||
throw runtime_error(
|
||||
"sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n"
|
||||
"<amount> is a real and is rounded to the nearest 0.01");
|
||||
|
||||
string strAddress = params[0].get_str();
|
||||
|
||||
// Amount
|
||||
if (params[1].get_real() <= 0.0 || params[1].get_real() > 21000000.0)
|
||||
throw runtime_error("Invalid amount");
|
||||
int64 nAmount = roundint64(params[1].get_real() * 100.00) * CENT;
|
||||
|
||||
// Wallet comments
|
||||
CWalletTx wtx;
|
||||
if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty())
|
||||
wtx.mapValue["message"] = params[2].get_str();
|
||||
if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
|
||||
wtx.mapValue["to"] = params[3].get_str();
|
||||
|
||||
string strError = SendMoneyToBitcoinAddress(strAddress, nAmount, wtx);
|
||||
if (strError != "")
|
||||
throw runtime_error(strError);
|
||||
return "sent";
|
||||
}
|
||||
|
||||
|
||||
Value listtransactions(const Array& params)
|
||||
{
|
||||
if (params.size() > 2)
|
||||
throw runtime_error(
|
||||
"listtransactions [count=10] [includegenerated=false]\n"
|
||||
"Returns up to [count] most recent transactions.");
|
||||
|
||||
int64 nCount = 10;
|
||||
if (params.size() > 0)
|
||||
nCount = params[0].get_int64();
|
||||
bool fGenerated = false;
|
||||
if (params.size() > 1)
|
||||
fGenerated = params[1].get_bool();
|
||||
|
||||
Array ret;
|
||||
//// not finished
|
||||
ret.push_back("not implemented yet");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Value getamountreceived(const Array& params)
|
||||
{
|
||||
if (params.size() < 1 || params.size() > 2)
|
||||
throw runtime_error(
|
||||
"getamountreceived <bitcoinaddress> [minconf=1]\n"
|
||||
"Returns the total amount received by <bitcoinaddress> in transactions with at least [minconf] confirmations.");
|
||||
|
||||
// Bitcoin address
|
||||
string strAddress = params[0].get_str();
|
||||
CScript scriptPubKey;
|
||||
if (!scriptPubKey.SetBitcoinAddress(strAddress))
|
||||
throw runtime_error("Invalid bitcoin address");
|
||||
|
||||
// Minimum confirmations
|
||||
int nMinDepth = 1;
|
||||
if (params.size() > 1)
|
||||
nMinDepth = params[1].get_int();
|
||||
|
||||
// Tally
|
||||
int64 nAmount = 0;
|
||||
CRITICAL_BLOCK(cs_mapWallet)
|
||||
{
|
||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
{
|
||||
const CWalletTx& wtx = (*it).second;
|
||||
if (wtx.IsCoinBase() || !wtx.IsFinal())
|
||||
continue;
|
||||
|
||||
foreach(const CTxOut& txout, wtx.vout)
|
||||
if (txout.scriptPubKey == scriptPubKey)
|
||||
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
||||
nAmount += txout.nValue;
|
||||
}
|
||||
}
|
||||
|
||||
return (double)nAmount / (double)COIN;
|
||||
}
|
||||
|
||||
|
||||
struct tallyitem
|
||||
{
|
||||
int64 nAmount;
|
||||
int nConf;
|
||||
tallyitem()
|
||||
{
|
||||
nAmount = 0;
|
||||
nConf = INT_MAX;
|
||||
}
|
||||
};
|
||||
|
||||
Value getallreceived(const Array& params)
|
||||
{
|
||||
if (params.size() > 1)
|
||||
throw runtime_error(
|
||||
"getallreceived [minconf=1]\n"
|
||||
"[minconf] is the minimum number of confirmations before payments are included.\n"
|
||||
"Returns an array of objects containing:\n"
|
||||
" \"address\" : receiving address\n"
|
||||
" \"amount\" : total amount received by the address\n"
|
||||
" \"confirmations\" : number of confirmations of the most recent transaction included\n"
|
||||
" \"label\" : the label of the receiving address");
|
||||
|
||||
// Minimum confirmations
|
||||
int nMinDepth = 1;
|
||||
if (params.size() > 0)
|
||||
nMinDepth = params[0].get_int();
|
||||
|
||||
// Tally
|
||||
map<uint160, tallyitem> mapTally;
|
||||
CRITICAL_BLOCK(cs_mapWallet)
|
||||
{
|
||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
{
|
||||
const CWalletTx& wtx = (*it).second;
|
||||
if (wtx.IsCoinBase() || !wtx.IsFinal())
|
||||
continue;
|
||||
|
||||
int nDepth = wtx.GetDepthInMainChain();
|
||||
if (nDepth < nMinDepth)
|
||||
continue;
|
||||
|
||||
// Filter out debits and payments to self, which may have change return
|
||||
// we don't want to count.
|
||||
int64 nCredit = wtx.GetCredit(true);
|
||||
int64 nDebit = wtx.GetDebit();
|
||||
int64 nNet = nCredit - nDebit;
|
||||
if (nNet <= 0)
|
||||
continue;
|
||||
|
||||
foreach(const CTxOut& txout, wtx.vout)
|
||||
{
|
||||
uint160 hash160 = txout.scriptPubKey.GetBitcoinAddressHash160();
|
||||
if (hash160 == 0 || !mapPubKeys.count(hash160))
|
||||
continue;
|
||||
|
||||
tallyitem& item = mapTally[hash160];
|
||||
item.nAmount += txout.nValue;
|
||||
item.nConf = min(item.nConf, nDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reply
|
||||
Array ret;
|
||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
||||
{
|
||||
for (map<uint160, tallyitem>::iterator it = mapTally.begin(); it != mapTally.end(); ++it)
|
||||
{
|
||||
string strAddress = Hash160ToAddress((*it).first);
|
||||
string strLabel;
|
||||
map<string, string>::iterator mi = mapAddressBook.find(strAddress);
|
||||
if (mi != mapAddressBook.end())
|
||||
strLabel = (*mi).second;
|
||||
|
||||
Object obj;
|
||||
obj.push_back(Pair("address", strAddress));
|
||||
obj.push_back(Pair("amount", (double)(*it).second.nAmount / (double)COIN));
|
||||
obj.push_back(Pair("confirmations", (*it).second.nConf));
|
||||
obj.push_back(Pair("label", strLabel));
|
||||
ret.push_back(obj);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Call Table
|
||||
//
|
||||
|
||||
typedef Value(*rpcfn_type)(const Array& params);
|
||||
pair<string, rpcfn_type> pCallTable[] =
|
||||
{
|
||||
make_pair("stop", &stop),
|
||||
make_pair("getblockcount", &getblockcount),
|
||||
make_pair("getblocknumber", &getblocknumber),
|
||||
make_pair("getconnectioncount", &getconnectioncount),
|
||||
make_pair("getdifficulty", &getdifficulty),
|
||||
make_pair("getbalance", &getbalance),
|
||||
make_pair("getgenerate", &getgenerate),
|
||||
make_pair("setgenerate", &setgenerate),
|
||||
make_pair("getinfo", &getinfo),
|
||||
make_pair("getnewaddress", &getnewaddress),
|
||||
make_pair("sendtoaddress", &sendtoaddress),
|
||||
make_pair("listtransactions", &listtransactions),
|
||||
make_pair("getamountreceived", &getamountreceived),
|
||||
make_pair("getallreceived", &getallreceived),
|
||||
};
|
||||
map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// HTTP protocol
|
||||
//
|
||||
// This ain't Apache. We're just using HTTP header for the length field
|
||||
// and to be compatible with other JSON-RPC implementations.
|
||||
//
|
||||
|
||||
string HTTPPost(const string& strMsg)
|
||||
{
|
||||
return strprintf(
|
||||
"POST / HTTP/1.1\r\n"
|
||||
"User-Agent: json-rpc/1.0\r\n"
|
||||
"Host: 127.0.0.1\r\n"
|
||||
"Content-Type: application/json\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"Accept: application/json\r\n"
|
||||
"\r\n"
|
||||
"%s",
|
||||
strMsg.size(),
|
||||
strMsg.c_str());
|
||||
}
|
||||
|
||||
string HTTPReply(const string& strMsg, int nStatus=200)
|
||||
{
|
||||
string strStatus;
|
||||
if (nStatus == 200) strStatus = "OK";
|
||||
if (nStatus == 500) strStatus = "Internal Server Error";
|
||||
return strprintf(
|
||||
"HTTP/1.1 %d %s\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"Content-Type: application/json\r\n"
|
||||
"Date: Sat, 08 Jul 2006 12:04:08 GMT\r\n"
|
||||
"Server: json-rpc/1.0\r\n"
|
||||
"\r\n"
|
||||
"%s",
|
||||
nStatus,
|
||||
strStatus.c_str(),
|
||||
strMsg.size(),
|
||||
strMsg.c_str());
|
||||
}
|
||||
|
||||
int ReadHTTPHeader(tcp::iostream& stream)
|
||||
{
|
||||
int nLen = 0;
|
||||
loop
|
||||
{
|
||||
string str;
|
||||
std::getline(stream, str);
|
||||
if (str.empty() || str == "\r")
|
||||
break;
|
||||
if (str.substr(0,15) == "Content-Length:")
|
||||
nLen = atoi(str.substr(15));
|
||||
}
|
||||
return nLen;
|
||||
}
|
||||
|
||||
inline string ReadHTTP(tcp::iostream& stream)
|
||||
{
|
||||
// Read header
|
||||
int nLen = ReadHTTPHeader(stream);
|
||||
if (nLen <= 0)
|
||||
return string();
|
||||
|
||||
// Read message
|
||||
vector<char> vch(nLen);
|
||||
stream.read(&vch[0], nLen);
|
||||
return string(vch.begin(), vch.end());
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// JSON-RPC protocol
|
||||
//
|
||||
// http://json-rpc.org/wiki/specification
|
||||
// http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx
|
||||
//
|
||||
|
||||
string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id)
|
||||
{
|
||||
Object request;
|
||||
request.push_back(Pair("method", strMethod));
|
||||
request.push_back(Pair("params", params));
|
||||
request.push_back(Pair("id", id));
|
||||
return write_string(Value(request), false) + "\n";
|
||||
}
|
||||
|
||||
string JSONRPCReply(const Value& result, const Value& error, const Value& id)
|
||||
{
|
||||
Object reply;
|
||||
if (error.type() != null_type)
|
||||
reply.push_back(Pair("result", Value::null));
|
||||
else
|
||||
reply.push_back(Pair("result", result));
|
||||
reply.push_back(Pair("error", error));
|
||||
reply.push_back(Pair("id", id));
|
||||
return write_string(Value(reply), false) + "\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ThreadRPCServer(void* parg)
|
||||
{
|
||||
IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer(parg));
|
||||
try
|
||||
{
|
||||
vnThreadsRunning[4]++;
|
||||
ThreadRPCServer2(parg);
|
||||
vnThreadsRunning[4]--;
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
vnThreadsRunning[4]--;
|
||||
PrintException(&e, "ThreadRPCServer()");
|
||||
} catch (...) {
|
||||
vnThreadsRunning[4]--;
|
||||
PrintException(NULL, "ThreadRPCServer()");
|
||||
}
|
||||
printf("ThreadRPCServer exiting\n");
|
||||
}
|
||||
|
||||
void ThreadRPCServer2(void* parg)
|
||||
{
|
||||
printf("ThreadRPCServer started\n");
|
||||
|
||||
// Bind to loopback 127.0.0.1 so the socket can only be accessed locally
|
||||
boost::asio::io_service io_service;
|
||||
tcp::endpoint endpoint(boost::asio::ip::address_v4::loopback(), 8332);
|
||||
tcp::acceptor acceptor(io_service, endpoint);
|
||||
|
||||
loop
|
||||
{
|
||||
// Accept connection
|
||||
tcp::iostream stream;
|
||||
tcp::endpoint peer;
|
||||
vnThreadsRunning[4]--;
|
||||
acceptor.accept(*stream.rdbuf(), peer);
|
||||
vnThreadsRunning[4]++;
|
||||
if (fShutdown)
|
||||
return;
|
||||
|
||||
// Shouldn't be possible for anyone else to connect, but just in case
|
||||
if (peer.address().to_string() != "127.0.0.1")
|
||||
continue;
|
||||
|
||||
// Receive request
|
||||
string strRequest = ReadHTTP(stream);
|
||||
printf("ThreadRPCServer request=%s", strRequest.c_str());
|
||||
|
||||
// Handle multiple invocations per request
|
||||
string::iterator begin = strRequest.begin();
|
||||
while (skipspaces(begin), begin != strRequest.end())
|
||||
{
|
||||
string::iterator prev = begin;
|
||||
Value id;
|
||||
try
|
||||
{
|
||||
// Parse request
|
||||
Value valRequest;
|
||||
if (!read_range(begin, strRequest.end(), valRequest))
|
||||
throw runtime_error("Parse error.");
|
||||
const Object& request = valRequest.get_obj();
|
||||
if (find_value(request, "method").type() != str_type ||
|
||||
find_value(request, "params").type() != array_type)
|
||||
throw runtime_error("Invalid request.");
|
||||
|
||||
string strMethod = find_value(request, "method").get_str();
|
||||
const Array& params = find_value(request, "params").get_array();
|
||||
id = find_value(request, "id");
|
||||
|
||||
// Execute
|
||||
map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
|
||||
if (mi == mapCallTable.end())
|
||||
throw runtime_error("Method not found.");
|
||||
Value result = (*(*mi).second)(params);
|
||||
|
||||
// Send reply
|
||||
string strReply = JSONRPCReply(result, Value::null, id);
|
||||
stream << HTTPReply(strReply, 200) << std::flush;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
// Send error reply
|
||||
string strReply = JSONRPCReply(Value::null, e.what(), id);
|
||||
stream << HTTPReply(strReply, 500) << std::flush;
|
||||
}
|
||||
if (begin == prev)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Value CallRPC(const string& strMethod, const Array& params)
|
||||
{
|
||||
// Connect to localhost
|
||||
tcp::iostream stream("127.0.0.1", "8332");
|
||||
if (stream.fail())
|
||||
throw runtime_error("couldn't connect to server");
|
||||
|
||||
// Send request
|
||||
string strRequest = JSONRPCRequest(strMethod, params, 1);
|
||||
stream << HTTPPost(strRequest) << std::flush;
|
||||
|
||||
// Receive reply
|
||||
string strReply = ReadHTTP(stream);
|
||||
if (strReply.empty())
|
||||
throw runtime_error("no response from server");
|
||||
|
||||
// Parse reply
|
||||
Value valReply;
|
||||
if (!read_string(strReply, valReply))
|
||||
throw runtime_error("couldn't parse reply from server");
|
||||
const Object& reply = valReply.get_obj();
|
||||
if (reply.empty())
|
||||
throw runtime_error("expected reply to have result, error and id properties");
|
||||
|
||||
const Value& result = find_value(reply, "result");
|
||||
const Value& error = find_value(reply, "error");
|
||||
const Value& id = find_value(reply, "id");
|
||||
|
||||
if (error.type() == str_type)
|
||||
throw runtime_error(error.get_str());
|
||||
else if (error.type() != null_type)
|
||||
throw runtime_error(write_string(error, false));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
void ConvertTo(Value& value)
|
||||
{
|
||||
if (value.type() == str_type)
|
||||
{
|
||||
// reinterpret string as unquoted json value
|
||||
Value value2;
|
||||
if (!read_string(value.get_str(), value2))
|
||||
throw runtime_error("type mismatch");
|
||||
value = value2.get_value<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
value = value.get_value<T>();
|
||||
}
|
||||
}
|
||||
|
||||
int CommandLineRPC(int argc, char *argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
// Check that method exists
|
||||
if (argc < 2)
|
||||
throw runtime_error("too few parameters");
|
||||
string strMethod = argv[1];
|
||||
if (!mapCallTable.count(strMethod))
|
||||
throw runtime_error(strprintf("unknown command: %s", strMethod.c_str()));
|
||||
|
||||
// Parameters default to strings
|
||||
Array params;
|
||||
for (int i = 2; i < argc; i++)
|
||||
params.push_back(argv[i]);
|
||||
int n = params.size();
|
||||
|
||||
//
|
||||
// Special case other types
|
||||
//
|
||||
if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
|
||||
if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||
if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
|
||||
if (strMethod == "listtransactions" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
||||
if (strMethod == "listtransactions" && n > 1) ConvertTo<bool>(params[1]);
|
||||
if (strMethod == "getamountreceived" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||
if (strMethod == "getallreceived" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
||||
|
||||
// Execute
|
||||
Value result = CallRPC(strMethod, params);
|
||||
|
||||
// Print result
|
||||
string strResult = (result.type() == str_type ? result.get_str() : write_string(result, true));
|
||||
if (result.type() != null_type)
|
||||
{
|
||||
if (fWindows)
|
||||
// Windows GUI apps can't print to command line,
|
||||
// so for now settle for a message box yuck
|
||||
wxMessageBox(strResult.c_str(), "Bitcoin", wxOK);
|
||||
else
|
||||
fprintf(stdout, "%s\n", strResult.c_str());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
if (fWindows)
|
||||
wxMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK);
|
||||
else
|
||||
fprintf(stderr, "error: %s\n", e.what());
|
||||
} catch (...) {
|
||||
PrintException(NULL, "CommandLineRPC()");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
// Turn off microsoft heap dump noise
|
||||
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
|
||||
#endif
|
||||
setbuf(stdin, NULL);
|
||||
setbuf(stdout, NULL);
|
||||
setbuf(stderr, NULL);
|
||||
|
||||
try
|
||||
{
|
||||
if (argc >= 2 && string(argv[1]) == "-server")
|
||||
{
|
||||
printf("server ready\n");
|
||||
ThreadRPCServer(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CommandLineRPC(argc, argv);
|
||||
}
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
PrintException(&e, "main()");
|
||||
} catch (...) {
|
||||
PrintException(NULL, "main()");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
6
rpc.h
Normal file
6
rpc.h
Normal file
@@ -0,0 +1,6 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
void ThreadRPCServer(void* parg);
|
||||
int CommandLineRPC(int argc, char *argv[]);
|
||||
21
script.cpp
21
script.cpp
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -660,7 +660,7 @@ bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nI
|
||||
if (stack.size() < 1)
|
||||
return false;
|
||||
valtype& vch = stacktop(-1);
|
||||
valtype vchHash(opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160 ? 20 : 32);
|
||||
valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32);
|
||||
if (opcode == OP_RIPEMD160)
|
||||
RIPEMD160(&vch[0], vch.size(), &vchHash[0]);
|
||||
else if (opcode == OP_SHA1)
|
||||
@@ -753,9 +753,9 @@ bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nI
|
||||
CScript scriptCode(pbegincodehash, pend);
|
||||
|
||||
// Drop the signatures, since there's no way for a signature to sign itself
|
||||
for (int i = 0; i < nSigsCount; i++)
|
||||
for (int k = 0; k < nSigsCount; k++)
|
||||
{
|
||||
valtype& vchSig = stacktop(-isig-i);
|
||||
valtype& vchSig = stacktop(-isig-k);
|
||||
scriptCode.FindAndDelete(CScript(vchSig));
|
||||
}
|
||||
|
||||
@@ -909,7 +909,6 @@ bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CSc
|
||||
|
||||
|
||||
|
||||
|
||||
bool Solver(const CScript& scriptPubKey, vector<pair<opcodetype, valtype> >& vSolutionRet)
|
||||
{
|
||||
// Templates
|
||||
@@ -919,7 +918,7 @@ bool Solver(const CScript& scriptPubKey, vector<pair<opcodetype, valtype> >& vSo
|
||||
// Standard tx, sender provides pubkey, receiver adds signature
|
||||
vTemplates.push_back(CScript() << OP_PUBKEY << OP_CHECKSIG);
|
||||
|
||||
// Short account number tx, sender provides hash of pubkey, receiver provides signature and pubkey
|
||||
// Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey
|
||||
vTemplates.push_back(CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG);
|
||||
}
|
||||
|
||||
@@ -1123,5 +1122,13 @@ bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsig
|
||||
if (txin.prevout.hash != txFrom.GetHash())
|
||||
return false;
|
||||
|
||||
return EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType);
|
||||
if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType))
|
||||
return false;
|
||||
|
||||
// Anytime a signature is successfully verified, it's proof the outpoint is spent,
|
||||
// so lets update the wallet spent flag if it doesn't know due to wallet.dat being
|
||||
// restored from backup or the user making copies of wallet.dat.
|
||||
WalletUpdateSpent(txin.prevout);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
49
script.h
49
script.h
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -472,7 +472,7 @@ public:
|
||||
|
||||
bool GetOp(iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet)
|
||||
{
|
||||
// This is why people hate C++
|
||||
// Wrapper so it can be called with either iterator or const_iterator
|
||||
const_iterator pc2 = pc;
|
||||
bool fRet = GetOp(pc2, opcodeRet, vchRet);
|
||||
pc = begin() + (pc2 - begin());
|
||||
@@ -551,6 +551,51 @@ public:
|
||||
}
|
||||
|
||||
|
||||
uint160 GetBitcoinAddressHash160() const
|
||||
{
|
||||
opcodetype opcode;
|
||||
vector<unsigned char> vch;
|
||||
CScript::const_iterator pc = begin();
|
||||
if (!GetOp(pc, opcode, vch) || opcode != OP_DUP) return 0;
|
||||
if (!GetOp(pc, opcode, vch) || opcode != OP_HASH160) return 0;
|
||||
if (!GetOp(pc, opcode, vch) || vch.size() != sizeof(uint160)) return 0;
|
||||
uint160 hash160 = uint160(vch);
|
||||
if (!GetOp(pc, opcode, vch) || opcode != OP_EQUALVERIFY) return 0;
|
||||
if (!GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG) return 0;
|
||||
if (pc != end()) return 0;
|
||||
return hash160;
|
||||
}
|
||||
|
||||
string GetBitcoinAddress() const
|
||||
{
|
||||
uint160 hash160 = GetBitcoinAddressHash160();
|
||||
if (hash160 == 0)
|
||||
return "";
|
||||
return Hash160ToAddress(hash160);
|
||||
}
|
||||
|
||||
void SetBitcoinAddress(const uint160& hash160)
|
||||
{
|
||||
this->clear();
|
||||
*this << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
|
||||
}
|
||||
|
||||
void SetBitcoinAddress(const vector<unsigned char>& vchPubKey)
|
||||
{
|
||||
SetBitcoinAddress(Hash160(vchPubKey));
|
||||
}
|
||||
|
||||
bool SetBitcoinAddress(const string& strAddress)
|
||||
{
|
||||
this->clear();
|
||||
uint160 hash160;
|
||||
if (!AddressToHash160(strAddress, hash160))
|
||||
return false;
|
||||
SetBitcoinAddress(hash160);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PrintHex() const
|
||||
{
|
||||
printf("CScript(%s)\n", HexStr(begin(), end()).c_str());
|
||||
|
||||
20
serialize.h
20
serialize.h
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -19,8 +19,8 @@ class CScript;
|
||||
class CDataStream;
|
||||
class CAutoFile;
|
||||
|
||||
static const int VERSION = 200;
|
||||
static const char* pszSubVer = " rc2";
|
||||
static const int VERSION = 206;
|
||||
static const char* pszSubVer = ".0";
|
||||
|
||||
|
||||
|
||||
@@ -194,28 +194,32 @@ uint64 ReadCompactSize(Stream& is)
|
||||
{
|
||||
unsigned char chSize;
|
||||
READDATA(is, chSize);
|
||||
uint64 nSizeRet = 0;
|
||||
if (chSize < UCHAR_MAX-2)
|
||||
{
|
||||
return chSize;
|
||||
nSizeRet = chSize;
|
||||
}
|
||||
else if (chSize == UCHAR_MAX-2)
|
||||
{
|
||||
unsigned short nSize;
|
||||
READDATA(is, nSize);
|
||||
return nSize;
|
||||
nSizeRet = nSize;
|
||||
}
|
||||
else if (chSize == UCHAR_MAX-1)
|
||||
{
|
||||
unsigned int nSize;
|
||||
READDATA(is, nSize);
|
||||
return nSize;
|
||||
nSizeRet = nSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64 nSize;
|
||||
READDATA(is, nSize);
|
||||
return nSize;
|
||||
nSizeRet = nSize;
|
||||
}
|
||||
if (nSizeRet > (uint64)INT_MAX)
|
||||
throw std::ios_base::failure("ReadCompactSize() : size too large");
|
||||
return nSizeRet;
|
||||
}
|
||||
|
||||
|
||||
@@ -460,7 +464,7 @@ void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion,
|
||||
unsigned int i = 0;
|
||||
while (i < nSize)
|
||||
{
|
||||
unsigned int blk = min(nSize - i, 1 + 4999999 / sizeof(T));
|
||||
unsigned int blk = min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
|
||||
v.resize(i + blk);
|
||||
is.read((char*)&v[i], blk * sizeof(T));
|
||||
i += blk;
|
||||
|
||||
230
ui.h
230
ui.h
@@ -1,33 +1,25 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
|
||||
|
||||
DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1)
|
||||
DECLARE_EVENT_TYPE(wxEVT_REPLY1, -1)
|
||||
DECLARE_EVENT_TYPE(wxEVT_REPLY2, -1)
|
||||
DECLARE_EVENT_TYPE(wxEVT_REPLY3, -1)
|
||||
|
||||
|
||||
|
||||
|
||||
extern map<string, string> mapArgs;
|
||||
|
||||
// Settings
|
||||
extern int fShowGenerated;
|
||||
extern int fMinimizeToTray;
|
||||
extern int fMinimizeOnClose;
|
||||
|
||||
|
||||
|
||||
extern void HandleCtrlA(wxKeyEvent& event);
|
||||
extern string FormatTxStatus(const CWalletTx& wtx);
|
||||
extern void UIThreadCall(boost::function0<void>);
|
||||
extern void MainFrameRepaint();
|
||||
extern void Shutdown(void* parg);
|
||||
extern int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1);
|
||||
void HandleCtrlA(wxKeyEvent& event);
|
||||
string FormatTxStatus(const CWalletTx& wtx);
|
||||
void UIThreadCall(boost::function0<void>);
|
||||
void MainFrameRepaint();
|
||||
void Shutdown(void* parg);
|
||||
int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1);
|
||||
bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent);
|
||||
|
||||
|
||||
|
||||
@@ -38,6 +30,7 @@ class CMainFrame : public CMainFrameBase
|
||||
{
|
||||
protected:
|
||||
// Event handlers
|
||||
void OnNotebookPageChanged(wxNotebookEvent& event);
|
||||
void OnClose(wxCloseEvent& event);
|
||||
void OnIconize(wxIconizeEvent& event);
|
||||
void OnMouseEvents(wxMouseEvent& event);
|
||||
@@ -46,8 +39,6 @@ protected:
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void OnPaintListCtrl(wxPaintEvent& event);
|
||||
void OnMenuFileExit(wxCommandEvent& event);
|
||||
void OnMenuViewShowGenerated(wxCommandEvent& event);
|
||||
void OnUpdateUIViewShowGenerated(wxUpdateUIEvent& event);
|
||||
void OnMenuOptionsGenerate(wxCommandEvent& event);
|
||||
void OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event);
|
||||
void OnMenuOptionsChangeYourAddress(wxCommandEvent& event);
|
||||
@@ -57,10 +48,10 @@ protected:
|
||||
void OnButtonAddressBook(wxCommandEvent& event);
|
||||
void OnSetFocusAddress(wxFocusEvent& event);
|
||||
void OnMouseEventsAddress(wxMouseEvent& event);
|
||||
void OnButtonNew(wxCommandEvent& event);
|
||||
void OnButtonCopy(wxCommandEvent& event);
|
||||
void OnButtonChange(wxCommandEvent& event);
|
||||
void OnListColBeginDrag(wxListEvent& event);
|
||||
void OnListItemActivatedAllTransactions(wxListEvent& event);
|
||||
void OnListItemActivated(wxListEvent& event);
|
||||
void OnListItemActivatedProductsSent(wxListEvent& event);
|
||||
void OnListItemActivatedOrdersSent(wxListEvent& event);
|
||||
void OnListItemActivatedOrdersReceived(wxListEvent& event);
|
||||
@@ -71,6 +62,18 @@ public:
|
||||
~CMainFrame();
|
||||
|
||||
// Custom
|
||||
enum
|
||||
{
|
||||
ALL = 0,
|
||||
SENTRECEIVED = 1,
|
||||
SENT = 2,
|
||||
RECEIVED = 3,
|
||||
};
|
||||
int nPage;
|
||||
wxListCtrl* m_listCtrl;
|
||||
bool fShowGenerated;
|
||||
bool fShowSent;
|
||||
bool fShowReceived;
|
||||
bool fRefreshListCtrl;
|
||||
bool fRefreshListCtrlRunning;
|
||||
bool fOnSetFocusAddress;
|
||||
@@ -211,190 +214,44 @@ void SendingDialogOnReply3(void* parg, CDataStream& vRecv);
|
||||
|
||||
|
||||
|
||||
class CYourAddressDialog : public CYourAddressDialogBase
|
||||
{
|
||||
protected:
|
||||
// Event handlers
|
||||
void OnListEndLabelEdit(wxListEvent& event);
|
||||
void OnListItemSelected(wxListEvent& event);
|
||||
void OnListItemActivated(wxListEvent& event);
|
||||
void OnButtonRename(wxCommandEvent& event);
|
||||
void OnButtonNew(wxCommandEvent& event);
|
||||
void OnButtonCopy(wxCommandEvent& event);
|
||||
void OnButtonOK(wxCommandEvent& event);
|
||||
void OnButtonCancel(wxCommandEvent& event);
|
||||
void OnClose(wxCloseEvent& event);
|
||||
|
||||
public:
|
||||
/** Constructor */
|
||||
CYourAddressDialog(wxWindow* parent);
|
||||
CYourAddressDialog(wxWindow* parent, const string& strInitSelected);
|
||||
|
||||
// Custom
|
||||
wxString GetAddress();
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CAddressBookDialog : public CAddressBookDialogBase
|
||||
{
|
||||
protected:
|
||||
// Event handlers
|
||||
void OnNotebookPageChanged(wxNotebookEvent& event);
|
||||
void OnListEndLabelEdit(wxListEvent& event);
|
||||
void OnListItemSelected(wxListEvent& event);
|
||||
void OnListItemActivated(wxListEvent& event);
|
||||
void OnButtonEdit(wxCommandEvent& event);
|
||||
void OnButtonDelete(wxCommandEvent& event);
|
||||
void OnButtonNew(wxCommandEvent& event);
|
||||
void OnButtonCopy(wxCommandEvent& event);
|
||||
void OnButtonEdit(wxCommandEvent& event);
|
||||
void OnButtonNew(wxCommandEvent& event);
|
||||
void OnButtonOK(wxCommandEvent& event);
|
||||
void OnButtonCancel(wxCommandEvent& event);
|
||||
void OnClose(wxCloseEvent& event);
|
||||
|
||||
public:
|
||||
/** Constructor */
|
||||
CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn);
|
||||
CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, int nPageIn, bool fDuringSendIn);
|
||||
|
||||
// Custom
|
||||
bool fSending;
|
||||
enum
|
||||
{
|
||||
SENDING = 0,
|
||||
RECEIVING = 1,
|
||||
};
|
||||
int nPage;
|
||||
wxListCtrl* m_listCtrl;
|
||||
bool fDuringSend;
|
||||
wxString GetAddress();
|
||||
wxString GetSelectedAddress();
|
||||
wxString GetSelectedSendingAddress();
|
||||
wxString GetSelectedReceivingAddress();
|
||||
bool CheckIfMine(const string& strAddress, const string& strTitle);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CProductsDialog : public CProductsDialogBase
|
||||
{
|
||||
protected:
|
||||
// Event handlers
|
||||
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
|
||||
void OnCombobox(wxCommandEvent& event);
|
||||
void OnButtonSearch(wxCommandEvent& event);
|
||||
void OnListItemActivated(wxListEvent& event);
|
||||
|
||||
public:
|
||||
/** Constructor */
|
||||
CProductsDialog(wxWindow* parent);
|
||||
|
||||
// Custom
|
||||
vector<CProduct> m_vProduct;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CEditProductDialog : public CEditProductDialogBase
|
||||
{
|
||||
protected:
|
||||
// Event handlers
|
||||
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
|
||||
void OnButtonDel0(wxCommandEvent& event);
|
||||
void OnButtonDel1(wxCommandEvent& event);
|
||||
void OnButtonDel2(wxCommandEvent& event);
|
||||
void OnButtonDel3(wxCommandEvent& event);
|
||||
void OnButtonDel4(wxCommandEvent& event);
|
||||
void OnButtonDel5(wxCommandEvent& event);
|
||||
void OnButtonDel6(wxCommandEvent& event);
|
||||
void OnButtonDel7(wxCommandEvent& event);
|
||||
void OnButtonDel8(wxCommandEvent& event);
|
||||
void OnButtonDel9(wxCommandEvent& event);
|
||||
void OnButtonDel10(wxCommandEvent& event);
|
||||
void OnButtonDel11(wxCommandEvent& event);
|
||||
void OnButtonDel12(wxCommandEvent& event);
|
||||
void OnButtonDel13(wxCommandEvent& event);
|
||||
void OnButtonDel14(wxCommandEvent& event);
|
||||
void OnButtonDel15(wxCommandEvent& event);
|
||||
void OnButtonDel16(wxCommandEvent& event);
|
||||
void OnButtonDel17(wxCommandEvent& event);
|
||||
void OnButtonDel18(wxCommandEvent& event);
|
||||
void OnButtonDel19(wxCommandEvent& event);
|
||||
void OnButtonAddField(wxCommandEvent& event);
|
||||
void OnButtonSend(wxCommandEvent& event);
|
||||
void OnButtonPreview(wxCommandEvent& event);
|
||||
void OnButtonCancel(wxCommandEvent& event);
|
||||
|
||||
public:
|
||||
/** Constructor */
|
||||
CEditProductDialog(wxWindow* parent);
|
||||
|
||||
// Custom
|
||||
enum { FIELDS_MAX = 20 };
|
||||
wxTextCtrl* m_textCtrlLabel[FIELDS_MAX];
|
||||
wxTextCtrl* m_textCtrlField[FIELDS_MAX];
|
||||
wxButton* m_buttonDel[FIELDS_MAX];
|
||||
|
||||
void LayoutAll();
|
||||
void ShowLine(int i, bool fShow=true);
|
||||
void OnButtonDel(wxCommandEvent& event, int n);
|
||||
void SetProduct(const CProduct& productIn);
|
||||
void GetProduct(CProduct& product);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CViewProductDialog : public CViewProductDialogBase
|
||||
{
|
||||
protected:
|
||||
// Event handlers
|
||||
void OnButtonSubmitForm(wxCommandEvent& event);
|
||||
void OnButtonCancelForm(wxCommandEvent& event);
|
||||
void OnButtonBack(wxCommandEvent& event);
|
||||
void OnButtonNext(wxCommandEvent& event);
|
||||
void OnButtonCancel(wxCommandEvent& event);
|
||||
|
||||
public:
|
||||
/** Constructor */
|
||||
CViewProductDialog(wxWindow* parent, const CProduct& productIn);
|
||||
~CViewProductDialog();
|
||||
|
||||
// Custom
|
||||
CProduct product;
|
||||
enum { FIELDS_MAX = 20 };
|
||||
wxStaticText* m_staticTextLabel[FIELDS_MAX];
|
||||
wxTextCtrl* m_textCtrlField[FIELDS_MAX];
|
||||
wxChoice* m_choiceField[FIELDS_MAX];
|
||||
|
||||
void GetOrder(CWalletTx& order);
|
||||
void UpdateProductDisplay(bool fDetails);
|
||||
void OnReply1(wxCommandEvent& event);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CViewOrderDialog : public CViewOrderDialogBase
|
||||
{
|
||||
protected:
|
||||
// Event handlers
|
||||
void OnButtonOK(wxCommandEvent& event);
|
||||
|
||||
public:
|
||||
/** Constructor */
|
||||
CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived);
|
||||
|
||||
// Custom
|
||||
bool fReceived;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CEditReviewDialog : public CEditReviewDialogBase
|
||||
{
|
||||
protected:
|
||||
// Event handlers
|
||||
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
|
||||
void OnButtonSubmit(wxCommandEvent& event);
|
||||
void OnButtonCancel(wxCommandEvent& event);
|
||||
|
||||
public:
|
||||
/** Constructor */
|
||||
CEditReviewDialog(wxWindow* parent);
|
||||
|
||||
// Custom
|
||||
void GetReview(CReview& review);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CGetTextFromUserDialog : public CGetTextFromUserDialogBase
|
||||
{
|
||||
protected:
|
||||
@@ -420,16 +277,25 @@ public:
|
||||
const string& strMessage2="",
|
||||
const string& strValue2="") : CGetTextFromUserDialogBase(parent, wxID_ANY, strCaption)
|
||||
{
|
||||
int x = GetSize().GetWidth();
|
||||
int y = GetSize().GetHeight();
|
||||
m_staticTextMessage1->SetLabel(strMessage1);
|
||||
m_textCtrl1->SetValue(strValue1);
|
||||
y += wxString(strMessage1).Freq('\n') * 14;
|
||||
if (!strMessage2.empty())
|
||||
{
|
||||
m_staticTextMessage2->Show(true);
|
||||
m_staticTextMessage2->SetLabel(strMessage2);
|
||||
m_textCtrl2->Show(true);
|
||||
m_textCtrl2->SetValue(strValue2);
|
||||
SetSize(wxDefaultCoord, 180);
|
||||
y += 46 + wxString(strMessage2).Freq('\n') * 14;
|
||||
}
|
||||
if (!fWindows)
|
||||
{
|
||||
x *= 1.14;
|
||||
y *= 1.14;
|
||||
}
|
||||
SetSize(x, y);
|
||||
}
|
||||
|
||||
// Custom
|
||||
|
||||
1130
uibase.cpp
1130
uibase.cpp
File diff suppressed because it is too large
Load Diff
374
uibase.h
374
uibase.h
@@ -8,6 +8,8 @@
|
||||
#ifndef __uibase__
|
||||
#define __uibase__
|
||||
|
||||
#include <wx/intl.h>
|
||||
|
||||
#include <wx/string.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/image.h>
|
||||
@@ -35,60 +37,34 @@
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/scrolwin.h>
|
||||
#include <wx/statbmp.h>
|
||||
#include <wx/combobox.h>
|
||||
#include <wx/richtext/richtextctrl.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define wxID_MAINFRAME 1000
|
||||
#define wxID_VIEWSHOWGENERATED 1001
|
||||
#define wxID_OPTIONSGENERATEBITCOINS 1002
|
||||
#define wxID_MENUOPTIONSOPTIONS 1003
|
||||
#define wxID_BUTTONSEND 1004
|
||||
#define wxID_BUTTONRECEIVE 1005
|
||||
#define wxID_TEXTCTRLADDRESS 1006
|
||||
#define wxID_OPTIONSGENERATEBITCOINS 1001
|
||||
#define wxID_MENUOPTIONSOPTIONS 1002
|
||||
#define wxID_BUTTONSEND 1003
|
||||
#define wxID_BUTTONRECEIVE 1004
|
||||
#define wxID_TEXTCTRLADDRESS 1005
|
||||
#define wxID_BUTTONNEW 1006
|
||||
#define wxID_BUTTONCOPY 1007
|
||||
#define wxID_BUTTONCHANGE 1008
|
||||
#define wxID_TRANSACTIONFEE 1009
|
||||
#define wxID_PROXYIP 1010
|
||||
#define wxID_PROXYPORT 1011
|
||||
#define wxID_TEXTCTRLPAYTO 1012
|
||||
#define wxID_BUTTONPASTE 1013
|
||||
#define wxID_BUTTONADDRESSBOOK 1014
|
||||
#define wxID_TEXTCTRLAMOUNT 1015
|
||||
#define wxID_CHOICETRANSFERTYPE 1016
|
||||
#define wxID_LISTCTRL 1017
|
||||
#define wxID_BUTTONRENAME 1018
|
||||
#define wxID_BUTTONNEW 1019
|
||||
#define wxID_BUTTONEDIT 1020
|
||||
#define wxID_BUTTONDELETE 1021
|
||||
#define wxID_DEL0 1022
|
||||
#define wxID_DEL1 1023
|
||||
#define wxID_DEL2 1024
|
||||
#define wxID_DEL3 1025
|
||||
#define wxID_DEL4 1026
|
||||
#define wxID_DEL5 1027
|
||||
#define wxID_DEL6 1028
|
||||
#define wxID_DEL7 1029
|
||||
#define wxID_DEL8 1030
|
||||
#define wxID_DEL9 1031
|
||||
#define wxID_DEL10 1032
|
||||
#define wxID_DEL11 1033
|
||||
#define wxID_DEL12 1034
|
||||
#define wxID_DEL13 1035
|
||||
#define wxID_DEL14 1036
|
||||
#define wxID_DEL15 1037
|
||||
#define wxID_DEL16 1038
|
||||
#define wxID_DEL17 1039
|
||||
#define wxID_DEL18 1040
|
||||
#define wxID_DEL19 1041
|
||||
#define wxID_BUTTONPREVIEW 1042
|
||||
#define wxID_BUTTONSAMPLE 1043
|
||||
#define wxID_CANCEL2 1044
|
||||
#define wxID_BUTTONBACK 1045
|
||||
#define wxID_BUTTONNEXT 1046
|
||||
#define wxID_SUBMIT 1047
|
||||
#define wxID_TEXTCTRL 1048
|
||||
#define wxID_TRANSACTIONFEE 1008
|
||||
#define wxID_PROXYIP 1009
|
||||
#define wxID_PROXYPORT 1010
|
||||
#define wxID_TEXTCTRLPAYTO 1011
|
||||
#define wxID_BUTTONPASTE 1012
|
||||
#define wxID_BUTTONADDRESSBOOK 1013
|
||||
#define wxID_TEXTCTRLAMOUNT 1014
|
||||
#define wxID_CHOICETRANSFERTYPE 1015
|
||||
#define wxID_LISTCTRL 1016
|
||||
#define wxID_BUTTONRENAME 1017
|
||||
#define wxID_PANELSENDING 1018
|
||||
#define wxID_LISTCTRLSENDING 1019
|
||||
#define wxID_PANELRECEIVING 1020
|
||||
#define wxID_LISTCTRLRECEIVING 1021
|
||||
#define wxID_BUTTONDELETE 1022
|
||||
#define wxID_BUTTONEDIT 1023
|
||||
#define wxID_TEXTCTRL 1024
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CMainFrameBase
|
||||
@@ -100,15 +76,13 @@ class CMainFrameBase : public wxFrame
|
||||
protected:
|
||||
wxMenuBar* m_menubar;
|
||||
wxMenu* m_menuFile;
|
||||
wxMenu* m_menuView;
|
||||
wxMenu* m_menuHelp;
|
||||
wxToolBar* m_toolBar;
|
||||
wxStatusBar* m_statusBar;
|
||||
|
||||
wxStaticText* m_staticText32;
|
||||
wxTextCtrl* m_textCtrlAddress;
|
||||
wxButton* m_buttonNew;
|
||||
wxButton* m_buttonCopy;
|
||||
wxButton* m_button91;
|
||||
|
||||
wxPanel* m_panel14;
|
||||
wxStaticText* m_staticText41;
|
||||
@@ -116,11 +90,10 @@ class CMainFrameBase : public wxFrame
|
||||
|
||||
wxChoice* m_choiceFilter;
|
||||
wxNotebook* m_notebook;
|
||||
wxPanel* m_panel7;
|
||||
wxPanel* m_panel9;
|
||||
wxPanel* m_panel8;
|
||||
wxPanel* m_panel10;
|
||||
wxPanel* m_panel11;
|
||||
wxPanel* m_panel91;
|
||||
wxPanel* m_panel92;
|
||||
wxPanel* m_panel93;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnClose( wxCloseEvent& event ){ event.Skip(); }
|
||||
@@ -129,8 +102,6 @@ class CMainFrameBase : public wxFrame
|
||||
virtual void OnMouseEvents( wxMouseEvent& event ){ event.Skip(); }
|
||||
virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); }
|
||||
virtual void OnMenuFileExit( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnMenuViewShowGenerated( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnUpdateUIViewShowGenerated( wxUpdateUIEvent& event ){ event.Skip(); }
|
||||
virtual void OnMenuOptionsGenerate( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnUpdateUIOptionsGenerate( wxUpdateUIEvent& event ){ event.Skip(); }
|
||||
virtual void OnMenuOptionsChangeYourAddress( wxCommandEvent& event ){ event.Skip(); }
|
||||
@@ -141,24 +112,22 @@ class CMainFrameBase : public wxFrame
|
||||
virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); }
|
||||
virtual void OnMouseEventsAddress( wxMouseEvent& event ){ event.Skip(); }
|
||||
virtual void OnSetFocusAddress( wxFocusEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonNew( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonChange( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnNotebookPageChanged( wxNotebookEvent& event ){ event.Skip(); }
|
||||
virtual void OnListColBeginDrag( wxListEvent& event ){ event.Skip(); }
|
||||
virtual void OnListItemActivatedAllTransactions( wxListEvent& event ){ event.Skip(); }
|
||||
virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); }
|
||||
virtual void OnPaintListCtrl( wxPaintEvent& event ){ event.Skip(); }
|
||||
virtual void OnListItemActivatedOrdersSent( wxListEvent& event ){ event.Skip(); }
|
||||
virtual void OnListItemActivatedProductsSent( wxListEvent& event ){ event.Skip(); }
|
||||
virtual void OnListItemActivatedOrdersReceived( wxListEvent& event ){ event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
wxMenu* m_menuOptions;
|
||||
wxListCtrl* m_listCtrl;
|
||||
wxListCtrl* m_listCtrlEscrows;
|
||||
wxListCtrl* m_listCtrlOrdersSent;
|
||||
wxListCtrl* m_listCtrlProductsSent;
|
||||
wxListCtrl* m_listCtrlOrdersReceived;
|
||||
CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 705,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL );
|
||||
wxTextCtrl* m_textCtrlAddress;
|
||||
wxListCtrl* m_listCtrlAll;
|
||||
wxListCtrl* m_listCtrlSentReceived;
|
||||
wxListCtrl* m_listCtrlSent;
|
||||
wxListCtrl* m_listCtrlReceived;
|
||||
CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = _("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 723,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL );
|
||||
~CMainFrameBase();
|
||||
|
||||
};
|
||||
@@ -179,7 +148,7 @@ class CTxDetailsDialogBase : public wxDialog
|
||||
|
||||
|
||||
public:
|
||||
CTxDetailsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Transaction Details"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 620,450 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
CTxDetailsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Transaction Details"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 620,450 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
~CTxDetailsDialogBase();
|
||||
|
||||
};
|
||||
@@ -215,8 +184,6 @@ class COptionsDialogBase : public wxDialog
|
||||
|
||||
wxStaticText* m_staticText321;
|
||||
wxStaticText* m_staticText69;
|
||||
wxStaticText* m_staticText70;
|
||||
wxStaticText* m_staticText71;
|
||||
wxButton* m_buttonOK;
|
||||
wxButton* m_buttonCancel;
|
||||
wxButton* m_buttonApply;
|
||||
@@ -234,7 +201,7 @@ class COptionsDialogBase : public wxDialog
|
||||
|
||||
|
||||
public:
|
||||
COptionsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 540,360 ), long style = wxDEFAULT_DIALOG_STYLE );
|
||||
COptionsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 540,360 ), long style = wxDEFAULT_DIALOG_STYLE );
|
||||
~COptionsDialogBase();
|
||||
|
||||
};
|
||||
@@ -247,7 +214,7 @@ class CAboutDialogBase : public wxDialog
|
||||
private:
|
||||
|
||||
protected:
|
||||
|
||||
wxStaticBitmap* m_bitmap;
|
||||
|
||||
wxStaticText* m_staticText40;
|
||||
|
||||
@@ -262,7 +229,7 @@ class CAboutDialogBase : public wxDialog
|
||||
|
||||
public:
|
||||
wxStaticText* m_staticTextVersion;
|
||||
CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 507,298 ), long style = wxDEFAULT_DIALOG_STYLE );
|
||||
CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,329 ), long style = wxDEFAULT_DIALOG_STYLE );
|
||||
~CAboutDialogBase();
|
||||
|
||||
};
|
||||
@@ -309,7 +276,7 @@ class CSendDialogBase : public wxDialog
|
||||
|
||||
|
||||
public:
|
||||
CSendDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 675,312 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
CSendDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 675,312 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
~CSendDialogBase();
|
||||
|
||||
};
|
||||
@@ -336,7 +303,7 @@ class CSendingDialogBase : public wxDialog
|
||||
|
||||
|
||||
public:
|
||||
CSendingDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Sending..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 442,151 ), long style = wxDEFAULT_DIALOG_STYLE );
|
||||
CSendingDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Sending..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 442,151 ), long style = wxDEFAULT_DIALOG_STYLE );
|
||||
~CSendingDialogBase();
|
||||
|
||||
};
|
||||
@@ -372,7 +339,7 @@ class CYourAddressDialogBase : public wxDialog
|
||||
|
||||
|
||||
public:
|
||||
CYourAddressDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Your Bitcoin Addresses"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
CYourAddressDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Your Bitcoin Addresses"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
~CYourAddressDialogBase();
|
||||
|
||||
};
|
||||
@@ -385,265 +352,44 @@ class CAddressBookDialogBase : public wxDialog
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxNotebook* m_notebook;
|
||||
wxPanel* m_panelSending;
|
||||
|
||||
wxStaticText* m_staticText55;
|
||||
wxListCtrl* m_listCtrl;
|
||||
wxListCtrl* m_listCtrlSending;
|
||||
wxPanel* m_panelReceiving;
|
||||
|
||||
wxStaticText* m_staticText45;
|
||||
|
||||
wxListCtrl* m_listCtrlReceiving;
|
||||
|
||||
wxButton* m_buttonDelete;
|
||||
wxButton* m_buttonCopy;
|
||||
wxButton* m_buttonEdit;
|
||||
wxButton* m_buttonNew;
|
||||
wxButton* m_buttonDelete;
|
||||
wxButton* m_buttonOK;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnClose( wxCloseEvent& event ){ event.Skip(); }
|
||||
virtual void OnNotebookPageChanged( wxNotebookEvent& event ){ event.Skip(); }
|
||||
virtual void OnListEndLabelEdit( wxListEvent& event ){ event.Skip(); }
|
||||
virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); }
|
||||
virtual void OnListItemSelected( wxListEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDelete( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonEdit( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonNew( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDelete( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
wxButton* m_buttonCancel;
|
||||
CAddressBookDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
CAddressBookDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
~CAddressBookDialogBase();
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CProductsDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CProductsDialogBase : public wxDialog
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxComboBox* m_comboBoxCategory;
|
||||
wxTextCtrl* m_textCtrlSearch;
|
||||
wxButton* m_buttonSearch;
|
||||
wxListCtrl* m_listCtrl;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnCombobox( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonSearch( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
CProductsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Marketplace"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 708,535 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
~CProductsDialogBase();
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CEditProductDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CEditProductDialogBase : public wxFrame
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxScrolledWindow* m_scrolledWindow;
|
||||
wxStaticText* m_staticText106;
|
||||
wxComboBox* m_comboBoxCategory;
|
||||
wxStaticText* m_staticText108;
|
||||
wxTextCtrl* m_textCtrlTitle;
|
||||
wxStaticText* m_staticText107;
|
||||
wxTextCtrl* m_textCtrlPrice;
|
||||
wxStaticText* m_staticText22;
|
||||
wxTextCtrl* m_textCtrlDescription;
|
||||
wxStaticText* m_staticText23;
|
||||
wxTextCtrl* m_textCtrlInstructions;
|
||||
wxStaticText* m_staticText24;
|
||||
wxStaticText* m_staticText25;
|
||||
|
||||
wxTextCtrl* m_textCtrlLabel0;
|
||||
wxTextCtrl* m_textCtrlField0;
|
||||
wxButton* m_buttonDel0;
|
||||
wxTextCtrl* m_textCtrlLabel1;
|
||||
wxTextCtrl* m_textCtrlField1;
|
||||
wxButton* m_buttonDel1;
|
||||
wxTextCtrl* m_textCtrlLabel2;
|
||||
wxTextCtrl* m_textCtrlField2;
|
||||
wxButton* m_buttonDel2;
|
||||
wxTextCtrl* m_textCtrlLabel3;
|
||||
wxTextCtrl* m_textCtrlField3;
|
||||
wxButton* m_buttonDel3;
|
||||
wxTextCtrl* m_textCtrlLabel4;
|
||||
wxTextCtrl* m_textCtrlField4;
|
||||
wxButton* m_buttonDel4;
|
||||
wxTextCtrl* m_textCtrlLabel5;
|
||||
wxTextCtrl* m_textCtrlField5;
|
||||
wxButton* m_buttonDel5;
|
||||
wxTextCtrl* m_textCtrlLabel6;
|
||||
wxTextCtrl* m_textCtrlField6;
|
||||
wxButton* m_buttonDel6;
|
||||
wxTextCtrl* m_textCtrlLabel7;
|
||||
wxTextCtrl* m_textCtrlField7;
|
||||
wxButton* m_buttonDel7;
|
||||
wxTextCtrl* m_textCtrlLabel8;
|
||||
wxTextCtrl* m_textCtrlField8;
|
||||
wxButton* m_buttonDel8;
|
||||
wxTextCtrl* m_textCtrlLabel9;
|
||||
wxTextCtrl* m_textCtrlField9;
|
||||
wxButton* m_buttonDel9;
|
||||
wxTextCtrl* m_textCtrlLabel10;
|
||||
wxTextCtrl* m_textCtrlField10;
|
||||
wxButton* m_buttonDel10;
|
||||
wxTextCtrl* m_textCtrlLabel11;
|
||||
wxTextCtrl* m_textCtrlField11;
|
||||
wxButton* m_buttonDel11;
|
||||
wxTextCtrl* m_textCtrlLabel12;
|
||||
wxTextCtrl* m_textCtrlField12;
|
||||
wxButton* m_buttonDel12;
|
||||
wxTextCtrl* m_textCtrlLabel13;
|
||||
wxTextCtrl* m_textCtrlField13;
|
||||
wxButton* m_buttonDel13;
|
||||
wxTextCtrl* m_textCtrlLabel14;
|
||||
wxTextCtrl* m_textCtrlField14;
|
||||
wxButton* m_buttonDel14;
|
||||
wxTextCtrl* m_textCtrlLabel15;
|
||||
wxTextCtrl* m_textCtrlField15;
|
||||
wxButton* m_buttonDel15;
|
||||
wxTextCtrl* m_textCtrlLabel16;
|
||||
wxTextCtrl* m_textCtrlField16;
|
||||
wxButton* m_buttonDel16;
|
||||
wxTextCtrl* m_textCtrlLabel17;
|
||||
wxTextCtrl* m_textCtrlField17;
|
||||
wxButton* m_buttonDel17;
|
||||
wxTextCtrl* m_textCtrlLabel18;
|
||||
wxTextCtrl* m_textCtrlField18;
|
||||
wxButton* m_buttonDel18;
|
||||
wxTextCtrl* m_textCtrlLabel19;
|
||||
wxTextCtrl* m_textCtrlField19;
|
||||
wxButton* m_buttonDel19;
|
||||
wxButton* m_buttonAddField;
|
||||
wxButton* m_buttonOK;
|
||||
wxButton* m_buttonPreview;
|
||||
wxButton* m_buttonCancel;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel0( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel1( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel2( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel3( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel4( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel5( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel6( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel7( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel8( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel9( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel10( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel11( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel12( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel13( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel14( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel15( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel16( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel17( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel18( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonDel19( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonAddField( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonSend( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonPreview( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
wxFlexGridSizer* fgSizer5;
|
||||
CEditProductDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Edit Product"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 660,640 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL );
|
||||
~CEditProductDialogBase();
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CViewProductDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CViewProductDialogBase : public wxFrame
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxHtmlWindow* m_htmlWinReviews;
|
||||
wxScrolledWindow* m_scrolledWindow;
|
||||
wxRichTextCtrl* m_richTextHeading;
|
||||
wxStaticText* m_staticTextInstructions;
|
||||
wxButton* m_buttonSubmitForm;
|
||||
wxButton* m_buttonCancelForm;
|
||||
wxButton* m_buttonBack;
|
||||
wxButton* m_buttonNext;
|
||||
wxButton* m_buttonCancel;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnButtonSubmitForm( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonCancelForm( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonBack( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonNext( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
CViewProductDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Order Form"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 630,520 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL );
|
||||
~CViewProductDialogBase();
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CViewOrderDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CViewOrderDialogBase : public wxFrame
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxHtmlWindow* m_htmlWin;
|
||||
wxButton* m_buttonOK;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
CViewOrderDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("View Order"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 630,520 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL );
|
||||
~CViewOrderDialogBase();
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CEditReviewDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CEditReviewDialogBase : public wxFrame
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
|
||||
wxStaticText* m_staticTextSeller;
|
||||
|
||||
wxStaticText* m_staticText110;
|
||||
wxChoice* m_choiceStars;
|
||||
wxStaticText* m_staticText43;
|
||||
wxTextCtrl* m_textCtrlReview;
|
||||
wxButton* m_buttonSubmit;
|
||||
wxButton* m_buttonCancel;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonSubmit( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
CEditReviewDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Enter Review"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 630,440 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL );
|
||||
~CEditReviewDialogBase();
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class CGetTextFromUserDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -670,7 +416,7 @@ class CGetTextFromUserDialogBase : public wxDialog
|
||||
|
||||
|
||||
public:
|
||||
CGetTextFromUserDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 403,138 ), long style = wxDEFAULT_DIALOG_STYLE );
|
||||
CGetTextFromUserDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 440,138 ), long style = wxDEFAULT_DIALOG_STYLE );
|
||||
~CGetTextFromUserDialogBase();
|
||||
|
||||
};
|
||||
|
||||
14
uint256.h
14
uint256.h
@@ -299,19 +299,18 @@ public:
|
||||
return string(psz, psz + sizeof(pn)*2);
|
||||
}
|
||||
|
||||
void SetHex(const std::string& str)
|
||||
void SetHex(const char* psz)
|
||||
{
|
||||
for (int i = 0; i < WIDTH; i++)
|
||||
pn[i] = 0;
|
||||
|
||||
// skip 0x
|
||||
const char* psz = str.c_str();
|
||||
// skip leading spaces
|
||||
while (isspace(*psz))
|
||||
psz++;
|
||||
|
||||
// skip 0x
|
||||
if (psz[0] == '0' && tolower(psz[1]) == 'x')
|
||||
psz += 2;
|
||||
while (isspace(*psz))
|
||||
psz++;
|
||||
|
||||
// hex string to uint
|
||||
static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
|
||||
@@ -332,6 +331,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void SetHex(const std::string& str)
|
||||
{
|
||||
SetHex(str.c_str());
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
return (GetHex());
|
||||
|
||||
7229
uiproject.fbp
7229
uiproject.fbp
File diff suppressed because it is too large
Load Diff
121
util.cpp
121
util.cpp
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
map<string, string> mapArgs;
|
||||
map<string, vector<string> > mapMultiArgs;
|
||||
bool fDebug = false;
|
||||
bool fPrintToDebugger = false;
|
||||
bool fPrintToConsole = false;
|
||||
bool fPrintToDebugger = false;
|
||||
char pszSetDataDir[MAX_PATH] = "";
|
||||
bool fShutdown = false;
|
||||
bool fDaemon = false;
|
||||
bool fCommandLine = false;
|
||||
|
||||
|
||||
|
||||
@@ -75,6 +77,8 @@ void RandAddSeed()
|
||||
|
||||
void RandAddSeedPerfmon()
|
||||
{
|
||||
RandAddSeed();
|
||||
|
||||
// This can take up to 2 seconds, so only do it every 10 minutes
|
||||
static int64 nLastPerfmon;
|
||||
if (GetTime() < nLastPerfmon + 10 * 60)
|
||||
@@ -87,7 +91,7 @@ void RandAddSeedPerfmon()
|
||||
unsigned char pdata[250000];
|
||||
memset(pdata, 0, sizeof(pdata));
|
||||
unsigned long nSize = sizeof(pdata);
|
||||
long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
|
||||
long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
|
||||
RegCloseKey(HKEY_PERFORMANCE_DATA);
|
||||
if (ret == ERROR_SUCCESS)
|
||||
{
|
||||
@@ -129,6 +133,79 @@ uint64 GetRand(uint64 nMax)
|
||||
|
||||
|
||||
|
||||
inline int OutputDebugStringF(const char* pszFormat, ...)
|
||||
{
|
||||
int ret = 0;
|
||||
if (fPrintToConsole || wxTheApp == NULL)
|
||||
{
|
||||
// print to console
|
||||
va_list arg_ptr;
|
||||
va_start(arg_ptr, pszFormat);
|
||||
ret = vprintf(pszFormat, arg_ptr);
|
||||
va_end(arg_ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// print to debug.log
|
||||
char pszFile[MAX_PATH+100];
|
||||
GetDataDir(pszFile);
|
||||
strlcat(pszFile, "/debug.log", sizeof(pszFile));
|
||||
FILE* fileout = fopen(pszFile, "a");
|
||||
if (fileout)
|
||||
{
|
||||
//// Debug print useful for profiling
|
||||
//fprintf(fileout, " %"PRI64d" ", wxGetLocalTimeMillis().GetValue());
|
||||
va_list arg_ptr;
|
||||
va_start(arg_ptr, pszFormat);
|
||||
ret = vfprintf(fileout, pszFormat, arg_ptr);
|
||||
va_end(arg_ptr);
|
||||
fclose(fileout);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __WXMSW__
|
||||
if (fPrintToDebugger)
|
||||
{
|
||||
// accumulate a line at a time
|
||||
static CCriticalSection cs_OutputDebugStringF;
|
||||
CRITICAL_BLOCK(cs_OutputDebugStringF)
|
||||
{
|
||||
static char pszBuffer[50000];
|
||||
static char* pend;
|
||||
if (pend == NULL)
|
||||
pend = pszBuffer;
|
||||
va_list arg_ptr;
|
||||
va_start(arg_ptr, pszFormat);
|
||||
int limit = END(pszBuffer) - pend - 2;
|
||||
int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);
|
||||
va_end(arg_ptr);
|
||||
if (ret < 0 || ret >= limit)
|
||||
{
|
||||
pend = END(pszBuffer) - 2;
|
||||
*pend++ = '\n';
|
||||
}
|
||||
else
|
||||
pend += ret;
|
||||
*pend = '\0';
|
||||
char* p1 = pszBuffer;
|
||||
char* p2;
|
||||
while (p2 = strchr(p1, '\n'))
|
||||
{
|
||||
p2++;
|
||||
char c = *p2;
|
||||
*p2 = '\0';
|
||||
OutputDebugStringA(p1);
|
||||
*p2 = c;
|
||||
p1 = p2;
|
||||
}
|
||||
if (p1 != pszBuffer)
|
||||
memmove(pszBuffer, p1, pend - p1 + 1);
|
||||
pend -= (p1 - pszBuffer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Safer snprintf
|
||||
@@ -355,6 +432,39 @@ void ParseParameters(int argc, char* argv[])
|
||||
}
|
||||
|
||||
|
||||
const char* wxGetTranslation(const char* pszEnglish)
|
||||
{
|
||||
// Wrapper of wxGetTranslation returning the same const char* type as was passed in
|
||||
static CCriticalSection cs;
|
||||
CRITICAL_BLOCK(cs)
|
||||
{
|
||||
// Look in cache
|
||||
static map<string, char*> mapCache;
|
||||
map<string, char*>::iterator mi = mapCache.find(pszEnglish);
|
||||
if (mi != mapCache.end())
|
||||
return (*mi).second;
|
||||
|
||||
// wxWidgets translation
|
||||
const char* pszTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8)).utf8_str();
|
||||
|
||||
// We don't cache unknown strings because caller might be passing in a
|
||||
// dynamic string and we would keep allocating memory for each variation.
|
||||
if (strcmp(pszEnglish, pszTranslated) == 0)
|
||||
return pszEnglish;
|
||||
|
||||
// Add to cache, memory doesn't need to be freed. We only cache because
|
||||
// we must pass back a pointer to permanently allocated memory.
|
||||
char* pszCached = new char[strlen(pszTranslated)+1];
|
||||
strcpy(pszCached, pszTranslated);
|
||||
mapCache[pszEnglish] = pszCached;
|
||||
return pszCached;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -365,7 +475,7 @@ void FormatException(char* pszMessage, std::exception* pex, const char* pszThrea
|
||||
#ifdef __WXMSW__
|
||||
char pszModule[MAX_PATH];
|
||||
pszModule[0] = '\0';
|
||||
GetModuleFileName(NULL, pszModule, sizeof(pszModule));
|
||||
GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
|
||||
#else
|
||||
// might not be thread safe, uses wxString
|
||||
//const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str();
|
||||
@@ -391,7 +501,8 @@ void PrintException(std::exception* pex, const char* pszThread)
|
||||
char pszMessage[1000];
|
||||
FormatException(pszMessage, pex, pszThread);
|
||||
printf("\n\n************************\n%s\n", pszMessage);
|
||||
if (wxTheApp)
|
||||
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
|
||||
if (wxTheApp && !fDaemon)
|
||||
wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
|
||||
throw;
|
||||
//DebugBreak();
|
||||
|
||||
119
util.h
119
util.h
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -55,6 +55,7 @@ inline T& REF(const T& val)
|
||||
}
|
||||
|
||||
#ifdef __WXMSW__
|
||||
static const bool fWindows = true;
|
||||
#define MSG_NOSIGNAL 0
|
||||
#define MSG_DONTWAIT 0
|
||||
#ifndef UINT64_MAX
|
||||
@@ -66,7 +67,10 @@ inline T& REF(const T& val)
|
||||
#define S_IRUSR 0400
|
||||
#define S_IWUSR 0200
|
||||
#endif
|
||||
#define unlink _unlink
|
||||
typedef int socklen_t;
|
||||
#else
|
||||
static const bool fWindows = false;
|
||||
#define WSAGetLastError() errno
|
||||
#define WSAEWOULDBLOCK EWOULDBLOCK
|
||||
#define WSAEMSGSIZE EMSGSIZE
|
||||
@@ -112,13 +116,16 @@ inline int myclosesocket(SOCKET& hSocket)
|
||||
extern map<string, string> mapArgs;
|
||||
extern map<string, vector<string> > mapMultiArgs;
|
||||
extern bool fDebug;
|
||||
extern bool fPrintToDebugger;
|
||||
extern bool fPrintToConsole;
|
||||
extern bool fPrintToDebugger;
|
||||
extern char pszSetDataDir[MAX_PATH];
|
||||
extern bool fShutdown;
|
||||
extern bool fDaemon;
|
||||
extern bool fCommandLine;
|
||||
|
||||
void RandAddSeed();
|
||||
void RandAddSeedPerfmon();
|
||||
int OutputDebugStringF(const char* pszFormat, ...);
|
||||
int my_snprintf(char* buffer, size_t limit, const char* format, ...);
|
||||
string strprintf(const char* format, ...);
|
||||
bool error(const char* format, ...);
|
||||
@@ -130,6 +137,7 @@ bool ParseMoney(const char* pszIn, int64& nRet);
|
||||
vector<unsigned char> ParseHex(const char* psz);
|
||||
vector<unsigned char> ParseHex(const std::string& str);
|
||||
void ParseParameters(int argc, char* argv[]);
|
||||
const char* wxGetTranslation(const char* psz);
|
||||
int GetFilesize(FILE* file);
|
||||
void GetDataDir(char* pszDirRet);
|
||||
string GetDataDir();
|
||||
@@ -219,92 +227,6 @@ public:
|
||||
|
||||
|
||||
|
||||
inline int OutputDebugStringF(const char* pszFormat, ...)
|
||||
{
|
||||
int ret = 0;
|
||||
#ifdef __WXDEBUG__
|
||||
if (!fPrintToConsole)
|
||||
{
|
||||
// print to debug.log
|
||||
char pszFile[MAX_PATH+100];
|
||||
GetDataDir(pszFile);
|
||||
strlcat(pszFile, "/debug.log", sizeof(pszFile));
|
||||
FILE* fileout = fopen(pszFile, "a");
|
||||
if (fileout)
|
||||
{
|
||||
//// Debug print useful for profiling
|
||||
//fprintf(fileout, " %"PRI64d" ", wxGetLocalTimeMillis().GetValue());
|
||||
va_list arg_ptr;
|
||||
va_start(arg_ptr, pszFormat);
|
||||
ret = vfprintf(fileout, pszFormat, arg_ptr);
|
||||
va_end(arg_ptr);
|
||||
fclose(fileout);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __WXMSW__
|
||||
if (fPrintToDebugger)
|
||||
{
|
||||
// accumulate a line at a time
|
||||
static CCriticalSection cs_OutputDebugStringF;
|
||||
CRITICAL_BLOCK(cs_OutputDebugStringF)
|
||||
{
|
||||
static char pszBuffer[50000];
|
||||
static char* pend;
|
||||
if (pend == NULL)
|
||||
pend = pszBuffer;
|
||||
va_list arg_ptr;
|
||||
va_start(arg_ptr, pszFormat);
|
||||
int limit = END(pszBuffer) - pend - 2;
|
||||
int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);
|
||||
va_end(arg_ptr);
|
||||
if (ret < 0 || ret >= limit)
|
||||
{
|
||||
pend = END(pszBuffer) - 2;
|
||||
*pend++ = '\n';
|
||||
}
|
||||
else
|
||||
pend += ret;
|
||||
*pend = '\0';
|
||||
char* p1 = pszBuffer;
|
||||
char* p2;
|
||||
while (p2 = strchr(p1, '\n'))
|
||||
{
|
||||
p2++;
|
||||
char c = *p2;
|
||||
*p2 = '\0';
|
||||
OutputDebugString(p1);
|
||||
*p2 = c;
|
||||
p1 = p2;
|
||||
}
|
||||
if (p1 != pszBuffer)
|
||||
memmove(pszBuffer, p1, pend - p1 + 1);
|
||||
pend -= (p1 - pszBuffer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (fPrintToConsole)
|
||||
{
|
||||
// print to console
|
||||
va_list arg_ptr;
|
||||
va_start(arg_ptr, pszFormat);
|
||||
ret = vprintf(pszFormat, arg_ptr);
|
||||
va_end(arg_ptr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inline string i64tostr(int64 n)
|
||||
{
|
||||
return strprintf("%"PRI64d, n);
|
||||
@@ -343,6 +265,11 @@ inline int roundint(double d)
|
||||
return (int)(d > 0 ? d + 0.5 : d - 0.5);
|
||||
}
|
||||
|
||||
inline int64 roundint64(double d)
|
||||
{
|
||||
return (int64)(d > 0 ? d + 0.5 : d - 0.5);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
string HexStr(const T itbegin, const T itend, bool fSpaces=true)
|
||||
{
|
||||
@@ -408,6 +335,17 @@ inline string DateTimeStrFormat(const char* pszFormat, int64 nTime)
|
||||
return pszTime;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void skipspaces(T& it)
|
||||
{
|
||||
while (isspace(*it))
|
||||
++it;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -418,8 +356,9 @@ inline string DateTimeStrFormat(const char* pszFormat, int64 nTime)
|
||||
inline void heapchk()
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
if (_heapchk() != _HEAPOK)
|
||||
DebugBreak();
|
||||
/// for debugging
|
||||
//if (_heapchk() != _HEAPOK)
|
||||
// DebugBreak();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
665
xpm/about.xpm
Normal file
665
xpm/about.xpm
Normal file
@@ -0,0 +1,665 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
/* XPM */
|
||||
static const char * about_xpm[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"96 564 92 1",
|
||||
" c #001269",
|
||||
". c #000C72",
|
||||
"X c #00057F",
|
||||
"o c #001175",
|
||||
"O c #000B6A",
|
||||
"+ c #000E84",
|
||||
"@ c #000489",
|
||||
"# c #001583",
|
||||
"$ c #001B89",
|
||||
"% c #001B99",
|
||||
"& c #000B92",
|
||||
"* c #00208B",
|
||||
"= c #002B97",
|
||||
"- c #0004A6",
|
||||
"; c #001DA7",
|
||||
": c #0014BC",
|
||||
"> c #0019BB",
|
||||
", c #0017B4",
|
||||
"< c #0023A3",
|
||||
"1 c #002CAA",
|
||||
"2 c #0030A4",
|
||||
"3 c #003BA3",
|
||||
"4 c #0033AB",
|
||||
"5 c #003FA8",
|
||||
"6 c #0027B8",
|
||||
"7 c #0035BB",
|
||||
"8 c #003CBA",
|
||||
"9 c #004ABD",
|
||||
"0 c #001DC4",
|
||||
"q c #0017CC",
|
||||
"w c #000CD0",
|
||||
"e c #0026C7",
|
||||
"r c #0035C4",
|
||||
"t c #003DC5",
|
||||
"y c #0032CB",
|
||||
"u c #003BCC",
|
||||
"i c #002BD3",
|
||||
"p c #0021DC",
|
||||
"a c #0025D5",
|
||||
"s c #0034D5",
|
||||
"d c #003ADB",
|
||||
"f c #0016F6",
|
||||
"g c #0008F9",
|
||||
"h c #0027E3",
|
||||
"j c #003CE9",
|
||||
"k c #002BF5",
|
||||
"l c #0024F9",
|
||||
"z c #0033F4",
|
||||
"x c #0035F8",
|
||||
"c c #0048CA",
|
||||
"v c #0055C5",
|
||||
"b c #0059C3",
|
||||
"n c #0053CB",
|
||||
"m c #005ACC",
|
||||
"M c #004FD4",
|
||||
"N c #004CDC",
|
||||
"B c #0047D0",
|
||||
"V c #005BD6",
|
||||
"C c #0049E5",
|
||||
"Z c #0042EA",
|
||||
"A c #0052E4",
|
||||
"S c #005CE4",
|
||||
"D c #0054EC",
|
||||
"F c #005EEB",
|
||||
"G c #004AF5",
|
||||
"H c #0051F2",
|
||||
"J c #005CFA",
|
||||
"K c #0058F9",
|
||||
"L c #0066E4",
|
||||
"P c #006BE3",
|
||||
"I c #0064EC",
|
||||
"U c #006DEF",
|
||||
"Y c #0074EB",
|
||||
"T c #0078EC",
|
||||
"R c #0073E7",
|
||||
"E c #0065F4",
|
||||
"W c #006BF5",
|
||||
"Q c #006BFB",
|
||||
"! c #0066FD",
|
||||
"~ c #0073F5",
|
||||
"^ c #007CF3",
|
||||
"/ c #0075FB",
|
||||
"( c #007DFC",
|
||||
") c #0084FF",
|
||||
"_ c #008AFF",
|
||||
"` c #0092FF",
|
||||
"' c #339CFF",
|
||||
"] c #33A3FF",
|
||||
"[ c #33AAFF",
|
||||
"{ c #66B5FF",
|
||||
"} c #66BBFF",
|
||||
"| c #66C0FF",
|
||||
/* pixels */
|
||||
"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}",
|
||||
"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}",
|
||||
"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}",
|
||||
"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}",
|
||||
"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}",
|
||||
"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}",
|
||||
"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}",
|
||||
"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}",
|
||||
"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}",
|
||||
"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}",
|
||||
"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}",
|
||||
"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}",
|
||||
"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{",
|
||||
"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{",
|
||||
"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{",
|
||||
"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{",
|
||||
"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{",
|
||||
"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{",
|
||||
"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{",
|
||||
"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{",
|
||||
"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{",
|
||||
"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{",
|
||||
"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{",
|
||||
"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{",
|
||||
"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{",
|
||||
"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{",
|
||||
"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{",
|
||||
"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{",
|
||||
"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{",
|
||||
"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{",
|
||||
"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{",
|
||||
"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{",
|
||||
"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{",
|
||||
"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{",
|
||||
"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{",
|
||||
"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{",
|
||||
"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{",
|
||||
"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{",
|
||||
" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}",
|
||||
" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}",
|
||||
" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}",
|
||||
" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}",
|
||||
" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}",
|
||||
" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}",
|
||||
" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}",
|
||||
" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}",
|
||||
" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}",
|
||||
" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}",
|
||||
" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}",
|
||||
" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}",
|
||||
"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{",
|
||||
"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{",
|
||||
"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{",
|
||||
"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{",
|
||||
"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{",
|
||||
"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{",
|
||||
"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{",
|
||||
"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{",
|
||||
"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{",
|
||||
"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{",
|
||||
"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{",
|
||||
"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{",
|
||||
"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{",
|
||||
"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{",
|
||||
"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{",
|
||||
"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{",
|
||||
"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{",
|
||||
"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{",
|
||||
"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{",
|
||||
"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{",
|
||||
"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{",
|
||||
"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{",
|
||||
"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{",
|
||||
"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{",
|
||||
"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||",
|
||||
"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||",
|
||||
"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||",
|
||||
"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||",
|
||||
"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||",
|
||||
"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||",
|
||||
"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||",
|
||||
"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||",
|
||||
"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||",
|
||||
"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||",
|
||||
"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||",
|
||||
"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||",
|
||||
"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{",
|
||||
"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{",
|
||||
"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{",
|
||||
"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{",
|
||||
"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{",
|
||||
"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{",
|
||||
"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{",
|
||||
"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{",
|
||||
"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{",
|
||||
"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{",
|
||||
"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{",
|
||||
"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{",
|
||||
">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}",
|
||||
"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}",
|
||||
"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{",
|
||||
"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{",
|
||||
"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{",
|
||||
"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{",
|
||||
"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{",
|
||||
"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{",
|
||||
"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{",
|
||||
"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{",
|
||||
"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{",
|
||||
"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{",
|
||||
"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{",
|
||||
"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{",
|
||||
"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{",
|
||||
"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}",
|
||||
"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}",
|
||||
"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{",
|
||||
"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{",
|
||||
"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{",
|
||||
"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{"
|
||||
};
|
||||
Reference in New Issue
Block a user