Bloblang Methods
Methods provide most of the power in Bloblang as they allow you to augment values and can be added to any expression (including other methods):
root.doc.id = this.thing.id.string().catch(uuid_v4())
root.doc.reduced_nums = this.thing.nums.map_each(num -> if num < 10 {
deleted()
} else {
num - 10
})
root.has_good_taste = ["pikachu","mewtwo","magmar"].contains(this.user.fav_pokemon)
Methods support both named and nameless style arguments:
root.foo_one = this.(bar | baz).trim().replace_all(old: "dog", new: "cat")
root.foo_two = this.(bar | baz).trim().replace_all("dog", "cat")
General
apply
Apply a declared mapping to a target value.
Parameters
mapping
<string> The mapping to apply.
Examples
map thing {
root.inner = this.first
}
root.foo = this.doc.apply("thing")
# In: {"doc":{"first":"hello world"}}
# Out: {"foo":{"inner":"hello world"}}
map create_foo {
root.name = "a foo"
root.purpose = "to be a foo"
}
root = this
root.foo = null.apply("create_foo")
# In: {"id":"1234"}
# Out: {"foo":{"name":"a foo","purpose":"to be a foo"},"id":"1234"}
catch
If the result of a target query fails (due to incorrect types, failed parsing, etc) the argument is returned instead.
Parameters
fallback
<query expression> A value to yield, or query to execute, if the target query fails.
Examples
root.doc.id = this.thing.id.string().catch(uuid_v4())
The fallback argument can be a mapping, allowing you to capture the error string and yield structured data back.
root.url = this.url.parse_url().catch(err -> {"error":err,"input":this.url})
# In: {"url":"invalid %&# url"}
# Out: {"url":{"error":"field `this.url`: parse \"invalid %&\": invalid URL escape \"%&\"","input":"invalid %&# url"}}
When the input document is not structured attempting to reference structured fields with this
will result in an error. Therefore, a convenient way to delete non-structured data is with a catch.
root = this.catch(deleted())
# In: {"doc":{"foo":"bar"}}
# Out: {"doc":{"foo":"bar"}}
# In: not structured data
# Out: <Message deleted>
exists
Checks that a field, identified via a dot path, exists in an object.
Parameters
path
<string> A dot path to a field.
Examples
root.result = this.foo.exists("bar.baz")
# In: {"foo":{"bar":{"baz":"yep, I exist"}}}
# Out: {"result":true}
# In: {"foo":{"bar":{}}}
# Out: {"result":false}
# In: {"foo":{}}
# Out: {"result":false}
from
Modifies a target query such that certain functions are executed from the perspective of another message in the batch. This allows you to mutate events based on the contents of other messages. Functions that support this behaviour are content
, json
and meta
.
Parameters
index
<integer> The message index to use as a perspective.
Examples
For example, the following map extracts the contents of the JSON field foo
specifically from message index 1
of a batch, effectively overriding the field foo
for all messages of a batch to that of message 1:
root = this
root.foo = json("foo").from(1)
from_all
Modifies a target query such that certain functions are executed from the perspective of each message in the batch, and returns the set of results as an array. Functions that support this behaviour are content
, json
and meta
.
Examples
root = this
root.foo_summed = json("foo").from_all().sum()
or
If the result of the target query fails or resolves to null
, returns the argument instead. This is an explicit method alternative to the coalesce pipe operator |
.
Parameters
fallback
<query expression> A value to yield, or query to execute, if the target query fails or resolves to null
.
Examples
root.doc.id = this.thing.id.or(uuid_v4())
String Manipulation
capitalize
Takes a string value and returns a copy with all Unicode letters that begin words mapped to their Unicode title case.
Examples
root.title = this.title.capitalize()
# In: {"title":"the foo bar"}
# Out: {"title":"The Foo Bar"}
compare_argon2
Checks whether a string matches a hashed secret using Argon2.
Parameters
hashed_secret
<string> The hashed secret to compare with the input. This must be a fully-qualified string which encodes the Argon2 options used to generate the hash.
Examples
root.match = this.secret.compare_argon2("$argon2id$v=19$m=4096,t=3,p=1$c2FsdHktbWNzYWx0ZmFjZQ$RMUMwgtS32/mbszd+ke4o4Ej1jFpYiUqY6MHWa69X7Y")
# In: {"secret":"there-are-many-blobs-in-the-sea"}
# Out: {"match":true}
root.match = this.secret.compare_argon2("$argon2id$v=19$m=4096,t=3,p=1$c2FsdHktbWNzYWx0ZmFjZQ$RMUMwgtS32/mbszd+ke4o4Ej1jFpYiUqY6MHWa69X7Y")
# In: {"secret":"will-i-ever-find-love"}
# Out: {"match":false}
compare_bcrypt
Checks whether a string matches a hashed secret using bcrypt.
Parameters
hashed_secret
<string> The hashed secret value to compare with the input.
Examples
root.match = this.secret.compare_bcrypt("$2y$10$Dtnt5NNzVtMCOZONT705tOcS8It6krJX8bEjnDJnwxiFKsz1C.3Ay")
# In: {"secret":"there-are-many-blobs-in-the-sea"}
# Out: {"match":true}
root.match = this.secret.compare_bcrypt("$2y$10$Dtnt5NNzVtMCOZONT705tOcS8It6krJX8bEjnDJnwxiFKsz1C.3Ay")
# In: {"secret":"will-i-ever-find-love"}
# Out: {"match":false}
contains
Checks whether a string contains a substring and returns a boolean result.
Parameters
value
<unknown> A value to test against elements of the target.
Examples
root.has_foo = this.thing.contains("foo")
# In: {"thing":"this foo that"}
# Out: {"has_foo":true}
# In: {"thing":"this bar that"}
# Out: {"has_foo":false}
escape_html
Escapes a string so that special characters like <
to become <
. It escapes only five such characters: <
, >
, &
, '
and "
so that it can be safely placed within an HTML entity.
Examples
root.escaped = this.value.escape_html()
# In: {"value":"foo & bar"}
# Out: {"escaped":"foo & bar"}
escape_url_query
Escapes a string so that it can be safely placed within a URL query.
Examples
root.escaped = this.value.escape_url_query()
# In: {"value":"foo & bar"}
# Out: {"escaped":"foo+%26+bar"}
filepath_join
Joins an array of path elements into a single file path. The separator depends on the operating system of the machine.
Examples
root.path = this.path_elements.filepath_join()
# In: {"path_elements":["/foo/","bar.txt"]}
# Out: {"path":"/foo/bar.txt"}
filepath_split
Splits a file path immediately following the final Separator, separating it into a directory and file name component returned as a two element array of strings. If there is no Separator in the path, the first element will be empty and the second will contain the path. The separator depends on the operating system of the machine.
Examples
root.path_sep = this.path.filepath_split()
# In: {"path":"/foo/bar.txt"}
# Out: {"path_sep":["/foo/","bar.txt"]}
# In: {"path":"baz.txt"}
# Out: {"path_sep":["","baz.txt"]}
format
Use a value string as a format specifier in order to produce a new string, using any number of provided arguments. Please refer to the Go fmt
package documentation for the list of valid format verbs.
Examples
root.foo = "%s(%v): %v".format(this.name, this.age, this.fingers)
# In: {"name":"lance","age":37,"fingers":13}
# Out: {"foo":"lance(37): 13"}
has_prefix
Checks whether a string has a prefix argument and returns a bool.
Parameters
value
<string> The string to test.
Examples
root.t1 = this.v1.has_prefix("foo")
root.t2 = this.v2.has_prefix("foo")
# In: {"v1":"foobar","v2":"barfoo"}
# Out: {"t1":true,"t2":false}
has_suffix
Checks whether a string has a suffix argument and returns a bool.
Parameters
value
<string> The string to test.
Examples
root.t1 = this.v1.has_suffix("foo")
root.t2 = this.v2.has_suffix("foo")
# In: {"v1":"foobar","v2":"barfoo"}
# Out: {"t1":false,"t2":true}
index_of
Returns the starting index of the argument substring in a string target, or -1
if the target doesn't contain the argument.
Parameters
value
<string> A string to search for.
Examples
root.index = this.thing.index_of("bar")
# In: {"thing":"foobar"}
# Out: {"index":3}
root.index = content().index_of("meow")
# In: the cat meowed, the dog woofed
# Out: {"index":8}
length
Returns the length of a string.
Examples
root.foo_len = this.foo.length()
# In: {"foo":"hello world"}
# Out: {"foo_len":11}
lowercase
Convert a string value into lowercase.
Examples
root.foo = this.foo.lowercase()
# In: {"foo":"HELLO WORLD"}
# Out: {"foo":"hello world"}
quote
Quotes a target string using escape sequences (\t
, \n
, \xFF
, \u0100
) for control characters and non-printable characters.
Examples
root.quoted = this.thing.quote()
# In: {"thing":"foo\nbar"}
# Out: {"quoted":"\"foo\\nbar\""}
repeat
Repeats the input string count
times and returns the concatenated result.
Introduced in version 1.5.0.
Parameters
count
<integer> Number of copies. If less than zero, it is treated as zero: resulting in an empty output.
Examples
root.fruit = this.fruit + "na".repeat(2)
# In: {"fruit":"ba"}
# Out: {"fruit":"banana"}
replace_all
Replaces all occurrences of the first argument in a target string with the second argument.
Parameters
old
<string> A string to match against.
new
<string> A string to replace with.
Examples
root.new_value = this.value.replace_all("foo","dog")
# In: {"value":"The foo ate my homework"}
# Out: {"new_value":"The dog ate my homework"}
replace_all_many
For each pair of strings in an argument array, replaces all occurrences of the first item of the pair with the second. This is a more compact way of chaining a series of replace_all
methods.
Parameters
values
<array> An array of values, each even value will be replaced with the following odd value.
Examples
root.new_value = this.value.replace_all_many([
"<b>", "<b>",
"</b>", "</b>",
"<i>", "<i>",
"</i>", "</i>",
])
# In: {"value":"<i>Hello</i> <b>World</b>"}
# Out: {"new_value":"<i>Hello</i> <b>World</b>"}
reverse
Returns the target string in reverse order.
Examples
root.reversed = this.thing.reverse()
# In: {"thing":"backwards"}
# Out: {"reversed":"sdrawkcab"}
root = content().reverse()
# In: {"thing":"backwards"}
# Out: }"sdrawkcab":"gniht"{
slice
Extract a slice from a string by specifying two indices, a low and high bound, which selects a half-open range that includes the first character, but excludes the last one. If the second index is omitted then it defaults to the length of the input sequence.
Parameters
low
<integer> The low bound, which is the first element of the selection, or if negative selects from the end.
high
<(optional) integer> An optional high bound.
Examples
root.beginning = this.value.slice(0, 2)
root.end = this.value.slice(4)
# In: {"value":"foo bar"}
# Out: {"beginning":"fo","end":"bar"}
A negative low index can be used, indicating an offset from the end of the sequence. If the low index is greater than the length of the sequence then an empty result is returned.
root.last_chunk = this.value.slice(-4)
root.the_rest = this.value.slice(0, -4)
# In: {"value":"foo bar"}
# Out: {"last_chunk":" bar","the_rest":"foo"}
slug
This method is mostly stable but breaking changes could still be made outside of major version releases if a fundamental problem with it is found.
Creates a "slug" from a given string. Wraps the github.com/gosimple/slug package. See its docs for more information.
Introduced in version 1.0.0.
Parameters
lang
<(optional) string, default "en"
>
Examples
Creates a slug from an English string
root.slug = this.value.slug()
# In: {"value":"Gopher & Bento"}
# Out: {"slug":"gopher-and-bento"}
Creates a slug from a French string
root.slug = this.value.slug("fr")
# In: {"value":"Gaufre & Poisson d'Eau Profonde"}
# Out: {"slug":"gaufre-et-poisson-deau-profonde"}
split
Split a string value into an array of strings by splitting it on a string separator.
Parameters
delimiter
<string> The delimiter to split with.
Examples
root.new_value = this.value.split(",")
# In: {"value":"foo,bar,baz"}
# Out: {"new_value":["foo","bar","baz"]}
strip_html
Attempts to remove all HTML tags from a target string.
Parameters
preserve
<(optional) array> An optional array of element types to preserve in the output.
Examples
root.stripped = this.value.strip_html()
# In: {"value":"<p>the plain <strong>old text</strong></p>"}
# Out: {"stripped":"the plain old text"}
It's also possible to provide an explicit list of element types to preserve in the output.
root.stripped = this.value.strip_html(["article"])
# In: {"value":"<article><p>the plain <strong>old text</strong></p></article>"}
# Out: {"stripped":"<article>the plain old text</article>"}
trim
Remove all leading and trailing characters from a string that are contained within an argument cutset. If no arguments are provided then whitespace is removed.
Parameters
cutset
<(optional) string> An optional string of characters to trim from the target value.
Examples
root.title = this.title.trim("!?")
root.description = this.description.trim()
# In: {"description":" something happened and its amazing! ","title":"!!!watch out!?"}
# Out: {"description":"something happened and its amazing!","title":"watch out"}
trim_prefix
Remove the provided leading prefix substring from a string. If the string does not have the prefix substring, it is returned unchanged.
Introduced in version 1.0.0.
Parameters
prefix
<string> The leading prefix substring to trim from the string.
Examples
root.name = this.name.trim_prefix("foobar_")
root.description = this.description.trim_prefix("foobar_")
# In: {"description":"unchanged","name":"foobar_blobton"}
# Out: {"description":"unchanged","name":"blobton"}
trim_suffix
Remove the provided trailing suffix substring from a string. If the string does not have the suffix substring, it is returned unchanged.
Introduced in version 1.0.0.
Parameters
suffix
<string> The trailing suffix substring to trim from the string.
Examples
root.name = this.name.trim_suffix("_foobar")
root.description = this.description.trim_suffix("_foobar")
# In: {"description":"unchanged","name":"blobton_foobar"}
# Out: {"description":"unchanged","name":"blobton"}
unescape_html
Unescapes a string so that entities like <
become <
. It unescapes a larger range of entities than escape_html
escapes. For example, á
unescapes to á
, as does á
and &xE1;
.
Examples
root.unescaped = this.value.unescape_html()
# In: {"value":"foo & bar"}
# Out: {"unescaped":"foo & bar"}
unescape_url_query
Expands escape sequences from a URL query string.
Examples
root.unescaped = this.value.unescape_url_query()
# In: {"value":"foo+%26+bar"}
# Out: {"unescaped":"foo & bar"}
unquote
Unquotes a target string, expanding any escape sequences (\t
, \n
, \xFF
, \u0100
) for control characters and non-printable characters.
Examples
root.unquoted = this.thing.unquote()
# In: {"thing":"\"foo\\nbar\""}
# Out: {"unquoted":"foo\nbar"}
uppercase
Convert a string value into uppercase.
Examples
root.foo = this.foo.uppercase()
# In: {"foo":"hello world"}
# Out: {"foo":"HELLO WORLD"}
Regular Expressions
re_find_all
Returns an array containing all successive matches of a regular expression in a string.
Parameters
pattern
<string> The pattern to match against.
Examples
root.matches = this.value.re_find_all("a.")
# In: {"value":"paranormal"}
# Out: {"matches":["ar","an","al"]}
re_find_all_object
Returns an array of objects containing all matches of the regular expression and the matches of its subexpressions. The key of each match value is the name of the group when specified, otherwise it is the index of the matching group, starting with the expression as a whole at 0.
Parameters
pattern
<string> The pattern to match against.
Examples
root.matches = this.value.re_find_all_object("a(?P<foo>x*)b")
# In: {"value":"-axxb-ab-"}
# Out: {"matches":[{"0":"axxb","foo":"xx"},{"0":"ab","foo":""}]}
root.matches = this.value.re_find_all_object("(?m)(?P<key>\\w+):\\s+(?P<value>\\w+)$")
# In: {"value":"option1: value1\noption2: value2\noption3: value3"}
# Out: {"matches":[{"0":"option1: value1","key":"option1","value":"value1"},{"0":"option2: value2","key":"option2","value":"value2"},{"0":"option3: value3","key":"option3","value":"value3"}]}
re_find_all_submatch
Returns an array of arrays containing all successive matches of the regular expression in a string and the matches, if any, of its subexpressions.
Parameters
pattern
<string> The pattern to match against.
Examples
root.matches = this.value.re_find_all_submatch("a(x*)b")
# In: {"value":"-axxb-ab-"}
# Out: {"matches":[["axxb","xx"],["ab",""]]}
re_find_object
Returns an object containing the first match of the regular expression and the matches of its subexpressions. The key of each match value is the name of the group when specified, otherwise it is the index of the matching group, starting with the expression as a whole at 0.
Parameters
pattern
<string> The pattern to match against.
Examples
root.matches = this.value.re_find_object("a(?P<foo>x*)b")
# In: {"value":"-axxb-ab-"}
# Out: {"matches":{"0":"axxb","foo":"xx"}}
root.matches = this.value.re_find_object("(?P<key>\\w+):\\s+(?P<value>\\w+)")
# In: {"value":"option1: value1"}
# Out: {"matches":{"0":"option1: value1","key":"option1","value":"value1"}}
re_match
Checks whether a regular expression matches against any part of a string and returns a boolean.
Parameters
pattern
<string> The pattern to match against.
Examples
root.matches = this.value.re_match("[0-9]")
# In: {"value":"there are 10 puppies"}
# Out: {"matches":true}
# In: {"value":"there are ten puppies"}
# Out: {"matches":false}
re_replace_all
Replaces all occurrences of the argument regular expression in a string with a value. Inside the value $ signs are interpreted as submatch expansions, e.g. $1
represents the text of the first submatch.
Parameters
pattern
<string> The pattern to match against.
value
<string> The value to replace with.
Examples
root.new_value = this.value.re_replace_all("ADD ([0-9]+)","+($1)")
# In: {"value":"foo ADD 70"}
# Out: {"new_value":"foo +(70)"}
Number Manipulation
abs
Returns the absolute value of an int64 or float64 number. As a special case, when an integer is provided that is the minimum value it is converted to the maximum value.
Examples
root.outs = this.ins.map_each(ele -> ele.abs())
# In: {"ins":[9,-18,1.23,-4.56]}
# Out: {"outs":[9,18,1.23,4.56]}
ceil
Returns the least integer value greater than or equal to a number. If the resulting value fits within a 64-bit integer then that is returned, otherwise a new floating point number is returned.
Examples
root.new_value = this.value.ceil()
# In: {"value":5.3}
# Out: {"new_value":6}
# In: {"value":-5.9}
# Out: {"new_value":-5}
cos
Calculates the cosine of a given angle specified in radians.
Examples
root.new_value = (this.value * (pi() / 180)).cos()
# In: {"value":45}
# Out: {"new_value":0.7071067811865476}
# In: {"value":0}
# Out: {"new_value":1}
# In: {"value":180}
# Out: {"new_value":-1}
float32
Converts a numerical type into a 32-bit floating point number, this is for advanced use cases where a specific data type is needed for a given component (such as the ClickHouse SQL driver).
If the value is a string then an attempt will be made to parse it as a 32-bit floating point number. Please refer to the strconv.ParseFloat
documentation for details regarding the supported formats.
Examples
root.out = this.in.float32()
# In: {"in":"6.674282313423543523453425345e-11"}
# Out: {"out":6.674283e-11}
float64
Converts a numerical type into a 64-bit floating point number, this is for advanced use cases where a specific data type is needed for a given component (such as the ClickHouse SQL driver).
If the value is a string then an attempt will be made to parse it as a 64-bit floating point number. Please refer to the strconv.ParseFloat
documentation for details regarding the supported formats.
Examples
root.out = this.in.float64()
# In: {"in":"6.674282313423543523453425345e-11"}
# Out: {"out":6.674282313423544e-11}
floor
Returns the greatest integer value less than or equal to the target number. If the resulting value fits within a 64-bit integer then that is returned, otherwise a new floating point number is returned.
Examples
root.new_value = this.value.floor()
# In: {"value":5.7}
# Out: {"new_value":5}
int16
Converts a numerical type into a 16-bit signed integer, this is for advanced use cases where a specific data type is needed for a given component (such as the ClickHouse SQL driver).
If the value is a string then an attempt will be made to parse it as a 16-bit signed integer. If the target value exceeds the capacity of an integer or contains decimal values then this method will throw an error. In order to convert a floating point number containing decimals first use .round()
on the value. Please refer to the strconv.ParseInt
documentation for details regarding the supported formats.
Examples
root.a = this.a.int16()
root.b = this.b.round().int16()
root.c = this.c.int16()
root.d = this.d.int16().catch(0)
# In: {"a":12,"b":12.34,"c":"12","d":-12}
# Out: {"a":12,"b":12,"c":12,"d":-12}
root = this.int16()
# In: "0xDE"
# Out: 222
int32
Converts a numerical type into a 32-bit signed integer, this is for advanced use cases where a specific data type is needed for a given component (such as the ClickHouse SQL driver).
If the value is a string then an attempt will be made to parse it as a 32-bit signed integer. If the target value exceeds the capacity of an integer or contains decimal values then this method will throw an error. In order to convert a floating point number containing decimals first use .round()
on the value. Please refer to the strconv.ParseInt
documentation for details regarding the supported formats.
Examples
root.a = this.a.int32()
root.b = this.b.round().int32()
root.c = this.c.int32()
root.d = this.d.int32().catch(0)
# In: {"a":12,"b":12.34,"c":"12","d":-12}
# Out: {"a":12,"b":12,"c":12,"d":-12}
root = this.int32()
# In: "0xDEAD"
# Out: 57005
int64
Converts a numerical type into a 64-bit signed integer, this is for advanced use cases where a specific data type is needed for a given component (such as the ClickHouse SQL driver).
If the value is a string then an attempt will be made to parse it as a 64-bit signed integer. If the target value exceeds the capacity of an integer or contains decimal values then this method will throw an error. In order to convert a floating point number containing decimals first use .round()
on the value. Please refer to the strconv.ParseInt
documentation for details regarding the supported formats.
Examples
root.a = this.a.int64()
root.b = this.b.round().int64()
root.c = this.c.int64()
root.d = this.d.int64().catch(0)
# In: {"a":12,"b":12.34,"c":"12","d":-12}
# Out: {"a":12,"b":12,"c":12,"d":-12}
root = this.int64()
# In: "0xDEADBEEF"
# Out: 3735928559
int8
Converts a numerical type into a 8-bit signed integer, this is for advanced use cases where a specific data type is needed for a given component (such as the ClickHouse SQL driver).
If the value is a string then an attempt will be made to parse it as a 8-bit signed integer. If the target value exceeds the capacity of an integer or contains decimal values then this method will throw an error. In order to convert a floating point number containing decimals first use .round()
on the value. Please refer to the strconv.ParseInt
documentation for details regarding the supported formats.
Examples
root.a = this.a.int8()
root.b = this.b.round().int8()
root.c = this.c.int8()
root.d = this.d.int8().catch(0)
# In: {"a":12,"b":12.34,"c":"12","d":-12}
# Out: {"a":12,"b":12,"c":12,"d":-12}
root = this.int8()
# In: "0xD"
# Out: 13
log
Returns the natural logarithm of a number.
Examples
root.new_value = this.value.log().round()
# In: {"value":1}
# Out: {"new_value":0}
# In: {"value":2.7183}
# Out: {"new_value":1}
log10
Returns the decimal logarithm of a number.
Examples
root.new_value = this.value.log10()
# In: {"value":100}
# Out: {"new_value":2}
# In: {"value":1000}
# Out: {"new_value":3}
max
Returns the largest numerical value found within an array. All values must be numerical and the array must not be empty, otherwise an error is returned.
Examples
root.biggest = this.values.max()
# In: {"values":[0,3,2.5,7,5]}
# Out: {"biggest":7}
root.new_value = [0,this.value].max()
# In: {"value":-1}
# Out: {"new_value":0}
# In: {"value":7}
# Out: {"new_value":7}
min
Returns the smallest numerical value found within an array. All values must be numerical and the array must not be empty, otherwise an error is returned.
Examples
root.smallest = this.values.min()
# In: {"values":[0,3,-2.5,7,5]}
# Out: {"smallest":-2.5}
root.new_value = [10,this.value].min()
# In: {"value":2}
# Out: {"new_value":2}
# In: {"value":23}
# Out: {"new_value":10}
pow
Returns the number raised to the specified exponent.
Parameters
exponent
<float> The exponent you want to raise to the power of.
Examples
root.new_value = this.value * 10.pow(-2)
# In: {"value":2}
# Out: {"new_value":0.02}
root.new_value = this.value.pow(-2)
# In: {"value":2}
# Out: {"new_value":0.25}
round
Rounds numbers to the nearest integer, rounding half away from zero. If the resulting value fits within a 64-bit integer then that is returned, otherwise a new floating point number is returned.
Examples
root.new_value = this.value.round()
# In: {"value":5.3}
# Out: {"new_value":5}
# In: {"value":5.9}
# Out: {"new_value":6}