<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <div class="markdown-here-wrapper" data-md-url="" style="">
      <p style="margin: 0px 0px 1.2em !important;">On 02/02/2023 13:15,
        <a class="moz-txt-link-abbreviated" href="mailto:radek@smogura.eu">radek@smogura.eu</a> wrote:</p>
      <blockquote style="margin: 1.2em 0px;border-left: 4px solid
        rgb(221, 221, 221); padding: 0px 1em; color: rgb(119, 119, 119);
        quotes: none;">
        <p style="margin: 0px 0px 1.2em !important;">Hi Maurizio,</p>
        <p style="margin: 0px 0px 1.2em !important;">Thank you for
          sharing this. I agree that there’s a tension between<br>
          Scope and Arena, and for i.e. passing Arena to
          FileChannel::map look<br>
          bit like we pass too big object there.</p>
        <p style="margin: 0px 0px 1.2em !important;">I just thought
          (sorry if it was proposed somewhere else), to<br>
          introduce supporting object Scopable (can’t imagine better
          name on<br>
          short notice). So something which can have a scope (own -
          freshly<br>
          generated or shared in some way).</p>
        <p style="margin: 0px 0px 1.2em !important;">The Scopable would
          have single method scope(), and for simplicity<br>
          Scope could be Scopable returning “this”.</p>
        <p style="margin: 0px 0px 1.2em !important;">If MemorySegment
          should be Scopable - I don’t know - as there’s next<br>
          issue of allocating segments which are dependent in some way
          and<br>
          deallocation should be executed in order.</p>
      </blockquote>
      <p style="margin: 0px 0px 1.2em !important;">Hi Rado,<br>
        Thanks for the comments. Having a common interface for all
        things with a scope accessor is possible, and something we have
        considered to bring Arena and SegmentScope under the same
        umbrella.</p>
      <p style="margin: 0px 0px 1.2em !important;">The main problem
        though, is where do you put the “allocate” method. It is
        unfortunate that, in the Java 20 API, there are <em>three</em>
        ways to allocate a native segment:</p>
      <pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">MemorySegment.allocateNative(100, arena.scope()) // 1

arena.allocate(100) // 2

SegmentAllocator.nativeAllocator(arena.scope()).allocate(100); // 3
</code></pre>
      <p style="margin: 0px 0px 1.2em !important;">This seems overkill,
        and adding an interface on top of Arena and SegmentScope doesn’t
        help much. Well, Scopeable might also extend SegmentAllocator,
        so you can do:</p>
      <pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">SegmentScope.auto().allocate(100)
</code></pre>
      <p style="margin: 0px 0px 1.2em !important;">But now this creates
        an issue: if a scope is an allocator, then an Arena provides <em>two</em>
        allocators: the allocator in its “allocate” method, and the
        “fallback” allocator, available accessing the arena’s scope.</p>
      <p style="margin: 0px 0px 1.2em !important;">This seemed overly
        confusing.</p>
      <p style="margin: 0px 0px 1.2em !important;">There’s also another
        aspect in this: what we call SegmentScope.auto() really does act
        as an arena (as the document explains) - just one that cannot be
        closed explicitly. So having too much splitting in the API seems
        to create unnecessary asymmetries and non-orthogonality.</p>
      <p style="margin: 0px 0px 1.2em !important;">Once you embrace the
        fact that Arena is your unit of allocation for native segments,
        everything becomes easier. In the API proposed in the document
        there is now only <em>one</em> way to allocate a native
        segment, namely Arena::allocate.</p>
      <p style="margin: 0px 0px 1.2em !important;">P.S.</p>
      <p style="margin: 0px 0px 1.2em !important;">Related to this, we
        also considered adding a Scopeable/Scoped interface (implemented
        by MemorySegment) instead of a separate “Scope” interface. While
        initially appealing, as:</p>
      <pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">segment.isAlive()
</code></pre>
      <p style="margin: 0px 0px 1.2em !important;">Seems better than:</p>
      <pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">segment.scope().isAlive()
</code></pre>
      <p style="margin: 0px 0px 1.2em !important;">That approach starts
        running out of gas when you consider things like “how do you
        compare the lifetime of two Scoped/Scopeable” ? You can’t use
        “equals” (as equals on MemorySegment means something else) - so
        you end up with something like this:</p>
      <pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">segment.isLifetimeEquals(....)
</code></pre>
      <p style="margin: 0px 0px 1.2em !important;">or, if we also
        consider lifetime containment:</p>
      <pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">segment.isLifetimeContainedBy(....)
</code></pre>
      <p style="margin: 0px 0px 1.2em !important;">Both of which seems
        less direct than:</p>
      <pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">segment.scope().equals(...)
</code></pre>
      <p style="margin: 0px 0px 1.2em !important;">or</p>
      <pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">segment.scope().containedBy(...)
</code></pre>
      <p style="margin: 0px 0px 1.2em !important;">On top of that, since
        now Arena does not have a scope, but <em>is</em> a scope, we
        need to make arena an abstract class, which somewhat limits
        extension options for clients.</p>
      <p style="margin: 0px 0px 1.2em !important;">So we have concluded
        that keeping a small scope interface off to the side
        (MemorySegment.Scope) represented the most pragmatic compromise.</p>
      <p style="margin: 0px 0px 1.2em !important;">Maurizio</p>
      <blockquote style="margin: 1.2em 0px;border-left: 4px solid
        rgb(221, 221, 221); padding: 0px 1em; color: rgb(119, 119, 119);
        quotes: none;">
        <p style="margin: 0px 0px 1.2em !important;">Kind regards,
          Radosław Smogura</p>
        <blockquote style="margin: 1.2em 0px;border-left: 4px solid
          rgb(221, 221, 221); padding: 0px 1em; color: rgb(119, 119,
          119); quotes: none;">
          <p style="margin: 0px 0px 1.2em !important;">On 31 Jan 2023,
            at 19:46, Maurizio Cimadamore</p>
          <p style="margin: 0px 0px 1.2em !important;"><a href="http://mailto:maurizio.cimadamore@oracle.com">maurizio.cimadamore@oracle.com</a>
            wrote:</p>
          <p style="margin: 0px 0px 1.2em !important;">Hi, as discussed
            here [1], it is not clear as to whether Java 20<br>
            iteration of the Foreign Function & Memory API (FFM API)
            has yet<br>
            reached bottom, especially when it comes to managing the
            lifetime<br>
            of the regions of memory backing memory segments. After
            collecting<br>
            some rounds of internal and external feedback, it was clear
            that<br>
            while the Java 20 API has all the functionalities we require
            for<br>
            writing efficient and robust native interop code, some of
            the<br>
            concepts in the API were made a bit harder to grok, as users
            had to<br>
            choose between two toplevel abstractions, namely <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">SegmentScope</code>
            and<br>
            <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>.
            This choice is made even more difficult, as some of the<br>
            functionalities (e.g. allocation) is duplicated in both API
            points.<br>
            As a result, we have been busy exploring different ways to
            restack<br>
            the FFM API in search of something more approachable.</p>
          <p style="margin: 0px 0px 1.2em !important;">The results of
            our findings are described in this document:</p>
          <p style="margin: 0px 0px 1.2em !important;"><a href="http://cr.openjdk.java.net/~mcimadamore/panama/scoped_arenas.html" class="moz-txt-link-freetext">http://cr.openjdk.java.net/~mcimadamore/panama/scoped_arenas.html</a></p>
          <p style="margin: 0px 0px 1.2em !important;">Here, we propose
            a possible simplification of the FFM API, where we<br>
            make <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>
            the true star of the show, which results in the<br>
            following changes:</p>
          <ul style="margin: 1.2em 0px;padding-left: 2em;">
            <li style="margin: 0.5em 0px;">factories such as <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">SegmentScope::auto</code>
              are now moved to <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>;
            </li>
            <li style="margin: 0.5em 0px;">all segment-producing methods
              (such as <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">FileChannel::map</code>)
              now<br>
              accept an <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>
              parameter; <em> static factories such as<br>
                <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">MemorySegment::allocateNative</code>
                have been dropped; </em> scopes are<br>
              made less prominent, and moved to a nested class<br>
              (<code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">MemorySegment.Scope</code>).</li>
          </ul>
          <p style="margin: 0px 0px 1.2em !important;">This gives us a
            remarkably simple API, which brings together the<br>
            best aspects of the Java 19 and Java 20 FFM API iterations.
            On the<br>
            one hand, <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>
            is now the most important abstraction that users<br>
            of the FFM API have to deal with (in a way, <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>
            is the new<br>
            <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">MemorySession</code>);
            at the same time, we still have a way to model<br>
            the lifetime of an <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>
            (and all the segments allocated by it)<br>
            using a <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">MemorySegment.Scope</code>
            - which is desirable both in terms of<br>
            debugging (e.g. inspecting whether two segments/arenas have
            the<br>
            same lifetime) and, more importantly, in terms of allowing
            the<br>
            definition of custom arenas via simple delegation (as in
            Java 20).</p>
          <p style="margin: 0px 0px 1.2em !important;">As always,
            feedback is welcome. While this proposal does not<br>
            significantly alter the expressiveness of the FFM API, the
            proposed<br>
            API comes with some limitations. For instance, since all
            allocation<br>
            routines are now <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>-centric
            (see above), it is no longer<br>
            possible to allocate a new segment if a corresponding arena
            is not<br>
            available (we call this co-allocation). As explained in the<br>
            document, while it would be possible to add back the missing<br>
            co-allocation functionality, extensive analysis of the code
            using<br>
            the FFM API has shown co-allocation to be <em>extremely</em>
            rare (**) -<br>
            and of dubious value. For these reasons, we would like to
            aim for a<br>
            more principled approach which avoids co-allocation
            altogether, and<br>
            allows for more encapsulation of the capabilities associated
            with<br>
            an <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>
            object.</p>
          <p style="margin: 0px 0px 1.2em !important;">Maurizio</p>
          <p style="margin: 0px 0px 1.2em !important;">(**) We have only
            found <em>one</em> usage [2] in over 10K Java files and<br>
            more than 11M LoC analyzed. Moreover, this usage is only
            present in<br>
            the Java 19 branch of the project, and removed in the “main”
            branch<br>
            (which tracks the Java 20 FFM API). We suspect that this use
            of<br>
            co-allocation has been made irrelevant after the unification
            of<br>
            <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">MemoryAddress</code>
            and <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">MemorySegment</code>.</p>
          <p style="margin: 0px 0px 1.2em !important;">[1] -<br>
            <a href="https://mail.openjdk.org/pipermail/panama-dev/2022-December/018182.html" class="moz-txt-link-freetext">https://mail.openjdk.org/pipermail/panama-dev/2022-December/018182.html</a></p>
          <p style="margin: 0px 0px 1.2em !important;">[2] - <a href="https://urldefense.com/v3/__https://github.com/boulder-on/JPassport/blob/Java_19/jpassport/src/main/java/jpassport/Utils.java*L418__;Iw!!ACWV5N9M2RV99hQ!N83lUkxsLt0-52DJ28iFtyghkVYTBrkIqpba_S_rHp-LgkOjS11XHE2aNR0-4t77U_S3UqP_HU-K1tufeLRhfQs$" class="moz-txt-link-freetext">https://urldefense.com/v3/__https://github.com/boulder-on/JPassport/blob/Java_19/jpassport/src/main/java/jpassport/Utils.java*L418__;Iw!!ACWV5N9M2RV99hQ!N83lUkxsLt0-52DJ28iFtyghkVYTBrkIqpba_S_rHp-LgkOjS11XHE2aNR0-4t77U_S3UqP_HU-K1tufeLRhfQs$</a>
          </p>
        </blockquote>
      </blockquote>
      <div title="MDH:PGJyPk9uIDAyLzAyLzIwMjMgMTM6MTUsIHJhZGVrQHNtb2d1cmEuZXUgd3JvdGU6PGJyPjxzcGFuIHN0eWxlPSJ3aGl0ZS1zcGFjZTogcHJlLXdyYXA7IGRpc3BsYXk6IGJsb2NrOyB3aWR0aDogOTh2
dzsiPiZndDsgSGkgTWF1cml6aW8sPGJyPiZndDsgPGJyPiZndDsgVGhhbmsgeW91IGZvciBzaGFy
aW5nIHRoaXMuIEkgYWdyZWUgdGhhdCB0aGVyZeKAmXMgYSB0ZW5zaW9uIGJldHdlZW48YnI+Jmd0
OyBTY29wZSBhbmQgQXJlbmEsIGFuZCBmb3IgaS5lLiBwYXNzaW5nIEFyZW5hIHRvIEZpbGVDaGFu
bmVsOjptYXAgbG9vazxicj4mZ3Q7IGJpdCBsaWtlIHdlIHBhc3MgdG9vIGJpZyBvYmplY3QgdGhl
cmUuPGJyPiZndDsgPGJyPiZndDsgSSBqdXN0IHRob3VnaHQgKHNvcnJ5IGlmIGl0IHdhcyBwcm9w
b3NlZCBzb21ld2hlcmUgZWxzZSksIHRvPGJyPiZndDsgaW50cm9kdWNlIHN1cHBvcnRpbmcgb2Jq
ZWN0IFNjb3BhYmxlIChjYW7igJl0IGltYWdpbmUgYmV0dGVyIG5hbWUgb248YnI+Jmd0OyBzaG9y
dCBub3RpY2UpLiBTbyBzb21ldGhpbmcgd2hpY2ggY2FuIGhhdmUgYSBzY29wZSAob3duIC0gZnJl
c2hseTxicj4mZ3Q7IGdlbmVyYXRlZCBvciBzaGFyZWQgaW4gc29tZSB3YXkpLjxicj4mZ3Q7IDxi
cj4mZ3Q7IFRoZSBTY29wYWJsZSB3b3VsZCBoYXZlIHNpbmdsZSBtZXRob2Qgc2NvcGUoKSwgYW5k
IGZvciBzaW1wbGljaXR5PGJyPiZndDsgU2NvcGUgY291bGQgYmUgU2NvcGFibGUgcmV0dXJuaW5n
IOKAnHRoaXMiLjxicj4mZ3Q7IDxicj4mZ3Q7IElmIE1lbW9yeVNlZ21lbnQgc2hvdWxkIGJlIFNj
b3BhYmxlIC0gSSBkb27igJl0IGtub3cgLSBhcyB0aGVyZeKAmXMgbmV4dDxicj4mZ3Q7IGlzc3Vl
IG9mIGFsbG9jYXRpbmcgc2VnbWVudHMgd2hpY2ggYXJlIGRlcGVuZGVudCBpbiBzb21lIHdheSBh
bmQ8YnI+Jmd0OyBkZWFsbG9jYXRpb24gc2hvdWxkIGJlIGV4ZWN1dGVkIGluIG9yZGVyLjxicj48
L3NwYW4+PGJyPkhpIFJhZG8sPGJyPlRoYW5rcyBmb3IgdGhlIGNvbW1lbnRzLiBIYXZpbmcgYSBj
b21tb24gaW50ZXJmYWNlIGZvciBhbGwgdGhpbmdzIHdpdGggYSBzY29wZSBhY2Nlc3NvciBpcyBw
b3NzaWJsZSwgYW5kIHNvbWV0aGluZyB3ZSBoYXZlIGNvbnNpZGVyZWQgdG8gYnJpbmcgQXJlbmEg
YW5kIFNlZ21lbnRTY29wZSB1bmRlciB0aGUgc2FtZSB1bWJyZWxsYS48YnI+PGJyPlRoZSBtYWlu
IHByb2JsZW0gdGhvdWdoLCBpcyB3aGVyZSBkbyB5b3UgcHV0IHRoZSAiYWxsb2NhdGUiIG1ldGhv
ZC4gSXQgaXMgdW5mb3J0dW5hdGUgdGhhdCwgaW4gdGhlIEphdmEgMjAgQVBJLCB0aGVyZSBhcmUg
X3RocmVlXyB3YXlzIHRvIGFsbG9jYXRlIGEgbmF0aXZlIHNlZ21lbnQ6PGJyPjxicj5gYGA8YnI+
TWVtb3J5U2VnbWVudC5hbGxvY2F0ZU5hdGl2ZSgxMDAsIGFyZW5hLnNjb3BlKCkpIC8vIDE8YnI+
PGJyPmFyZW5hLmFsbG9jYXRlKDEwMCkgLy8gMjxicj48YnI+U2VnbWVudEFsbG9jYXRvci5uYXRp
dmVBbGxvY2F0b3IoYXJlbmEuc2NvcGUoKSkuYWxsb2NhdGUoMTAwKTsgLy8gMzxicj5gYGA8YnI+
PGJyPlRoaXMgc2VlbXMgb3ZlcmtpbGwsIGFuZCBhZGRpbmcgYW4gaW50ZXJmYWNlIG9uIHRvcCBv
ZiBBcmVuYSBhbmQgU2VnbWVudFNjb3BlIGRvZXNuJ3QgaGVscCBtdWNoLiBXZWxsLCBTY29wZWFi
bGUgbWlnaHQgYWxzbyBleHRlbmQgU2VnbWVudEFsbG9jYXRvciwgc28geW91IGNhbiBkbzo8YnI+
PGJyPmBgYDxicj5TZWdtZW50U2NvcGUuYXV0bygpLmFsbG9jYXRlKDEwMCk8YnI+YGBgPGJyPjxi
cj5CdXQgbm93IHRoaXMgY3JlYXRlcyBhbiBpc3N1ZTogaWYgYSBzY29wZSBpcyBhbiBhbGxvY2F0
b3IsIHRoZW4gYW4gQXJlbmEgcHJvdmlkZXMgX3R3b18gYWxsb2NhdG9yczogdGhlIGFsbG9jYXRv
ciBpbiBpdHMgImFsbG9jYXRlIiBtZXRob2QsIGFuZCB0aGUgImZhbGxiYWNrIiBhbGxvY2F0b3Is
IGF2YWlsYWJsZSBhY2Nlc3NpbmcgdGhlIGFyZW5hJ3Mgc2NvcGUuPGJyPjxicj5UaGlzIHNlZW1l
ZCBvdmVybHkgY29uZnVzaW5nLjxicj48YnI+VGhlcmUncyBhbHNvIGFub3RoZXIgYXNwZWN0IGlu
IHRoaXM6IHdoYXQgd2UgY2FsbCBTZWdtZW50U2NvcGUuYXV0bygpIHJlYWxseSBkb2VzIGFjdCBh
cyBhbiBhcmVuYSAoYXMgdGhlIGRvY3VtZW50IGV4cGxhaW5zKSAtIGp1c3Qgb25lIHRoYXQgY2Fu
bm90IGJlIGNsb3NlZCBleHBsaWNpdGx5LiBTbyBoYXZpbmcgdG9vIG11Y2ggc3BsaXR0aW5nIGlu
IHRoZSBBUEkgc2VlbXMgdG8gY3JlYXRlIHVubmVjZXNzYXJ5IGFzeW1tZXRyaWVzIGFuZCBub24t
b3J0aG9nb25hbGl0eS48YnI+PGJyPk9uY2UgeW91IGVtYnJhY2UgdGhlIGZhY3QgdGhhdCBBcmVu
YSBpcyB5b3VyIHVuaXQgb2YgYWxsb2NhdGlvbiBmb3IgbmF0aXZlIHNlZ21lbnRzLCBldmVyeXRo
aW5nIGJlY29tZXMgZWFzaWVyLiBJbiB0aGUgQVBJIHByb3Bvc2VkIGluIHRoZSBkb2N1bWVudCB0
aGVyZSBpcyBub3cgb25seSBfb25lXyB3YXkgdG8gYWxsb2NhdGUgYSBuYXRpdmUgc2VnbWVudCwg
bmFtZWx5IEFyZW5hOjphbGxvY2F0ZS48YnI+PGJyPlAuUy48YnI+PGJyPlJlbGF0ZWQgdG8gdGhp
cywgd2UgYWxzbyBjb25zaWRlcmVkIGFkZGluZyBhIFNjb3BlYWJsZS9TY29wZWQgaW50ZXJmYWNl
IChpbXBsZW1lbnRlZCBieSBNZW1vcnlTZWdtZW50KSBpbnN0ZWFkIG9mIGEgc2VwYXJhdGUgIlNj
b3BlIiBpbnRlcmZhY2UuIFdoaWxlIGluaXRpYWxseSBhcHBlYWxpbmcsIGFzOjxicj48YnI+YGBg
PGJyPnNlZ21lbnQuaXNBbGl2ZSgpPGJyPmBgYDxicj48YnI+U2VlbXMgYmV0dGVyIHRoYW46PGJy
Pjxicj5gYGA8YnI+c2VnbWVudC5zY29wZSgpLmlzQWxpdmUoKTxicj5gYGA8YnI+PGJyPlRoYXQg
YXBwcm9hY2ggc3RhcnRzIHJ1bm5pbmcgb3V0IG9mIGdhcyB3aGVuIHlvdSBjb25zaWRlciB0aGlu
Z3MgbGlrZSAiaG93IGRvIHlvdSBjb21wYXJlIHRoZSBsaWZldGltZSBvZiB0d28gU2NvcGVkL1Nj
b3BlYWJsZSIgPyBZb3UgY2FuJ3QgdXNlICJlcXVhbHMiIChhcyBlcXVhbHMgb24gTWVtb3J5U2Vn
bWVudCBtZWFucyBzb21ldGhpbmcgZWxzZSkgLSBzbyB5b3UgZW5kIHVwIHdpdGggc29tZXRoaW5n
IGxpa2UgdGhpczo8YnI+PGJyPmBgYDxicj5zZWdtZW50LmlzTGlmZXRpbWVFcXVhbHMoLi4uLik8
YnI+YGBgPGJyPjxicj5vciwgaWYgd2UgYWxzbyBjb25zaWRlciBsaWZldGltZSBjb250YWlubWVu
dDo8YnI+PGJyPmBgYDxicj5zZWdtZW50LmlzTGlmZXRpbWVDb250YWluZWRCeSguLi4uKTxicj5g
YGA8YnI+PGJyPkJvdGggb2Ygd2hpY2ggc2VlbXMgbGVzcyBkaXJlY3QgdGhhbjo8YnI+PGJyPmBg
YDxicj5zZWdtZW50LnNjb3BlKCkuZXF1YWxzKC4uLik8YnI+YGBgPGJyPjxicj5vcjxicj48YnI+
YGBgPGJyPnNlZ21lbnQuc2NvcGUoKS5jb250YWluZWRCeSguLi4pPGJyPmBgYDxicj48YnI+T24g
dG9wIG9mIHRoYXQsIHNpbmNlIG5vdyBBcmVuYSBkb2VzIG5vdCBoYXZlIGEgc2NvcGUsIGJ1dCBf
aXNfIGEgc2NvcGUsIHdlIG5lZWQgdG8gbWFrZSBhcmVuYSBhbiBhYnN0cmFjdCBjbGFzcywgd2hp
Y2ggc29tZXdoYXQgbGltaXRzIGV4dGVuc2lvbiBvcHRpb25zIGZvciBjbGllbnRzLjxicj48YnI+
U28gd2UgaGF2ZSBjb25jbHVkZWQgdGhhdCBrZWVwaW5nIGEgc21hbGwgc2NvcGUgaW50ZXJmYWNl
IG9mZiB0byB0aGUgc2lkZSAoTWVtb3J5U2VnbWVudC5TY29wZSkgcmVwcmVzZW50ZWQgdGhlIG1v
c3QgcHJhZ21hdGljIGNvbXByb21pc2UuPGJyPjxicj5NYXVyaXppbzxicj48YnI+PGJyPjxzcGFu
IHN0eWxlPSJ3aGl0ZS1zcGFjZTogcHJlLXdyYXA7IGRpc3BsYXk6IGJsb2NrOyB3aWR0aDogOTh2
dzsiPiZndDsgS2luZCByZWdhcmRzLCBSYWRvc8WCYXcgU21vZ3VyYTxicj4mZ3Q7IDxicj4mZ3Q7
Jmd0OyBPbiAzMSBKYW4gMjAyMywgYXQgMTk6NDYsIE1hdXJpemlvIENpbWFkYW1vcmU8YnI+Jmd0
OyZndDsgJmx0O21hdXJpemlvLmNpbWFkYW1vcmVAb3JhY2xlLmNvbSZndDsgd3JvdGU6PGJyPiZn
dDsmZ3Q7IDxicj4mZ3Q7Jmd0OyBIaSwgYXMgZGlzY3Vzc2VkIGhlcmUgWzFdLCBpdCBpcyBub3Qg
Y2xlYXIgYXMgdG8gd2hldGhlciBKYXZhIDIwPGJyPiZndDsmZ3Q7IGl0ZXJhdGlvbiBvZiB0aGUg
Rm9yZWlnbiBGdW5jdGlvbiAmYW1wOyBNZW1vcnkgQVBJIChGRk0gQVBJKSBoYXMgeWV0PGJyPiZn
dDsmZ3Q7IHJlYWNoZWQgYm90dG9tLCBlc3BlY2lhbGx5IHdoZW4gaXQgY29tZXMgdG8gbWFuYWdp
bmcgdGhlIGxpZmV0aW1lPGJyPiZndDsmZ3Q7IG9mIHRoZSByZWdpb25zIG9mIG1lbW9yeSBiYWNr
aW5nIG1lbW9yeSBzZWdtZW50cy4gQWZ0ZXIgY29sbGVjdGluZzxicj4mZ3Q7Jmd0OyBzb21lIHJv
dW5kcyBvZiBpbnRlcm5hbCBhbmQgZXh0ZXJuYWwgZmVlZGJhY2ssIGl0IHdhcyBjbGVhciB0aGF0
PGJyPiZndDsmZ3Q7IHdoaWxlIHRoZSBKYXZhIDIwIEFQSSBoYXMgYWxsIHRoZSBmdW5jdGlvbmFs
aXRpZXMgd2UgcmVxdWlyZSBmb3I8YnI+Jmd0OyZndDsgd3JpdGluZyBlZmZpY2llbnQgYW5kIHJv
YnVzdCBuYXRpdmUgaW50ZXJvcCBjb2RlLCBzb21lIG9mIHRoZTxicj4mZ3Q7Jmd0OyBjb25jZXB0
cyBpbiB0aGUgQVBJIHdlcmUgbWFkZSBhIGJpdCBoYXJkZXIgdG8gZ3JvaywgYXMgdXNlcnMgaGFk
IHRvPGJyPiZndDsmZ3Q7IGNob29zZSBiZXR3ZWVuIHR3byB0b3BsZXZlbCBhYnN0cmFjdGlvbnMs
IG5hbWVseSBgU2VnbWVudFNjb3BlYCBhbmQ8YnI+Jmd0OyZndDsgYEFyZW5hYC4gVGhpcyBjaG9p
Y2UgaXMgbWFkZSBldmVuIG1vcmUgZGlmZmljdWx0LCBhcyBzb21lIG9mIHRoZTxicj4mZ3Q7Jmd0
OyBmdW5jdGlvbmFsaXRpZXMgKGUuZy4gYWxsb2NhdGlvbikgaXMgZHVwbGljYXRlZCBpbiBib3Ro
IEFQSSBwb2ludHMuPGJyPiZndDsmZ3Q7IEFzIGEgcmVzdWx0LCB3ZSBoYXZlIGJlZW4gYnVzeSBl
eHBsb3JpbmcgZGlmZmVyZW50IHdheXMgdG8gcmVzdGFjazxicj4mZ3Q7Jmd0OyB0aGUgRkZNIEFQ
SSBpbiBzZWFyY2ggb2Ygc29tZXRoaW5nIG1vcmUgYXBwcm9hY2hhYmxlLjxicj4mZ3Q7Jmd0OyA8
YnI+Jmd0OyZndDsgVGhlIHJlc3VsdHMgb2Ygb3VyIGZpbmRpbmdzIGFyZSBkZXNjcmliZWQgaW4g
dGhpcyBkb2N1bWVudDo8YnI+Jmd0OyZndDsgPGJyPiZndDsmZ3Q7IGh0dHA6Ly9jci5vcGVuamRr
LmphdmEubmV0L35tY2ltYWRhbW9yZS9wYW5hbWEvc2NvcGVkX2FyZW5hcy5odG1sPGJyPiZndDsm
Z3Q7IDxicj4mZ3Q7Jmd0OyBIZXJlLCB3ZSBwcm9wb3NlIGEgcG9zc2libGUgc2ltcGxpZmljYXRp
b24gb2YgdGhlIEZGTSBBUEksIHdoZXJlIHdlPGJyPiZndDsmZ3Q7IG1ha2UgYEFyZW5hYCB0aGUg
dHJ1ZSBzdGFyIG9mIHRoZSBzaG93LCB3aGljaCByZXN1bHRzIGluIHRoZTxicj4mZ3Q7Jmd0OyBm
b2xsb3dpbmcgY2hhbmdlczo8YnI+Jmd0OyZndDsgPGJyPiZndDsmZ3Q7ICogZmFjdG9yaWVzIHN1
Y2ggYXMgYFNlZ21lbnRTY29wZTo6YXV0b2AgYXJlIG5vdyBtb3ZlZCB0byBgQXJlbmFgOyA8YnI+
Jmd0OyZndDsgKiBhbGwgc2VnbWVudC1wcm9kdWNpbmcgbWV0aG9kcyAoc3VjaCBhcyBgRmlsZUNo
YW5uZWw6Om1hcGApIG5vdzxicj4mZ3Q7Jmd0OyBhY2NlcHQgYW4gYEFyZW5hYCBwYXJhbWV0ZXI7
ICogc3RhdGljIGZhY3RvcmllcyBzdWNoIGFzPGJyPiZndDsmZ3Q7IGBNZW1vcnlTZWdtZW50Ojph
bGxvY2F0ZU5hdGl2ZWAgaGF2ZSBiZWVuIGRyb3BwZWQ7ICogc2NvcGVzIGFyZTxicj4mZ3Q7Jmd0
OyBtYWRlIGxlc3MgcHJvbWluZW50LCBhbmQgbW92ZWQgdG8gYSBuZXN0ZWQgY2xhc3M8YnI+Jmd0
OyZndDsgKGBNZW1vcnlTZWdtZW50LlNjb3BlYCkuPGJyPiZndDsmZ3Q7IDxicj4mZ3Q7Jmd0OyBU
aGlzIGdpdmVzIHVzIGEgcmVtYXJrYWJseSBzaW1wbGUgQVBJLCB3aGljaCBicmluZ3MgdG9nZXRo
ZXIgdGhlPGJyPiZndDsmZ3Q7IGJlc3QgYXNwZWN0cyBvZiB0aGUgSmF2YSAxOSBhbmQgSmF2YSAy
MCBGRk0gQVBJIGl0ZXJhdGlvbnMuIE9uIHRoZTxicj4mZ3Q7Jmd0OyBvbmUgaGFuZCwgYEFyZW5h
YCBpcyBub3cgdGhlIG1vc3QgaW1wb3J0YW50IGFic3RyYWN0aW9uIHRoYXQgdXNlcnM8YnI+Jmd0
OyZndDsgb2YgdGhlIEZGTSBBUEkgaGF2ZSB0byBkZWFsIHdpdGggKGluIGEgd2F5LCBgQXJlbmFg
IGlzIHRoZSBuZXc8YnI+Jmd0OyZndDsgYE1lbW9yeVNlc3Npb25gKTsgYXQgdGhlIHNhbWUgdGlt
ZSwgd2Ugc3RpbGwgaGF2ZSBhIHdheSB0byBtb2RlbDxicj4mZ3Q7Jmd0OyB0aGUgbGlmZXRpbWUg
b2YgYW4gYEFyZW5hYCAoYW5kIGFsbCB0aGUgc2VnbWVudHMgYWxsb2NhdGVkIGJ5IGl0KTxicj4m
Z3Q7Jmd0OyB1c2luZyBhIGBNZW1vcnlTZWdtZW50LlNjb3BlYCAtIHdoaWNoIGlzIGRlc2lyYWJs
ZSBib3RoIGluIHRlcm1zIG9mPGJyPiZndDsmZ3Q7IGRlYnVnZ2luZyAoZS5nLiBpbnNwZWN0aW5n
IHdoZXRoZXIgdHdvIHNlZ21lbnRzL2FyZW5hcyBoYXZlIHRoZTxicj4mZ3Q7Jmd0OyBzYW1lIGxp
ZmV0aW1lKSBhbmQsIG1vcmUgaW1wb3J0YW50bHksIGluIHRlcm1zIG9mIGFsbG93aW5nIHRoZTxi
cj4mZ3Q7Jmd0OyBkZWZpbml0aW9uIG9mIGN1c3RvbSBhcmVuYXMgdmlhIHNpbXBsZSBkZWxlZ2F0
aW9uIChhcyBpbiBKYXZhIDIwKS48YnI+Jmd0OyZndDsgPGJyPiZndDsmZ3Q7IEFzIGFsd2F5cywg
ZmVlZGJhY2sgaXMgd2VsY29tZS4gV2hpbGUgdGhpcyBwcm9wb3NhbCBkb2VzIG5vdDxicj4mZ3Q7
Jmd0OyBzaWduaWZpY2FudGx5IGFsdGVyIHRoZSBleHByZXNzaXZlbmVzcyBvZiB0aGUgRkZNIEFQ
SSwgdGhlIHByb3Bvc2VkPGJyPiZndDsmZ3Q7IEFQSSBjb21lcyB3aXRoIHNvbWUgbGltaXRhdGlv
bnMuIEZvciBpbnN0YW5jZSwgc2luY2UgYWxsIGFsbG9jYXRpb248YnI+Jmd0OyZndDsgcm91dGlu
ZXMgYXJlIG5vdyBgQXJlbmFgLWNlbnRyaWMgKHNlZSBhYm92ZSksIGl0IGlzIG5vIGxvbmdlcjxi
cj4mZ3Q7Jmd0OyBwb3NzaWJsZSB0byBhbGxvY2F0ZSBhIG5ldyBzZWdtZW50IGlmIGEgY29ycmVz
cG9uZGluZyBhcmVuYSBpcyBub3Q8YnI+Jmd0OyZndDsgYXZhaWxhYmxlICh3ZSBjYWxsIHRoaXMg
Y28tYWxsb2NhdGlvbikuIEFzIGV4cGxhaW5lZCBpbiB0aGU8YnI+Jmd0OyZndDsgZG9jdW1lbnQs
IHdoaWxlIGl0IHdvdWxkIGJlIHBvc3NpYmxlIHRvIGFkZCBiYWNrIHRoZSBtaXNzaW5nPGJyPiZn
dDsmZ3Q7IGNvLWFsbG9jYXRpb24gZnVuY3Rpb25hbGl0eSwgZXh0ZW5zaXZlIGFuYWx5c2lzIG9m
IHRoZSBjb2RlIHVzaW5nPGJyPiZndDsmZ3Q7IHRoZSBGRk0gQVBJIGhhcyBzaG93biBjby1hbGxv
Y2F0aW9uIHRvIGJlIF9leHRyZW1lbHlfIHJhcmUgKCoqKSAtPGJyPiZndDsmZ3Q7IGFuZCBvZiBk
dWJpb3VzIHZhbHVlLiBGb3IgdGhlc2UgcmVhc29ucywgd2Ugd291bGQgbGlrZSB0byBhaW0gZm9y
IGE8YnI+Jmd0OyZndDsgbW9yZSBwcmluY2lwbGVkIGFwcHJvYWNoIHdoaWNoIGF2b2lkcyBjby1h
bGxvY2F0aW9uIGFsdG9nZXRoZXIsIGFuZDxicj4mZ3Q7Jmd0OyBhbGxvd3MgZm9yIG1vcmUgZW5j
YXBzdWxhdGlvbiBvZiB0aGUgY2FwYWJpbGl0aWVzIGFzc29jaWF0ZWQgd2l0aDxicj4mZ3Q7Jmd0
OyBhbiBgQXJlbmFgIG9iamVjdC48YnI+Jmd0OyZndDsgPGJyPiZndDsmZ3Q7IE1hdXJpemlvPGJy
PiZndDsmZ3Q7IDxicj4mZ3Q7Jmd0OyAoKiopIFdlIGhhdmUgb25seSBmb3VuZCBfb25lXyB1c2Fn
ZSBbMl0gaW4gb3ZlciAxMEsgSmF2YSBmaWxlcyBhbmQ8YnI+Jmd0OyZndDsgbW9yZSB0aGFuIDEx
TSBMb0MgYW5hbHl6ZWQuIE1vcmVvdmVyLCB0aGlzIHVzYWdlIGlzIG9ubHkgcHJlc2VudCBpbjxi
cj4mZ3Q7Jmd0OyB0aGUgSmF2YSAxOSBicmFuY2ggb2YgdGhlIHByb2plY3QsIGFuZCByZW1vdmVk
IGluIHRoZSAibWFpbiIgYnJhbmNoPGJyPiZndDsmZ3Q7ICh3aGljaCB0cmFja3MgdGhlIEphdmEg
MjAgRkZNIEFQSSkuIFdlIHN1c3BlY3QgdGhhdCB0aGlzIHVzZSBvZjxicj4mZ3Q7Jmd0OyBjby1h
bGxvY2F0aW9uIGhhcyBiZWVuIG1hZGUgaXJyZWxldmFudCBhZnRlciB0aGUgdW5pZmljYXRpb24g
b2Y8YnI+Jmd0OyZndDsgYE1lbW9yeUFkZHJlc3NgIGFuZCBgTWVtb3J5U2VnbWVudGAuPGJyPiZn
dDsmZ3Q7IDxicj4mZ3Q7Jmd0OyBbMV0gLTxicj4mZ3Q7Jmd0OyBodHRwczovL21haWwub3Blbmpk
ay5vcmcvcGlwZXJtYWlsL3BhbmFtYS1kZXYvMjAyMi1EZWNlbWJlci8wMTgxODIuaHRtbDxicj4m
Z3Q7Jmd0Ozxicj4mZ3Q7Jmd0OyA8YnI+PC9zcGFuPlsyXSAtIGh0dHBzOi8vdXJsZGVmZW5zZS5j
b20vdjMvX19odHRwczovL2dpdGh1Yi5jb20vYm91bGRlci1vbi9KUGFzc3BvcnQvYmxvYi9KYXZh
XzE5L2pwYXNzcG9ydC9zcmMvbWFpbi9qYXZhL2pwYXNzcG9ydC9VdGlscy5qYXZhKkw0MThfXztJ
dyEhQUNXVjVOOU0yUlY5OWhRIU44M2xVa3hzTHQwLTUyREoyOGlGdHlnaGtWWVRCcmtJcXBiYV9T
X3JIcC1MZ2tPalMxMVhIRTJhTlIwLTR0NzdVX1MzVXFQX0hVLUsxdHVmZUxSaGZRcyQgPGJyPjxz
cGFuIHN0eWxlPSJ3aGl0ZS1zcGFjZTogcHJlLXdyYXA7IGRpc3BsYXk6IGJsb2NrOyB3aWR0aDog
OTh2dzsiPiZndDsmZ3Q7IDxicj4mZ3Q7Jmd0OyA8YnI+Jmd0OyZndDsgPGJyPiZndDsmZ3Q7IDxi
        cj4mZ3Q7Jmd0OyA8YnI+Jmd0OyZndDsgPGJyPjwvc3Bhbj48YnI+" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0;">​</div>
    </div>
  </body>
</html>