Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

This version of ShowItShowIt first shown by Leonid Shifrin is particularly useful, it can be used in conjunction with the function ReapTags[] defined below also.

This version of ShowIt first shown by Leonid Shifrin is particularly useful, it can be used in conjunction with the function ReapTags[] defined below also.

This version of ShowIt first shown by Leonid Shifrin is particularly useful, it can be used in conjunction with the function ReapTags[] defined below also.

replaced http://mathematica.stackexchange.com/ with https://mathematica.stackexchange.com/
Source Link

It now uses the LetL[] function also from Leonid defined herehere (in order to avoid a nested With for printedExpr).

I've incorporated the answer of Szabolcs to the question Is it possible to Print expressions in reverse order?Is it possible to Print expressions in reverse order?, the answer of Mr. Wizard to the question Delete contexts from a string representation of a symbolDelete contexts from a string representation of a symbol and the answer of rm -rf to How to Print to the ConsoleHow to Print to the Console.

To see the list of keys defined in the debugSymbol containing the results extracted from a program you can use the function KeysKeys.

  • $ConsoleIt = True allows to output what would be output with Print but in the Messages console accessible in the menu Window > Messages.
  • $GroupIt prints expressions in groups of two cells, for example x as title, and x=2; as expression.
  • The System`* context of ShowIt and ShowItList allows to use them in the Private`* context of other packages without having to define the package in which these functions are defined (in BeginPackage[], see herehere for more info on the organisation of packages).
  • ShowIt[] is not shown inside another ShowIt.
  • You can define a tag when calling ShowIt, and restrict which tags let ShowIt output things using $ShowItTagPattern.
  • You can use Debug`ShowIt in parallel kernels (as System`ShowIt is recognised as a Global` symbol in a parallel kernel).

It now uses the LetL[] function also from Leonid defined here (in order to avoid a nested With for printedExpr).

I've incorporated the answer of Szabolcs to the question Is it possible to Print expressions in reverse order?, the answer of Mr. Wizard to the question Delete contexts from a string representation of a symbol and the answer of rm -rf to How to Print to the Console.

To see the list of keys defined in the debugSymbol containing the results extracted from a program you can use the function Keys.

  • $ConsoleIt = True allows to output what would be output with Print but in the Messages console accessible in the menu Window > Messages.
  • $GroupIt prints expressions in groups of two cells, for example x as title, and x=2; as expression.
  • The System`* context of ShowIt and ShowItList allows to use them in the Private`* context of other packages without having to define the package in which these functions are defined (in BeginPackage[], see here for more info on the organisation of packages).
  • ShowIt[] is not shown inside another ShowIt.
  • You can define a tag when calling ShowIt, and restrict which tags let ShowIt output things using $ShowItTagPattern.
  • You can use Debug`ShowIt in parallel kernels (as System`ShowIt is recognised as a Global` symbol in a parallel kernel).

It now uses the LetL[] function also from Leonid defined here (in order to avoid a nested With for printedExpr).

I've incorporated the answer of Szabolcs to the question Is it possible to Print expressions in reverse order?, the answer of Mr. Wizard to the question Delete contexts from a string representation of a symbol and the answer of rm -rf to How to Print to the Console.

To see the list of keys defined in the debugSymbol containing the results extracted from a program you can use the function Keys.

  • $ConsoleIt = True allows to output what would be output with Print but in the Messages console accessible in the menu Window > Messages.
  • $GroupIt prints expressions in groups of two cells, for example x as title, and x=2; as expression.
  • The System`* context of ShowIt and ShowItList allows to use them in the Private`* context of other packages without having to define the package in which these functions are defined (in BeginPackage[], see here for more info on the organisation of packages).
  • ShowIt[] is not shown inside another ShowIt.
  • You can define a tag when calling ShowIt, and restrict which tags let ShowIt output things using $ShowItTagPattern.
  • You can use Debug`ShowIt in parallel kernels (as System`ShowIt is recognised as a Global` symbol in a parallel kernel).
added 97 characters in body
Source Link
xyz
  • 655
  • 4
  • 38
  • 117

This version of ShowIt first shown by Leonid Shifrin is particularly useful, it can be used in conjunction with the function ReapTagsReapTags[] defined below also.

It now uses the LetLLetL[] function also from Leonid defined here (in order to avoid a nested With for printedExpr).

  • The Print output using \$ShowIt = True$ShowIt = True allows to use it in the front end if you change its style to Input.
  • \$ReverseIt = True$ReverseIt = True allows to Print the result of Print in a reverse order as asked in this question.
  • The Message if you switch it on using On[Debug::ShowIt]On[Debug::ShowIt] prints a MathematicaMathematica message and would stop the code if you used a message breakpoint in MathematicaMathematica or Wolfram WorkbenchWolfram Workbench.
  • \$SowIt = True$SowIt = True allows to store what would be printed with Print in a symbol.

To see the list of keys defined in the debugSymboldebugSymbol containing the results extracted from a program you can use the function Keys.

  • \$ConsoleIt = True$ConsoleIt = True allows to output what would be output with Print but in the MessagesMessages console accessible in the menu Window>MessagesWindow > Messages.
  • \$GroupIt$GroupIt prints expressions in groups of two cells, for example xx as title, and x=2;x=2; as expression.
  • The System`System`* context of ShowItShowIt and ShowItListShowItList allows to use them in the Private`Private`* context of other packages without having to define the package in which these functions are defined (in BeginPackageBeginPackage[], see here for more info on the organisation of packages).
  • ShowItShowIt[] is not shown inside another ShowItShowIt.
  • You can define a tag when calling ShowItShowIt, and restrict which tags let ShowItShowIt output things using \$ShowItTagPattern$ShowItTagPattern.
  • You can use Debug`ShowItDebug`ShowIt in parallel kernels (as System`ShowItSystem`ShowIt is recognised as a Global` symbolGlobal` symbol in a parallel kernel).

All in all ShowItShowIt and the functions around it show a lot of different aspects of advanced evaluation in MathematicaMathematica that could be interesting to a lot of people.

(*Auxiliary functions*)
SetAttributes[ExtractSymbolName, HoldAll];
ExtractSymbolName[expr_] :=
Module[{T,SR = StringReplace[#, a__ ~~ "$" ~~ DigitCharacter .. :> a] &}, 
    Defer[expr] 
        //. HoldPattern[System`ShowIt@x_] :> x
        /. s_Symbol :> T@MakeExpression@SR@SymbolName@Unevaluated@s 
        /. T@_@x___ :> x
];

insertBelowEvaluationCell[expr_]:=
(
    SelectionMove[EvaluationNotebook[],After,EvaluationCell];
    NotebookWrite[EvaluationNotebook[],Cell[BoxData@ToBoxes[expr],"Print"]]
);

$OldLine=-1;
SetAttributes[PrintToConsole,HoldFirst];
PrintToConsole[Defer[expr_],reversePrint_:False]:=PrintToConsole[expr,reversePrint];
PrintToConsole[expr_,reversePrint_:False]:=
(
    If[$OldLine!=$Line,
        SelectionMove[MessagesNotebook[],After,Notebook];
        
        NotebookWrite[MessagesNotebook[],
            Cell[
                BoxData@ToBoxes@"","Print",
                CellLabel->"During evaluation of In["<>ToString[$Line-1]<>"]:=",
                ShowCellLabel->True
            ]
        ];
    ];
    
    If[$OldLine==$Line,
        If[reversePrint,
            SelectionMove[MessagesNotebook[],Previous,Cell];
            SelectionMove[MessagesNotebook[],Before,Cell];
            ,
            SelectionMove[MessagesNotebook[], After, Cell];
        ]
    ];
    
    NotebookWrite[MessagesNotebook[],
        Cell[
            BoxData@ToBoxes@Defer@expr,"Print"
        ]
    ];
    
    $OldLine=$Line;
);

SetAttributes[PrintGroupedCells, HoldAll]
 PrintGroupedCells[label_, expr_] :=
Module[{tag = ToString@Unique[]},
    CellPrint[
        CellGroup[
            {
                ExpressionCell[label, "Item", CellTags -> tag]
                ,
                ExpressionCell[expr, "Input", CellTags -> tag]
            }
        ]
    ];
      
    NotebookFind[EvaluationNotebook[], tag, All, CellTags];
    FrontEndExecute[FrontEndToken["CellGroup"]];
    FrontEndExecute[FrontEndToken["OpenCloseGroup"]];
    SelectionMove[EvaluationNotebook[], After, Cell];
];  

(*Main function*)  
System`$ShowIt = True;  

System$SowIt = False; System`$ConsoleIt = False; System$ReverseIt = False;
System`$GroupIt = False; Off[System`Debug::ShowIt]; System`$ShowItTagPattern = None;


System`$SowIt = False;  
System`$ConsoleIt = False;
System`$ReverseIt = False;  
System`$GroupIt = False;  
Off[System`Debug::ShowIt];  
System`$ShowItTagPattern = None;

System`Debug::ShowIt = "`1`";
SetAttributes[System`ShowIt, HoldAll];
System`ShowIt[expr_,tag_:None]:=
LetL[{evaluatedExpr = expr,exprWithSymbolNamesCorrected = ExtractSymbolName@expr,printedExpr = Replace[Defer[CompoundExpression[exprWithSymbolNamesCorrected = evaluatedExpr,Null]],Defer[x_]:>x,{3}]},
    If[MatchQ[tag,System`$ShowItTagPattern],
       Message[Debug::ShowIt,printedExpr];

       If[TrueQ@System`$ShowIt,
       If[TrueQ@System`$ReverseIt,
               insertBelowEvaluationCell[printedExpr];
               ,
                If[TrueQ@System`$GroupIt,
                   PrintGroupedCells[exprWithSymbolNamesCorrected,printedExpr]
                   ,
                   Print[printedExpr];
               ];
           ];
       ];

       If[TrueQ@System`$ConsoleIt,
      PrintToConsole[printedExpr,TrueQ@System`$ReverseIt];
       ];

       If[TrueQ@System`$SowIt,
           Sow[
               evaluatedExpr
               ,
               Function[deferedExpr, ToString@Unevaluated@deferedExpr, HoldFirst] @@ exprWithSymbolNamesCorrected
           ];
       ];
    ];

    evaluatedExpr
]; 

SetSharedFunction[System`ShowItList];
SetAttributes[System`ShowItList, {HoldAll,Listable}];
System`ShowItList[expr_,tag_:None] := System`ShowIt[expr];

SetAttributes[ReapTags,HoldFirst];
ReapTags[expr_]:=
   Module[{elements},
      Reap[Check[expr,"failed"],_,(elements[#1]=If[Length@#2==1,First@#2,#2])&];
      elements
   ];

SetSharedFunction[Debug`ShowIt];
SetAttributes[Debug`ShowIt,HoldFirst];
Debug`ShowIt[x_]:=ShowIt[x];

SetSharedFunction[Debug`ShowItList];
SetAttributes[Debug`ShowItList,HoldFirst];
Debug`ShowItList[x_]:=ShowItList[x];

The argument of ReapTagsReapTags can be any expression including the call to a function which is hard to split into simple pieces thus using ReapReap[] and SowSow[] as underlying functions is useful in such a case.

This version of ShowIt first shown by Leonid Shifrin is particularly useful, it can be used in conjunction with the function ReapTags defined below also.

It now uses the LetL function also from Leonid defined here (in order to avoid a nested With for printedExpr).

  • The Print output using \$ShowIt = True allows to use it in the front end if you change its style to Input.
  • \$ReverseIt = True allows to Print the result of Print in a reverse order as asked in this question.
  • The Message if you switch it on using On[Debug::ShowIt] prints a Mathematica message and would stop the code if you used a message breakpoint in Mathematica or Wolfram Workbench.
  • \$SowIt = True allows to store what would be printed with Print in a symbol.

To see the list of keys defined in the debugSymbol containing the results extracted from a program you can use the function Keys.

  • \$ConsoleIt = True allows to output what would be output with Print but in the Messages console accessible in the menu Window>Messages.
  • \$GroupIt prints expressions in groups of two cells, for example x as title, and x=2; as expression.
  • The System` context of ShowIt and ShowItList allows to use them in the Private` context of other packages without having to define the package in which these functions are defined (in BeginPackage, see here for more info on the organisation of packages).
  • ShowIt is not shown inside another ShowIt.
  • You can define a tag when calling ShowIt, and restrict which tags let ShowIt output things using \$ShowItTagPattern.
  • You can use Debug`ShowIt in parallel kernels (as System`ShowIt is recognised as a Global` symbol in a parallel kernel).

All in all ShowIt and the functions around it show a lot of different aspects of advanced evaluation in Mathematica that could be interesting to a lot of people.

(*Auxiliary functions*)
SetAttributes[ExtractSymbolName, HoldAll];
ExtractSymbolName[expr_] :=
Module[{T,SR = StringReplace[#, a__ ~~ "$" ~~ DigitCharacter .. :> a] &}, 
    Defer[expr] 
        //. HoldPattern[System`ShowIt@x_] :> x
        /. s_Symbol :> T@MakeExpression@SR@SymbolName@Unevaluated@s 
        /. T@_@x___ :> x
];

insertBelowEvaluationCell[expr_]:=
(
    SelectionMove[EvaluationNotebook[],After,EvaluationCell];
    NotebookWrite[EvaluationNotebook[],Cell[BoxData@ToBoxes[expr],"Print"]]
);

$OldLine=-1;
SetAttributes[PrintToConsole,HoldFirst];
PrintToConsole[Defer[expr_],reversePrint_:False]:=PrintToConsole[expr,reversePrint];
PrintToConsole[expr_,reversePrint_:False]:=
(
    If[$OldLine!=$Line,
        SelectionMove[MessagesNotebook[],After,Notebook];
        
        NotebookWrite[MessagesNotebook[],
            Cell[
                BoxData@ToBoxes@"","Print",
                CellLabel->"During evaluation of In["<>ToString[$Line-1]<>"]:=",
                ShowCellLabel->True
            ]
        ];
    ];
    
    If[$OldLine==$Line,
        If[reversePrint,
            SelectionMove[MessagesNotebook[],Previous,Cell];
            SelectionMove[MessagesNotebook[],Before,Cell];
            ,
            SelectionMove[MessagesNotebook[], After, Cell];
        ]
    ];
    
    NotebookWrite[MessagesNotebook[],
        Cell[
            BoxData@ToBoxes@Defer@expr,"Print"
        ]
    ];
    
    $OldLine=$Line;
);

SetAttributes[PrintGroupedCells, HoldAll]
 PrintGroupedCells[label_, expr_] :=
Module[{tag = ToString@Unique[]},
    CellPrint[
        CellGroup[
            {
                ExpressionCell[label, "Item", CellTags -> tag]
                ,
                ExpressionCell[expr, "Input", CellTags -> tag]
            }
        ]
    ];
      
    NotebookFind[EvaluationNotebook[], tag, All, CellTags];
    FrontEndExecute[FrontEndToken["CellGroup"]];
    FrontEndExecute[FrontEndToken["OpenCloseGroup"]];
    SelectionMove[EvaluationNotebook[], After, Cell];
];  

(*Main function*)  
System`$ShowIt = True;  

System$SowIt = False; System`$ConsoleIt = False; System$ReverseIt = False;
System`$GroupIt = False; Off[System`Debug::ShowIt]; System`$ShowItTagPattern = None;

System`Debug::ShowIt = "`1`";
SetAttributes[System`ShowIt, HoldAll];
System`ShowIt[expr_,tag_:None]:=
LetL[{evaluatedExpr = expr,exprWithSymbolNamesCorrected = ExtractSymbolName@expr,printedExpr = Replace[Defer[CompoundExpression[exprWithSymbolNamesCorrected = evaluatedExpr,Null]],Defer[x_]:>x,{3}]},
    If[MatchQ[tag,System`$ShowItTagPattern],
       Message[Debug::ShowIt,printedExpr];

       If[TrueQ@System`$ShowIt,
       If[TrueQ@System`$ReverseIt,
               insertBelowEvaluationCell[printedExpr];
               ,
                If[TrueQ@System`$GroupIt,
                   PrintGroupedCells[exprWithSymbolNamesCorrected,printedExpr]
                   ,
                   Print[printedExpr];
               ];
           ];
       ];

       If[TrueQ@System`$ConsoleIt,
      PrintToConsole[printedExpr,TrueQ@System`$ReverseIt];
       ];

       If[TrueQ@System`$SowIt,
           Sow[
               evaluatedExpr
               ,
               Function[deferedExpr, ToString@Unevaluated@deferedExpr, HoldFirst] @@ exprWithSymbolNamesCorrected
           ];
       ];
    ];

    evaluatedExpr
]; 

SetSharedFunction[System`ShowItList];
SetAttributes[System`ShowItList, {HoldAll,Listable}];
System`ShowItList[expr_,tag_:None] := System`ShowIt[expr];

SetAttributes[ReapTags,HoldFirst];
ReapTags[expr_]:=
   Module[{elements},
      Reap[Check[expr,"failed"],_,(elements[#1]=If[Length@#2==1,First@#2,#2])&];
      elements
   ];

SetSharedFunction[Debug`ShowIt];
SetAttributes[Debug`ShowIt,HoldFirst];
Debug`ShowIt[x_]:=ShowIt[x];

SetSharedFunction[Debug`ShowItList];
SetAttributes[Debug`ShowItList,HoldFirst];
Debug`ShowItList[x_]:=ShowItList[x];

The argument of ReapTags can be any expression including the call to a function which is hard to split into simple pieces thus using Reap and Sow as underlying functions is useful in such a case.

This version of ShowIt first shown by Leonid Shifrin is particularly useful, it can be used in conjunction with the function ReapTags[] defined below also.

It now uses the LetL[] function also from Leonid defined here (in order to avoid a nested With for printedExpr).

  • The Print output using $ShowIt = True allows to use it in the front end if you change its style to Input.
  • $ReverseIt = True allows to Print the result of Print in a reverse order as asked in this question.
  • The Message if you switch it on using On[Debug::ShowIt] prints a Mathematica message and would stop the code if you used a message breakpoint in Mathematica or Wolfram Workbench.
  • $SowIt = True allows to store what would be printed with Print in a symbol.

To see the list of keys defined in the debugSymbol containing the results extracted from a program you can use the function Keys.

  • $ConsoleIt = True allows to output what would be output with Print but in the Messages console accessible in the menu Window > Messages.
  • $GroupIt prints expressions in groups of two cells, for example x as title, and x=2; as expression.
  • The System`* context of ShowIt and ShowItList allows to use them in the Private`* context of other packages without having to define the package in which these functions are defined (in BeginPackage[], see here for more info on the organisation of packages).
  • ShowIt[] is not shown inside another ShowIt.
  • You can define a tag when calling ShowIt, and restrict which tags let ShowIt output things using $ShowItTagPattern.
  • You can use Debug`ShowIt in parallel kernels (as System`ShowIt is recognised as a Global` symbol in a parallel kernel).

All in all ShowIt and the functions around it show a lot of different aspects of advanced evaluation in Mathematica that could be interesting to a lot of people.

(*Auxiliary functions*)
SetAttributes[ExtractSymbolName, HoldAll];
ExtractSymbolName[expr_] :=
Module[{T,SR = StringReplace[#, a__ ~~ "$" ~~ DigitCharacter .. :> a] &}, 
    Defer[expr] 
        //. HoldPattern[System`ShowIt@x_] :> x
        /. s_Symbol :> T@MakeExpression@SR@SymbolName@Unevaluated@s 
        /. T@_@x___ :> x
];

insertBelowEvaluationCell[expr_]:=
(
    SelectionMove[EvaluationNotebook[],After,EvaluationCell];
    NotebookWrite[EvaluationNotebook[],Cell[BoxData@ToBoxes[expr],"Print"]]
);

$OldLine=-1;
SetAttributes[PrintToConsole,HoldFirst];
PrintToConsole[Defer[expr_],reversePrint_:False]:=PrintToConsole[expr,reversePrint];
PrintToConsole[expr_,reversePrint_:False]:=
(
    If[$OldLine!=$Line,
        SelectionMove[MessagesNotebook[],After,Notebook];
        
        NotebookWrite[MessagesNotebook[],
            Cell[
                BoxData@ToBoxes@"","Print",
                CellLabel->"During evaluation of In["<>ToString[$Line-1]<>"]:=",
                ShowCellLabel->True
            ]
        ];
    ];
    
    If[$OldLine==$Line,
        If[reversePrint,
            SelectionMove[MessagesNotebook[],Previous,Cell];
            SelectionMove[MessagesNotebook[],Before,Cell];
            ,
            SelectionMove[MessagesNotebook[], After, Cell];
        ]
    ];
    
    NotebookWrite[MessagesNotebook[],
        Cell[
            BoxData@ToBoxes@Defer@expr,"Print"
        ]
    ];
    
    $OldLine=$Line;
);

SetAttributes[PrintGroupedCells, HoldAll]
 PrintGroupedCells[label_, expr_] :=
Module[{tag = ToString@Unique[]},
    CellPrint[
        CellGroup[
            {
                ExpressionCell[label, "Item", CellTags -> tag]
                ,
                ExpressionCell[expr, "Input", CellTags -> tag]
            }
        ]
    ];
      
    NotebookFind[EvaluationNotebook[], tag, All, CellTags];
    FrontEndExecute[FrontEndToken["CellGroup"]];
    FrontEndExecute[FrontEndToken["OpenCloseGroup"]];
    SelectionMove[EvaluationNotebook[], After, Cell];
];  

(*Main function*)  
System`$ShowIt = True;  

System`$SowIt = False;  
System`$ConsoleIt = False;
System`$ReverseIt = False;  
System`$GroupIt = False;  
Off[System`Debug::ShowIt];  
System`$ShowItTagPattern = None;

System`Debug::ShowIt = "`1`";
SetAttributes[System`ShowIt, HoldAll];
System`ShowIt[expr_,tag_:None]:=
LetL[{evaluatedExpr = expr,exprWithSymbolNamesCorrected = ExtractSymbolName@expr,printedExpr = Replace[Defer[CompoundExpression[exprWithSymbolNamesCorrected = evaluatedExpr,Null]],Defer[x_]:>x,{3}]},
    If[MatchQ[tag,System`$ShowItTagPattern],
       Message[Debug::ShowIt,printedExpr];

       If[TrueQ@System`$ShowIt,
       If[TrueQ@System`$ReverseIt,
               insertBelowEvaluationCell[printedExpr];
               ,
                If[TrueQ@System`$GroupIt,
                   PrintGroupedCells[exprWithSymbolNamesCorrected,printedExpr]
                   ,
                   Print[printedExpr];
               ];
           ];
       ];

       If[TrueQ@System`$ConsoleIt,
      PrintToConsole[printedExpr,TrueQ@System`$ReverseIt];
       ];

       If[TrueQ@System`$SowIt,
           Sow[
               evaluatedExpr
               ,
               Function[deferedExpr, ToString@Unevaluated@deferedExpr, HoldFirst] @@ exprWithSymbolNamesCorrected
           ];
       ];
    ];

    evaluatedExpr
]; 

SetSharedFunction[System`ShowItList];
SetAttributes[System`ShowItList, {HoldAll,Listable}];
System`ShowItList[expr_,tag_:None] := System`ShowIt[expr];

SetAttributes[ReapTags,HoldFirst];
ReapTags[expr_]:=
   Module[{elements},
      Reap[Check[expr,"failed"],_,(elements[#1]=If[Length@#2==1,First@#2,#2])&];
      elements
   ];

SetSharedFunction[Debug`ShowIt];
SetAttributes[Debug`ShowIt,HoldFirst];
Debug`ShowIt[x_]:=ShowIt[x];

SetSharedFunction[Debug`ShowItList];
SetAttributes[Debug`ShowItList,HoldFirst];
Debug`ShowItList[x_]:=ShowItList[x];

The argument of ReapTags can be any expression including the call to a function which is hard to split into simple pieces thus using Reap[] and Sow[] as underlying functions is useful in such a case.

deleted 13 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 277 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 130 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
deleted 127 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
deleted 72 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 449 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 46 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 175 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
deleted 115 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 779 characters in body; Post Made Community Wiki
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 5 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
deleted 5 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 27 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 93 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 100 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 1 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 91 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 8 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
added 345 characters in body
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading
Source Link
faysou
  • 11k
  • 3
  • 50
  • 131
Loading