288

I'm using and I need to pretty-print JSON data (make it more human readable).

I haven't been able to find this functionality within that library. How is this commonly achieved?

spongebob
  • 8,370
  • 15
  • 50
  • 83
mabuzer
  • 6,497
  • 6
  • 35
  • 41

20 Answers20

362

Google's GSON can do this in a nice way:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(uglyJsonString);
String prettyJsonString = gson.toJson(je);

or since it is now recommended to use the static parse method from JsonParser you can also use this instead:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonElement je = JsonParser.parseString​(uglyJsonString);
String prettyJsonString = gson.toJson(je);

Here is the import statement:

import com.google.gson.*;

Here is the Gradle dependency:

implementation 'com.google.code.gson:gson:2.8.7'
Ray Hulha
  • 10,701
  • 5
  • 53
  • 53
  • 1
    Well I included code to parse a string into a JsonElement, usually you already have that from previous work you do with the JSON data. But I wanted to include it here to make the usage clearer. – Ray Hulha Feb 20 '14 at 15:01
  • Since this answer helped me. I have added code below to shrink this statement to fewer lines if this is what you are looking for. public String prettifyJson(String json) { JsonElement jsonElement = new JsonParser().parse(json); return new GsonBuilder().setPrettyPrinting().create().toJson(jsonElement); } – ahmad Feb 11 '15 at 18:50
  • 2
    It is possible to answer the OP's question without needing additional libraries, as you can simply access the JSON parser embedded in Rhino (JDK 1.7 and up). I don't think it is desirable to add a library to a project just to format some debugging output. `scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)");` – Agnes Mar 19 '15 at 08:31
  • 2
    In contrast to the org.json alternative, the GSON way of pretty printing keeps the order of the elements intact after transformation. – Aydin K. Jul 05 '17 at 13:25
  • Check my [answer](https://stackoverflow.com/a/47845996/6413377) to another related question if interested in more generic solution for example when logging. – pirho Dec 16 '17 at 13:31
  • 1
    Thanks for the pointer to `GsonBuilder`, since I was using `gson.toJson(object)` I simply had to change my instantiation from `Gson gson = new Gson();` to `Gson gson = new GsonBuilder().setPrettyPrinting().create();` and my code continued to work but pretty printed the object instead of a single line. – cptully Dec 06 '19 at 17:40
  • I urge anyone who only has Jackson as a dependency to see the answer below https://stackoverflow.com/a/44101386/1087131 – Stephen Paul Jan 23 '20 at 11:35
  • 3
    JsonParser is deprecated: https://stackoverflow.com/a/63397831/5626568 – ℛɑƒæĿᴿᴹᴿ Aug 20 '20 at 13:12
  • Why use Google and an additional library if JSON can do this out of the box? This answer should not get marked as solution! This one is better: https://stackoverflow.com/a/9583835/356815 – basZero Mar 10 '23 at 11:36
214

I used org.json built-in methods to pretty-print the data.

import org.json.JSONObject;
JSONObject json = new JSONObject(jsonString); // Convert text to object
System.out.println(json.toString(4)); // Print it with specified indentation

The order of fields in JSON is random per definition. A specific order is subject to parser implementation.

JohnK
  • 6,865
  • 8
  • 49
  • 75
Raghu Kiran
  • 2,347
  • 1
  • 15
  • 11
72

With Jackson (com.fasterxml.jackson.databind):

ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject))

From: How to enable pretty print JSON output (Jackson)

I know this is already in the answers, but I want to write it separately here because chances are, you already have Jackson as a dependency and so all you will need would be an extra line of code

kkurian
  • 3,844
  • 3
  • 30
  • 49
oktieh
  • 979
  • 6
  • 7
  • This will print out an object as a string. Don't believe it works as-is to pretty print a string of JSON. – Cuga Apr 28 '22 at 19:58
  • 3
    If you have a json in a String you could do: ```ObjectMapper mapper = new ObjectMapper(); mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mapper.readTree(jsonString));``` – Josejulio Aug 25 '22 at 12:29
45

It seems like GSON supports this, although I don't know if you want to switch from the library you are using.

From the user guide:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);
spongebob
  • 8,370
  • 15
  • 50
  • 83
BuffaloBuffalo
  • 7,703
  • 4
  • 28
  • 29
32

Using org json. Reference link

JSONObject jsonObject = new JSONObject(obj);
String prettyJson = jsonObject.toString(4);

Using Gson. Reference link

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(obj);

Using Jackson. Reference link

ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
String json = mapper.writeValueAsString(obj);

Using Genson. Reference link.

Genson prettyGenson = new GensonBuilder().useIndentation(true).create();
String prettyJson = prettyGenson.serialize(obj);

Using javax.json. Reference link.

Map<String, Boolean> config = new HashMap<>();

config.put(JsonGenerator.PRETTY_PRINTING, true);

JsonWriterFactory writerFactory = Json.createWriterFactory(config);
Writer writer = new StringWriter();

writerFactory.createWriter(writer).write(jsonObject);

String json = writer.toString();

Using Moshi library. Reference link.

String json = jsonAdapter.indent("  ").toJson(emp1);

(OR)

Buffer buffer = new Buffer();
JsonWriter jsonWriter = JsonWriter.of(buffer);
jsonWriter.setIndent("   ");

jsonAdapter.toJson(jsonWriter, emp1);

json = buffer.readUtf8();
Hari Krishna
  • 3,658
  • 1
  • 36
  • 57
23

If you are using a Java API for JSON Processing (JSR-353) implementation then you can specify the JsonGenerator.PRETTY_PRINTING property when you create a JsonGeneratorFactory.

The following example has been originally published on my blog post.

import java.util.*;
import javax.json.Json;
import javax.json.stream.*;

Map<String, Object> properties = new HashMap<String, Object>(1);
properties.put(JsonGenerator.PRETTY_PRINTING, true);
JsonGeneratorFactory jgf = Json.createGeneratorFactory(properties);
JsonGenerator jg = jgf.createGenerator(System.out);

jg.writeStartObject()                    // {
    .write("name", "Jane Doe")           //    "name":"Jane Doe",
    .writeStartObject("address")         //    "address":{
        .write("type", 1)                //        "type":1,
        .write("street", "1 A Street")   //        "street":"1 A Street",
        .writeNull("city")               //        "city":null,
        .write("verified", false)        //        "verified":false
    .writeEnd()                          //    },
    .writeStartArray("phone-numbers")    //    "phone-numbers":[
        .writeStartObject()              //        {
            .write("number", "555-1111") //            "number":"555-1111",
            .write("extension", "123")   //            "extension":"123"
        .writeEnd()                      //        },
        .writeStartObject()              //        {
            .write("number", "555-2222") //            "number":"555-2222",
            .writeNull("extension")      //            "extension":null
        .writeEnd()                      //        }
    .writeEnd()                          //    ]
.writeEnd()                              // }
.close();
spongebob
  • 8,370
  • 15
  • 50
  • 83
bdoughan
  • 147,609
  • 23
  • 300
  • 400
21

Pretty printing with GSON in one line:

System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(new JsonParser().parse(jsonString)));

Besides inlining, this is equivalent to the accepted answer.

Community
  • 1
  • 1
Bengt
  • 14,011
  • 7
  • 48
  • 66
19

My situation is my project uses a legacy (non-JSR) JSON parser that does not support pretty printing. However, I needed to produce pretty-printed JSON samples; this is possible without having to add any extra libraries as long as you are using Java 7 and above:

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine scriptEngine = manager.getEngineByName("JavaScript");
scriptEngine.put("jsonString", jsonStringNoWhitespace);
scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)");
String prettyPrintedJson = (String) scriptEngine.get("result");
Agnes
  • 654
  • 6
  • 11
18

Most of the existing answers either depend on some external library, or requiring a special Java version. Here is a simple code to pretty print a JSON string, only using general Java APIs (available in Java 7 for higher; haven't tried older version although).

The basic idea is to tigger the formatting based on special characters in JSON. For example, if a '{' or '[' is observed, the code will create a new line and increase the indent level.

Disclaimer: I only tested this for some simple JSON cases (basic key-value pair, list, nested JSON) so it may need some work for more general JSON text, like string value with quotes inside, or special characters (\n, \t etc.).

/**
 * A simple implementation to pretty-print JSON file.
 *
 * @param unformattedJsonString
 * @return
 */
public static String prettyPrintJSON(String unformattedJsonString) {
  StringBuilder prettyJSONBuilder = new StringBuilder();
  int indentLevel = 0;
  boolean inQuote = false;
  for(char charFromUnformattedJson : unformattedJsonString.toCharArray()) {
    switch(charFromUnformattedJson) {
      case '"':
        // switch the quoting status
        inQuote = !inQuote;
        prettyJSONBuilder.append(charFromUnformattedJson);
        break;
      case ' ':
        // For space: ignore the space if it is not being quoted.
        if(inQuote) {
          prettyJSONBuilder.append(charFromUnformattedJson);
        }
        break;
      case '{':
      case '[':
        // Starting a new block: increase the indent level
        prettyJSONBuilder.append(charFromUnformattedJson);
        indentLevel++;
        appendIndentedNewLine(indentLevel, prettyJSONBuilder);
        break;
      case '}':
      case ']':
        // Ending a new block; decrese the indent level
        indentLevel--;
        appendIndentedNewLine(indentLevel, prettyJSONBuilder);
        prettyJSONBuilder.append(charFromUnformattedJson);
        break;
      case ',':
        // Ending a json item; create a new line after
        prettyJSONBuilder.append(charFromUnformattedJson);
        if(!inQuote) {
          appendIndentedNewLine(indentLevel, prettyJSONBuilder);
        }
        break;
      default:
        prettyJSONBuilder.append(charFromUnformattedJson);
    }
  }
  return prettyJSONBuilder.toString();
}

/**
 * Print a new line with indention at the beginning of the new line.
 * @param indentLevel
 * @param stringBuilder
 */
private static void appendIndentedNewLine(int indentLevel, StringBuilder stringBuilder) {
  stringBuilder.append("\n");
  for(int i = 0; i < indentLevel; i++) {
    // Assuming indention using 2 spaces
    stringBuilder.append("  ");
  }
}
asksw0rder
  • 1,066
  • 1
  • 12
  • 19
  • 1
    On first reading I was highly displeasured with this suggestion, but after reading all answers, this is the best solution. At least, if it is for just for some debugging output, and you don't want to drag in dependencies, that you might want to remove later on again. Thank you very much! – Thomas Schütt Aug 08 '19 at 11:28
10

Now this can be achieved with the JSONLib library:

http://json-lib.sourceforge.net/apidocs/net/sf/json/JSONObject.html

If (and only if) you use the overloaded toString(int indentationFactor) method and not the standard toString() method.

I have verified this on the following version of the API:

<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20140107</version>
</dependency>
spongebob
  • 8,370
  • 15
  • 50
  • 83
Sridhar Sarnobat
  • 25,183
  • 12
  • 93
  • 106
  • 3
    While this library may help answer the question, it would be better to include an _example_ of how it is applicable to the problem with some _explanation_ regarding how it works. – spongebob Sep 11 '15 at 15:51
  • 1
    Ok thanks for the feedback. Though do remember, people like me are volunteers and are not getting paid to provide a service that guarantees meeting quality standards. We have limited time because we're often in the middle of work, or have family duties. That's why "edit" is available to readers, so we can make each others' posts more helpful. – Sridhar Sarnobat Aug 24 '16 at 19:41
8

Following the JSON-P 1.0 specs (JSR-353) a more current solution for a given JsonStructure (JsonObject or JsonArray) could look like this:

import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import javax.json.Json;
import javax.json.JsonStructure;
import javax.json.JsonWriter;
import javax.json.JsonWriterFactory;
import javax.json.stream.JsonGenerator;

public class PrettyJson {

    private static JsonWriterFactory FACTORY_INSTANCE;

    public static String toString(final JsonStructure status) {

        final StringWriter stringWriter = new StringWriter();

        final JsonWriter jsonWriter = getPrettyJsonWriterFactory()
                .createWriter(stringWriter);

        jsonWriter.write(status);
        jsonWriter.close();

        return stringWriter.toString();
    }

    private static JsonWriterFactory getPrettyJsonWriterFactory() {
        if (null == FACTORY_INSTANCE) {
            final Map<String, Object> properties = new HashMap<>(1);
            properties.put(JsonGenerator.PRETTY_PRINTING, true);
            FACTORY_INSTANCE = Json.createWriterFactory(properties);
        }
        return FACTORY_INSTANCE;
    }

}
Jens Piegsa
  • 7,399
  • 5
  • 58
  • 106
7

In JSONLib you can use this:

String jsonTxt = JSONUtils.valueToString(json, 8, 4);

From the Javadoc:

spongebob
  • 8,370
  • 15
  • 50
  • 83
Enrique San Martín
  • 2,202
  • 7
  • 30
  • 51
6

You can use Gson like below

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonString = gson.toJson(object);

From the post JSON pretty print using Gson

Alternatively, You can use Jackson like below

ObjectMapper mapper = new ObjectMapper();
String perttyStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);

From the post Pretty print JSON in Java (Jackson)

Hope this help!

David Pham
  • 1,673
  • 19
  • 17
2

Update: new JsonParser().parse(...) is @deprecated


Based on the javadoc for Gson 2.8.6:

No need to instantiate this class, use the static methods instead.

JsonParser static methods:

JsonParser.parseString​(jsonString);
JsonParser.parseReader​(reader);

Packages:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParser;

Example:

private Gson GSON = new GsonBuilder().setPrettyPrinting().create();
public static String getPerfectJSON(String unformattedJSON) {
    String perfectJSON = GSON.toJson(JsonParser.parseString(unformattedJSON));
    return perfectJSON;
}

Google Gson dependency using Maven:

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.6</version>
</dependency>

Reference:

ℛɑƒæĿᴿᴹᴿ
  • 4,983
  • 4
  • 38
  • 58
1

This worked for me, using Jackson:

mapper.writerWithDefaultPrettyPrinter().writeValueAsString(JSONString)
1

So I too like the json-simple lib, and looked into pretty printing its output. Unfortunately, while it's an open issue there, I couldn't find any code for it. So I thought I'd give it a try, here's what I came up with (using their own source)..

public class JsonPrinter {
  
  
  
  public static String toJson(Map<?,?> map) {
    StringBuilder out = new StringBuilder(32);
    new JsonPrinter(out).print(map);
    return out.toString();
  }
  
  
  public static String toJson(List<?> list) {
    StringBuilder out = new StringBuilder(32);
    new JsonPrinter(out).print(list);
    return out.toString();
  }
  
  
  
  
  
  
  
  private final Appendable out;
  private final String indentUnit;
  private final String newLine;
  
  
  private int indents;
  
  public JsonPrinter(Appendable out) {
    this(out, "  ", System.lineSeparator());
  }

  /**
   * 
   */
  public JsonPrinter(Appendable out, String indentUnit, String newLine) {
    this.out = Objects.requireNonNull(out, "null out");
    this.indentUnit = Objects.requireNonNull(indentUnit, "null indentUnit");
    this.newLine = Objects.requireNonNull(newLine, "null newLine");
    
    if (!indentUnit.isBlank())
      throw new IllegalArgumentException(
          "indentUnit must be a blank sequence (quoted): '" + indentUnit + "'");
    if (!"\r\n".equals(newLine) && ! "\n".equals(newLine))
      throw new IllegalArgumentException(
          "unrecognized newLine (quoted): '" + newLine + "'");
  }
  
  
  public void print(List<?> list) throws UncheckedIOException {
    try {
      assert indents == 0;
      printImpl(list);
      assert indents == 0;
    } catch (IOException iox) {
      throw new UncheckedIOException("on print(List): " + list, iox);
    }
  }
  
  
  public void print(Map<?,?> map) throws UncheckedIOException {
    try {
      assert indents == 0;
      printImpl(map);
      assert indents == 0;
    } catch (IOException iox) {
      throw new UncheckedIOException("on print(Map): " + map, iox);
    }
  }
  
  
  protected void printImpl(List<?> list) throws IOException {
    if (list == null) {
      out.append("null");
      return;
    }
    
    
    boolean first = true;
    var iter = list.iterator();
    
    open('[');
    while (iter.hasNext()) {
      if (first)
        first = false;
      else
        out.append(',');
      
      out.append(newLine);
      appendIndents();
      
      appendValue(iter.next());
    }
    close(']');
  }
  
  
  protected void printImpl(Map<?, ?> map) throws IOException {
    if (map == null) {
      out.append("null");
      return;
    }
    
    
    boolean first = true;
    var iter = map.entrySet().iterator();
    
    open('{');
    while (iter.hasNext()) {
      if (first)
        first = false;
      else
        out.append(',');
      
      out.append(newLine);
      appendIndents();
      
      var entry = iter.next();
      print(entry.getKey().toString(), entry.getValue());
    }
    close('}');
  }
  
  
  private void open(char c) throws IOException {
    out.append(c);
    ++indents;
  }
  
  private void close(char c) throws IOException {
    --indents;
    out.append(newLine);
    appendIndents();
    out.append(c);
  }
  
  private void appendIndents() throws IOException {
    for (int count = indents; count-- > 0; )
      out.append(indentUnit);
  }
  
  
  
  private void print(String key, Object value) throws IOException {
    out.append('"');
    appendString(key);
    out.append('"').append(':').append(' ');
    appendValue(value);
  }
  
  
  
  private void appendString(String s) throws IOException {
    for (int i = 0; i < s.length(); i++) {
      char ch = s.charAt(i);
      switch(ch){
      case '"':
        out.append("\\\"");
        break;
      case '\\':
        out.append("\\\\");
        break;
      case '\b':
        out.append("\\b");
        break;
      case '\f':
        out.append("\\f");
        break;
      case '\n':
        out.append("\\n");
        break;
      case '\r':
        out.append("\\r");
        break;
      case '\t':
        out.append("\\t");
        break;
      case '/':
        out.append("\\/");
        break;
      default:
                //Reference: http://www.unicode.org/versions/Unicode5.1.0/
        if ((ch>='\u0000' && ch<='\u001F') || (ch>='\u007F' && ch<='\u009F') || (ch>='\u2000' && ch<='\u20FF')) {
          String ss = Integer.toHexString(ch);
          out.append("\\u");
          for (int k=0; k < 4-ss.length(); k++) {
            out.append('0');
          }
          out.append(ss.toUpperCase());
        }
        else{
          out.append(ch);
        }
      }
    }//for
  }
  
  
  private void appendValue(Object value) throws IOException {
    if (value == null) {
      out.append("null");
      
    } else if (value instanceof String) {
      out.append('"');
      appendString(value.toString());
      out.append('"');
      
    } else if (value instanceof Double) {
      var num = (Double) value;
      if (num.isInfinite() || num.isNaN())
        out.append("null");
      else
        out.append(value.toString());
      
    } else if (value instanceof Float) {
      var num = (Float) value;
      if (num.isInfinite() || num.isNaN())
        out.append("null");
      else
        out.append(value.toString());
      
    } else if (value instanceof Map) {
      printImpl((Map<?,?>) value);
      
    } else if (value instanceof List) {
      printImpl((List<?>) value);
      
//    } else if (value instanceof Number || value instanceof Boolean) {
//      out.append(value.toString());
      
    } else {
      out.append(value.toString());
      
    }
  }

}

It works for JSONObject and JSONArray even tho it has no dependeny on them.. cuz these are regular Map and List objects resp. (and the fact code was lifted from same lib).

https://github.com/crums-io/io-util/blob/master/src/main/java/io/crums/util/json/JsonPrinter.java

Babak Farhang
  • 79
  • 1
  • 8
0

You can use small json library

String jsonstring = ....;
JsonValue json = JsonParser.parse(jsonstring);
String jsonIndendedByTwoSpaces = json.toPrettyString("  ");
Anton Straka
  • 139
  • 2
0

I also use the org.json.simple package. I have simply coded the formatter, but since I don't have nulls, numbers or booleans in my JSON objects in the program that I wrote, I only coded for strings, objects and arrays. If anyone is interested, let this just be in the public domain. You are welcome to add the missing data types (where it says in the comment "it's a string"). Also, you can add the indentation as a parameter whereas mine is just two spaces. Please reshare after you've tested your improvements.

Usage: printJsonObject(jsonObject, "");

Functions:

    public static void printJsonObject(JSONObject object, String prefix) {
        boolean notFirst = false;
        System.out.println(prefix + "{");
        for (Object key : object.keySet()) {
            if (notFirst) {
                System.out.println(", ");
            }
            notFirst = true;
            Object value = object.get(key);
            System.out.print(prefix + "  " + "\"" + key + "\"" + ": ");
            if (value instanceof JSONObject) {
                printJsonObject((JSONObject) value, prefix + "  ");
            } else if (value instanceof JSONArray) {
                printJsonArray((JSONArray) value, prefix + "  ");
            } else {  // it's a string
                System.out.print("\"" + value + "\"");
            }
        }
        System.out.println("");
        System.out.print(prefix + "}");
    }

    public static void printJsonArray(JSONArray array, String prefix) {
        boolean notFirst = false;
        System.out.println("[");
        for (Object item : array) {
            if (notFirst) {
                System.out.println(", ");
            }
            notFirst = true;
            if (item instanceof JSONObject) {
                printJsonObject((JSONObject) item, prefix + "  ");
            } else if (item instanceof JSONArray) {
                printJsonArray((JSONArray) item, prefix + "  ");
            } else {
                System.out.print(prefix + "  " + "\"" + item + "\"");
            }
        }
        System.out.println("");
        System.out.print(prefix + "]");
    }

Shimon
  • 155
  • 1
  • 1
  • 11
0

This would be a public method to print a pretty version of your object (You need the Gson dependency installed:

import com.google.gson.GsonBuilder;
...

public void printMe(){
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    String prettyJSON = gson.toJson(this);
    System.out.println(printable);
}
ivandax
  • 607
  • 6
  • 5
-2

Underscore-java has static method U.formatJson(json). Five format types are supported: 2, 3, 4, tabs and compact. Live example

import com.github.underscore.U;

import static com.github.underscore.Json.JsonStringBuilder.Step.TABS;
import static com.github.underscore.Json.JsonStringBuilder.Step.TWO_SPACES;

public class MyClass {

    public static void main(String args[]) {
        String json = "{\"Price\": {"
        + "    \"LineItems\": {"
        + "        \"LineItem\": {"
        + "            \"UnitOfMeasure\": \"EACH\", \"Quantity\": 2, \"ItemID\": \"ItemID\""
        + "        }"
        + "    },"
        + "    \"Currency\": \"USD\","
        + "    \"EnterpriseCode\": \"EnterpriseCode\""
        + "}}";
        System.out.println(U.formatJson(json, TWO_SPACES)); 
        System.out.println(U.formatJson(json, TABS)); 
    }
}

Output:

{
  "Price": {
    "LineItems": {
      "LineItem": {
        "UnitOfMeasure": "EACH",
        "Quantity": 2,
        "ItemID": "ItemID"
      }
    },
    "Currency": "USD",
    "EnterpriseCode": "EnterpriseCode"
  }
}
{
    "Price": {
        "LineItems": {
            "LineItem": {
                "UnitOfMeasure": "EACH",
                "Quantity": 2,
                "ItemID": "ItemID"
            }
        },
        "Currency": "USD",
        "EnterpriseCode": "EnterpriseCode"
    }
}
Valentyn Kolesnikov
  • 2,029
  • 1
  • 24
  • 31