mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
STYLE: use #+BEGIN_EXAMPLE / #+END_EXAMPLE in codingStyleGuide.org
- seems to work more reliably than the previous indented colons
This commit is contained in:
@ -18,97 +18,116 @@
|
|||||||
made with 'break' or 'continue' as part of a control structure.
|
made with 'break' or 'continue' as part of a control structure.
|
||||||
|
|
||||||
+ stream output
|
+ stream output
|
||||||
=<<= is always four characters after the start of the stream,
|
+ =<<= is always four characters after the start of the stream,
|
||||||
so that the =<<= symbols align, i.e.
|
so that the =<<= symbols align, i.e.
|
||||||
|
|
||||||
:Info<< ...
|
#+BEGIN_EXAMPLE
|
||||||
:os << ...
|
Info<< ...
|
||||||
|
os << ...
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
so
|
so
|
||||||
|
|
||||||
:WarningIn("className::functionName()")
|
#+BEGIN_EXAMPLE
|
||||||
: << "Warning message"
|
WarningIn("className::functionName()")
|
||||||
|
<< "Warning message"
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
NOT
|
NOT
|
||||||
|
|
||||||
:WarningIn("className::functionName()")
|
#+BEGIN_EXAMPLE
|
||||||
:<< "Warning message"
|
WarningIn("className::functionName()")
|
||||||
|
<< "Warning message"
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
|
|
||||||
+ no unnecessary class section headers, i.e. remove
|
+ no unnecessary class section headers, i.e. remove
|
||||||
|
|
||||||
:// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
#+BEGIN_EXAMPLE
|
||||||
:
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
:// Check
|
|
||||||
:
|
// Check
|
||||||
:// Edit
|
|
||||||
:
|
// Edit
|
||||||
:// Write
|
|
||||||
|
// Write
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
|
|
||||||
if they contain nothing, even if planned for 'future use'
|
if they contain nothing, even if planned for 'future use'
|
||||||
|
|
||||||
+ class titles are centred
|
+ class titles are centred
|
||||||
|
|
||||||
:/*---------------------------------------------------------------------------*\
|
#+BEGIN_EXAMPLE
|
||||||
: Class exampleClass Declaration
|
/*---------------------------------------------------------------------------*\
|
||||||
:\*---------------------------------------------------------------------------*/
|
Class exampleClass Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
NOT
|
NOT
|
||||||
|
|
||||||
:/*---------------------------------------------------------------------------*\
|
#+BEGIN_EXAMPLE
|
||||||
: Class exampleClass Declaration
|
/*---------------------------------------------------------------------------*\
|
||||||
:\*---------------------------------------------------------------------------*/
|
Class exampleClass Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
*** The =.H= Files
|
*** The =.H= Files
|
||||||
+ header file spacing
|
+ header file spacing
|
||||||
Leave two empty lines between sections (as per functions in the =.C= file etc)
|
+ Leave two empty lines between sections
|
||||||
|
(as per functions in the =.C= file etc)
|
||||||
|
|
||||||
+ use "//- Comment" comments in header file
|
+ use "//- Comment" comments in header file
|
||||||
+ add descriptions to class data and functions
|
+ add descriptions to class data and functions
|
||||||
+ destructor
|
+ destructor
|
||||||
If adding a comment to the destructor - use //- and code as a normal function:
|
+ If adding a comment to the destructor -
|
||||||
|
use //- and code as a normal function:
|
||||||
|
|
||||||
://- Destructor
|
#+BEGIN_EXAMPLE
|
||||||
:~className();
|
//- Destructor
|
||||||
|
~className();
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
+ inline functions
|
+ inline functions
|
||||||
Use inline functions where appropriate in a separate classNameI.H file.
|
+ Use inline functions where appropriate in a separate classNameI.H file.
|
||||||
Avoid cluttering the header file with function bodies.
|
Avoid cluttering the header file with function bodies.
|
||||||
|
|
||||||
*** The =.C= Files
|
*** The =.C= Files
|
||||||
+ Do not open/close namespaces in a =.C= file
|
+ Do not open/close namespaces in a =.C= file
|
||||||
Fully scope the function name, i.e.
|
+ Fully scope the function name, i.e.
|
||||||
|
|
||||||
:Foam::returnType Foam::className::functionName()
|
#+BEGIN_EXAMPLE
|
||||||
|
Foam::returnType Foam::className::functionName()
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
NOT
|
NOT
|
||||||
|
|
||||||
:namespace Foam
|
#+BEGIN_EXAMPLE
|
||||||
:{
|
namespace Foam
|
||||||
: ...
|
{
|
||||||
:
|
...
|
||||||
: returnType className::functionName()
|
returnType className::functionName()
|
||||||
:
|
...
|
||||||
: ...
|
}
|
||||||
:}
|
#+END_EXAMPLE
|
||||||
|
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
|
|
||||||
When there are multiple levels of namespace, they may be used in the =.C=
|
When there are multiple levels of namespace, they may be used in the =.C=
|
||||||
file, i.e.
|
file, i.e.
|
||||||
|
|
||||||
:namespace Foam
|
#+BEGIN_EXAMPLE
|
||||||
:{
|
namespace Foam
|
||||||
:namespace compressible
|
{
|
||||||
:{
|
namespace compressible
|
||||||
:namespace RASModels
|
{
|
||||||
:{
|
namespace RASModels
|
||||||
:
|
{
|
||||||
: ...
|
...
|
||||||
:
|
} // End namespace RASModels
|
||||||
:} // End namespace RASModels
|
} // End namespace compressible
|
||||||
:} // End namespace compressible
|
} // End namespace Foam
|
||||||
:} // End namespace Foam
|
#+END_EXAMPLE
|
||||||
|
|
||||||
+ Use two empty lines between functions
|
+ Use two empty lines between functions
|
||||||
|
|
||||||
@ -131,64 +150,95 @@
|
|||||||
If a class is virtual - make all derived classes virtual.
|
If a class is virtual - make all derived classes virtual.
|
||||||
|
|
||||||
*** Conditional Statements
|
*** Conditional Statements
|
||||||
:if (condition)
|
#+BEGIN_EXAMPLE
|
||||||
:{
|
if (condition)
|
||||||
: code;
|
{
|
||||||
:}
|
code;
|
||||||
|
}
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
OR
|
OR
|
||||||
|
|
||||||
:if
|
#+BEGIN_EXAMPLE
|
||||||
:(
|
if
|
||||||
: long condition
|
(
|
||||||
:)
|
long condition
|
||||||
:{
|
)
|
||||||
: code;
|
{
|
||||||
:}
|
code;
|
||||||
|
}
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
NOT (no space between "if" and "(")
|
NOT (no space between "if" and "(")
|
||||||
|
|
||||||
:if(condition)
|
#+BEGIN_EXAMPLE
|
||||||
:{
|
if(condition)
|
||||||
: code;
|
{
|
||||||
:}
|
code;
|
||||||
|
}
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
*** =for= and =while= Loops
|
*** =for= and =while= Loops
|
||||||
:for (i = 0; i < maxI; i++)
|
|
||||||
:{
|
#+BEGIN_EXAMPLE
|
||||||
: code;
|
for (i = 0; i < maxI; i++)
|
||||||
:}
|
{
|
||||||
|
code;
|
||||||
|
}
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
OR
|
OR
|
||||||
|
|
||||||
:for
|
#+BEGIN_EXAMPLE
|
||||||
:(
|
for
|
||||||
: i = 0;
|
(
|
||||||
: i < maxI;
|
i = 0;
|
||||||
: i++
|
i < maxI;
|
||||||
:)
|
i++
|
||||||
:{
|
)
|
||||||
: code;
|
{
|
||||||
:}
|
code;
|
||||||
|
}
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
NOT (no space between "for" and "(")
|
NOT (no space between "for" and "(")
|
||||||
|
|
||||||
:for(i = 0; i < maxI; i++)
|
#+BEGIN_EXAMPLE
|
||||||
:{
|
for(i = 0; i < maxI; i++)
|
||||||
: code;
|
{
|
||||||
:}
|
code;
|
||||||
|
}
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
Note that when indexing through iterators, it is often slightly more
|
Note that when indexing through iterators, it is often slightly more
|
||||||
efficient to use the pre-increment form. Eg, =++iter= instead of =iter++=
|
efficient to use the pre-increment form. Eg, =++iter= instead of =iter++=
|
||||||
|
|
||||||
*** =forAll= , =forAllIter=, etc. loops
|
*** =forAll=, =forAllIter=, =forAllConstIter=, etc. loops
|
||||||
like =for= loops, but
|
like =for= loops, but
|
||||||
|
|
||||||
:forAll(
|
#+BEGIN_EXAMPLE
|
||||||
|
forAll(
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
NOT
|
NOT
|
||||||
|
|
||||||
:forAll (
|
#+BEGIN_EXAMPLE
|
||||||
|
forAll (
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
|
Using the =forAllIter= and =forAllConstIter= macros is generally
|
||||||
|
advantageous - less typing, easier to find later. However, since
|
||||||
|
they are macros, they will fail if the iterated object contains
|
||||||
|
any commas.
|
||||||
|
|
||||||
|
The following will FAIL!:
|
||||||
|
|
||||||
|
#+BEGIN_EXAMPLE
|
||||||
|
forAllIter(HashTable<labelPair, edge, Hash<edge> >, foo, iter)
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
|
These convenience macros are also generally avoided in other
|
||||||
|
container classes and OpenFOAM primitive classes.
|
||||||
|
|
||||||
*** Splitting Over Multiple Lines
|
*** Splitting Over Multiple Lines
|
||||||
|
|
||||||
@ -198,64 +248,81 @@
|
|||||||
+ do not put "const" onto its own line - use a split to keep it with
|
+ do not put "const" onto its own line - use a split to keep it with
|
||||||
the function name and arguments.
|
the function name and arguments.
|
||||||
|
|
||||||
so:
|
so
|
||||||
|
|
||||||
:const Foam::longReturnTypeName&
|
#+BEGIN_EXAMPLE
|
||||||
:Foam::longClassName::longFunctionName const
|
const Foam::longReturnTypeName&
|
||||||
|
Foam::longClassName::longFunctionName const
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
NOT
|
NOT
|
||||||
|
|
||||||
:const Foam::longReturnTypeName&
|
#+BEGIN_EXAMPLE
|
||||||
: Foam::longClassName::longFunctionName const
|
const Foam::longReturnTypeName&
|
||||||
|
Foam::longClassName::longFunctionName const
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
NOR
|
NOR
|
||||||
|
|
||||||
:const Foam::longReturnTypeName& Foam::longClassName::longFunctionName
|
#+BEGIN_EXAMPLE
|
||||||
:const
|
const Foam::longReturnTypeName& Foam::longClassName::longFunctionName
|
||||||
|
const
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
NOR
|
NOR
|
||||||
|
|
||||||
:const Foam::longReturnTypeName& Foam::longClassName::
|
#+BEGIN_EXAMPLE
|
||||||
:longFunctionName const
|
const Foam::longReturnTypeName& Foam::longClassName::
|
||||||
|
longFunctionName const
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
+ if it needs to be split again, split at the function name (leaving
|
+ if it needs to be split again, split at the function name (leaving
|
||||||
behind the preceding scoping "::"s), and again, left align, i.e.
|
behind the preceding scoping "::"s), and again, left align, i.e.
|
||||||
|
|
||||||
For example,
|
For example,
|
||||||
|
|
||||||
:const Foam::longReturnTypeName&
|
#+BEGIN_EXAMPLE
|
||||||
:Foam::veryveryveryverylongClassName::
|
const Foam::longReturnTypeName&
|
||||||
:veryveryveryverylongFunctionName const
|
Foam::veryveryveryverylongClassName::
|
||||||
|
veryveryveryverylongFunctionName const
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
**** Splitting long lines at an "="
|
**** Splitting long lines at an "="
|
||||||
|
|
||||||
Indent after split
|
Indent after split
|
||||||
|
|
||||||
:variableName =
|
#+BEGIN_EXAMPLE
|
||||||
: longClassName.longFunctionName(longArgument);
|
variableName =
|
||||||
|
longClassName.longFunctionName(longArgument);
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
OR (where necessary)
|
OR (where necessary)
|
||||||
|
|
||||||
:variableName =
|
#+BEGIN_EXAMPLE
|
||||||
: longClassName.longFunctionName
|
variableName =
|
||||||
: (
|
longClassName.longFunctionName
|
||||||
: longArgument1,
|
(
|
||||||
: longArgument2
|
longArgument1,
|
||||||
: );
|
longArgument2
|
||||||
|
);
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
NOT
|
NOT
|
||||||
|
|
||||||
:variableName =
|
#+BEGIN_EXAMPLE
|
||||||
:longClassName.longFunctionName(longArgument);
|
variableName =
|
||||||
|
longClassName.longFunctionName(longArgument);
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
NOR
|
NOR
|
||||||
|
|
||||||
:variableName = longClassName.longFunctionName
|
#+BEGIN_EXAMPLE
|
||||||
:(
|
variableName = longClassName.longFunctionName
|
||||||
: longArgument1,
|
(
|
||||||
: longArgument2
|
longArgument1,
|
||||||
:);
|
longArgument2
|
||||||
|
);
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
*** Maths and Logic
|
*** Maths and Logic
|
||||||
+ operator spacing
|
+ operator spacing
|
||||||
@ -267,34 +334,41 @@
|
|||||||
+ a || b, a && b
|
+ a || b, a && b
|
||||||
|
|
||||||
+ splitting formulae over several lines
|
+ splitting formulae over several lines
|
||||||
|
|
||||||
Split and indent as per "splitting long lines at an "=""
|
Split and indent as per "splitting long lines at an "=""
|
||||||
with the operator on the lower line. Align operator so that first
|
with the operator on the lower line. Align operator so that first
|
||||||
variable, function or bracket on the next line is 4 spaces indented i.e.
|
variable, function or bracket on the next line is 4 spaces indented i.e.
|
||||||
|
|
||||||
:variableName =
|
#+BEGIN_EXAMPLE
|
||||||
: a * (a + b)
|
variableName =
|
||||||
: - exp(c/d)
|
a * (a + b)
|
||||||
: * (k + t);
|
- exp(c/d)
|
||||||
|
* (k + t);
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
This is sometime more legible when surrounded by extra parentheses:
|
This is sometime more legible when surrounded by extra parentheses:
|
||||||
|
|
||||||
:variableName =
|
#+BEGIN_EXAMPLE
|
||||||
:(
|
variableName =
|
||||||
: a * (a + b)
|
(
|
||||||
: - exp(c/d)
|
a * (a + b)
|
||||||
: * (k + t)
|
- exp(c/d)
|
||||||
:);
|
* (k + t)
|
||||||
|
);
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
+ splitting logical tests over several lines
|
+ splitting logical tests over several lines
|
||||||
|
|
||||||
outdent the operator so that the next variable to test is aligned with
|
outdent the operator so that the next variable to test is aligned with
|
||||||
the four space indentation, i.e.
|
the four space indentation, i.e.
|
||||||
|
|
||||||
:if
|
#+BEGIN_EXAMPLE
|
||||||
:(
|
if
|
||||||
: a == true
|
(
|
||||||
: && b == c
|
a == true
|
||||||
:)
|
&& b == c
|
||||||
|
)
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
** Documentation
|
** Documentation
|
||||||
|
|
||||||
@ -315,14 +389,16 @@
|
|||||||
|
|
||||||
For example,
|
For example,
|
||||||
|
|
||||||
:Class
|
#+BEGIN_EXAMPLE
|
||||||
: Foam::myClass
|
Class
|
||||||
:
|
Foam::myClass
|
||||||
:Description
|
|
||||||
: A class for specifying the documentation style.
|
Description
|
||||||
:
|
A class for specifying the documentation style.
|
||||||
: The class is implemented as a set of recommendations that may
|
|
||||||
: sometimes be useful.
|
The class is implemented as a set of recommendations that may
|
||||||
|
sometimes be useful.
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
+ The class name must be qualified by its namespace, otherwise Doxygen
|
+ The class name must be qualified by its namespace, otherwise Doxygen
|
||||||
will think you are documenting some other class.
|
will think you are documenting some other class.
|
||||||
@ -332,11 +408,13 @@
|
|||||||
finding these under-documented classes later.
|
finding these under-documented classes later.
|
||||||
|
|
||||||
|
|
||||||
:Class
|
#+BEGIN_EXAMPLE
|
||||||
: Foam::myUnderDocumentedClass
|
Class
|
||||||
:
|
Foam::myUnderDocumentedClass
|
||||||
:Description
|
|
||||||
: Foam::myUnderDocumentedClass
|
Description
|
||||||
|
Foam::myUnderDocumentedClass
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
|
|
||||||
+ Use 'Class' and 'Namespace' tags in the header files.
|
+ Use 'Class' and 'Namespace' tags in the header files.
|
||||||
@ -346,11 +424,13 @@
|
|||||||
The Description block then applies to documenting the file itself.
|
The Description block then applies to documenting the file itself.
|
||||||
|
|
||||||
|
|
||||||
:InClass
|
#+BEGIN_EXAMPLE
|
||||||
: Foam::myClass
|
InClass
|
||||||
:
|
Foam::myClass
|
||||||
:Description
|
|
||||||
: Implements the read and writing of files.
|
Description
|
||||||
|
Implements the read and writing of files.
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
*** Doxygen Special Commands
|
*** Doxygen Special Commands
|
||||||
|
|
||||||
@ -368,29 +448,31 @@
|
|||||||
Doxygen commmands can be inserted within the block without problems.
|
Doxygen commmands can be inserted within the block without problems.
|
||||||
|
|
||||||
|
|
||||||
:InClass
|
#+BEGIN_EXAMPLE
|
||||||
: Foam::myClass
|
InClass
|
||||||
:
|
Foam::myClass
|
||||||
:Description
|
|
||||||
: Implements the read and writing of files.
|
Description
|
||||||
:
|
Implements the read and writing of files.
|
||||||
: An example input file:
|
|
||||||
: @verbatim
|
An example input file:
|
||||||
: patchName
|
@verbatim
|
||||||
: {
|
patchName
|
||||||
: type myPatchType;
|
{
|
||||||
: refValue 100;
|
type myPatchType;
|
||||||
: value uniform 1;
|
refValue 100;
|
||||||
: }
|
value uniform 1;
|
||||||
: @endverbatim
|
}
|
||||||
:
|
@endverbatim
|
||||||
: Within the implementation, a loop over all patches is done:
|
|
||||||
: @code
|
Within the implementation, a loop over all patches is done:
|
||||||
: forAll(patches, patchI)
|
@code
|
||||||
: {
|
forAll(patches, patchI)
|
||||||
: ... // some operation
|
{
|
||||||
: }
|
... // some operation
|
||||||
: @endcode
|
}
|
||||||
|
@endcode
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
*** HTML Special Commands
|
*** HTML Special Commands
|
||||||
|
|
||||||
@ -399,28 +481,34 @@
|
|||||||
Doxygen to complain, but seem to work anyhow.
|
Doxygen to complain, but seem to work anyhow.
|
||||||
|
|
||||||
eg,
|
eg,
|
||||||
+ The template with type <HR> is a bad example.
|
+ The template with type =<HR>= is a bad example.
|
||||||
|
|
||||||
+ The template with type \<HR\> is a better example.
|
+ The template with type =\<HR\>= is a better example.
|
||||||
|
|
||||||
+ The template with type <Type> causes Doxygen to complain about an
|
+ The template with type =<Type>= causes Doxygen to complain about an
|
||||||
unknown html type, but it seems to work okay anyhow.
|
unknown html type, but it seems to work okay anyhow.
|
||||||
|
|
||||||
|
|
||||||
*** Documenting Namespaces
|
*** Documenting Namespaces
|
||||||
|
|
||||||
+ If namespaces are explictly declared with the Namespace() macro,
|
+ If namespaces are explictly declared with the =Namespace()= macro,
|
||||||
they should be documented there.
|
they should be documented there.
|
||||||
|
|
||||||
+ If the namespaces is used to hold sub-models, the namespace can be
|
+ If the namespaces is used to hold sub-models, the namespace can be
|
||||||
documented in the same file as the class with the model selector.
|
documented in the same file as the class with the model selector.
|
||||||
eg,
|
eg,
|
||||||
:documented namespace 'Foam::functionEntries' within the
|
|
||||||
:class 'Foam::functionEntry'
|
#+BEGIN_EXAMPLE
|
||||||
|
documented namespace 'Foam::functionEntries' within the
|
||||||
|
class 'Foam::functionEntry'
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
+ If nothing else helps, find some sensible header.
|
+ If nothing else helps, find some sensible header.
|
||||||
eg,
|
eg,
|
||||||
:namespace 'Foam' is documented in the foamVersion.H file
|
|
||||||
|
#+BEGIN_EXAMPLE
|
||||||
|
namespace 'Foam' is documented in the foamVersion.H file
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
|
|
||||||
*** Documenting Typedefs and classes defined via macros
|
*** Documenting Typedefs and classes defined via macros
|
||||||
@ -459,7 +547,9 @@
|
|||||||
Press.
|
Press.
|
||||||
|
|
||||||
Eg,
|
Eg,
|
||||||
:myClass.initialize()
|
#+BEGIN_EXAMPLE
|
||||||
|
myClass.initialize()
|
||||||
|
#+END_EXAMPLE
|
||||||
|
|
||||||
|
|
||||||
The word "its" (possesive) vs. "it's" (colloquial for "it is" or "it has")
|
The word "its" (possesive) vs. "it's" (colloquial for "it is" or "it has")
|
||||||
@ -468,4 +558,3 @@
|
|||||||
Any remaining "it's" are likely an incorrect spelling of "its".
|
Any remaining "it's" are likely an incorrect spelling of "its".
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user