Browse Source

Restructure code files

Herman Schoenfeld 7 years ago
parent
commit
b0c80ff2a0

+ 1 - 1
src/core/UCore.pas → src/core.utils/UCoreUtils.pas

@@ -1,4 +1,4 @@
-unit UCore;
+unit UCoreUtils;
 
 { Copyright (c) 2018 by PascalCoin Project
 

+ 469 - 0
src/core.utils/UDataSources.pas

@@ -0,0 +1,469 @@
+unit UDataSources;
+
+{$mode delphi}
+{$modeswitch nestedprocvars}
+
+interface
+
+uses
+  Classes, SysUtils, UAccounts, UNode, UBlockchain, UCommon, UMemory, UConst, UCommon.Data, UCommon.Collections, Generics.Collections, Generics.Defaults, syncobjs;
+
+type
+
+  { TAccountsDataSourceBase }
+
+  TAccountsDataSourceBase = class(TCustomDataSource<TAccount>)
+    protected
+      function GetItemDisposePolicy : TDisposePolicy; override;
+      function GetColumns : TDataColumns; override;
+    public
+      function GetEntityKey(constref AItem: TAccount) : Variant; override;
+      function GetItemField(constref AItem: TAccount; const ABindingName : AnsiString) : Variant; override;
+  end;
+
+  { TAccountsDataSource }
+
+  TAccountsDataSource = class(TAccountsDataSourceBase)
+    public type
+      TOverview = record
+        TotalPASC : UInt64;
+        TotalPASA : Cardinal;
+      end;
+    private
+      FLastKnownUserAccounts : TArray<TAccount>;
+      FKeys : TSortedHashSet<TAccountKey>;
+    protected
+      FLastOverview : TOverview;
+      function GetFilterKeys : TArray<TAccountKey>;
+      procedure SetFilterKeys (const AKeys : TArray<TAccountKey>);
+    public
+      property Overview : TOverview read FLastOverview;
+      property LastFetchResult : TArray<TAccount> read FLastKnownUserAccounts;
+      property FilterKeys : TArray<TAccountKey> read GetFilterKeys write SetFilterKeys;
+      constructor Create(AOwner: TComponent); override;
+      destructor Destroy; override;
+      procedure FetchAll(const AContainer : TList<TAccount>); override;
+  end;
+
+  { TOperationsDataSourceBase }
+
+  TOperationsDataSourceBase = class(TCustomDataSource<TOperationResume>)
+    private
+      FStart, FEnd : Cardinal;
+      function GetTimeSpan : TTimeSpan;
+      procedure SetTimeSpan(const ASpan : TTimeSpan);
+    protected
+      function GetItemDisposePolicy : TDisposePolicy; override;
+      function GetColumns : TDataColumns;  override;
+    public
+      constructor Create(AOwner: TComponent); override;
+      property TimeSpan : TTimeSpan read GetTimeSpan write SetTimeSpan;
+      property StartBlock : Cardinal read FStart write FStart;
+      property EndBlock : Cardinal read FEnd write FEnd;
+      function GetEntityKey(constref AItem: TOperationResume) : Variant; override;
+      function GetItemField(constref AItem: TOperationResume; const ABindingName : AnsiString) : Variant; override;
+  end;
+
+  { TAccountsOperationsDataSource }
+
+  TAccountsOperationsDataSource = class(TOperationsDataSourceBase)
+    private
+      FAccounts : TSortedHashSet<Cardinal>;
+      function GetAccounts : TArray<Cardinal> ;
+      procedure SetAccounts(const AAccounts : TArray<Cardinal>);
+    public
+      constructor Create(AOwner: TComponent);
+      destructor Destroy;
+      property Accounts : TArray<Cardinal> read GetAccounts write SetAccounts;
+      procedure FetchAll(const AContainer : TList<TOperationResume>); override;
+  end;
+
+  { TPendingOperationsDataSource }
+
+  TPendingOperationsDataSource = class(TOperationsDataSourceBase)
+    public
+      procedure FetchAll(const AContainer : TList<TOperationResume>); override;
+  end;
+
+  { TOperationsDataSource }
+
+  TOperationsDataSource = class(TOperationsDataSourceBase)
+    public
+      procedure FetchAll(const AContainer : TList<TOperationResume>); override;
+  end;
+
+implementation
+
+uses
+  math, UCore, UWallet, UUserInterface, UTime;
+
+{ TAccountsDataSourceBase }
+
+function TAccountsDataSourceBase.GetItemDisposePolicy : TDisposePolicy;
+begin
+  Result := idpNone;
+end;
+
+function TAccountsDataSourceBase.GetColumns : TDataColumns;
+begin
+  Result := TDataColumns.Create(
+    TDataColumn.From('Account'),
+    TDataColumn.From('AccountNumber'),
+    TDataColumn.From('Name'),
+    TDataColumn.From('Balance'),
+    TDataColumn.From('BalanceDecimal'),
+    TDataColumn.From('Key'),
+    TDataColumn.From('Type'),
+    TDataColumn.From('State'),
+    TDataColumn.From('Price'),
+    TDataColumn.From('PriceDecimal'),
+    TDataColumn.From('LockedUntil')
+  );
+end;
+
+function TAccountsDataSourceBase.GetEntityKey(constref AItem: TAccount) : Variant;
+begin
+  Result := AItem.account;
+end;
+
+function TAccountsDataSourceBase.GetItemField(constref AItem: TAccount; const ABindingName : AnsiString) : Variant;
+var
+  index : Integer;
+begin
+   if ABindingName = 'Account' then
+     Result := TAccountComp.AccountNumberToAccountTxtNumber(AItem.account)
+   else if ABindingName = 'AccountNumber' then
+     Result := AItem.account
+   else if ABindingName = 'Name' then
+     Result := AItem.name
+   else if ABindingName = 'Balance' then
+     Result := AItem.Balance
+   else if ABindingName = 'BalanceDecimal' then
+     Result := TAccountComp.FormatMoneyDecimal(AItem.Balance)
+   else if ABindingName = 'Key' then
+     Result := TAccountComp.AccountPublicKeyExport(AItem.accountInfo.accountKey)
+   else if ABindingName = 'Type' then
+     Result := AItem.account_type
+   else if ABindingName = 'State' then
+     Result := AItem.accountInfo.state
+   else if ABindingName = 'Price' then
+     Result := AItem.accountInfo.price
+   else if ABindingName = 'PriceDecimal' then
+     Result := TAccountComp.FormatMoneyDecimal(AItem.accountInfo.price)
+   else if ABindingName = 'LockedUntil' then
+     Result := AItem.accountInfo.locked_until_block
+   else raise Exception.Create(Format('Field not found "%s"', [ABindingName]));
+end;
+
+
+{ TAccountsDataSource }
+
+constructor TAccountsDataSource.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  FKeys := TSortedHashSet<TAccountKey>.Create(TAccountKeyComparer.Create, TAccountKeyEqualityComparer.Create);
+end;
+
+destructor TAccountsDataSource.Destroy;
+begin
+  FKeys.Free;
+end;
+
+function TAccountsDataSource.GetFilterKeys : TArray<TAccountKey>;
+begin
+  Result := FKeys.ToArray;
+end;
+
+procedure TAccountsDataSource.SetFilterKeys (const AKeys : TArray<TAccountKey>);
+var i : Integer;
+begin
+  FKeys.Clear;
+  for i := Low(AKeys) to High(AKeys) do
+    FKeys.Add(AKeys[i]);
+end;
+
+procedure TAccountsDataSource.FetchAll(const AContainer : TList<TAccount>);
+var
+  i,j : integer;
+  acc : TAccount;
+  safeBox : TPCSafeBox;
+  GC : TDisposables;
+  left,right:TAccountKey;
+begin
+  FLastOverview.TotalPASC := 0;
+  FLastOverview.TotalPASA := 0;
+  safeBox := TUserInterface.Node.Bank.SafeBox;
+  safeBox.StartThreadSafe;
+  try
+   if FKeys.Count = 0 then
+     for i := 0 to safeBox.AccountsCount - 1 do begin
+       // Load all accounts
+       AContainer.Add(safeBox.Account(i));
+       FLastOverview.TotalPASC := FLastOverview.TotalPASC + acc.Balance;
+       inc(FLastOverview.TotalPASA);
+     end
+   else begin
+     // load key-matching accounts
+     for i := 0 to safeBox.AccountsCount - 1 do begin
+       acc := safeBox.Account(i);
+       if FKeys.Contains(acc.accountInfo.accountKey) then begin
+         AContainer.Add(acc);
+         FLastOverview.TotalPASC := FLastOverview.TotalPASC + acc.Balance;
+         inc(FLastOverview.TotalPASA);
+       end else begin
+         for left in FKeys do begin
+           right := acc.accountInfo.accountKey;
+
+         end;
+       end;
+     end;
+   end;
+  finally
+   safeBox.EndThreadSave;
+  end;
+  FLastKnownUserAccounts := AContainer.ToArray;
+end;
+
+{ TOperationsDataSourceBase }
+
+constructor TOperationsDataSourceBase.Create(AOwner:TComponent);
+var
+  node : TNode;
+begin
+ inherited Create(AOwner);
+ node := TNode.Node;
+  if Assigned(Node) then begin
+    FStart := 0;
+    FEnd := node.Bank.BlocksCount - 1;
+  end else begin
+    FStart := 0;
+    FEnd := 0;
+  end;
+end;
+
+function TOperationsDataSourceBase.GetTimeSpan : TTimeSpan;
+begin
+  Result := TTimeSpan.FromSeconds( CT_NewLineSecondsAvg * (FEnd - FStart + 1) );
+  //XXXXXXXXXX TTimeSpan use not available at TPCOperationsComp  Result := TPCOperationsComp.ConvertBlockCountToTimeSpan(FEnd - FStart + 1);
+end;
+
+procedure TOperationsDataSourceBase.SetTimeSpan(const ASpan : TTimeSpan);
+var
+  node : TNode;
+begin
+ node := TNode.Node;
+ if Not Assigned(Node) then exit;
+ FEnd := node.Bank.BlocksCount - 1;
+ FStart := ClipValue(FEnd - (Round( ASpan.TotalSeconds / CT_NewLineSecondsAvg ) + 1), 0, FEnd);
+ //XXXXXXXXXX TTimeSpan use not available at TPCOperationsComp  FStart := ClipValue(FEnd - (TPCOperationsComp.ConvertTimeSpanToBlockCount(ASpan) + 1), 0, FEnd);
+end;
+
+function TOperationsDataSourceBase.GetItemDisposePolicy : TDisposePolicy;
+begin
+  Result := idpNone;
+end;
+
+function TOperationsDataSourceBase.GetColumns : TDataColumns;
+begin
+  Result := TDataColumns.Create(
+    TDataColumn.From('UnixTime'),
+    TDataColumn.From('Time'),
+    TDataColumn.From('Block'),
+    TDataColumn.From('Index'),
+    TDataColumn.From('BlockLocation'),
+    TDataColumn.From('BlockLocationSortable'),
+    TDataColumn.From('Account'),
+    TDataColumn.From('AccountNumber'),
+    TDataColumn.From('Type'),
+    TDataColumn.From('SubType'),
+    TDataColumn.From('Amount'),
+    TDataColumn.From('AmountDecimal'),
+    TDataColumn.From('Fee'),
+    TDataColumn.From('FeeDecimal'),
+    TDataColumn.From('Balance'),
+    TDataColumn.From('BalanceDecimal'),
+    TDataColumn.From('Payload'),
+    TDataColumn.From('OPHASH'),
+    TDataColumn.From('Description')
+  );
+end;
+
+function TOperationsDataSourceBase.GetEntityKey(constref AItem: TOperationResume) : Variant;
+begin
+  if AItem.valid then
+    Result := TPCOperation.OperationHashAsHexa(AItem.OperationHash)
+  else
+    Result := nil;
+end;
+
+function TOperationsDataSourceBase.GetItemField(constref AItem: TOperationResume; const ABindingName : AnsiString) : Variant;
+var
+  index : Integer;
+begin
+  if ABindingName = 'UnixTime' then
+    Result := AItem.Time
+  else if ABindingName = 'Time' then
+    Result := UnixTimeToLocalStr(AItem.time)
+  else if ABindingName = 'Block' then
+    Result := AItem.Block
+  else if ABindingName = 'Index' then
+    Result := AItem.NOpInsideBlock
+  else if ABindingName = 'BlockLocation' then
+    Result := IIF(AItem.OpType <> CT_PseudoOp_Reward, Inttostr(AItem.Block) + '/' + Inttostr(AItem.NOpInsideBlock+1), Inttostr(AItem.Block))
+  else if ABindingName = 'BlockLocationSortable' then
+    Result := UInt64(AItem.Block) * 4294967296 + UInt32(AItem.NOpInsideBlock)   // number pattern = [block][opindex]
+  else if ABindingName = 'Account' then
+    Result := TAccountComp.AccountNumberToAccountTxtNumber(AItem.AffectedAccount)
+  else if ABindingName = 'AccountNumber' then
+    Result := AItem.AffectedAccount
+  else if ABindingName = 'Type' then
+    Result := AItem.OpType
+  else if ABindingName = 'SubType' then
+    Result := AItem.OpSubtype
+  else if ABindingName = 'Amount' then
+    Result := AItem.Amount
+  else if ABindingName = 'AmountDecimal' then
+    Result := TAccountComp.FormatMoneyDecimal(AItem.Amount)
+  else if ABindingName = 'Fee' then
+    Result := AItem.Fee
+  else if ABindingName = 'FeeDecimal' then
+    Result := TAccountComp.FormatMoneyDecimal(AItem.Fee)
+  else if ABindingName = 'Balance' then
+    Result := AItem.Balance
+  else if ABindingName = 'BalanceDecimal' then
+    Result := TAccountComp.FormatMoneyDecimal(AItem.Balance)
+  else if ABindingName = 'Payload' then
+    Result := AItem.PrintablePayload
+  else if ABindingName = 'OPHASH' then
+    Result := TPCOperation.OperationHashAsHexa(AItem.OperationHash)
+  else if ABindingName = 'Description' then
+    Result := AItem.OperationTxt
+  else raise Exception.Create(Format('Field not found [%s]', [ABindingName]));
+end;
+
+{ TAccountsOperationsDataSource }
+
+constructor TAccountsOperationsDataSource.Create(AOwner:TComponent);
+begin
+  inherited Create(AOwner);
+  FAccounts := TSortedHashSet<Cardinal>.Create;
+end;
+
+destructor TAccountsOperationsDataSource.Destroy;
+begin
+ Inherited;
+ FAccounts.Free;
+end;
+
+function TAccountsOperationsDataSource.GetAccounts : TArray<Cardinal> ;
+begin
+  Result := FAccounts.ToArray;
+end;
+
+procedure TAccountsOperationsDataSource.SetAccounts(const AAccounts : TArray<Cardinal>);
+begin
+  FAccounts.Clear;
+  FAccounts.AddRange(AAccounts);
+end;
+
+procedure TAccountsOperationsDataSource.FetchAll(const AContainer : TList<TOperationResume>);
+var
+  block, i, keyIndex : integer;
+  OPR : TOperationResume;
+  accountBlockOps : TOperationsResumeList;
+  node : TNode;
+  list : Classes.TList;
+  Op : TPCOperation;
+  acc : Cardinal;
+  GC : TDisposables;
+begin
+  if FAccounts.Count = 0
+    then exit;
+  node := TNode.Node;
+  if Not Assigned(Node)
+    then exit;
+  TUserInterface.Node.Bank.SafeBox.StartThreadSafe;
+  try
+    accountBlockOps := GC.AddObject(TOperationsResumeList.Create ) as TOperationsResumeList;
+    list := GC.AddObject( Classes.TList.Create ) as Classes.TList;
+    for acc in FAccounts do begin
+      // Load pending operations first
+      list.Clear;
+      accountBlockOps.Clear;
+      Node.Operations.OperationsHashTree.GetOperationsAffectingAccount( acc, list );
+      if list.Count > 0 then
+        for i := list.Count - 1 downto 0 do begin
+          Op := node.Operations.OperationsHashTree.GetOperation( PtrInt( list[i] ) );
+          If TPCOperation.OperationToOperationResume( 0, Op, acc, OPR ) then begin
+            OPR.NOpInsideBlock := i;
+            OPR.Block := Node.Operations.OperationBlock.block; ;
+            OPR.Balance := Node.Operations.SafeBoxTransaction.Account( acc {Op.SignerAccount} ).balance;
+            AContainer.Add(OPR);
+          end;
+      end;
+
+      // Load block ops
+      Node.GetStoredOperationsFromAccount(accountBlockOps, acc, MaxInt, 0, MaxInt);
+      for i := 0 to accountBlockOps.Count - 1 do
+        AContainer.Add(accountBlockOps[i]);
+    end;
+  finally
+   TUserInterface.Node.Bank.SafeBox.EndThreadSave;
+  end;
+end;
+
+{ TPendingOperationsDataSource }
+
+procedure TPendingOperationsDataSource.FetchAll(const AContainer : TList<TOperationResume>);
+var
+  i : integer;
+  node : TNode;
+  Op : TPCOperation;
+  OPR : TOperationResume;
+begin
+ node := TNode.Node;
+  if Not Assigned(Node) then exit;
+  for i := Node.Operations.Count - 1 downto 0 do begin
+    Op := Node.Operations.OperationsHashTree.GetOperation(i);
+    If TPCOperation.OperationToOperationResume(0,Op,Op.SignerAccount,OPR) then begin
+      OPR.NOpInsideBlock := i;
+      OPR.Block := Node.Bank.BlocksCount;
+      OPR.Balance := Node.Operations.SafeBoxTransaction.Account(Op.SignerAccount).balance;
+      AContainer.Add(OPR);
+    end;
+  end;
+end;
+
+{ TOperationsDataSource }
+
+procedure TOperationsDataSource.FetchAll(const AContainer : TList<TOperationResume>);
+var
+  block, i, j, keyIndex : integer;
+  OPR : TOperationResume;
+  blockOps : TPCOperationsComp;
+  node : TNode;
+  GC : TDisposables;
+
+begin
+  node := TNode.Node;
+  if Not Assigned(Node) then exit;
+  blockOps := GC.AddObject(TPCOperationsComp.Create(Nil)) as TPCOperationsComp;
+  for block := FEnd downto FStart do begin  /// iterate blocks correctly
+    opr := CT_TOperationResume_NUL;
+    if (Node.Bank.Storage.LoadBlockChainBlock(blockOps, block)) then begin
+      AContainer.Add( blockOps.GetMinerRewardPseudoOperation );
+      if blockOps.Count = 0 then exit;
+      for i := blockOps.Count - 1 downto 0 do begin    // reverse order
+        if TPCOperation.OperationToOperationResume(block, blockOps.Operation[i], blockOps.Operation[i].SignerAccount, opr) then begin
+          opr.NOpInsideBlock := i;
+          opr.Block := block;
+          opr.time := blockOps.OperationBlock.timestamp;
+          AContainer.Add(opr);
+        end;
+      end;
+    end else break;
+  end;
+end;
+
+end.
+

+ 1 - 1
src/core/UDataSources.pas

@@ -95,7 +95,7 @@ type
 implementation
 
 uses
-  math, UCore, UWallet, UUserInterface, UTime;
+  math, UCoreUtils, UWallet, UUserInterface, UTime;
 
 { TAccountsDataSourceBase }
 

+ 1 - 1
src/gui/UCTRLWallet.pas

@@ -85,7 +85,7 @@ type
 implementation
 
 uses
-  UUserInterface, UCellRenderers, UBlockChain, UWallet, UCrypto, UCore,
+  UUserInterface, UCellRenderers, UBlockChain, UWallet, UCrypto, UCoreUtils,
   UCommon, UMemory, Generics.Defaults, UCommon.Data, UCommon.Collections;
 
 {$R *.lfm}

+ 1 - 1
src/gui/UUserInterface.pas

@@ -161,7 +161,7 @@ implementation
 
 uses
   UFRMAbout, UFRMNodesIp, UFRMPascalCoinWalletConfig, UFRMPayloadDecoder, UFRMMemoText,
-  UOpenSSL, UFileStorage, UTime, UCommon, USettings, UCore;
+  UOpenSSL, UFileStorage, UTime, UCommon, USettings, UCoreUtils;
 
 {%region UI Lifecyle}
 

+ 0 - 0
src/common/UAppParams.pas → src/libraries/pascalcoin/UAppParams.pas


+ 0 - 0
src/common/UFolderHelper.pas → src/libraries/pascalcoin/UFolderHelper.pas


+ 0 - 0
src/common/UGridUtils.pas → src/libraries/pascalcoin/UGridUtils.pas


+ 0 - 0
src/common/UJSONFunctions.pas → src/libraries/pascalcoin/UJSONFunctions.pas


+ 131 - 120
src/pascalcoin_wallet.lpi

@@ -33,7 +33,7 @@
         <PackageName Value="LCL"/>
       </Item1>
     </RequiredPackages>
-    <Units Count="76">
+    <Units Count="78">
       <Unit0>
         <Filename Value="pascalcoin_wallet.dpr"/>
         <IsPartOfProject Value="True"/>
@@ -87,343 +87,354 @@
         <IsPartOfProject Value="True"/>
       </Unit12>
       <Unit13>
-        <Filename Value="common\UFolderHelper.pas"/>
+        <Filename Value="gui\UFRMPascalCoinWalletConfig.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="FRMPascalCoinWalletConfig"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit13>
       <Unit14>
-        <Filename Value="common\UAppParams.pas"/>
+        <Filename Value="gui\UFRMAbout.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="FRMAbout"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit14>
       <Unit15>
-        <Filename Value="common\UGridUtils.pas"/>
+        <Filename Value="gui\UFRMOperation.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="FRMOperation"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit15>
       <Unit16>
-        <Filename Value="gui\UFRMPascalCoinWalletConfig.pas"/>
+        <Filename Value="gui\UFRMPayloadDecoder.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMPascalCoinWalletConfig"/>
+        <ComponentName Value="FRMPayloadDecoder"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit16>
       <Unit17>
-        <Filename Value="gui\UFRMAbout.pas"/>
+        <Filename Value="gui\UFRMNodesIp.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMAbout"/>
+        <ComponentName Value="FRMNodesIp"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit17>
       <Unit18>
-        <Filename Value="gui\UFRMOperation.pas"/>
+        <Filename Value="core\UTCPIP.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMOperation"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit18>
       <Unit19>
-        <Filename Value="gui\UFRMPayloadDecoder.pas"/>
+        <Filename Value="core\URPC.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMPayloadDecoder"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit19>
       <Unit20>
-        <Filename Value="gui\UFRMNodesIp.pas"/>
+        <Filename Value="core\UPoolMining.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMNodesIp"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit20>
       <Unit21>
-        <Filename Value="core\UTCPIP.pas"/>
+        <Filename Value="core\UOpenSSL.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit21>
       <Unit22>
-        <Filename Value="common\UJSONFunctions.pas"/>
+        <Filename Value="core\UOpenSSLdef.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit22>
       <Unit23>
-        <Filename Value="core\URPC.pas"/>
+        <Filename Value="core\UFileStorage.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit23>
       <Unit24>
-        <Filename Value="core\UPoolMining.pas"/>
+        <Filename Value="core\UAES.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit24>
       <Unit25>
-        <Filename Value="core\UOpenSSL.pas"/>
+        <Filename Value="core\UChunk.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit25>
       <Unit26>
-        <Filename Value="core\UOpenSSLdef.pas"/>
+        <Filename Value="gui\UFRMAccountSelect.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="FRMAccountSelect"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit26>
       <Unit27>
-        <Filename Value="core\UFileStorage.pas"/>
+        <Filename Value="core\UBaseTypes.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit27>
       <Unit28>
-        <Filename Value="core\UAES.pas"/>
+        <Filename Value="gui\UFRMMessages.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="FRMMessages"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit28>
       <Unit29>
-        <Filename Value="core\UChunk.pas"/>
+        <Filename Value="gui\UFRMNodes.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="FRMNodes"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit29>
       <Unit30>
-        <Filename Value="gui\UFRMAccountSelect.pas"/>
+        <Filename Value="gui\UFRMLogs.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMAccountSelect"/>
+        <ComponentName Value="FRMLogs"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit30>
       <Unit31>
-        <Filename Value="core\UBaseTypes.pas"/>
+        <Filename Value="gui\UFRMOperationExplorer.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="FRMOperationExplorer"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit31>
       <Unit32>
-        <Filename Value="gui\UFRMMessages.pas"/>
+        <Filename Value="gui\UFRMBlockExplorer.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMMessages"/>
+        <ComponentName Value="FRMBlockExplorer"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit32>
       <Unit33>
-        <Filename Value="gui\UFRMNodes.pas"/>
+        <Filename Value="gui\UFRMPendingOperations.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMNodes"/>
+        <ComponentName Value="FRMPendingOperations"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit33>
       <Unit34>
-        <Filename Value="gui\UFRMLogs.pas"/>
+        <Filename Value="gui\UFRMAccountExplorer.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMLogs"/>
+        <ComponentName Value="FRMAccountExplorer"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit34>
       <Unit35>
-        <Filename Value="gui\UFRMOperationExplorer.pas"/>
+        <Filename Value="gui\UUserInterface.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMOperationExplorer"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit35>
       <Unit36>
-        <Filename Value="gui\UFRMBlockExplorer.pas"/>
+        <Filename Value="core\UGPUMining.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMBlockExplorer"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit36>
       <Unit37>
-        <Filename Value="gui\UFRMPendingOperations.pas"/>
+        <Filename Value="core\upcdaemon.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMPendingOperations"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit37>
       <Unit38>
-        <Filename Value="gui\UFRMAccountExplorer.pas"/>
+        <Filename Value="core\UPoolMinerThreads.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMAccountExplorer"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit38>
       <Unit39>
-        <Filename Value="gui\UUserInterface.pas"/>
+        <Filename Value="core\UServerApp.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit39>
       <Unit40>
-        <Filename Value="core\UGPUMining.pas"/>
+        <Filename Value="core\USha256.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit40>
       <Unit41>
-        <Filename Value="core\upcdaemon.pas"/>
+        <Filename Value="gui\UFRMAccountInfo.pas"/>
         <IsPartOfProject Value="True"/>
+        <HasResources Value="True"/>
       </Unit41>
       <Unit42>
-        <Filename Value="core\UPoolMinerThreads.pas"/>
+        <Filename Value="gui\UFRMMemoText.pas"/>
         <IsPartOfProject Value="True"/>
+        <HasResources Value="True"/>
       </Unit42>
       <Unit43>
-        <Filename Value="core\UServerApp.pas"/>
+        <Filename Value="gui\UFRMSaleAccounts.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit43>
       <Unit44>
-        <Filename Value="core\USha256.pas"/>
+        <Filename Value="gui\UCTRLBanner.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="CTRLBanner"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit44>
       <Unit45>
-        <Filename Value="gui\UFRMAccountInfo.pas"/>
+        <Filename Value="gui\UFRMMainForm.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="FRMMainForm"/>
         <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit45>
       <Unit46>
-        <Filename Value="gui\UFRMMemoText.pas"/>
+        <Filename Value="gui\UCTRLSyncronization.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="CTRLSyncronization"/>
         <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit46>
       <Unit47>
-        <Filename Value="gui\UFRMSaleAccounts.pas"/>
+        <Filename Value="gui\wizards\UWIZAddKey_Start.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZAddKey_Start"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit47>
       <Unit48>
-        <Filename Value="gui\UCTRLBanner.pas"/>
+        <Filename Value="gui\wizards\UWIZAddKey_GenerateOrImport.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="CTRLBanner"/>
+        <ComponentName Value="WIZAddKey_GenerateOrImport"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit48>
       <Unit49>
-        <Filename Value="gui\UFRMMainForm.pas"/>
+        <Filename Value="gui\wizards\UWIZAddKey_ImportPubKey.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMMainForm"/>
+        <ComponentName Value="WIZAddKey_ImportPubKey"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit49>
       <Unit50>
-        <Filename Value="gui\UCTRLSyncronization.pas"/>
+        <Filename Value="gui\wizards\UWIZAddKey_ImportPrivKey.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="CTRLSyncronization"/>
+        <ComponentName Value="WIZAddKey_ImportPrivKey"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit50>
       <Unit51>
-        <Filename Value="gui\wizards\UWIZAddKey_Start.pas"/>
+        <Filename Value="gui\wizards\UWIZAddKey_EnterName.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZAddKey_Start"/>
+        <ComponentName Value="WIZAddKey_EnterName"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit51>
       <Unit52>
-        <Filename Value="gui\wizards\UWIZAddKey_GenerateOrImport.pas"/>
+        <Filename Value="gui\UFRMWalletKeys.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZAddKey_GenerateOrImport"/>
+        <ComponentName Value="FRMWalletKeys"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit52>
       <Unit53>
-        <Filename Value="gui\wizards\UWIZAddKey_ImportPubKey.pas"/>
+        <Filename Value="gui\wizards\UWIZAddKey.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZAddKey_ImportPubKey"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit53>
       <Unit54>
-        <Filename Value="gui\wizards\UWIZAddKey_ImportPrivKey.pas"/>
+        <Filename Value="core\USettings.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZAddKey_ImportPrivKey"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit54>
       <Unit55>
-        <Filename Value="gui\wizards\UWIZAddKey_EnterName.pas"/>
+        <Filename Value="gui\wizards\UWIZAddKey_SelectEncryption.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZAddKey_EnterName"/>
+        <ComponentName Value="WIZAddKey_SelectEncryption"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit55>
       <Unit56>
-        <Filename Value="gui\UFRMWalletKeys.pas"/>
+        <Filename Value="gui\UCTRLWallet.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMWalletKeys"/>
+        <ComponentName Value="CTRLWallet"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit56>
       <Unit57>
-        <Filename Value="gui\wizards\UWIZAddKey.pas"/>
+        <Filename Value="libraries\sphere10\UCommon.Collections.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit57>
       <Unit58>
-        <Filename Value="core\USettings.pas"/>
+        <Filename Value="libraries\sphere10\UCommon.Data.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit58>
       <Unit59>
-        <Filename Value="gui\wizards\UWIZAddKey_SelectEncryption.pas"/>
+        <Filename Value="libraries\sphere10\UCommon.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZAddKey_SelectEncryption"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit59>
       <Unit60>
-        <Filename Value="gui\UCTRLWallet.pas"/>
+        <Filename Value="libraries\sphere10\UCommon.UI.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="CTRLWallet"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit60>
       <Unit61>
-        <Filename Value="core\UDataSources.pas"/>
+        <Filename Value="libraries\sphere10\UVisualGrid.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit61>
       <Unit62>
-        <Filename Value="libraries\sphere10\UCommon.Collections.pas"/>
+        <Filename Value="libraries\sphere10\UWizard.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="WizardHostForm"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit62>
       <Unit63>
-        <Filename Value="libraries\sphere10\UCommon.Data.pas"/>
+        <Filename Value="config.inc"/>
         <IsPartOfProject Value="True"/>
       </Unit63>
       <Unit64>
-        <Filename Value="libraries\sphere10\UCommon.pas"/>
+        <Filename Value="gui\wizards\UWIZSendPASC.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit64>
       <Unit65>
-        <Filename Value="libraries\sphere10\UCommon.UI.pas"/>
+        <Filename Value="gui\wizards\UWIZSendPASC_Confirmation.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZSendPASC_Confirmation"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit65>
       <Unit66>
-        <Filename Value="libraries\sphere10\UVisualGrid.pas"/>
+        <Filename Value="gui\wizards\UWIZSendPASC_Start.pas"/>
         <IsPartOfProject Value="True"/>
+        <ComponentName Value="WIZSendPASC_Start"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
       </Unit66>
       <Unit67>
-        <Filename Value="libraries\sphere10\UWizard.pas"/>
+        <Filename Value="gui\wizards\UWIZSendPASC_Transaction.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WizardHostForm"/>
+        <ComponentName Value="WIZSendPASC_Transaction"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit67>
       <Unit68>
-        <Filename Value="config.inc"/>
+        <Filename Value="libraries\sphere10\UMemory.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit68>
       <Unit69>
-        <Filename Value="gui\wizards\UWIZSendPASC.pas"/>
+        <Filename Value="gui\UCellRenderers.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit69>
       <Unit70>
-        <Filename Value="gui\wizards\UWIZSendPASC_Confirmation.pas"/>
+        <Filename Value="gui\wizards\UWIZSendPASC_Completion.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZSendPASC_Confirmation"/>
+        <ComponentName Value="WIZSendPASC_Completion"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
       </Unit70>
       <Unit71>
-        <Filename Value="gui\wizards\UWIZSendPASC_Start.pas"/>
+        <Filename Value="libraries\generics.collections\inc\generics.dictionaries.inc"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZSendPASC_Start"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit71>
       <Unit72>
-        <Filename Value="gui\wizards\UWIZSendPASC_Transaction.pas"/>
+        <Filename Value="libraries\pascalcoin\UAppParams.pas"/>
         <IsPartOfProject Value="True"/>
-        <ComponentName Value="WIZSendPASC_Transaction"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
       </Unit72>
       <Unit73>
-        <Filename Value="core\UCore.pas"/>
+        <Filename Value="libraries\pascalcoin\UFolderHelper.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit73>
       <Unit74>
-        <Filename Value="libraries\sphere10\UMemory.pas"/>
+        <Filename Value="libraries\pascalcoin\UGridUtils.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit74>
       <Unit75>
-        <Filename Value="gui\UCellRenderers.pas"/>
+        <Filename Value="libraries\pascalcoin\UJSONFunctions.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit75>
+      <Unit76>
+        <Filename Value="core.utils\UCoreUtils.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit76>
+      <Unit77>
+        <Filename Value="core.utils\UDataSources.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit77>
     </Units>
   </ProjectOptions>
   <CompilerOptions>
@@ -433,8 +444,8 @@
       <Filename Value="PascalCoinWallet"/>
     </Target>
     <SearchPaths>
-      <IncludeFiles Value="$(ProjOutDir)"/>
-      <OtherUnitFiles Value="common;core;gui;gui\wizards;libraries\synapse;libraries\sphere10;libraries\generics.collections"/>
+      <IncludeFiles Value="$(ProjOutDir);libraries\generics.collections\inc"/>
+      <OtherUnitFiles Value="core;gui;gui\wizards;libraries\synapse;libraries\sphere10;libraries\generics.collections;libraries\pascalcoin;core.utils"/>
       <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
     </SearchPaths>
     <Parsing>