<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<font size="4" face="monospace">Let's pull on this string some
more. Assuming we settled on disjoint types and syntaxes, with no
magic conversions, what library support do we need directly for
ST? I am thinking (please, let's focus on the functionality
before we nitpick the names): <br>
<br>
// on String<br>
static join(StringTemplate) // previously STR<br>
<br>
// on StringTemplate<br>
String join() // STR,
instance/suffix version<br>
static StringTemplate join(StringTemplate...) // + for string
templates<br>
<br>
This is a pleasantly short set; is anything missing? (Not
addressing the "which things were previously processors, but now
need API points" right now -- that's a separate discussion.)<br>
</font><br>
<div class="moz-cite-prefix">On 3/18/2024 9:38 AM, Brian Goetz
wrote:<br>
</div>
<blockquote type="cite" cite="mid:4ad249e1-49de-4e83-bf5a-3577e2aaa5df@oracle.com">
I think this has been a good discussion, and it looks like we're
starting to see some convergence. <br>
<br>
I think we keep trying to exploit ambiguity / implicitness, and it
doesn't go well:<br>
<br>
- Many users want STR to be the "implicit processor", but that
isn't good for security<br>
- We tried reusing the String delimiters for string templates to
reduce the perception of how many different things there are here,
but that creates cognitive load (can't tell strings from templates
without parsing the entire contents), among other problems<br>
- We tried making String a poly expression (and other tricks) to
reduce the number of explicit conversions, but that created
problems too<br>
<br>
John's characterization captures the feeling and eventual
conclusion that I think many of us share: <br>
<br>
<blockquote type="cite">
<pre class="moz-quote-pre" wrap="">I kind of like Guy’s offensive-to-everyone suggestion that $ is required to make a true ST. </pre>
</blockquote>
<br>
Indeed, my first reaction to the $ sigil was "please no", but I am
grudgingly coming to the conclusion that we should stop trying to
implicitly "just figure out what the user wants" and acknowledge
the reality: templates are not strings, strings are not templates,
and they can be converted to each other with ... methods, just
like any other relatable types. So string literals are as they
always were; string templates are a new thing, whose syntax and
type is disjoint from that of strings, as Guy also seems to be
converging on:<br>
<br>
<blockquote type="cite">
<div>And now that I have that better understanding, I think I
lean toward (a) abandoning string interpolation and (b) having
a single, short, _non-optional_ prefix for templates (“$”
would be a plausible choice), on the grounds that I think it
makes code more readable if templates are always distinguished
up front from strings—and this is especially helpful when the
templates are rather long and any `\{` present might be far
from the beginning. It has a minimal number of cases to
explain:</div>
<div><br>
</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>“…”
string literal, must not contain \{…}, type String</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>$”…”
template literal, may contain \{…}, type StringTemplate</div>
</blockquote>
<br>
(concrete syntax TBB (to be bikeshod), along with the spellings of
S -> ST and ST -> S.) <br>
<br>
Some more useful observations: <br>
<br>
- The toString behavior cannot be mere interpolation. Besides
the principled objections and inevitable
propping-open-the-security-door that this would lead to, people
will quickly learn to abuse "" + ST as the "fewest characters
required" way to get interpolation, which is "clever" in the same
way that John's "empty \{}" trick is clever, but not good for
clarity. <br>
- We need a story to tell for how to write good overloads, which
seems to be more subtle than initially thought.<br>
- If the only way to make a StringTemplate is the literal syntax,
then STs gain a valuable security property: all fragments in the
ST are strings that appeared literally in code, and therefore
untainted. This is probably too restrictive but we should be
aware of what we are giving up as we explore the API options.<br>
- Processors should be encouraged to "flatten" embedded STs.<br>
<br>
A few people have implied that only the tainted parts of an ST
(the embedded expressions) need special processing, but I'll point
out that the untainted parts may often require domain-specific
validation. For example, a ST representing a SQL query wants
balanced quotes, and might want to require quotes around embedded
expressions. <br>
<br>
<br>
<br>
<div class="moz-cite-prefix">On 3/8/2024 1:35 PM, Brian Goetz
wrote:<br>
</div>
<blockquote type="cite" cite="mid:8EF82E14-DDF9-48A2-8CAE-7E7DC3C2AC9F@oracle.com"> <br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">Time to check in with where were are with String
Templates. We’ve gone through two rounds of preview, and have
received some feedback. </span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<font class="" color="#000000">As a reminder, the primary goal
of gathering feedback is to learn things about the design or
implementation that we don’t already know. This could be bug
reports, experience reports, code review, careful analysis,
novel alternatives, etc. And the best feedback usually
comes from using the feature “in anger” — trying to actually
write code with it. </font><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">(“Some people would prefer a different syntax”
or “some people would prefer we focused on string
interpolation only” fall squarely in the “things we already
knew” camp.) </span>
<div class=""><font class="" color="#000000"><span style="caret-color: rgb(0, 0, 0);" class=""><br class="">
</span></font>
<div class="">
<div class=""><font class="" color="#000000">In the course
of using this feature in the `jextract` project, we did
learn quite a few things we didn’t already know, and
this was conclusive enough that it has motivated us to
adjust our approach in this feature. Specifically, the
role of processors is “outsized” to the value they
offer, and, after further exploration, we now believe it
is possible to achieve the goals of the feature without
an explicit “processor” abstraction at all! This is a
very positive development. </font><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">First, I want to affirm that that the goals of
the project have not changed. From JEP 459:</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">Goals</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span class="Apple-tab-span" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); white-space: pre;"></span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">• Simplify the writing of Java programs by
making it easy to express strings that include values
computed at run time.</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span class="Apple-tab-span" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); white-space: pre;"></span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">• Enhance the readability of expressions that
mix text and expressions, whether the text fits on a
single source line (as with string literals) or spans
several source lines (as with text blocks).</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span class="Apple-tab-span" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); white-space: pre;"></span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">• Improve the security of Java programs that
compose strings from user-provided values and pass them
to other systems (e.g., building queries for databases)
by supporting validation and transformation of both the
template and the values of its embedded expressions.</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span class="Apple-tab-span" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); white-space: pre;"></span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">• Retain flexibility by allowing Java libraries
to define the formatting syntax used in string
templates.</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span class="Apple-tab-span" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); white-space: pre;"></span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">• Simplify the use of APIs that accept strings
written in non-Java languages (e.g., SQL, XML, and
JSON).</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span class="Apple-tab-span" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); white-space: pre;"></span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">• Enable the creation of non-string values
computed from literal text and embedded expressions
without having to transit through an intermediate string
representation.</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">Non-Goals</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span class="Apple-tab-span" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); white-space: pre;"></span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">• It is not a goal to introduce syntactic sugar
for Java's string concatenation operator (+), since that
would circumvent the goal of validation.</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span class="Apple-tab-span" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); white-space: pre;"></span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">• It is not a goal to deprecate or remove the
StringBuilder and StringBuffer classes, which have
traditionally been used for complex or programmatic
string composition.</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">Another thing that has not changed is our view
on the syntax for embedding expressions. While many
people did express the opinion of “why not ‘just' do
what Kotlin/Scala does”, this issue was more than fully
explored during the initial design round. (In fact,
while syntax disagreements are often purely subjective,
this one was far more clear — the $-syntax is
objectively worse, and would be doubly so if injected
into an existing language where there were already
string literals in the wild. This has all been more
than adequately covered elsewhere, so I won’t rehash it
here.)</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">Now, let’s talk about what we do think should
change: the role of processors and the StringTemplate
type. </span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<font class="" color="#000000">Processors were envisioned
as a means to abstract the transformation of templates
to their final form (whether string, or something else.)
However, Java already has a well established means of
abstracting behavior: methods. (In fact, a processor
application can be viewed as merely a new syntax for a
method call.) Our experience using the feature
highlighted the question: When converting a SQL query
expressed as a template to the form required by the
database (such as PreparedStatement), why do we need to
say:</font><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""> DB.”… template …”</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">When we could use an ordinary Java library:</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""> Query q = Query.of(“…template…”)</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<font class="" color="#000000">Indeed, one of the worst
things about having processors in the language is that
API designers are put in the difficult situation of not
knowing whether to write a processor or an ordinary API,
and often have to make that choice before the
consequences are fully understood. (To add to this,
processors raise similar questions at the use site.) But
the real criticism here is that template capture and
processing are complected, when they should be separate,
composable features. </font><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">This motivated us to revisit some of the
reasons why processors were so central to the initial
design in the first place. And it turned out, this
choice had been influenced — perhaps overly so — by
early implementation experiments. (One of the
background design goals was to enable expensive
operations like `String::format` to be (much) cheaper.
Without digressing too deeply on performance,
String::format can be more than an order of magnitude
worse than the equivalent concatenation operation, and
this in turn sometimes motivates developers to use worse
idioms for formatting. The FMT processor brough that
cost back in line with the equivalent concatenation.)
These early experiments biased the design towards
needing to know the processor at the point of template
capture, but upon reexamination we realized that there
are other ways to achieve the desired performance goals
without requiring processors to be known at capture
time. This, in turn, enabled us to revisit a point in
the design space we had transited through earlier, where
string templates were “just a new kind of literal” and
the job performed by processors could instead be
performed by ordinary APIs.</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">At this point, a simpler design and
implementation emerged that met the semantic,
correctness, and performance goals: template literals
(“Hello \{name}”) are simply the literal form of
StringTemplate:</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<font class="" color="#000000"><span style="caret-color: rgb(0, 0, 0);" class=""> StringTemplate
st = “Hello \{name}”;</span></font><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<font class="" color="#000000"><span style="caret-color: rgb(0, 0, 0);" class="">String and
StringTemplate remain unrelated types. (We explored a
number of ways to interconvert them, but they caused
more trouble than they solved.) Processing of string
templates, including interpolation, is done by
ordinary APIs that deal in StringTemplate, aided by
some clever implementation tricks to ensure good
performance. </span></font></div>
<div class=""><font class="" color="#000000"><span style="caret-color: rgb(0, 0, 0);" class=""><br class="">
</span></font></div>
<div class=""><font class="" color="#000000"><span style="caret-color: rgb(0, 0, 0);" class="">For APIs
where interpolation is known to be safe in the domain,
such as PrintWriter, APIs can make that choice on
behalf of the domain, by providing overloads to embody
this design choice: </span></font><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""> void println(String) { … }</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<font class="" color="#000000"> void
println(StringTemplate) { … interpolate and delegate to
println(String) …. }</font><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">The upshot is that for interpolation-safe APIs
like println, we can use a template directly without
giving up any safety:</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""> System.out.println(“Hello \{name}”);</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br class="">
In this example, the string template evaluates to
StringTemplate, not String (no implicit interpolation),
and chooses the StringTemplate overload of println, which
in turn chooses how to process the template. <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">This stays true to the design principle that
interpolation is dangerous enough that it should be an
explicit choice in the code — but it allows that choice
to be made by libraries when the library is comfortable
doing so. </span></div>
<div class=""><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">Similarly, the FMT processor is replaced by an
overload of String::format that interprets templates
with embedded format specifiers (e.g., “%d”):</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""> String format(String formatString, Object…
parameters) { … same as today … }</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""> String format(StringTemplate template) {...
equivalent of FMT ...}</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">And users can call this as:</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""> String s = String.format(“Hello
%12s\{name}”);</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<font class="" color="#000000"><span style="caret-color: rgb(0, 0, 0);" class="">Here, the
String::format API has chosen to interpret string
templates according to the rules previously specified
in the FMT processor (not ordinary interpolation), but
that choice is embedded in the library semantics so no
further explicit choice at the use site is required.
The user already chose to pass it to String::format;
that’s all the processing selection that is needed. </span></font><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">Where APIs do not express a choice of what
template expansion means, users continue to be free to
process them explicitly before passing them, using APIs
that do (such as String::format or ordinary
interpolation.). </span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">The result is:</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">- The need for use-site "goop" (previously, the
processor name; now, static or instance methods to
process a template) goes away entirely when dealing with
libraries that are already template-friendly. </span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">- Even with libraries that require use-site
goop, it is no more intrusive than before, and can be
reduced over time as APIs get with the program. </span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">- StringTemplate is just another type that APIs
can support if they want. The "DB" processor becomes an
ordinary factory method that accepts a string template
or an ordinary builder API. </span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">- APIs now can have _more_ control over the
timing and meaning of template processing, because we
are not biasing so strongly towards early processing.</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">- It becomes easier to abstract over template
processing (i.e., combine or manipulate templates as
templates before processing)</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">- Interpolation remains an explicit choice, but
ST-aware libraries can make this choice on behalf of the
user.</span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">- The language feature and API surface get
considerably smaller, which is good. Core JDK APIs
(e.g., println, format, exception constructors) get
upgraded to work with string templates. </span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">The remaining question that everyone is
probably asking is: “so how do we do interpolation.”
The answer there is “ordinary library methods”. This
might be a static method (String.join(StringTemplate))
or an instance method (template.join()), shed to be
painted (but please, not right now.). </span><br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<br style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">
<font class="" color="#000000"><span style="caret-color: rgb(0, 0, 0);" class="">This is a
sketch of direction, so feel free to pose
questions/comments on the direction. We’ll discuss
the details as we go. </span></font></div>
</div>
</div>
<div class=""><font class="" color="#000000"><span style="caret-color: rgb(0, 0, 0);" class=""><br class="">
</span></font></div>
<div class=""><font class="" color="#000000"><span style="caret-color: rgb(0, 0, 0);" class=""><br class="">
</span></font></div>
</blockquote>
<br>
</blockquote>
<br>
</body>
</html>