Convert Valve KV into JSON Valve's KV file format is as follows (in pseudo-EBNF):
&lt;pair&gt; ::= &lt;text&gt; &lt;value&gt;
&lt;value&gt; ::= &lt;text&gt; | &lt;block&gt;
&lt;text&gt; ::= &quot;\&quot;&quot; &lt;char&gt;* &quot;\&quot;&quot;
&lt;block&gt; ::= &quot;{&quot; &lt;pair&gt;* &quot;}&quot;

The parsing starts on &lt;pair&gt; state. Whitespace is allowed anywhere, but is only required between two consecutive &lt;text&gt; tokens (&quot;a&quot;&quot;b&quot; is invalid, but &quot;a&quot; &quot;b&quot; is valid, and so is &quot;a&quot;{}).
And since I'm lazy, &lt;char&gt; is any character, except &quot;, unless preceded by \.
You can also see KV as JSON without commas and colons, and with only strings and objects as possible types.
Your task is to write a program or function that converts a input string (stdin, file or argument) in KV to a output string in JSON. You can output anywhere (stdout, file or return value), as long as it's a valid json string.
It isn't necessary to preserve whitespace in the output, as long as quoted text doesn't change.
Standard loopholes apply, of course.
Bonus
You get a -20 byte bonus if the output is pretty-printed, regardless of input. Pretty printed means indenting each level of blocks with 4 spaces, separating colons from values by 1 space and have one pair per line. Closing braces should stand on their own line.
Test cases
Input:
&quot;foo&quot; {
    &quot;bar&quot; &quot;baz&quot;
    &quot;oof&quot; {
        &quot;rab&quot; &quot;zab&quot;
    }
}

Output:
{
    &quot;foo&quot;: {
        &quot;bar&quot;: &quot;baz&quot;,
        &quot;oof&quot;: {
            &quot;rab&quot;: &quot;zab&quot;
        }
    }
}

Input:
&quot;obj&quot; {
    &quot;emptyo&quot; {}
    &quot;troll&quot; &quot;}{&quot;
}

Output:
{
    &quot;obj&quot;: {
        &quot;emptyo&quot;: {},
        &quot;troll&quot;: &quot;}{&quot;
    }
}

Input:
&quot;newline&quot; &quot;
&quot;

Output:
{
    &quot;newline&quot;: &quot;\n&quot;
}

Input:
&quot;key
with_newline&quot; {
    &quot;\&quot;escaped\&quot;quotes&quot; &quot;escaped_end\&quot;&quot;
}

Output:
{
    &quot;key\nwith_newline&quot;: {
        &quot;\&quot;escaped\&quot;quotes&quot;: &quot;escaped_end\&quot;&quot;
    }
}
CJam, 57 54 bytes

{[~]2/{`_'{#{1&gt;W&lt;"\u%04x"fe%s`}{~J}?}f%':f*',*{}s\*}:J


This is a named function that pops a VDF string from the stack and pushes a JSON string in return.

CJam has no JSON built-ins, so the bonus won't be worth it. Since conditionally escaping some characters would be a pain for the same reason, I decided to escape everything.

The result isn't pretty, but it's valid JSON. Try it online in the CJam interpreter.