Import Geant4 0.0.0 source tree
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
# $Id: GNUmakefile,v 2.0 1998/07/02 16:18:12 gunter Exp $
|
||||
# --------------------------------------------------------------
|
||||
# GNUmakefile for processes/decay library. G.Folger 9/12/97
|
||||
# --------------------------------------------------------------
|
||||
|
||||
name := G4decay
|
||||
|
||||
ifndef G4INSTALL
|
||||
G4INSTALL = ../../..
|
||||
endif
|
||||
|
||||
include $(G4INSTALL)/config/architecture.gmk
|
||||
|
||||
CPPFLAGS += -I$(G4BASE)/global/management/include \
|
||||
-I$(G4BASE)/global/HEPRandom/include \
|
||||
-I$(G4BASE)/global/HEPGeometry/include \
|
||||
-I$(G4BASE)/geometry/management/include \
|
||||
-I$(G4BASE)/geometry/volumes/include \
|
||||
-I$(G4BASE)/geometry/solids/CSG/include \
|
||||
-I$(G4BASE)/geometry/magneticfield/include \
|
||||
-I$(G4BASE)/track/include \
|
||||
-I$(G4BASE)/processes/management/include \
|
||||
-I$(G4BASE)/particles/management/include \
|
||||
-I$(G4BASE)/intercoms/include \
|
||||
-I$(G4BASE)/materials/include
|
||||
|
||||
include $(G4INSTALL)/config/common.gmk
|
||||
@@ -0,0 +1,183 @@
|
||||
// This code implementation is the intellectual property of
|
||||
// the RD44 GEANT4 collaboration.
|
||||
//
|
||||
// By copying, distributing or modifying the Program (or any work
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4Decay.hh,v 2.2 1998/08/10 13:03:15 kurasige Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
// GEANT 4 class header file
|
||||
//
|
||||
// For information related to this code contact:
|
||||
// CERN, CN Division, ASD group
|
||||
// History: first implementation, based on object model of
|
||||
// 7 July 1996 H.Kurashige
|
||||
// ------------------------------------------------------------
|
||||
// New Physics scheme 18 Jan. 1997 H.Kurahige
|
||||
// ------------------------------------------------------------
|
||||
// modified 4 Feb. 1997 H.Kurahige
|
||||
// modified 8 Sep. 1997 H.Kurahige
|
||||
// remove BuildPhysicsTable() 27 Nov. 1997 H.Kurashige
|
||||
// modified for new ParticleChange 12 Mar. 1998 H.Kurashige
|
||||
// added aPhysicsTable 2 Aug. 1998 H.Kurashige
|
||||
|
||||
#ifndef G4Decay_h
|
||||
#define G4Decay_h 1
|
||||
|
||||
#include "G4ios.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4VRestDiscreteProcess.hh"
|
||||
#include "G4ParticleChangeForDecay.hh"
|
||||
|
||||
class G4Decay : public G4VRestDiscreteProcess
|
||||
{
|
||||
public:
|
||||
// Constructors
|
||||
G4Decay(const G4String& processName ="Decay");
|
||||
|
||||
// Destructor
|
||||
virtual ~G4Decay();
|
||||
|
||||
private:
|
||||
// copy constructor
|
||||
G4Decay(const G4Decay &right);
|
||||
|
||||
// Assignment Operation (generated)
|
||||
G4Decay & operator=(const G4Decay &right);
|
||||
|
||||
public:
|
||||
// G4Decay Process has both
|
||||
// PostStepDoIt (for decay in flight)
|
||||
// and
|
||||
// AtRestDoIt (for decay at rest)
|
||||
|
||||
G4VParticleChange *PostStepDoIt(
|
||||
const G4Track& aTrack,
|
||||
const G4Step& aStep
|
||||
);
|
||||
|
||||
G4VParticleChange* AtRestDoIt(
|
||||
const G4Track& aTrack,
|
||||
const G4Step& aStep
|
||||
);
|
||||
|
||||
virtual void BuildPhysicsTable(const G4ParticleDefinition&);
|
||||
// In G4Decay, thePhysicsTable stores values of
|
||||
// beta * sqrt( 1 - beta*beta)
|
||||
// as a function of normalized kinetic enregy (=Ekin/mass),
|
||||
// becasuse this table is universal for all particle types,
|
||||
|
||||
|
||||
G4bool IsApplicable(const G4ParticleDefinition&);
|
||||
// returns "true" if the decay process can be applied to
|
||||
// the particle type.
|
||||
|
||||
protected:
|
||||
virtual G4VParticleChange* DecayIt(
|
||||
const G4Track& aTrack,
|
||||
const G4Step& aStep
|
||||
);
|
||||
// The DecayIt() method returns by pointer a particle-change object,
|
||||
// which has information of daughter particles.
|
||||
|
||||
public:
|
||||
G4double AtRestGetPhysicalInteractionLength(
|
||||
const G4Track& track,
|
||||
G4ForceCondition* condition
|
||||
);
|
||||
|
||||
protected:
|
||||
// GetMeanFreePath returns ctau*beta*gamma for decay in flight
|
||||
// GetMeanLifeTime returns ctau for decay at rest
|
||||
virtual G4double GetMeanFreePath(const G4Track& aTrack,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition* condition
|
||||
);
|
||||
|
||||
virtual G4double GetMeanLifeTime(const G4Track& aTrack,
|
||||
G4ForceCondition* condition
|
||||
);
|
||||
|
||||
public:
|
||||
void SetVerboseLevel(G4int value);
|
||||
G4int GetVerboseLevel() const;
|
||||
|
||||
private:
|
||||
G4int verboseLevel;
|
||||
// controle flag for output message
|
||||
// 0: Silent
|
||||
// 1: Warning message
|
||||
// 2: More
|
||||
|
||||
private:
|
||||
// In G4Decay, thePhysicsTable stores values of
|
||||
// beta * sqrt( 1 - beta*beta)
|
||||
// as a function of normalized kinetic enregy (=Ekin/mass)
|
||||
// TotBin = number of bins in thePhysicsTable
|
||||
// The PhysicsTable is created for the range of
|
||||
// from LowestBinValue to HighestBinValue.
|
||||
const G4double LowestBinValue;
|
||||
const G4double HighestBinValue;
|
||||
const G4int TotBin;
|
||||
|
||||
G4PhysicsTable* aPhysicsTable;
|
||||
|
||||
// Remainder of life time at rest
|
||||
G4double fRemainderLifeTime;
|
||||
|
||||
// ParticleChange for decay process
|
||||
G4ParticleChangeForDecay fParticleChangeForDecay;
|
||||
};
|
||||
|
||||
inline
|
||||
G4double G4Decay::AtRestGetPhysicalInteractionLength(
|
||||
const G4Track& track,
|
||||
G4ForceCondition* condition
|
||||
)
|
||||
{
|
||||
fRemainderLifeTime =
|
||||
G4VRestDiscreteProcess::AtRestGetPhysicalInteractionLength(
|
||||
track, condition );
|
||||
return fRemainderLifeTime;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4Decay::SetVerboseLevel(G4int value){ verboseLevel = value; }
|
||||
|
||||
inline
|
||||
G4int G4Decay::GetVerboseLevel() const { return verboseLevel; }
|
||||
|
||||
inline
|
||||
G4VParticleChange* G4Decay::AtRestDoIt(
|
||||
const G4Track& aTrack,
|
||||
const G4Step& aStep
|
||||
)
|
||||
{
|
||||
return DecayIt(aTrack, aStep);
|
||||
}
|
||||
|
||||
inline
|
||||
G4VParticleChange* G4Decay::PostStepDoIt(
|
||||
const G4Track& aTrack,
|
||||
const G4Step& aStep
|
||||
)
|
||||
{
|
||||
return DecayIt(aTrack, aStep);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,352 @@
|
||||
// This code implementation is the intellectual property of
|
||||
// the RD44 GEANT4 collaboration.
|
||||
//
|
||||
// By copying, distributing or modifying the Program (or any work
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4Decay.cc,v 2.5 1998/12/15 09:40:26 kurasige Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
//
|
||||
// For information related to this code contact:
|
||||
// CERN, CN Division, ASD group
|
||||
// History: first implementation, based on object model of
|
||||
// 2nd December 1995, G.Cosmo
|
||||
// 7 July 1996 H.Kurashige
|
||||
// ------------------------------------------------------------
|
||||
// remove BuildPhysicsTable() 28 Nov. 1997 H.Kurashige
|
||||
// change DBL_EPSIRON to DBL_MIN 14 Dec. 1997 H.Kurashige
|
||||
// modified for new ParticleChange 12 Mar. 1998 H.Kurashige
|
||||
// modified for "GoodForTrackingFlag" 19 June 1998 H.Kurashige
|
||||
// rename thePhysicsTable to aPhyscisTable 2 Aug. 1998 H.Kurashige
|
||||
// modified IsApplicable in order to protect the decay from registered
|
||||
// to resonances 12 Dec. 1998 H.Kurashige
|
||||
|
||||
|
||||
#include "G4Decay.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4DecayProducts.hh"
|
||||
#include "G4DecayTable.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
#include "G4ParticleChangeForDecay.hh"
|
||||
|
||||
// constructor
|
||||
G4Decay::G4Decay(const G4String& processName)
|
||||
:G4VRestDiscreteProcess(processName, fDecay),
|
||||
HighestBinValue(10.0),
|
||||
LowestBinValue(1.0e-3),
|
||||
TotBin(200),
|
||||
verboseLevel(1)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cerr << "G4Decay constructor " << " Name:" << processName << endl;
|
||||
}
|
||||
#endif
|
||||
aPhysicsTable = NULL;
|
||||
pParticleChange = &fParticleChangeForDecay;
|
||||
}
|
||||
|
||||
G4Decay::~G4Decay()
|
||||
{
|
||||
if (aPhysicsTable != NULL) {
|
||||
aPhysicsTable->clearAndDestroy();
|
||||
delete aPhysicsTable;
|
||||
}
|
||||
}
|
||||
|
||||
G4bool G4Decay::IsApplicable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// return false if resonances
|
||||
if (aParticleType.IsShortLived()) return false;
|
||||
|
||||
// check if the particle is stable?
|
||||
if (aParticleType.GetPDGLifeTime() <0.0) {
|
||||
return false;
|
||||
} else if (aParticleType.GetPDGMass() <= 0.0*MeV) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4Decay::GetMeanLifeTime(const G4Track& aTrack,
|
||||
G4ForceCondition*)
|
||||
{
|
||||
// get particle type
|
||||
const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
|
||||
|
||||
// returns the mean free path in GEANT4 internal units
|
||||
G4double meanlife;
|
||||
G4ParticleDefinition* aParticleDef = aParticle->GetDefinition();
|
||||
G4double aLife = aParticleDef->GetPDGLifeTime();
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cerr << "G4Decay::GetMeanLifeTime() "<< endl;
|
||||
G4cerr << "KineticEnergy:" << aParticle->GetKineticEnergy()/GeV <<"[GeV]";
|
||||
G4cerr << "Mass:" << aParticle->GetMass()/GeV <<"[GeV]";
|
||||
G4cerr << "Life time: "<< aLife/ns << "[ns]" << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
// check if the particle is stable?
|
||||
if (aParticleDef->GetPDGStable()) {
|
||||
meanlife = DBL_MAX;
|
||||
|
||||
} else if (aLife < 0.0) {
|
||||
meanlife = DBL_MAX;
|
||||
|
||||
} else {
|
||||
meanlife = aLife;
|
||||
}
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cerr << "mean life time: "<< meanlife/ns << "[ns]" << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
return meanlife;
|
||||
}
|
||||
|
||||
G4double G4Decay::GetMeanFreePath(const G4Track& aTrack,G4double, G4ForceCondition*)
|
||||
{
|
||||
// constants
|
||||
G4bool isOutRange ;
|
||||
|
||||
// get particle
|
||||
const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
|
||||
|
||||
// returns the mean free path in GEANT4 internal units
|
||||
G4double pathlength;
|
||||
G4ParticleDefinition* aParticleDef = aParticle->GetDefinition();
|
||||
G4double aCtau = c_light * aParticleDef->GetPDGLifeTime();
|
||||
G4double aMass = aParticle->GetMass();
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cerr << "G4Decay::GetMeanFreePath() "<< endl;
|
||||
G4cerr << "KineticEnergy:" << aParticle->GetKineticEnergy()/GeV <<"[GeV]";
|
||||
G4cerr << "Mass:" << aMass/GeV <<"[GeV]";
|
||||
G4cerr << "c*Tau:" << aCtau/m <<"[m]" <<endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
// check if the particle is stable?
|
||||
if (aParticleDef->GetPDGStable()) {
|
||||
pathlength = DBL_MAX;
|
||||
|
||||
} else if (aCtau < 0.0) {
|
||||
pathlength = DBL_MAX;
|
||||
|
||||
//check if the particle has very short life time ?
|
||||
} else if (aCtau < DBL_MIN) {
|
||||
pathlength = DBL_MIN;
|
||||
|
||||
//check if zero mass
|
||||
} else if (aMass < DBL_MIN) {
|
||||
pathlength = DBL_MAX;
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cerr << " Zero Mass particle " << endl;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
//calculate the mean free path
|
||||
// by using normalized kinetic energy (= Ekin/mass)
|
||||
G4double rKineticEnergy = aParticle->GetKineticEnergy()/aMass;
|
||||
if ( rKineticEnergy > HighestBinValue) {
|
||||
// beta >> 1
|
||||
pathlength = ( rKineticEnergy + 1.0)* aCtau;
|
||||
} else if ( rKineticEnergy > LowestBinValue) {
|
||||
// check if aPhysicsTable exists
|
||||
if (aPhysicsTable == NULL) BuildPhysicsTable(*aParticleDef);
|
||||
// beta is in the range valid for PhysicsTable
|
||||
pathlength = aCtau *
|
||||
((*aPhysicsTable)(0))-> GetValue(rKineticEnergy,isOutRange);
|
||||
} else if ( rKineticEnergy < DBL_MIN ) {
|
||||
// too slow particle
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cerr << "G4Decay::GetMeanFreePath() !!particle stops!!";
|
||||
G4cerr << aParticleDef->GetParticleName() << endl;
|
||||
G4cerr << "KineticEnergy:" << aParticle->GetKineticEnergy()/GeV <<"[GeV]";
|
||||
}
|
||||
#endif
|
||||
pathlength = DBL_MIN;
|
||||
} else {
|
||||
// beta << 1
|
||||
pathlength = (aParticle->GetTotalMomentum())/aMass*aCtau ;
|
||||
}
|
||||
}
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cerr << "mean free path: "<< pathlength/m << "[m]" << endl;
|
||||
}
|
||||
#endif
|
||||
return pathlength;
|
||||
}
|
||||
|
||||
void G4Decay::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
{
|
||||
// if aPhysicsTableis has already been created, do nothing
|
||||
if (aPhysicsTable != NULL) return;
|
||||
|
||||
// create aPhysicsTable
|
||||
if (GetVerboseLevel()>1) G4cerr <<" G4Decay::BuildPhysicsTable() "<< endl;
|
||||
aPhysicsTable = new G4PhysicsTable(1);
|
||||
|
||||
//create physics vector
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
|
||||
LowestBinValue,
|
||||
HighestBinValue,
|
||||
TotBin);
|
||||
|
||||
G4double beta, gammainv;
|
||||
// fill physics Vector
|
||||
G4int i;
|
||||
for ( i = 0 ; i < TotBin ; i++ ) {
|
||||
gammainv = 1.0/(aVector->GetLowEdgeEnergy(i) + 1.0);
|
||||
beta = sqrt((1.0 - gammainv)*(1.0 +gammainv));
|
||||
aVector->PutValue(i, beta/gammainv);
|
||||
}
|
||||
aPhysicsTable->insert(aVector);
|
||||
}
|
||||
|
||||
G4VParticleChange* G4Decay::DecayIt(const G4Track& aTrack, const G4Step& )
|
||||
{
|
||||
// The DecayIt() method returns by pointer a particle-change object.
|
||||
// Units are expressed in GEANT4 internal units.
|
||||
|
||||
// Initialize ParticleChange
|
||||
// all members of G4VParticleChange are set to equal to
|
||||
// corresponding member in G4Track
|
||||
fParticleChangeForDecay.Initialize(aTrack);
|
||||
|
||||
// get particle
|
||||
const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
|
||||
|
||||
//check if thePreAssignedDecayProducts exists
|
||||
G4DecayProducts* products = aParticle->GetPreAssignedDecayProducts();
|
||||
G4bool isPreAssigned = (products != NULL);
|
||||
|
||||
if (!isPreAssigned) {
|
||||
// decay acoording to decay table
|
||||
G4DecayTable *decaytable = aParticle->GetDefinition()->GetDecayTable();
|
||||
|
||||
if (decaytable == NULL){
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>0) {
|
||||
G4cerr << "G4Decay::DoIt : decay table not defined for";
|
||||
G4cerr << aParticle->GetDefinition()->GetParticleName()<< endl;
|
||||
}
|
||||
#endif
|
||||
fParticleChangeForDecay.SetNumberOfSecondaries(0);
|
||||
// Kill the parent particle
|
||||
fParticleChangeForDecay.SetStatusChange( fStopAndKill ) ;
|
||||
fParticleChangeForDecay.SetLocalEnergyDeposit(0.0);
|
||||
|
||||
ClearNumberOfInteractionLengthLeft();
|
||||
return &fParticleChangeForDecay ;
|
||||
} else {
|
||||
// choose a decay channel
|
||||
G4VDecayChannel *decaychannel = decaytable->SelectADecayChannel();
|
||||
if (decaychannel == NULL){
|
||||
// decay channel not found
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>0) {
|
||||
G4cerr << "G4Decay::DoIt : can not determine decay channel " <<endl;
|
||||
decaytable ->DumpInfo();
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
G4int temp;
|
||||
// execute DecayIt()
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cerr << "G4Decay::DoIt : selected decay channel addr:" << decaychannel <<endl;
|
||||
temp = decaychannel->GetVerboseLevel();
|
||||
decaychannel->SetVerboseLevel(GetVerboseLevel());
|
||||
}
|
||||
#endif
|
||||
products = decaychannel->DecayIt(aParticle->GetMass());
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>1) {
|
||||
decaychannel->SetVerboseLevel(temp);
|
||||
}
|
||||
#endif
|
||||
#ifdef G4VERBOSE
|
||||
// for debug
|
||||
//if (! products->IsChecked() ) products->DumpInfo();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get parent particle information ...................................
|
||||
G4double ParentEnergy = aParticle->GetTotalEnergy();
|
||||
G4ParticleMomentum ParentDirection(aParticle->GetMomentumDirection());
|
||||
|
||||
//boost all decay products to laboratory frame
|
||||
G4double energyDeposit = 0.0;
|
||||
G4double finalGlobalTime = aTrack.GetGlobalTime();
|
||||
if (aTrack.GetTrackStatus() == fStopButAlive ){
|
||||
// AtRest case
|
||||
finalGlobalTime += fRemainderLifeTime;
|
||||
energyDeposit += aParticle->GetKineticEnergy();
|
||||
} else {
|
||||
// PostStep case
|
||||
products->Boost( ParentEnergy, ParentDirection);
|
||||
}
|
||||
|
||||
//add products in fParticleChangeForDecay
|
||||
G4int numberOfSecondaries = products->entries();
|
||||
fParticleChangeForDecay.SetNumberOfSecondaries(numberOfSecondaries);
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cerr << "G4Decay::DoIt : Decay vertex :";
|
||||
G4cerr << " Time: " << finalGlobalTime/ns << "[ns]";
|
||||
G4cerr << " X:" << (aTrack.GetPosition()).x() /cm << "[cm]";
|
||||
G4cerr << " Y:" << (aTrack.GetPosition()).y() /cm << "[cm]";
|
||||
G4cerr << " Z:" << (aTrack.GetPosition()).z() /cm << "[cm]";
|
||||
G4cerr << endl;
|
||||
G4cerr << "G4Decay::DoIt : decay products in Lab. Frame" << endl;
|
||||
products->DumpInfo();
|
||||
}
|
||||
#endif
|
||||
G4int index;
|
||||
G4ThreeVector currentPosition;
|
||||
for (index=0; index < numberOfSecondaries; index++)
|
||||
{
|
||||
// get current position of the track
|
||||
currentPosition = aTrack.GetPosition();
|
||||
// create a new track object
|
||||
G4Track* secondary = new G4Track( products->PopProducts(),
|
||||
finalGlobalTime ,
|
||||
currentPosition );
|
||||
// switch on good for tracking flag
|
||||
secondary->SetGoodForTrackingFlag();
|
||||
// add the secondary track in the List
|
||||
fParticleChangeForDecay.AddSecondary(secondary);
|
||||
}
|
||||
if (!isPreAssigned) delete products;
|
||||
|
||||
// Kill the parent particle
|
||||
fParticleChangeForDecay.SetStatusChange( fStopAndKill ) ;
|
||||
fParticleChangeForDecay.SetLocalEnergyDeposit(energyDeposit);
|
||||
fParticleChangeForDecay.SetTimeChange( finalGlobalTime );
|
||||
// reset NumberOfInteractionLengthLeft
|
||||
ClearNumberOfInteractionLengthLeft();
|
||||
|
||||
return &fParticleChangeForDecay ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user